Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/docker-gradle-build-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,14 @@ jobs:
# happened to grounds-forge 4.3.0 in its migrate init container. Building
# an amd64 image on an arm64 runner would mean QEMU for the whole build.
# Public fork PRs remain on GitHub-hosted runners; private repositories
# use their own ARC scale set. Missing repository payloads safely fall
# back to GitHub-hosted rather than the unavailable Blacksmith pool.
# use the shared self-hosted pool `grounds-runners` (org-level ARC; the
# org's Default runner group refuses public repositories). Missing
# repository payloads safely fall back to GitHub-hosted.
runs-on: >-
${{ inputs.runner != '' && inputs.runner
|| (github.event.repository.visibility == 'public'
&& 'ubuntu-24.04')
|| github.event.repository.name
|| (github.event.repository.name && 'grounds-runners')
|| 'ubuntu-24.04' }}
# Cold ARC builds can exceed 30m downloading builder/runtime base images
# even after Gradle succeeds. Keep the default repo-ARC path bounded at
Expand Down
32 changes: 13 additions & 19 deletions .github/workflows/gradle-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ on:
description: >
Runner label. Leave unset and the job picks one by repository
visibility: GitHub's arm64 hosted runner in public repos, where it
is free and has 4 vCPUs, and a 2 vCPU arm64 Blacksmith runner in
private repos, where GitHub-hosted arm64 is not offered. Set it
explicitly to override — an amd64 label if a test image has no
arm64 variant, or a larger Blacksmith label for a build that is
measurably CPU-bound and on someone's critical path.
is free and has 4 vCPUs, and the shared self-hosted `grounds-runners`
pool (amd64) in private repos, where GitHub-hosted arm64 is not
offered. Set it explicitly to override, e.g. `grounds-runners-large`
for a build that needs more memory than the shared pool gives.
required: false
type: string
default: ""
Expand All @@ -33,26 +32,21 @@ concurrency:

jobs:
build:
# Falls back to Blacksmith whenever `visibility` is absent from the event
# payload, because GitHub-hosted arm64 does not exist for private repos and
# guessing wrong there means "no runner matches" rather than a bigger bill.
# Self-hosted ARC runners on hbr1. The label is the calling repository's
# own name, which is how each repo reaches its own scale set without
# passing anything.
#
# Read the three branches in order. A public repo keeps a GitHub-hosted
# runner: on a self-hosted pool a fork PR would run arbitrary code on
# hbr1, which also hosts production containers. A private repo goes to
# its own runner. And if `repository` is missing from the event payload
# -- which is why this used to fall back to Blacksmith -- the name is
# empty and Blacksmith still catches it, because an empty label matches
# no runner at all and the job would queue until someone cancels it.
# hbr1, which also hosts production containers (the org's Default runner
# group refuses public repositories as a second line). A private repo goes
# to `grounds-runners`, the shared self-hosted ARC pool (org-level, on
# hbr1 today). And if `repository` is missing from the event payload, the
# job lands on hosted amd64 `ubuntu-24.04`, which exists for public and
# private repos alike -- hosted arm64 does not exist for private ones, and
# a label no runner matches queues until someone cancels the job.
runs-on: >-
${{ inputs.runner != '' && inputs.runner
|| (github.event.repository.visibility == 'public'
&& 'ubuntu-24.04-arm')
|| github.event.repository.name
|| 'blacksmith-2vcpu-ubuntu-2404-arm' }}
|| (github.event.repository.name && 'grounds-runners')
|| 'ubuntu-24.04' }}
timeout-minutes: 30
steps:
- name: Check out
Expand Down
32 changes: 13 additions & 19 deletions .github/workflows/gradle-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ on:
description: >
Runner label. Leave unset and the job picks one by repository
visibility: GitHub's arm64 hosted runner in public repos, where it
is free and has 4 vCPUs, and a 2 vCPU arm64 Blacksmith runner in
private repos, where GitHub-hosted arm64 is not offered. Set it
explicitly to override — an amd64 label if a test image has no
arm64 variant, or a larger Blacksmith label for a build that is
measurably CPU-bound and on someone's critical path.
is free and has 4 vCPUs, and the shared self-hosted `grounds-runners`
pool (amd64) in private repos, where GitHub-hosted arm64 is not
offered. Set it explicitly to override, e.g. `grounds-runners-large`
for a build that needs more memory than the shared pool gives.
required: false
type: string
default: ""
Expand All @@ -33,26 +32,21 @@ concurrency:

jobs:
release:
# Falls back to Blacksmith whenever `visibility` is absent from the event
# payload, because GitHub-hosted arm64 does not exist for private repos and
# guessing wrong there means "no runner matches" rather than a bigger bill.
# Self-hosted ARC runners on hbr1. The label is the calling repository's
# own name, which is how each repo reaches its own scale set without
# passing anything.
#
# Read the three branches in order. A public repo keeps a GitHub-hosted
# runner: on a self-hosted pool a fork PR would run arbitrary code on
# hbr1, which also hosts production containers. A private repo goes to
# its own runner. And if `repository` is missing from the event payload
# -- which is why this used to fall back to Blacksmith -- the name is
# empty and Blacksmith still catches it, because an empty label matches
# no runner at all and the job would queue until someone cancels it.
# hbr1, which also hosts production containers (the org's Default runner
# group refuses public repositories as a second line). A private repo goes
# to `grounds-runners`, the shared self-hosted ARC pool (org-level, on
# hbr1 today). And if `repository` is missing from the event payload, the
# job lands on hosted amd64 `ubuntu-24.04`, which exists for public and
# private repos alike -- hosted arm64 does not exist for private ones, and
# a label no runner matches queues until someone cancels the job.
runs-on: >-
${{ inputs.runner != '' && inputs.runner
|| (github.event.repository.visibility == 'public'
&& 'ubuntu-24.04-arm')
|| github.event.repository.name
|| 'blacksmith-2vcpu-ubuntu-2404-arm' }}
|| (github.event.repository.name && 'grounds-runners')
|| 'ubuntu-24.04' }}
timeout-minutes: 30
steps:
- name: Checkout
Expand Down
22 changes: 10 additions & 12 deletions .github/workflows/label-sync.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,25 @@ concurrency:

jobs:
sync-labels:
# Free GitHub-hosted runner in public repos; Blacksmith in private ones,
# Free GitHub-hosted runner in public repos; `grounds-runners` in private ones,
# where GitHub-hosted arm64 is not offered. Tests `visibility` rather than
# `repository.private` because GitHub coerces `==` operands to numbers, so
# an absent `private` field would compare equal to false and hand a private
# repo a label that does not exist there.
# Self-hosted ARC runners on hbr1. The label is the calling repository's
# own name, which is how each repo reaches its own scale set without
# passing anything.
#
# Read the three branches in order. A public repo keeps a GitHub-hosted
# runner: on a self-hosted pool a fork PR would run arbitrary code on
# hbr1, which also hosts production containers. A private repo goes to
# its own runner. And if `repository` is missing from the event payload
# -- which is why this used to fall back to Blacksmith -- the name is
# empty and Blacksmith still catches it, because an empty label matches
# no runner at all and the job would queue until someone cancels it.
# hbr1, which also hosts production containers (the org's Default runner
# group refuses public repositories as a second line). A private repo goes
# to `grounds-runners`, the shared self-hosted ARC pool (org-level, on
# hbr1 today). And if `repository` is missing from the event payload, the
# job lands on hosted amd64 `ubuntu-24.04`, which exists for public and
# private repos alike -- hosted arm64 does not exist for private ones, and
# a label no runner matches queues until someone cancels the job.
runs-on: >-
${{ (github.event.repository.visibility == 'public'
&& 'ubuntu-24.04-arm')
|| github.event.repository.name
|| 'blacksmith-2vcpu-ubuntu-2404-arm' }}
|| (github.event.repository.name && 'grounds-runners')
|| 'ubuntu-24.04' }}
timeout-minutes: 10
steps:
- name: Download labels.yml
Expand Down
20 changes: 9 additions & 11 deletions .github/workflows/platform-test-preview-slashcmd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,22 +52,20 @@ jobs:
# `if: github.event.issue.pull_request != null`, but we double-up
# here because reusable workflows shouldn't trust their callers.
if: github.event.issue.pull_request != null
# Self-hosted ARC runners on hbr1. The label is the calling repository's
# own name, which is how each repo reaches its own scale set without
# passing anything.
#
# Read the three branches in order. A public repo keeps a GitHub-hosted
# runner: on a self-hosted pool a fork PR would run arbitrary code on
# hbr1, which also hosts production containers. A private repo goes to
# its own runner. And if `repository` is missing from the event payload
# -- which is why this used to fall back to Blacksmith -- the name is
# empty and Blacksmith still catches it, because an empty label matches
# no runner at all and the job would queue until someone cancels it.
# hbr1, which also hosts production containers (the org's Default runner
# group refuses public repositories as a second line). A private repo goes
# to `grounds-runners`, the shared self-hosted ARC pool (org-level, on
# hbr1 today). And if `repository` is missing from the event payload, the
# job lands on hosted amd64 `ubuntu-24.04`, which exists for public and
# private repos alike -- hosted arm64 does not exist for private ones, and
# a label no runner matches queues until someone cancels the job.
runs-on: >-
${{ (github.event.repository.visibility == 'public'
&& 'ubuntu-24.04-arm')
|| github.event.repository.name
|| 'blacksmith-2vcpu-ubuntu-2404-arm' }}
|| (github.event.repository.name && 'grounds-runners')
|| 'ubuntu-24.04' }}
timeout-minutes: 10
permissions:
issues: write
Expand Down
42 changes: 19 additions & 23 deletions .github/workflows/platform-test-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ jobs:
runs-on: >-
${{ (github.event.repository.visibility == 'public'
&& 'ubuntu-24.04')
|| github.event.repository.name
|| (github.event.repository.name && 'grounds-runners')
|| 'ubuntu-24.04' }}
timeout-minutes: 30
outputs:
Expand Down Expand Up @@ -171,22 +171,20 @@ jobs:
mint:
if: github.event.action != 'closed'
needs: build
# Self-hosted ARC runners on hbr1. The label is the calling repository's
# own name, which is how each repo reaches its own scale set without
# passing anything.
#
# Read the three branches in order. A public repo keeps a GitHub-hosted
# runner: on a self-hosted pool a fork PR would run arbitrary code on
# hbr1, which also hosts production containers. A private repo goes to
# its own runner. And if `repository` is missing from the event payload
# -- which is why this used to fall back to Blacksmith -- the name is
# empty and Blacksmith still catches it, because an empty label matches
# no runner at all and the job would queue until someone cancels it.
# hbr1, which also hosts production containers (the org's Default runner
# group refuses public repositories as a second line). A private repo goes
# to `grounds-runners`, the shared self-hosted ARC pool (org-level, on
# hbr1 today). And if `repository` is missing from the event payload, the
# job lands on hosted amd64 `ubuntu-24.04`, which exists for public and
# private repos alike -- hosted arm64 does not exist for private ones, and
# a label no runner matches queues until someone cancels the job.
runs-on: >-
${{ (github.event.repository.visibility == 'public'
&& 'ubuntu-24.04-arm')
|| github.event.repository.name
|| 'blacksmith-2vcpu-ubuntu-2404-arm' }}
|| (github.event.repository.name && 'grounds-runners')
|| 'ubuntu-24.04' }}
timeout-minutes: 20
permissions:
pull-requests: write
Expand Down Expand Up @@ -386,22 +384,20 @@ jobs:
# ── Evict on PR close ─────────────────────────────────────────────
evict:
if: github.event.action == 'closed'
# Self-hosted ARC runners on hbr1. The label is the calling repository's
# own name, which is how each repo reaches its own scale set without
# passing anything.
#
# Read the three branches in order. A public repo keeps a GitHub-hosted
# runner: on a self-hosted pool a fork PR would run arbitrary code on
# hbr1, which also hosts production containers. A private repo goes to
# its own runner. And if `repository` is missing from the event payload
# -- which is why this used to fall back to Blacksmith -- the name is
# empty and Blacksmith still catches it, because an empty label matches
# no runner at all and the job would queue until someone cancels it.
# hbr1, which also hosts production containers (the org's Default runner
# group refuses public repositories as a second line). A private repo goes
# to `grounds-runners`, the shared self-hosted ARC pool (org-level, on
# hbr1 today). And if `repository` is missing from the event payload, the
# job lands on hosted amd64 `ubuntu-24.04`, which exists for public and
# private repos alike -- hosted arm64 does not exist for private ones, and
# a label no runner matches queues until someone cancels the job.
runs-on: >-
${{ (github.event.repository.visibility == 'public'
&& 'ubuntu-24.04-arm')
|| github.event.repository.name
|| 'blacksmith-2vcpu-ubuntu-2404-arm' }}
|| (github.event.repository.name && 'grounds-runners')
|| 'ubuntu-24.04' }}
timeout-minutes: 10
steps:
- name: Mint forge access token
Expand Down
22 changes: 10 additions & 12 deletions .github/workflows/release-please.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,25 @@ concurrency:
jobs:
release-please:
name: Create Release
# Free GitHub-hosted runner in public repos; Blacksmith in private ones,
# Free GitHub-hosted runner in public repos; `grounds-runners` in private ones,
# where GitHub-hosted arm64 is not offered. Tests `visibility` rather than
# `repository.private` because GitHub coerces `==` operands to numbers, so
# an absent `private` field would compare equal to false and hand a private
# repo a label that does not exist there.
# Self-hosted ARC runners on hbr1. The label is the calling repository's
# own name, which is how each repo reaches its own scale set without
# passing anything.
#
# Read the three branches in order. A public repo keeps a GitHub-hosted
# runner: on a self-hosted pool a fork PR would run arbitrary code on
# hbr1, which also hosts production containers. A private repo goes to
# its own runner. And if `repository` is missing from the event payload
# -- which is why this used to fall back to Blacksmith -- the name is
# empty and Blacksmith still catches it, because an empty label matches
# no runner at all and the job would queue until someone cancels it.
# hbr1, which also hosts production containers (the org's Default runner
# group refuses public repositories as a second line). A private repo goes
# to `grounds-runners`, the shared self-hosted ARC pool (org-level, on
# hbr1 today). And if `repository` is missing from the event payload, the
# job lands on hosted amd64 `ubuntu-24.04`, which exists for public and
# private repos alike -- hosted arm64 does not exist for private ones, and
# a label no runner matches queues until someone cancels the job.
runs-on: >-
${{ (github.event.repository.visibility == 'public'
&& 'ubuntu-24.04-arm')
|| github.event.repository.name
|| 'blacksmith-2vcpu-ubuntu-2404-arm' }}
|| (github.event.repository.name && 'grounds-runners')
|| 'ubuntu-24.04' }}
timeout-minutes: 10
steps:
- name: Checkout code
Expand Down
30 changes: 29 additions & 1 deletion tests/test_docker_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def test_build_and_cache_contract_for_public_and_private_events(self):
self.assertEqual(len(pushes), 1)
self.assertEqual(len(cache_writes), 1)
self.assertEqual(cache_writes[0]['with']['cache-to'], '${{ steps.layer_cache.outputs.to }}')
expected_runner = 'ubuntu-24.04' if visibility == 'public' else 'plugin-notifications'
expected_runner = 'ubuntu-24.04' if visibility == 'public' else 'grounds-runners'
self.assertEqual(resolve(job['runs-on'], context).strip(), expected_runner)
expected_budget = 30 if visibility == 'public' else 60
self.assertEqual(int(resolve(job['timeout-minutes'], context)), expected_budget)
Expand Down Expand Up @@ -149,6 +149,34 @@ def test_cold_arc_budget_preserves_hosted_override_and_fallback_limits(self):
self.assertEqual(budget, expected)
self.assertLessEqual(budget, 60)

def test_every_central_workflow_routes_private_repos_to_the_shared_pool(self):
"""Public -> GitHub-hosted, private -> grounds-runners, no payload -> hosted amd64.

The last case matters: hosted arm64 does not exist for private repos, and a
public repo sent to the self-hosted pool is refused by the org's runner group,
so either wrong guess queues a job forever.
"""
checked = 0
for path in sorted(WORKFLOW.parent.glob('*.yml')):
jobs = (yaml.safe_load(path.read_text()) or {}).get('jobs', {})
for name, job in jobs.items():
runs_on = job.get('runs-on')
if not isinstance(runs_on, str) or 'grounds-runners' not in runs_on:
continue
checked += 1
base = {'inputs.runner': ''}
with self.subTest(workflow=path.name, job=name):
private = resolve(runs_on, {**base, 'github.event.repository.visibility': 'private',
'github.event.repository.name': 'plugin-match'}).strip()
self.assertEqual(private, 'grounds-runners')
public = resolve(runs_on, {**base, 'github.event.repository.visibility': 'public',
'github.event.repository.name': 'service-maps'}).strip()
self.assertTrue(public.startswith('ubuntu-24.04'), public)
missing = resolve(runs_on, {**base, 'github.event.repository.visibility': '',
'github.event.repository.name': ''}).strip()
self.assertEqual(missing, 'ubuntu-24.04')
self.assertEqual(checked, 9, 'every repo-routed job should target the shared pool')

def test_runner_override_and_missing_event_payload(self):
job = yaml.safe_load(WORKFLOW.read_text())['jobs']['docker-build-push']
context = {'inputs.runner': '', 'github.event.repository.visibility': '', 'github.event.repository.name': ''}
Expand Down