fix build issue
Build & Push / Pipeline Tests (push) Successful in 1m47s
Test / Type Check (all packages) (push) Successful in 55s
Build & Push / Build & Push Docker Image (push) Failing after 34s
Test / API Unit Tests (push) Successful in 1m9s
Test / Homepage Unit Tests (push) Successful in 49s
Test / Carplace Unit Tests (push) Successful in 45s
Test / Admin Unit Tests (push) Successful in 44s
Test / Dashboard Unit Tests (push) Successful in 44s
Test / API Integration Tests (push) Successful in 1m10s
Build & Push / Pipeline Tests (push) Successful in 1m47s
Test / Type Check (all packages) (push) Successful in 55s
Build & Push / Build & Push Docker Image (push) Failing after 34s
Test / API Unit Tests (push) Successful in 1m9s
Test / Homepage Unit Tests (push) Successful in 49s
Test / Carplace Unit Tests (push) Successful in 45s
Test / Admin Unit Tests (push) Successful in 44s
Test / Dashboard Unit Tests (push) Successful in 44s
Test / API Integration Tests (push) Successful in 1m10s
This commit is contained in:
@@ -447,101 +447,18 @@ jobs:
|
|||||||
ENV_DOCKER_PRODUCTION_RAW_B64="$(printf '%s' "$ENV_DOCKER_PRODUCTION" | base64 | tr -d '\n')"
|
ENV_DOCKER_PRODUCTION_RAW_B64="$(printf '%s' "$ENV_DOCKER_PRODUCTION" | base64 | tr -d '\n')"
|
||||||
STRIPE_API_KEY_B64="$(printf '%s' "$STRIPE_API_KEY" | base64 | tr -d '\n')"
|
STRIPE_API_KEY_B64="$(printf '%s' "$STRIPE_API_KEY" | base64 | tr -d '\n')"
|
||||||
STRIPE_WEBHOOK_SECRET_B64="$(printf '%s' "$STRIPE_WEBHOOK_SECRET" | base64 | tr -d '\n')"
|
STRIPE_WEBHOOK_SECRET_B64="$(printf '%s' "$STRIPE_WEBHOOK_SECRET" | base64 | tr -d '\n')"
|
||||||
validate_stripe_secret_inputs() {
|
|
||||||
local env_file stripe_api_key stripe_webhook_secret
|
|
||||||
|
|
||||||
env_file="$(mktemp)"
|
|
||||||
trap 'rm -f "$env_file"' EXIT
|
|
||||||
|
|
||||||
if [ -n "$ENV_DOCKER_PRODUCTION_B64_CLEAN" ]; then
|
|
||||||
if ! printf '%s' "$ENV_DOCKER_PRODUCTION_B64_CLEAN" | base64 -d > "$env_file"; then
|
|
||||||
echo "::error::ENV_DOCKER_PRODUCTION_B64 is not valid base64"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
elif [ -n "$ENV_DOCKER_PRODUCTION" ]; then
|
|
||||||
printf '%s' "$ENV_DOCKER_PRODUCTION" > "$env_file"
|
|
||||||
else
|
|
||||||
: > "$env_file"
|
|
||||||
fi
|
|
||||||
|
|
||||||
read_env_key() {
|
|
||||||
local key="$1"
|
|
||||||
awk -F= -v key="$key" '
|
|
||||||
/^[[:space:]]*#/ || index($0, "=") == 0 {
|
|
||||||
next
|
|
||||||
}
|
|
||||||
{
|
|
||||||
name = $1
|
|
||||||
sub(/^[[:space:]]*export[[:space:]]+/, "", name)
|
|
||||||
gsub(/^[[:space:]]+|[[:space:]]+$/, "", name)
|
|
||||||
if (name == key) {
|
|
||||||
value = substr($0, index($0, "=") + 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
END {
|
|
||||||
print value
|
|
||||||
}
|
|
||||||
' "$env_file"
|
|
||||||
}
|
|
||||||
|
|
||||||
normalize_secret() {
|
|
||||||
local value="$1"
|
|
||||||
value="${value%$'\r'}"
|
|
||||||
value="${value#"${value%%[![:space:]]*}"}"
|
|
||||||
value="${value%"${value##*[![:space:]]}"}"
|
|
||||||
if [[ "$value" == \"*\" && "$value" == *\" ]]; then
|
|
||||||
value="${value#\"}"
|
|
||||||
value="${value%\"}"
|
|
||||||
elif [[ "$value" == \'*\' && "$value" == *\' ]]; then
|
|
||||||
value="${value#\'}"
|
|
||||||
value="${value%\'}"
|
|
||||||
fi
|
|
||||||
printf '%s' "$value"
|
|
||||||
}
|
|
||||||
|
|
||||||
stripe_api_key="$(normalize_secret "${STRIPE_API_KEY:-$(read_env_key STRIPE_API_KEY)}")"
|
|
||||||
stripe_webhook_secret="$(normalize_secret "${STRIPE_WEBHOOK_SECRET:-$(read_env_key STRIPE_WEBHOOK_SECRET)}")"
|
|
||||||
|
|
||||||
case "$stripe_api_key" in
|
|
||||||
sk_live_*|rk_live_*) ;;
|
|
||||||
"")
|
|
||||||
echo "::error::STRIPE_API_KEY is missing. Add a live sk_live_ or restricted rk_live_ key to the STRIPE_API_KEY secret, ENV_DOCKER_PRODUCTION, or ENV_DOCKER_PRODUCTION_B64."
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
placeholder|replace-with-*|*changeme*|*change-me*)
|
|
||||||
echo "::error::STRIPE_API_KEY is still a placeholder. Replace it with a live sk_live_ or restricted rk_live_ key in Gitea Actions secrets."
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "::error::STRIPE_API_KEY must start with sk_live_ or rk_live_ for production billing."
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
case "$stripe_webhook_secret" in
|
|
||||||
whsec_*) ;;
|
|
||||||
"")
|
|
||||||
echo "::error::STRIPE_WEBHOOK_SECRET is missing. Add the Stripe webhook signing secret to the STRIPE_WEBHOOK_SECRET secret, ENV_DOCKER_PRODUCTION, or ENV_DOCKER_PRODUCTION_B64."
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
placeholder|replace-with-*|*changeme*|*change-me*)
|
|
||||||
echo "::error::STRIPE_WEBHOOK_SECRET is still a placeholder. Replace it with the Stripe webhook signing secret in Gitea Actions secrets."
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "::error::STRIPE_WEBHOOK_SECRET must start with whsec_."
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
validate_stripe_secret_inputs
|
|
||||||
REGISTRY_USERNAME="${REGISTRY_USERNAME:-${REGISTRY_USER:-}}"
|
REGISTRY_USERNAME="${REGISTRY_USERNAME:-${REGISTRY_USER:-}}"
|
||||||
REGISTRY_PASSWORD="${REGISTRY_PASSWORD:-${REGISTRY_TOKEN:-}}"
|
REGISTRY_PASSWORD="${REGISTRY_PASSWORD:-${REGISTRY_TOKEN:-}}"
|
||||||
REGISTRY_PASSWORD_B64="$(printf '%s' "$REGISTRY_PASSWORD" | base64 | tr -d '\n')"
|
REGISTRY_PASSWORD_B64="$(printf '%s' "$REGISTRY_PASSWORD" | base64 | tr -d '\n')"
|
||||||
ssh $SSH_OPTIONS "${{ secrets.VPS_USER }}@$VPS_HOST" "
|
ssh $SSH_OPTIONS "${{ secrets.VPS_USER }}@$VPS_HOST" "
|
||||||
set -e
|
set -e
|
||||||
mkdir -p '$DEPLOY_ROOT' '$REMOTE_BUILD_DIR'
|
mkdir -p '$DEPLOY_ROOT' '$REMOTE_BUILD_DIR'
|
||||||
|
previous_env_file=''
|
||||||
|
if [ -f '$DEPLOY_ROOT/.env.docker.production' ]; then
|
||||||
|
previous_env_file=\"\$(mktemp)\"
|
||||||
|
cp '$DEPLOY_ROOT/.env.docker.production' \"\$previous_env_file\"
|
||||||
|
trap 'rm -f \"\$previous_env_file\"' EXIT
|
||||||
|
fi
|
||||||
if [ -n '$ENV_DOCKER_PRODUCTION_B64_CLEAN' ]; then
|
if [ -n '$ENV_DOCKER_PRODUCTION_B64_CLEAN' ]; then
|
||||||
printf '%s' '$ENV_DOCKER_PRODUCTION_B64_CLEAN' | base64 -d > '$DEPLOY_ROOT/.env.docker.production'
|
printf '%s' '$ENV_DOCKER_PRODUCTION_B64_CLEAN' | base64 -d > '$DEPLOY_ROOT/.env.docker.production'
|
||||||
chmod 600 '$DEPLOY_ROOT/.env.docker.production'
|
chmod 600 '$DEPLOY_ROOT/.env.docker.production'
|
||||||
@@ -557,9 +474,14 @@ jobs:
|
|||||||
cp '$DEPLOY_ROOT/.env.docker.production' '$REMOTE_BUILD_DIR/.env.docker.production'
|
cp '$DEPLOY_ROOT/.env.docker.production' '$REMOTE_BUILD_DIR/.env.docker.production'
|
||||||
chmod 600 '$REMOTE_BUILD_DIR/.env.docker.production'
|
chmod 600 '$REMOTE_BUILD_DIR/.env.docker.production'
|
||||||
cd '$REMOTE_BUILD_DIR'
|
cd '$REMOTE_BUILD_DIR'
|
||||||
|
if [ -n \"\$previous_env_file\" ]; then
|
||||||
|
bash scripts/preserve-env-values.sh \"\$previous_env_file\" .env.docker.production STRIPE_API_KEY STRIPE_WEBHOOK_SECRET
|
||||||
|
fi
|
||||||
export STRIPE_API_KEY_B64='$STRIPE_API_KEY_B64'
|
export STRIPE_API_KEY_B64='$STRIPE_API_KEY_B64'
|
||||||
export STRIPE_WEBHOOK_SECRET_B64='$STRIPE_WEBHOOK_SECRET_B64'
|
export STRIPE_WEBHOOK_SECRET_B64='$STRIPE_WEBHOOK_SECRET_B64'
|
||||||
bash scripts/apply-env-secret-overrides.sh .env.docker.production STRIPE_API_KEY STRIPE_WEBHOOK_SECRET
|
bash scripts/apply-env-secret-overrides.sh .env.docker.production STRIPE_API_KEY STRIPE_WEBHOOK_SECRET
|
||||||
|
cp .env.docker.production '$DEPLOY_ROOT/.env.docker.production'
|
||||||
|
chmod 600 '$DEPLOY_ROOT/.env.docker.production'
|
||||||
export APP_IMAGE='$DEPLOY_REGISTRY_HOST/$IMAGE_REPOSITORY'
|
export APP_IMAGE='$DEPLOY_REGISTRY_HOST/$IMAGE_REPOSITORY'
|
||||||
export IMAGE_TAG='$IMAGE_TAG'
|
export IMAGE_TAG='$IMAGE_TAG'
|
||||||
export REGISTRY_HOST='$DEPLOY_REGISTRY_HOST'
|
export REGISTRY_HOST='$DEPLOY_REGISTRY_HOST'
|
||||||
|
|||||||
@@ -174,6 +174,8 @@ Paste that single-line output into `ENV_DOCKER_PRODUCTION_B64` when using the ba
|
|||||||
|
|
||||||
You can also store `STRIPE_API_KEY` and `STRIPE_WEBHOOK_SECRET` as separate Gitea Actions secrets. When those secrets are present, the deploy workflow overwrites the Stripe values from `ENV_DOCKER_PRODUCTION`/`ENV_DOCKER_PRODUCTION_B64` before deploying. This is useful when the production env file secret still contains placeholders for billing secrets.
|
You can also store `STRIPE_API_KEY` and `STRIPE_WEBHOOK_SECRET` as separate Gitea Actions secrets. When those secrets are present, the deploy workflow overwrites the Stripe values from `ENV_DOCKER_PRODUCTION`/`ENV_DOCKER_PRODUCTION_B64` before deploying. This is useful when the production env file secret still contains placeholders for billing secrets.
|
||||||
|
|
||||||
|
If `/opt/rentaldrivego/.env.docker.production` already exists on the VPS and a newly supplied env-file secret omits `STRIPE_API_KEY` or `STRIPE_WEBHOOK_SECRET`, the deploy workflow preserves the existing VPS values for those keys. Final production validation still fails if the merged env file does not contain a live `sk_live_`/`rk_live_` key and a `whsec_` webhook signing secret.
|
||||||
|
|
||||||
Production now derives `DATABASE_URL` inside the app container from `POSTGRES_HOST`, `POSTGRES_PORT`, `POSTGRES_DB`, `POSTGRES_USER`, and `POSTGRES_PASSWORD` when `DATABASE_URL_FROM_POSTGRES=true`. That avoids Prisma auth failures when the database password contains reserved URL characters such as `@`, `:`, or `/`.
|
Production now derives `DATABASE_URL` inside the app container from `POSTGRES_HOST`, `POSTGRES_PORT`, `POSTGRES_DB`, `POSTGRES_USER`, and `POSTGRES_PASSWORD` when `DATABASE_URL_FROM_POSTGRES=true`. That avoids Prisma auth failures when the database password contains reserved URL characters such as `@`, `:`, or `/`.
|
||||||
|
|
||||||
The example file uses `rentaldrivego.ma` for the carplace and public site. The dashboard and admin panel are routed under that same host at `/dashboard` and `/admin`.
|
The example file uses `rentaldrivego.ma` for the carplace and public site. The dashboard and admin panel are routed under that same host at `/dashboard` and `/admin`.
|
||||||
|
|||||||
@@ -0,0 +1,117 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'EOF'
|
||||||
|
Usage:
|
||||||
|
preserve-env-values.sh <source-env-file> <target-env-file> <KEY> [KEY...]
|
||||||
|
|
||||||
|
For each KEY, copy the value from <source-env-file> into <target-env-file> only
|
||||||
|
when the target value is missing or still looks like a placeholder.
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ $# -lt 3 ]]; then
|
||||||
|
usage >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
source_env_file="$1"
|
||||||
|
target_env_file="$2"
|
||||||
|
shift 2
|
||||||
|
|
||||||
|
for env_file in "${source_env_file}" "${target_env_file}"; do
|
||||||
|
if [[ ! -f "${env_file}" ]]; then
|
||||||
|
echo "Missing env file: ${env_file}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
read_env_value() {
|
||||||
|
local env_file="$1"
|
||||||
|
local key="$2"
|
||||||
|
local value
|
||||||
|
|
||||||
|
value="$(
|
||||||
|
awk -F= -v key="${key}" '
|
||||||
|
/^[[:space:]]*#/ || index($0, "=") == 0 {
|
||||||
|
next
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = $1
|
||||||
|
sub(/^[[:space:]]*export[[:space:]]+/, "", name)
|
||||||
|
gsub(/^[[:space:]]+|[[:space:]]+$/, "", name)
|
||||||
|
if (name == key) {
|
||||||
|
value = substr($0, index($0, "=") + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
print value
|
||||||
|
}
|
||||||
|
' "${env_file}"
|
||||||
|
)"
|
||||||
|
|
||||||
|
value="${value%$'\r'}"
|
||||||
|
value="${value#"${value%%[![:space:]]*}"}"
|
||||||
|
value="${value%"${value##*[![:space:]]}"}"
|
||||||
|
if [[ "${value}" == \"*\" && "${value}" == *\" ]]; then
|
||||||
|
value="${value#\"}"
|
||||||
|
value="${value%\"}"
|
||||||
|
elif [[ "${value}" == \'*\' && "${value}" == *\' ]]; then
|
||||||
|
value="${value#\'}"
|
||||||
|
value="${value%\'}"
|
||||||
|
fi
|
||||||
|
printf '%s' "${value}"
|
||||||
|
}
|
||||||
|
|
||||||
|
should_preserve_value() {
|
||||||
|
local value="$1"
|
||||||
|
|
||||||
|
[[ -z "${value}" || "${value}" == placeholder || "${value}" == replace-with-* || "${value}" == *changeme* || "${value}" == *change-me* ]]
|
||||||
|
}
|
||||||
|
|
||||||
|
upsert_env_value() {
|
||||||
|
local key="$1"
|
||||||
|
local value="$2"
|
||||||
|
local tmp_file
|
||||||
|
|
||||||
|
tmp_file="$(mktemp "${target_env_file}.tmp.XXXXXX")"
|
||||||
|
awk -v key="${key}" -v value="${value}" '
|
||||||
|
BEGIN {
|
||||||
|
updated = 0
|
||||||
|
}
|
||||||
|
/^[[:space:]]*#/ || index($0, "=") == 0 {
|
||||||
|
print
|
||||||
|
next
|
||||||
|
}
|
||||||
|
{
|
||||||
|
name = $1
|
||||||
|
sub(/=.*/, "", name)
|
||||||
|
sub(/^[[:space:]]*export[[:space:]]+/, "", name)
|
||||||
|
gsub(/^[[:space:]]+|[[:space:]]+$/, "", name)
|
||||||
|
if (name == key) {
|
||||||
|
print key "=" value
|
||||||
|
updated = 1
|
||||||
|
next
|
||||||
|
}
|
||||||
|
print
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
if (!updated) {
|
||||||
|
print key "=" value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
' "${target_env_file}" > "${tmp_file}"
|
||||||
|
|
||||||
|
mv "${tmp_file}" "${target_env_file}"
|
||||||
|
}
|
||||||
|
|
||||||
|
for key in "$@"; do
|
||||||
|
source_value="$(read_env_value "${source_env_file}" "${key}")"
|
||||||
|
target_value="$(read_env_value "${target_env_file}" "${key}")"
|
||||||
|
|
||||||
|
if [[ -n "${source_value}" ]] && should_preserve_value "${target_value}"; then
|
||||||
|
upsert_env_value "${key}" "${source_value}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
Reference in New Issue
Block a user