name: Deploy health (daily drift check) # Gitea rewrite of .github/workflows/deploy-health.yml. GitHub's version read # GitHub Deployment objects, which Gitea does not have. This one compares what is # ACTUALLY on the server: the deploy composite action stamps # ~/.peptide-deploys/production/ with the deployed commit, and this job # compares that stamp with each repo's main HEAD. Drift (or a missing stamp after # cutover) opens one issue in peptide-e2e; it never opens duplicates. on: schedule: - cron: '0 13 * * *' # 21:00 SGT, same slot as the GitHub job workflow_dispatch: {} jobs: drift: name: Compare deployed commit with main runs-on: peptide-vps steps: - uses: actions/checkout@v4 - name: Check every deployable repo shell: bash env: TOKEN: ${{ secrets.GITHUB_TOKEN }} SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }} SSH_HOST: ${{ secrets.SSH_HOST }} SSH_PORT: ${{ secrets.SSH_PORT }} SSH_USERNAME: ${{ secrets.SSH_USERNAME }} PROD_ENABLED: ${{ vars.PROD_DEPLOY_ENABLED }} run: | set -euo pipefail WORK=$(mktemp -d); trap 'rm -rf "$WORK"' EXIT printf '%s\n' "$SSH_PRIVATE_KEY" > "$WORK/key"; chmod 600 "$WORK/key" ssh-keyscan -p "$SSH_PORT" "$SSH_HOST" > "$WORK/kh" 2>/dev/null || true SSHOPT="-n -i $WORK/key -p $SSH_PORT -o UserKnownHostsFile=$WORK/kh -o StrictHostKeyChecking=accept-new -o ConnectTimeout=30 -o BatchMode=yes" API="$GITHUB_SERVER_URL/api/v1"; H="Authorization: token $TOKEN" problems="" for row in $(python3 -c 'import json; d=json.load(open("tools/gitea-pipeline/repos.json")); [print(k+"="+v["target_path"]) for k,v in d.items() if not k.startswith("_") and v.get("target_path")]'); do repo=${row%%=*}; tp=${row#*=}; slug=$(printf '%s' "$tp" | tr '/' '_') head=$(curl -s -H "$H" "$API/repos/peptide-repo/$repo/branches/main" | python3 -c 'import json,sys;print(json.load(sys.stdin)["commit"]["id"])') stamp=$(ssh $SSHOPT "$SSH_USERNAME@$SSH_HOST" "cat ~/.peptide-deploys/production/$slug 2>/dev/null" || true) dep=${stamp%% *} if [ -z "$dep" ]; then msg="$repo: no Gitea production deploy recorded" if [ "$PROD_ENABLED" = "true" ]; then problems="$problems\n- $msg (main is ${head:0:7})"; else echo "::notice::$msg (expected before cutover)"; fi elif [ "$dep" != "$head" ]; then problems="$problems\n- $repo: production has ${dep:0:7}, main is ${head:0:7}" else echo "OK $repo ${head:0:7}" fi done [ -z "$problems" ] && { echo "No drift."; exit 0; } printf "Drift found:%b\n" "$problems" open=$(curl -s -H "$H" "$API/repos/$GITHUB_REPOSITORY/issues?state=open&type=issues&limit=50" | python3 -c 'import json,sys;print(sum(1 for i in json.load(sys.stdin) if i["title"]=="Deploy drift detected"))') if [ "$open" -gt 0 ]; then echo "An open drift issue already exists; not opening another."; exit 1; fi python3 -c 'import json,sys; print(json.dumps({"title": "Deploy drift detected", "body": "Daily deploy-health found production out of step with main:\n" + sys.argv[1].replace("\\n","\n") + "\n\nRe-run the repo pipeline on main (workflow_dispatch) or investigate the failed deploy. Opened by deploy-health.yml."}))' "$problems" > issue.json curl -s -o /dev/null -w "issue HTTP %{http_code}\n" -H "$H" -H 'Content-Type: application/json' -X POST "$API/repos/$GITHUB_REPOSITORY/issues" --data-binary @issue.json exit 1