Background
The windows-arm64-11 builder currently runs on Azure VMs managed by the Go team. As part of expanding Windows ARM64 CI coverage and reducing reliance on Azure infrastructure, we'd like to use GitHub Actions windows-11-arm runners as LUCI Swarming bots.
GitHub Actions recently added native Windows ARM64 runners, which provide fresh, hermetic environments suitable for Go's CI needs.
Problem
LUCI Swarming expects bots to be pre-provisioned (always-on or auto-scaled VMs that run bootstrapswarm on startup). GitHub Actions runners are ephemeral — they're provisioned on demand per workflow run and destroyed afterward. There's currently no mechanism for LUCI to trigger GitHub Actions workflows when it needs a bot with specific dimensions, nor for GHA runners to authenticate with Swarming without long-lived credentials.
Proposed design
GHA workflow (golang.org/x/build)
A workflow_dispatch-triggered GitHub Actions workflow provisions a Windows 11 ARM64 runner that:
- Installs dependencies
- Authenticates with Google Cloud via Workload Identity Federation using GitHub's OIDC tokens (no stored secrets)
- Runs
bootstrapswarm.exe to register as a LUCI Swarming bot
- LUCI schedules
golangbuild on the bot, which handles the full build+test lifecycle
Authentication (OIDC federation)
GHA OIDC token → Workload Identity Federation → GCP service account token → Swarming identity token
- GitHub Actions provides per-job OIDC JWTs
- Workload Identity Federation in the
golang-ci-luci GCP project exchanges them for GCP credentials
bootstrapswarm uses the GCP identity token to authenticate with Swarming (same X-Luci-Gce-Vm-Token path as GCE bots)
- Attribute conditions restrict token exchange to the
golang/go repository (or whatever repo end up running the workflow)
This requires a small change to bootstrapswarm to support GCP identity tokens from Workload Identity Federation (instead of only GCE metadata or luci_machine_tokend).
On-demand bot provisioning
A lightweight service (or Cloud Function) watches LUCI BuildBucket for pending builds that require windows-arm64-gha Swarming dimensions. When a pending build is detected:
- Service dispatches a
workflow_dispatch event via the GitHub API
- GHA runner starts, runs
bootstrapswarm, becomes a Swarming bot
- Swarming assigns the pending
golangbuild task to the new bot
- Build runs; runner is destroyed when the workflow ends
This service could run alongside the existing coordinator or as a standalone Cloud Run service. The dispatch mechanism would use a GitHub App to authenticate. The service would store the GitHub App private key as a secret, and golang/go would have the app installed.
CC @golang/release @dmitshur
Background
The
windows-arm64-11builder currently runs on Azure VMs managed by the Go team. As part of expanding Windows ARM64 CI coverage and reducing reliance on Azure infrastructure, we'd like to use GitHub Actionswindows-11-armrunners as LUCI Swarming bots.GitHub Actions recently added native Windows ARM64 runners, which provide fresh, hermetic environments suitable for Go's CI needs.
Problem
LUCI Swarming expects bots to be pre-provisioned (always-on or auto-scaled VMs that run
bootstrapswarmon startup). GitHub Actions runners are ephemeral — they're provisioned on demand per workflow run and destroyed afterward. There's currently no mechanism for LUCI to trigger GitHub Actions workflows when it needs a bot with specific dimensions, nor for GHA runners to authenticate with Swarming without long-lived credentials.Proposed design
GHA workflow (
golang.org/x/build)A
workflow_dispatch-triggered GitHub Actions workflow provisions a Windows 11 ARM64 runner that:bootstrapswarm.exeto register as a LUCI Swarming botgolangbuildon the bot, which handles the full build+test lifecycleAuthentication (OIDC federation)
golang-ci-luciGCP project exchanges them for GCP credentialsbootstrapswarmuses the GCP identity token to authenticate with Swarming (sameX-Luci-Gce-Vm-Tokenpath as GCE bots)golang/gorepository (or whatever repo end up running the workflow)This requires a small change to bootstrapswarm to support GCP identity tokens from Workload Identity Federation (instead of only GCE metadata or
luci_machine_tokend).On-demand bot provisioning
A lightweight service (or Cloud Function) watches LUCI BuildBucket for pending builds that require
windows-arm64-ghaSwarming dimensions. When a pending build is detected:workflow_dispatchevent via the GitHub APIbootstrapswarm, becomes a Swarming botgolangbuildtask to the new botThis service could run alongside the existing coordinator or as a standalone Cloud Run service. The dispatch mechanism would use a GitHub App to authenticate. The service would store the GitHub App private key as a secret, and
golang/gowould have the app installed.CC @golang/release @dmitshur