Skip to content

ci: run CI on the self-hosted triton runners - #8

Merged
ncalvas merged 4 commits into
triton-mainfrom
ci/self-hosted-runners
Oct 8, 2026
Merged

ncalvas merged 4 commits into
triton-mainfrom
ci/self-hosted-runners

Conversation

@ncalvas

@ncalvas ncalvas commented Oct 8, 2026

Copy link
Copy Markdown
Member

Description

Moves meteroid's CI onto the self-hosted triton runners (group triton, label APP; three in DA3, three in IAD39, all Ubuntu 24.04, 8 cores, 120 GB+ free disk). These runners keep their state between jobs, so three steps that assumed a throwaway VM are fixed first, each in its own commit.

Runner safety

  • rust-setup: copy the protoc includes instead of mv, which fails once /usr/local/include/google exists from an earlier job.
  • rust-setup: on self-hosted, rui314/setup-mold installs mold without make-default. Otherwise it links the host's /usr/bin/ld to mold for every later job, including other repos' builds (pkgsrc, rust-bhyve). These CI jobs don't use the .cargo-templates/ci.toml config, so on self-hosted they link with the system ld. That's slower, but the result is the same.
  • ci-rust Free disk space: GitHub-hosted only. On our runners it would uninstall LLVM and the system Chromium and run docker image prune -a.
  • docker: image digests go under runner.temp instead of /tmp/digests. /tmp survives on a self-hosted runner, and manifest would pick up digests from earlier builds.

What moves

Workflow Jobs Runner
CI (ci-rust) Test, Rustfmt, Clippy triton; fork PRs on ubuntu-latest
CI Web Lint triton; fork PRs on ubuntu-latest
Audit Rust Dependencies, OpenAPI all triton; fork PRs on ubuntu-latest
Release Drafter both triton; fork PRs on ubuntu-latest
Docker Build amd64 builds, manifest triton
Docker Build arm64 builds still ubuntu-24.04-arm (no arm64 self-hosted runners)
Release artifact build triton (Ubuntu 24.04, same glibc as the deploy targets)

Stays on GitHub-hosted

  • CI Helm Chart: the smoke jobs start minikube, which would leave a cluster and its state on the host. It runs weekly and has failed every run since August.
  • Preview: a job of up to 6 hours that tunnels to upstream's preview.meteroid.dev and would hold a runner the whole time.
  • Claude Code: triggered by comments, which anyone can post on a public repo.
  • Publish portal-embed: disabled (ENABLE_NPM_PUBLISH).

Notes

  • Depends on parler-tech/pct-ansible#235. dtolnay/rust-toolchain runs rustup default 1.96.0, which would persist on the host and become rust-bhyve's toolchain. That PR resets the default to stable before every job. Apply it before merging this one.
  • Fork PRs: the repo is public, so pull requests from forks stay on ubuntu-latest, as in ci: run on the self-hosted triton runners, except fork PRs聽cloud-image-index#3. Pushes, dispatches and same-repo PRs use triton.
  • The triton runner group must allow this repo, and public repositories.
  • The Test job's Postgres service binds host port 5432. Nothing listens there on any of the six runners today.
  • rust-setup still runs apt-get install cmake clang unzip libsasl2-dev and installs protoc 21.8 into /usr/local. On these runners that stays installed for later jobs, which is harmless.
  • actions/checkout runs git clean -ffdx, so target/ doesn't build up in the workspace. Rust caching works as before: Swatinem/rust-cache saves only from main.
  • Upstream (meteroid-oss/meteroid) edits these files too, so expect conflicts on the runs-on lines when syncing.
  • Not run yet. The first runs will test it: the PR's own CI, then Docker Build on the merge push and a dispatched Release artifact. Check that the jobs land on 1b-cicd-* / 2a-cicd-* runners and that arm64 is still GitHub-hosted.

Checklist

  • The code follows the project's coding conventions and style
  • All tests related to the changes have passed successfully (first run on the runners)
  • Documentation has been updated to reflect the changes (if applicable)
  • All new and existing unit tests have passed
  • I have self-reviewed my code and ensured its quality
  • I have added/updated necessary comments to aid understanding

The protoc includes are copied rather than moved, since mv fails once
/usr/local/include/google exists from an earlier job. On self-hosted
runners mold is installed without replacing the system ld, which would
otherwise stay in place for every later job on the host.
The step strips the hosted image. On a persistent self-hosted runner it
would uninstall toolchains and prune Docker images other jobs use.
/tmp outlives the job on a self-hosted runner, so digests from earlier
builds would end up in the manifest list. runner.temp is emptied after
every job.
Pushes, dispatches and same-repo pull requests run on the triton group.
Pull requests from forks stay on GitHub-hosted runners since the repo is
public. The arm64 Docker builds stay on GitHub-hosted, as there are no
arm64 self-hosted runners. The Helm chart, preview and Claude workflows
are unchanged.
@ncalvas ncalvas self-assigned this Oct 8, 2026
@ncalvas
ncalvas merged commit 781dd52 into triton-main Oct 8, 2026
10 of 15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants