Skip to main content
Copying the same airship.yaml into twenty repositories means twenty places to change when a machine family is deprecated. Organization runners put the shapes in one place.
1

Create a .airship repository

A repository literally named .airship in the organization. Private is fine, and recommended.
2

Give the GitHub App access to it

Add it to the installation’s repository list like any other.
3

Add airship.global.yaml at its root

Same format as airship.yaml, idle included.
airship.global.yaml
4

Use the labels from anywhere

Any activated repository in the organization can now ask for them, with no airship.yaml of its own.
.github/workflows/ci.yml

Repository definitions win

If a repository’s own airship.yaml has a definition whose labels include the same label, that one is used. Organization definitions are tried after repository ones, which makes two useful patterns:

A sensible default, overridable

Publish airship-build organization-wide. A repository that needs something different defines its own airship-build and changes no workflow file.

A shared fallback

A repository’s large machine first, the organization’s smaller shared one behind it, under one label. See Fallbacks.

Which branch it is read from

airship.global.yaml is read from the .airship repository’s default branch — unlike a repository’s own airship.yaml, which is read at each job’s commit. A push to that branch refreshes it within a reconcile pass, and the Events page records the read, including a file that stopped parsing.
If airship.global.yaml does not parse, jobs relying on its labels are skipped with Config problem until it is fixed. Changes to it affect every repository at once, so it is worth protecting that branch and reviewing changes to it like any other shared infrastructure.

Shared idle pools

An idle: block in airship.global.yaml is organization-wide. Those runners register on the organization, in a runner group named airship-<runner name>, visible to every activated private repository — or only to the repositories the runner’s access policies name. Any such repository can take one.
airship.global.yaml
This needs the GitHub App’s organization Self-hosted runners: read & write permission. One warm pool serving every repository is usually both faster and cheaper than a pool per repository.

Restricting the expensive ones

By default an organization runner is open to every activated repository. A GPU box or a 48xlarge usually should not be. access.yaml in the same .airship repository restricts them by repository, team, role or login:
access.yaml

Access control

The policy format, how a person is matched, what happens to pull requests, and the API that edits the file for you.

A layout that works

Most repositories then have no airship.yaml at all — they name a label and get a reviewed, shared machine definition. Teams that need something unusual still have the per-repository file, read at their own commit, to experiment on a branch.