Compare commits
1 Commits
chore/fix-
...
chore/fix-
| Author | SHA1 | Date | |
|---|---|---|---|
| 4dec9e182b |
@@ -37,75 +37,71 @@ jobs:
|
|||||||
node --version
|
node --version
|
||||||
npm --version
|
npm --version
|
||||||
|
|
||||||
- name: Checkout (from event.json, no external actions)
|
- name: Checkout (push or workflow_dispatch, no external actions)
|
||||||
|
env:
|
||||||
|
EVENT_JSON: /var/run/act/workflow/event.json
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
EVENT_JSON="/var/run/act/workflow/event.json"
|
|
||||||
test -f "$EVENT_JSON" || { echo "❌ Missing $EVENT_JSON"; exit 1; }
|
test -f "$EVENT_JSON" || { echo "❌ Missing $EVENT_JSON"; exit 1; }
|
||||||
|
|
||||||
# Node prints REPO_URL, DEFAULT_BRANCH, REF, SHA_CAND (may be empty in workflow_dispatch)
|
# Write /tmp/deploy.env with shell-safe quoting (NO eval)
|
||||||
OUT="$(node --input-type=module -e '
|
node --input-type=module <<'NODE'
|
||||||
import fs from "node:fs";
|
import fs from "node:fs";
|
||||||
const ev = JSON.parse(fs.readFileSync(process.env.EVENT_JSON,"utf8"));
|
|
||||||
|
|
||||||
const repoObj = ev?.repository || {};
|
const ev = JSON.parse(fs.readFileSync(process.env.EVENT_JSON, "utf8"));
|
||||||
const repo =
|
const repoObj = ev?.repository || {};
|
||||||
repoObj?.clone_url ||
|
|
||||||
(repoObj?.html_url ? (repoObj.html_url.replace(/\/$/,"") + ".git") : "");
|
|
||||||
|
|
||||||
if (!repo) throw new Error("No repository url in event.json");
|
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";
|
const defaultBranch = repoObj?.default_branch || "main";
|
||||||
|
|
||||||
const ref =
|
// On push, act/Gitea usually provides GITHUB_SHA; on workflow_dispatch it may be empty.
|
||||||
ev?.ref || `refs/heads/${defaultBranch}`;
|
const sha =
|
||||||
|
(process.env.GITHUB_SHA && String(process.env.GITHUB_SHA).trim()) ||
|
||||||
|
ev?.after ||
|
||||||
|
ev?.sha ||
|
||||||
|
ev?.head_commit?.id ||
|
||||||
|
ev?.pull_request?.head?.sha ||
|
||||||
|
"";
|
||||||
|
|
||||||
const sha =
|
const shq = (s) => "'" + String(s).replace(/'/g, "'\\''") + "'";
|
||||||
ev?.after ||
|
|
||||||
ev?.pull_request?.head?.sha ||
|
|
||||||
ev?.head_commit?.id ||
|
|
||||||
ev?.sha ||
|
|
||||||
"";
|
|
||||||
|
|
||||||
process.stdout.write(
|
const out = [
|
||||||
`REPO_URL=${JSON.stringify(repo)}\n` +
|
`REPO_URL=${shq(cloneUrl)}`,
|
||||||
`DEFAULT_BRANCH=${JSON.stringify(defaultBranch)}\n` +
|
`DEFAULT_BRANCH=${shq(defaultBranch)}`,
|
||||||
`REF=${JSON.stringify(ref)}\n` +
|
`SHA=${shq(sha)}`
|
||||||
`SHA_CAND=${JSON.stringify(sha)}\n`
|
].join("\n") + "\n";
|
||||||
);
|
|
||||||
' EVENT_JSON="$EVENT_JSON")" || { echo "❌ Cannot parse event.json"; exit 1; }"
|
|
||||||
|
|
||||||
eval "$OUT"
|
fs.writeFileSync("/tmp/deploy.env", out);
|
||||||
|
process.stdout.write(out);
|
||||||
|
NODE
|
||||||
|
|
||||||
echo "Repo URL: $REPO_URL"
|
source /tmp/deploy.env
|
||||||
echo "Default branch: $DEFAULT_BRANCH"
|
|
||||||
echo "Ref: $REF"
|
echo "Repo URL: $REPO_URL"
|
||||||
echo "SHA candidate: ${SHA_CAND:-<empty>}"
|
echo "Default branch: $DEFAULT_BRANCH"
|
||||||
|
echo "SHA: ${SHA:-<empty>}"
|
||||||
|
|
||||||
rm -rf .git
|
rm -rf .git
|
||||||
git init -q
|
git init -q
|
||||||
git remote add origin "$REPO_URL"
|
git remote add origin "$REPO_URL"
|
||||||
|
|
||||||
if [[ -n "${SHA_CAND:-}" ]]; then
|
if [[ -n "${SHA:-}" ]]; then
|
||||||
echo "Checkout by SHA: $SHA_CAND"
|
git fetch --depth 1 origin "$SHA"
|
||||||
git fetch --depth 1 origin "$SHA_CAND"
|
|
||||||
git -c advice.detachedHead=false checkout -q FETCH_HEAD
|
git -c advice.detachedHead=false checkout -q FETCH_HEAD
|
||||||
else
|
else
|
||||||
# workflow_dispatch often has no SHA; fetch by ref/branch
|
# workflow_dispatch fallback: checkout latest of default branch
|
||||||
REF_TO_FETCH="$REF"
|
git fetch --depth 1 origin "$DEFAULT_BRANCH"
|
||||||
if [[ "$REF_TO_FETCH" == refs/heads/* ]]; then
|
git -c advice.detachedHead=false checkout -q "origin/$DEFAULT_BRANCH"
|
||||||
REF_TO_FETCH="${REF_TO_FETCH#refs/heads/}"
|
SHA="$(git rev-parse HEAD)"
|
||||||
fi
|
echo "SHA='$SHA'" >> /tmp/deploy.env
|
||||||
echo "Checkout by ref: $REF_TO_FETCH"
|
echo "Resolved SHA: $SHA"
|
||||||
git fetch --depth 1 origin "$REF_TO_FETCH"
|
|
||||||
git -c advice.detachedHead=false checkout -q FETCH_HEAD
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
SHA="$(git rev-parse HEAD)"
|
|
||||||
git log -1 --oneline
|
git log -1 --oneline
|
||||||
echo "SHA=$SHA" >> /tmp/deploy.env
|
|
||||||
echo "REPO_URL=$REPO_URL" >> /tmp/deploy.env
|
|
||||||
echo "DEFAULT_BRANCH=$DEFAULT_BRANCH" >> /tmp/deploy.env
|
|
||||||
|
|
||||||
- name: Gate — auto deploy only on annotations/media changes
|
- name: Gate — auto deploy only on annotations/media changes
|
||||||
env:
|
env:
|
||||||
@@ -121,19 +117,9 @@ jobs:
|
|||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Robust changed-files list (merge commits included)
|
CHANGED="$(git show --name-only --pretty="" "$SHA" | sed '/^$/d' || true)"
|
||||||
# Prefer diff vs first parent; fallback to git show.
|
|
||||||
if git rev-parse "${SHA}^" >/dev/null 2>&1; then
|
|
||||||
CHANGED="$(git diff --name-only "${SHA}^" "$SHA" || true)"
|
|
||||||
else
|
|
||||||
CHANGED=""
|
|
||||||
fi
|
|
||||||
if [[ -z "$CHANGED" ]]; then
|
|
||||||
CHANGED="$(git show --name-only --pretty="" -m "$SHA" | sed '/^$/d' || true)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "== changed files =="
|
echo "== changed files =="
|
||||||
echo "$CHANGED" | sed -n '1,200p'
|
echo "$CHANGED" | sed -n '1,240p'
|
||||||
|
|
||||||
if echo "$CHANGED" | grep -qE '^(src/annotations/|public/media/)'; then
|
if echo "$CHANGED" | grep -qE '^(src/annotations/|public/media/)'; then
|
||||||
echo "GO=1" >> /tmp/deploy.env
|
echo "GO=1" >> /tmp/deploy.env
|
||||||
@@ -149,9 +135,6 @@ jobs:
|
|||||||
source /tmp/deploy.env
|
source /tmp/deploy.env
|
||||||
[[ "${GO:-0}" == "1" ]] || { echo "ℹ️ skipped"; exit 0; }
|
[[ "${GO:-0}" == "1" ]] || { echo "ℹ️ skipped"; exit 0; }
|
||||||
|
|
||||||
# Must have docker socket mounted by runner
|
|
||||||
test -S /var/run/docker.sock || { echo "❌ /var/run/docker.sock missing in job container"; exit 10; }
|
|
||||||
|
|
||||||
apt-get -o Acquire::Retries=5 -o Acquire::ForceIPv4=true update
|
apt-get -o Acquire::Retries=5 -o Acquire::ForceIPv4=true update
|
||||||
apt-get install -y --no-install-recommends ca-certificates curl docker.io
|
apt-get install -y --no-install-recommends ca-certificates curl docker.io
|
||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
@@ -202,13 +185,12 @@ jobs:
|
|||||||
[[ "${GO:-0}" == "1" ]] || { echo "ℹ️ skipped"; exit 0; }
|
[[ "${GO:-0}" == "1" ]] || { echo "ℹ️ skipped"; exit 0; }
|
||||||
|
|
||||||
TS="$(date -u +%Y%m%d-%H%M%S)"
|
TS="$(date -u +%Y%m%d-%H%M%S)"
|
||||||
echo "TS=$TS" >> /tmp/deploy.env
|
echo "TS='$TS'" >> /tmp/deploy.env
|
||||||
|
|
||||||
docker image tag archicratie-web:blue "archicratie-web:blue.BAK.${TS}" || true
|
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 image tag archicratie-web:green "archicratie-web:green.BAK.${TS}" || true
|
||||||
|
|
||||||
docker compose build --no-cache web_blue
|
docker compose -f docker-compose.yml build --no-cache web_blue
|
||||||
docker compose up -d --force-recreate web_blue
|
docker compose -f docker-compose.yml up -d --force-recreate web_blue
|
||||||
|
|
||||||
curl -fsS "http://127.0.0.1:8081/para-index.json" >/dev/null
|
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
|
curl -fsS "http://127.0.0.1:8081/annotations-index.json" >/dev/null
|
||||||
@@ -216,7 +198,9 @@ jobs:
|
|||||||
|
|
||||||
CANON="$(curl -fsS "http://127.0.0.1:8081/archicrat-ia/chapitre-1/" | grep -oE 'rel="canonical" href="[^"]+"' | head -n1 || true)"
|
CANON="$(curl -fsS "http://127.0.0.1:8081/archicrat-ia/chapitre-1/" | grep -oE 'rel="canonical" href="[^"]+"' | head -n1 || true)"
|
||||||
echo "canonical(blue)=$CANON"
|
echo "canonical(blue)=$CANON"
|
||||||
echo "$CANON" | grep -q 'https://staging\.archicratie\.trans-hands\.synology\.me/' || { echo "❌ staging canonical mismatch"; exit 3; }
|
echo "$CANON" | grep -q 'https://staging\.archicratie\.trans-hands\.synology\.me/' || {
|
||||||
|
echo "❌ staging canonical mismatch"; exit 3;
|
||||||
|
}
|
||||||
|
|
||||||
echo "✅ staging OK"
|
echo "✅ staging OK"
|
||||||
|
|
||||||
@@ -235,25 +219,22 @@ jobs:
|
|||||||
rollback() {
|
rollback() {
|
||||||
echo "⚠️ rollback green -> previous image tag (best effort)"
|
echo "⚠️ rollback green -> previous image tag (best effort)"
|
||||||
docker image tag "archicratie-web:green.BAK.${TS}" archicratie-web:green || true
|
docker image tag "archicratie-web:green.BAK.${TS}" archicratie-web:green || true
|
||||||
docker compose up -d --force-recreate web_green || true
|
docker compose -f docker-compose.yml up -d --force-recreate web_green || true
|
||||||
}
|
}
|
||||||
|
|
||||||
set +e
|
set +e
|
||||||
docker compose build --no-cache web_green
|
docker compose -f docker-compose.yml build --no-cache web_green
|
||||||
BRC=$?
|
docker compose -f docker-compose.yml up -d --force-recreate web_green
|
||||||
[[ "$BRC" -eq 0 ]] || { echo "❌ build green failed"; rollback; exit 4; }
|
|
||||||
|
|
||||||
docker compose up -d --force-recreate web_green
|
curl -fsS "http://127.0.0.1:8082/para-index.json" >/dev/null
|
||||||
URC=$?
|
curl -fsS "http://127.0.0.1:8082/annotations-index.json" >/dev/null
|
||||||
[[ "$URC" -eq 0 ]] || { echo "❌ up green failed"; rollback; exit 4; }
|
curl -fsS "http://127.0.0.1:8082/pagefind/pagefind.js" >/dev/null
|
||||||
|
|
||||||
curl -fsS "http://127.0.0.1:8082/para-index.json" >/dev/null || { rollback; exit 4; }
|
|
||||||
curl -fsS "http://127.0.0.1:8082/annotations-index.json" >/dev/null || { rollback; exit 4; }
|
|
||||||
curl -fsS "http://127.0.0.1:8082/pagefind/pagefind.js" >/dev/null || { rollback; exit 4; }
|
|
||||||
|
|
||||||
CANON="$(curl -fsS "http://127.0.0.1:8082/archicrat-ia/chapitre-1/" | grep -oE 'rel="canonical" href="[^"]+"' | head -n1 || true)"
|
CANON="$(curl -fsS "http://127.0.0.1:8082/archicrat-ia/chapitre-1/" | grep -oE 'rel="canonical" href="[^"]+"' | head -n1 || true)"
|
||||||
echo "canonical(green)=$CANON"
|
echo "canonical(green)=$CANON"
|
||||||
echo "$CANON" | grep -q 'https://archicratie\.trans-hands\.synology\.me/' || { echo "❌ live canonical mismatch"; rollback; exit 4; }
|
echo "$CANON" | grep -q 'https://archicratie\.trans-hands\.synology\.me/' || {
|
||||||
|
echo "❌ live canonical mismatch"; rollback; exit 4;
|
||||||
|
}
|
||||||
|
|
||||||
echo "✅ live OK"
|
echo "✅ live OK"
|
||||||
set -e
|
set -e
|
||||||
Reference in New Issue
Block a user