From 859173f145650b99c2022c6ca281f450c0d9ddbc Mon Sep 17 00:00:00 2001 From: efiten Date: Wed, 2 Sep 2026 18:24:27 +0200 Subject: [PATCH] =?UTF-8?q?ci:=20unblock=20the=20master=20pipeline=20?= =?UTF-8?q?=E2=80=94=20gate=20the=20staging=20deploy,=20detach=20the=20bad?= =?UTF-8?q?ges=20job=20(#1938)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes the problem @sylr reported on #1922. ## What is broken **master has produced no completed pipeline result since 2026-08-31.** Thirty-plus runs today alone were cancelled or left queued, while `go-test`, `e2e-test` and `build-and-publish` were passing inside them. The `deploy` job runs on `[self-hosted, meshcore-runner-2]`, and no such runner has picked up a job since at least 2026-08-31. It has no `timeout-minutes`, so it sits queued indefinitely. That job holds its run open, the run holds the concurrency group `ci-refs/heads/master`, and GitHub then cancels every subsequent master push while one waits. Two runs showing it, one from yesterday and one from right now: ``` 8ce5291b (2026-09-01) 89544b1d (2026-09-02) ✅ Go Build & Test ok ✅ Go Build & Test ok 🎭 Playwright E2E ok 🎭 Playwright E2E ok 🏗️ Build & Publish ok 🏗️ Build & Publish ok 🚀 Deploy Staging cancel 🚀 Deploy Staging queued ← runner: none ``` The tests were fine the whole time. Only the deploy hangs, and it takes the branch's pipeline with it. ## What this changes **1. The deploy job is gated on a repository variable.** ```yaml if: | vars.ENABLE_STAGING_DEPLOY == 'true' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/master' timeout-minutes: 10 ``` Unset means it does not run. Setting `ENABLE_STAGING_DEPLOY` to `true` in Settings restores the old behaviour with **no code change**. The `timeout-minutes: 10` is there so that enabling it while the runner is still absent fails in ten minutes instead of blocking the branch again. A bare timeout would have unblocked the queue but left master permanently red on a job that cannot succeed while the runner is gone. Gating it means master goes green when the tests pass, which is what a branch pipeline is for. **2. The badges job stops depending on the deploy.** `needs: [deploy]` → `needs: [build-and-publish]`. That job downloads the `go-badges` and `e2e-badges` artifacts and commits them to `.badges/`. It never needed the deploy step, and that dependency is why the coverage badges also stopped updating. `build-and-publish` already requires both test jobs transitively, so ordering is unchanged. ## What this does not change Nothing about what the deploy job *does*. No test job is touched. One file, +26/-2. ## The part that is not mine to fix Why `meshcore-runner-2` is gone is the repository owner's to answer, and they have been unreachable since June, which is what #1922 is about. Whoever brings the runner back flips one variable and the deploy returns exactly as it was. Thanks @sylr — I had been working around this all day by verifying master locally after each batch, without understanding why master never completed. Your report is what made it legible. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Wzwr3eXseyNM7Xj598djjE Co-authored-by: Claude Opus 5 (1M context) --- .github/workflows/deploy.yml | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 1e8be8f6..0d5698c3 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -690,11 +690,30 @@ jobs: # ─────────────────────────────────────────────────────────────── deploy: name: "🚀 Deploy Staging" + # DISABLED. Re-enable by setting the repository variable + # ENABLE_STAGING_DEPLOY to 'true' (Settings > Secrets and variables > + # Actions > Variables). No code change needed. + # + # Why: this job runs on [self-hosted, meshcore-runner-2] and that runner + # has not picked up a job since at least 2026-08-31. It has no + # timeout-minutes, so it sat queued for 22+ hours, held its run open, and + # through the concurrency group ci-refs/heads/master caused GitHub to + # cancel every subsequent master push. The result was that master produced + # no completed pipeline result at all: 30+ runs cancelled or stuck while + # go-test, e2e-test and build-and-publish were passing inside them. + # + # timeout-minutes alone would unblock the queue but leave master + # permanently red on a job that cannot succeed while the runner is absent, + # so the deploy is gated instead. It is added here as well, so that if the + # variable is set while the runner is still missing the job fails in ten + # minutes rather than blocking the branch again. if: | - (github.event_name == 'push' || github.event_name == 'workflow_dispatch') + vars.ENABLE_STAGING_DEPLOY == 'true' + && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/master' needs: [build-and-publish] runs-on: [self-hosted, meshcore-runner-2] + timeout-minutes: 10 steps: - name: Checkout code uses: actions/checkout@v5 @@ -781,7 +800,12 @@ jobs: publish: name: "📝 Publish Badges & Summary" if: github.event_name == 'push' - needs: [deploy] + # Was needs: [deploy]. The badges are built from the go-test and e2e-test + # artifacts and never needed the deploy step; depending on it meant the + # coverage badges stopped updating whenever the self-hosted runner was + # unavailable. build-and-publish already transitively requires both test + # jobs, so ordering is unchanged. + needs: [build-and-publish] runs-on: ubuntu-latest steps: - name: Checkout code