From 6b21bdbec7be3a794aa7f732e47912d7df2358ad Mon Sep 17 00:00:00 2001 From: Vitor Bandeira Date: Thu, 15 Oct 2026 07:11:04 -0300 Subject: [PATCH 1/3] ci: pin GitHub-hosted runners to ubuntu-26.04 Select the hosted image explicitly and update the existing check. Keep the self-hosted jobs and evaluation controls unchanged. Signed-off-by: Vitor Bandeira --- .github/workflows/ci-changelog.yaml | 2 +- .github/workflows/ci-secret.yaml | 12 ++++++------ .github/workflows/ci.yaml | 10 +++++----- .github/workflows/upload.yml | 2 +- backend/tests/test_ci_secret_workflow.py | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci-changelog.yaml b/.github/workflows/ci-changelog.yaml index 10b09c19..016fa8f3 100644 --- a/.github/workflows/ci-changelog.yaml +++ b/.github/workflows/ci-changelog.yaml @@ -9,7 +9,7 @@ on: jobs: changelog: - runs-on: ubuntu-latest + runs-on: ubuntu-26.04 permissions: contents: write steps: diff --git a/.github/workflows/ci-secret.yaml b/.github/workflows/ci-secret.yaml index ba1bf198..4b857b76 100644 --- a/.github/workflows/ci-secret.yaml +++ b/.github/workflows/ci-secret.yaml @@ -35,7 +35,7 @@ jobs: # Only people with write access can dispatch this workflow, so the secrets stay # with reviewed code. resolve: - runs-on: ubuntu-latest + runs-on: ubuntu-26.04 permissions: contents: read pull-requests: read @@ -84,7 +84,7 @@ jobs: lint-backend: needs: [resolve] - runs-on: ubuntu-latest + runs-on: ubuntu-26.04 steps: - name: Setup python uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 @@ -103,7 +103,7 @@ jobs: lint-frontend: needs: [resolve] - runs-on: ubuntu-latest + runs-on: ubuntu-26.04 steps: - name: Setup python uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 @@ -122,7 +122,7 @@ jobs: lint-evaluation: needs: [resolve] - runs-on: ubuntu-latest + runs-on: ubuntu-26.04 steps: - name: Setup python uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 @@ -324,7 +324,7 @@ jobs: baseline-gate: if: always() && needs.docker-eval.result == 'success' needs: [resolve, docker-eval] - runs-on: ubuntu-latest + runs-on: ubuntu-26.04 permissions: actions: read contents: read @@ -389,7 +389,7 @@ jobs: report: if: always() && needs.resolve.outputs.pr != '' needs: [resolve, lint-backend, lint-frontend, lint-evaluation, test, docker-eval, baseline-gate] - runs-on: ubuntu-latest + runs-on: ubuntu-26.04 permissions: actions: read pull-requests: write diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 25e3f919..c4189e41 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -10,7 +10,7 @@ defaults: jobs: lint-backend: - runs-on: ubuntu-latest + runs-on: ubuntu-26.04 steps: - name: Setup python uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 @@ -30,7 +30,7 @@ jobs: run: cd backend && make check lint-frontend: - runs-on: ubuntu-latest + runs-on: ubuntu-26.04 steps: - name: Setup python uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 @@ -50,7 +50,7 @@ jobs: run: cd frontend && make check lint-nextjs: - runs-on: ubuntu-latest + runs-on: ubuntu-26.04 steps: - name: Setup node uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 @@ -75,7 +75,7 @@ jobs: run: yarn lint lint-evaluation: - runs-on: ubuntu-latest + runs-on: ubuntu-26.04 steps: - name: Setup python uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 @@ -131,7 +131,7 @@ jobs: ci-gate: if: always() needs: [lint-backend, lint-frontend, lint-nextjs, lint-evaluation, test, docker-build] - runs-on: ubuntu-latest + runs-on: ubuntu-26.04 steps: - name: Require successful CI jobs env: diff --git a/.github/workflows/upload.yml b/.github/workflows/upload.yml index f18b004e..14678004 100644 --- a/.github/workflows/upload.yml +++ b/.github/workflows/upload.yml @@ -26,7 +26,7 @@ env: jobs: or-manpages: - runs-on: ubuntu-latest + runs-on: ubuntu-26.04 steps: - name: Check the branch env: diff --git a/backend/tests/test_ci_secret_workflow.py b/backend/tests/test_ci_secret_workflow.py index d0b7b77f..39ee39dc 100644 --- a/backend/tests/test_ci_secret_workflow.py +++ b/backend/tests/test_ci_secret_workflow.py @@ -755,7 +755,7 @@ def test_baseline_gate_runs_after_the_eval_on_a_hosted_runner() -> None: jobs = yaml.safe_load(WORKFLOW.read_text())["jobs"] gate = jobs["baseline-gate"] - assert gate["runs-on"] == "ubuntu-latest" + assert gate["runs-on"] == "ubuntu-26.04" assert "docker-eval" in gate["needs"] assert "needs.docker-eval.result == 'success'" in gate["if"] assert gate["permissions"] == {"actions": "read", "contents": "read"} From 6b668dd744f856f6faec567af8d11914903900a4 Mon Sep 17 00:00:00 2001 From: Vitor Bandeira Date: Thu, 15 Oct 2026 09:02:29 -0300 Subject: [PATCH 2/3] ci: use the Ubuntu 26.04 ephemeral runner labels Route general work and paid evaluation to their separate registrations on the shared pool while preserving evaluation concurrency. Signed-off-by: Vitor Bandeira --- .github/workflows/ci-secret.yaml | 4 ++-- .github/workflows/ci.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci-secret.yaml b/.github/workflows/ci-secret.yaml index 4b857b76..4701e9fb 100644 --- a/.github/workflows/ci-secret.yaml +++ b/.github/workflows/ci-secret.yaml @@ -141,7 +141,7 @@ jobs: test: needs: [resolve, lint-backend] - runs-on: self-hosted + runs-on: self-hosted-ubuntu-26.04 steps: - name: Setup python uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 @@ -163,7 +163,7 @@ jobs: docker-eval: needs: [resolve, test, lint-frontend, lint-evaluation] - runs-on: self-hosted + runs-on: self-hosted-ubuntu-26.04-eval # Each eval is paid and holds a self-hosted runner. Run one at a time per # target (a PR number, or the branch). A started eval finishes; a newer # eval replaces the one that waits. diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index c4189e41..178ea437 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -96,7 +96,7 @@ jobs: test: needs: [lint-backend] - runs-on: self-hosted + runs-on: self-hosted-ubuntu-26.04 steps: - name: Setup python uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 @@ -120,7 +120,7 @@ jobs: docker-build: needs: [test, lint-frontend, lint-evaluation] - runs-on: self-hosted + runs-on: self-hosted-ubuntu-26.04 steps: - name: Checkout code uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 From 7ac767ab3f7fc00270b009acc51a20772aad5352 Mon Sep 17 00:00:00 2001 From: Vitor Bandeira Date: Thu, 15 Oct 2026 09:44:59 -0300 Subject: [PATCH 3/3] fix(ci): bound test workers to the shared runner quota Signed-off-by: Vitor Bandeira --- .github/workflows/ci.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 178ea437..639fbabf 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -113,6 +113,9 @@ jobs: run: cd backend && make init-dev - name: Run unit tests + env: + # Auto detection sees the shared host's CPUs instead of the slot quota. + PYTEST_XDIST_AUTO_NUM_WORKERS: '8' working-directory: backend run: | cp .env.test .env