From 0d5b790e52348941f7201628e88c1df29bd33916 Mon Sep 17 00:00:00 2001 From: Archicratia Date: Thu, 26 Feb 2026 18:48:12 +0100 Subject: [PATCH] ci: fix deploy checkout (no eval) + workflow_dispatch fallback --- .gitea/workflows/deploy-staging-live.yml | 45 ++++++++++++++---------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/.gitea/workflows/deploy-staging-live.yml b/.gitea/workflows/deploy-staging-live.yml index 8ac4a4d..0d2b475 100644 --- a/.gitea/workflows/deploy-staging-live.yml +++ b/.gitea/workflows/deploy-staging-live.yml @@ -44,21 +44,16 @@ jobs: set -euo pipefail test -f "$EVENT_JSON" || { echo "❌ Missing $EVENT_JSON"; exit 1; } - # Write /tmp/deploy.env with shell-safe quoting (NO eval) node --input-type=module <<'NODE' import fs from "node:fs"; - const ev = JSON.parse(fs.readFileSync(process.env.EVENT_JSON, "utf8")); const repoObj = ev?.repository || {}; - const cloneUrl = repoObj?.clone_url || (repoObj?.html_url ? (repoObj.html_url.replace(/\/$/,"") + ".git") : ""); if (!cloneUrl) throw new Error("No repository clone_url/html_url in event.json"); const defaultBranch = repoObj?.default_branch || "main"; - - // On push, act/Gitea usually provides GITHUB_SHA; on workflow_dispatch it may be empty. const sha = (process.env.GITHUB_SHA && String(process.env.GITHUB_SHA).trim()) || ev?.after || @@ -68,19 +63,14 @@ jobs: ""; const shq = (s) => "'" + String(s).replace(/'/g, "'\\''") + "'"; - - const out = [ + fs.writeFileSync("/tmp/deploy.env", [ `REPO_URL=${shq(cloneUrl)}`, `DEFAULT_BRANCH=${shq(defaultBranch)}`, `SHA=${shq(sha)}` - ].join("\n") + "\n"; - - fs.writeFileSync("/tmp/deploy.env", out); - process.stdout.write(out); + ].join("\n") + "\n"); NODE source /tmp/deploy.env - echo "Repo URL: $REPO_URL" echo "Default branch: $DEFAULT_BRANCH" echo "SHA: ${SHA:-}" @@ -93,7 +83,6 @@ jobs: git fetch --depth 1 origin "$SHA" git -c advice.detachedHead=false checkout -q FETCH_HEAD else - # workflow_dispatch fallback: checkout latest of default branch git fetch --depth 1 origin "$DEFAULT_BRANCH" git -c advice.detachedHead=false checkout -q "origin/$DEFAULT_BRANCH" SHA="$(git rev-parse HEAD)" @@ -148,6 +137,15 @@ jobs: docker version docker compose version + # đŸ”Ĩ KEY FIX: reuse existing compose project name if containers already exist + PROJ="$(docker inspect archicratie-web-blue --format '{{ index .Config.Labels "com.docker.compose.project" }}' 2>/dev/null || true)" + if [[ -z "${PROJ:-}" ]]; then + PROJ="$(docker inspect archicratie-web-green --format '{{ index .Config.Labels "com.docker.compose.project" }}' 2>/dev/null || true)" + fi + if [[ -z "${PROJ:-}" ]]; then PROJ="archicratie-web"; fi + echo "COMPOSE_PROJECT_NAME='$PROJ'" >> /tmp/deploy.env + echo "✅ Using COMPOSE_PROJECT_NAME=$PROJ" + - name: Assert required vars (PUBLIC_GITEA_*) env: PUBLIC_GITEA_BASE: ${{ vars.PUBLIC_GITEA_BASE }} @@ -183,14 +181,20 @@ jobs: set -euo pipefail source /tmp/deploy.env [[ "${GO:-0}" == "1" ]] || { echo "â„šī¸ skipped"; exit 0; } + PROJ="${COMPOSE_PROJECT_NAME:-archicratie-web}" TS="$(date -u +%Y%m%d-%H%M%S)" echo "TS='$TS'" >> /tmp/deploy.env docker image tag archicratie-web:blue "archicratie-web:blue.BAK.${TS}" || true docker image tag archicratie-web:green "archicratie-web:green.BAK.${TS}" || true - docker compose -f docker-compose.yml build --no-cache web_blue - docker compose -f docker-compose.yml up -d --force-recreate web_blue + # ✅ use cache (DO NOT --no-cache) + docker compose -p "$PROJ" -f docker-compose.yml build web_blue + + # ✅ hard fix: remove existing container if name conflicts + docker rm -f archicratie-web-blue || true + + docker compose -p "$PROJ" -f docker-compose.yml up -d --force-recreate --remove-orphans web_blue curl -fsS "http://127.0.0.1:8081/para-index.json" >/dev/null curl -fsS "http://127.0.0.1:8081/annotations-index.json" >/dev/null @@ -213,18 +217,21 @@ jobs: set -euo pipefail source /tmp/deploy.env [[ "${GO:-0}" == "1" ]] || { echo "â„šī¸ skipped"; exit 0; } - + PROJ="${COMPOSE_PROJECT_NAME:-archicratie-web}" TS="${TS:-$(date -u +%Y%m%d-%H%M%S)}" rollback() { echo "âš ī¸ rollback green -> previous image tag (best effort)" docker image tag "archicratie-web:green.BAK.${TS}" archicratie-web:green || true - docker compose -f docker-compose.yml up -d --force-recreate web_green || true + docker rm -f archicratie-web-green || true + docker compose -p "$PROJ" -f docker-compose.yml up -d --force-recreate --remove-orphans web_green || true } set +e - docker compose -f docker-compose.yml build --no-cache web_green - docker compose -f docker-compose.yml up -d --force-recreate web_green + docker compose -p "$PROJ" -f docker-compose.yml build web_green + + docker rm -f archicratie-web-green || true + docker compose -p "$PROJ" -f docker-compose.yml up -d --force-recreate --remove-orphans web_green curl -fsS "http://127.0.0.1:8082/para-index.json" >/dev/null curl -fsS "http://127.0.0.1:8082/annotations-index.json" >/dev/null