From 83673938130d5a91f0c5045d01535ae576176df8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20SAILLANT?= <108685187+electron-rare@users.noreply.github.com> Date: Mon, 18 May 2026 22:23:44 +0200 Subject: [PATCH] fix: post-audit CI and governance cleanup (#6) * ci: enforce typecheck and add quality gates Remove continue-on-error on the Typecheck step: astro check currently reports 0 errors / 13 hints, so the step can block. Also run tracking:check and image:budget after the build so these quality gates actually fail CI when broken (they are defined in package.json but were never wired into the workflow). * chore: remove obsolete Tower deploy workflow The 'Deploy to Tower' workflow built the Astro Node adapter and scp'd it to Tower to run as a container on port 4321. Production has been served by Cloudflare since PR #5, so this pipeline only ever fails (Tower SSH secrets are stale and the target host is not the live origin). Removing it eliminates noisy red runs. * chore: monthly report tracks live required checks The report hardcoded a probe for 'Cross-stack coherence', which is no longer a required status check on main. Dump the live set from required_status_checks.contexts[] and .checks[].context instead, so the monthly report reflects whatever branch protection is configured at that point rather than a stale name. --- .github/workflows/ci.yml | 9 +- .github/workflows/deploy-cloudflare.yml | 83 ------------------- .../workflows/monthly-cross-stack-report.yml | 27 +++--- 3 files changed, 24 insertions(+), 95 deletions(-) delete mode 100644 .github/workflows/deploy-cloudflare.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ca7d2df..223143d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,13 +21,18 @@ jobs: - name: Install run: npm ci - - name: Typecheck (non-blocking — repo has known debt) - continue-on-error: true + - name: Typecheck run: npm run typecheck - name: Build run: npm run build + - name: Tracking check + run: npm run tracking:check + + - name: Image budget + run: npm run image:budget + - name: Notify ntfy on failure if: failure() run: | diff --git a/.github/workflows/deploy-cloudflare.yml b/.github/workflows/deploy-cloudflare.yml deleted file mode 100644 index 8380928..0000000 --- a/.github/workflows/deploy-cloudflare.yml +++ /dev/null @@ -1,83 +0,0 @@ -name: Deploy to Tower - -on: - push: - branches: [main] - workflow_dispatch: - -permissions: - contents: read - -concurrency: - group: deploy-production - cancel-in-progress: true - -jobs: - build-and-deploy: - runs-on: ubuntu-latest - env: - PUBLIC_SITE_URL: https://www.lelectronrare.fr/ - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Setup Node - uses: actions/setup-node@v4 - with: - node-version: 22 - cache: npm - - - name: Install dependencies - run: npm ci - - - name: Build site - run: npm run build - - - name: Deploy to Tower - uses: appleboy/scp-action@v0.1.7 - with: - host: ${{ secrets.TOWER_HOST }} - username: ${{ secrets.TOWER_USER }} - key: ${{ secrets.TOWER_SSH_KEY }} - source: "dist/" - target: "/home/clems/electron-rare-site/" - overwrite: true - rm: true - - - name: Restart site container - uses: appleboy/ssh-action@v1.0.3 - with: - host: ${{ secrets.TOWER_HOST }} - username: ${{ secrets.TOWER_USER }} - key: ${{ secrets.TOWER_SSH_KEY }} - script: | - cd /home/clems/electron-rare-site - docker rm -f electron-rare-site 2>/dev/null || true - docker run -d \ - --name electron-rare-site \ - --network mascarade-frontend \ - -v /home/clems/electron-rare-site/dist:/app/dist \ - -v /home/clems/electron-rare-site/node_modules:/app/node_modules \ - -w /app \ - -p 4321:4321 \ - -e HOST=0.0.0.0 \ - -e PORT=4321 \ - --restart unless-stopped \ - node:22-alpine \ - node dist/server/entry.mjs - - - name: Verify deployment - uses: appleboy/ssh-action@v1.0.3 - with: - host: ${{ secrets.TOWER_HOST }} - username: ${{ secrets.TOWER_USER }} - key: ${{ secrets.TOWER_SSH_KEY }} - script: | - sleep 5 - STATUS=$(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:4321/) - if [ "$STATUS" != "200" ]; then - echo "Site returned $STATUS instead of 200" - exit 1 - fi - echo "Site is live (HTTP 200)" diff --git a/.github/workflows/monthly-cross-stack-report.yml b/.github/workflows/monthly-cross-stack-report.yml index e504082..e043875 100644 --- a/.github/workflows/monthly-cross-stack-report.yml +++ b/.github/workflows/monthly-cross-stack-report.yml @@ -41,14 +41,16 @@ jobs: fi done - CHECK_STATE="unknown" + REQUIRED_CHECKS_LIST="(unknown)" if [ "$PROTECTION_HTTP_CODE" = "200" ]; then - REQ_CHECK_CHECKS=$(echo "$PROTECTION_JSON" | jq -r '.required_status_checks.checks[]?.context // empty' | grep -Fx 'Cross-stack coherence' || true) - REQ_CHECK_CONTEXTS=$(echo "$PROTECTION_JSON" | jq -r '.required_status_checks.contexts[]? // empty' | grep -Fx 'Cross-stack coherence' || true) - if [ -n "$REQ_CHECK_CHECKS" ] || [ -n "$REQ_CHECK_CONTEXTS" ]; then - CHECK_STATE="required" - else - CHECK_STATE="not-required" + REQUIRED_CHECKS_LIST="$(echo "$PROTECTION_JSON" | jq -r ' + [ + (.required_status_checks.contexts // [])[], + (.required_status_checks.checks // [])[].context + ] | unique | .[] + ' 2>/dev/null || true)" + if [ -z "$REQUIRED_CHECKS_LIST" ]; then + REQUIRED_CHECKS_LIST="(none)" fi fi @@ -58,10 +60,15 @@ jobs: echo "Generated: $NOW_UTC" echo "Repository: $GH_REPO" echo - echo "## Branch Protection (main)" - echo "- Cross-stack coherence: $CHECK_STATE" - if [ "$CHECK_STATE" = "unknown" ]; then + echo "## Branch Protection (main) — Required Status Checks" + if [ "$PROTECTION_HTTP_CODE" != "200" ]; then echo "- Note: branch protection endpoint not readable with current token (HTTP $PROTECTION_HTTP_CODE)." + elif [ "$REQUIRED_CHECKS_LIST" = "(none)" ]; then + echo "- No required status checks configured." + else + echo "$REQUIRED_CHECKS_LIST" | while IFS= read -r ctx; do + [ -n "$ctx" ] && echo "- $ctx" + done fi echo echo "## Expected Labels"