Skip to content

Self-hosted and configurable runners - #31

Open
Interlap01 wants to merge 8 commits into
mainfrom
runners
Open

Interlap01 wants to merge 8 commits into
mainfrom
runners

Conversation

@Interlap01

Copy link
Copy Markdown
Collaborator

What

  • builder.json takes runner as a label or label list ("macos-15", ["self-hosted", "macOS", "ARM64"]), at the top level and per profile. builder init --runner sets it (one label or a comma list).
  • ios-build.yml now has runs-on: ${{ fromJSON(inputs.profile || '{}').runner || <default> }}. The CLI sends the profile's runner (else the top-level one) inside the existing profile input, so no new dispatch input is needed. When only a runner is configured, the input goes with an empty name, which the workflow treats as no profile. init renders the top-level runner as the default. Tag-triggered builds and ios-share.yml have no profile input, so they use the rendered runner.
  • Codemagic instance_type and Bitrise machine_type_id / stack come from codemagic.instance_type, bitrise.machine_type_id and bitrise.stack, set by init --provider ... --runner/--stack. An unknown machine type is kept and prints a warning. A value that is not a plain name is refused.
  • Changes so the template is safe on a persistent machine:
    • setup-xcode runs only on GitHub-hosted runners. A self-hosted runner gets a Check Xcode step instead.
    • brew install runs only when the tool is missing (XcodeGen, CocoaPods).
    • The previous run's IPA, archive and export are cleared.
    • The signing keychain is put in front of the existing search list instead of replacing it.
    • Cleanup signing restores the search list, deletes the keychain and removes every provisioning profile the job installed. It uses fixed $RUNNER_TEMP paths, so it also works when signing failed partway.
  • The ios build banner prints the runner.
  • Docs: README "Self-hosted runners" section with runner requirements, provider machine flags, CLAUDE.md config and patterns.

Why

Every template hardcoded its machine (macos-latest, mac_mini_m2, g2.mac.medium). The GitHub template also assumed a fresh VM: it replaced the user keychain search list, left provisioning profiles behind, and switched Xcode with sudo.

How tested

  • go test -race ./... and go vet ./... pass; gofmt -l . reports nothing. golangci-lint could not run locally: the installed binary was built with Go 1.25 and panics on the Go 1.26 standard library.
  • New tests cover:
    • runner JSON parsing and writing (string or array)
    • --runner parsing and validation
    • profile precedence and the runner inside the profile input
    • rendering of each runner form, with the YAML parsed back
    • setup-xcode gating and the brew guard
    • the Cleanup signing step, run against a fake security (search list restored, keychain deleted, only the job's profiles removed)
    • the keychain search-list prepend
    • Codemagic and Bitrise machine rendering
    • provider init flags and the banner
  • The rendered workflows (default, single label, label list) pass actionlint. actionlint also confirmed that inputs is an allowed context in runs-on. Nothing was run against real repositories or CI services.

Left out

  • Per-profile runners for Codemagic and Bitrise: their machine is fixed in the committed YAML.
  • Per-run runners for tag builds and ios share: they have no profile input, so they use the runner init rendered.
  • Runner groups (runs-on: {group: ..., labels: ...}).
  • runner.sh (Codemagic/Bitrise) was not changed: those services run on fresh VMs.

builder.json takes "runner" as a string or an array of labels at the top
level and in a profile. The resolved runner travels in the profile dispatch
input, which is now also sent when only a runner is configured. Codemagic
instance_type and Bitrise machine_type_id/stack join the provider config.
ios-build.yml takes runs-on from the profile input's runner, else the
default init renders; tag builds always use the rendered default.
ios-share.yml renders the top-level runner. Setup Xcode runs only on
GitHub-hosted runners (a self-hosted one keeps its selected Xcode and
gets a check), brew installs only missing tools, earlier outputs are
cleared, and Cleanup signing restores the keychain search list and
removes every provisioning profile the job installed.
init --provider codemagic|bitrise takes --runner (instance_type or
machine_type_id) and, for Bitrise, --stack. Unknown machine types are
kept with a warning; values that are not plain names are refused before
anything is written.
init --runner takes one label or a comma list, stores it as the
top-level runner in builder.json (left out, the saved one is kept), and
renders it into ios-build.yml and ios-share.yml. A label that is neither
macos-* nor self-hosted gets a warning. pkg exposes the renderers.
The GitHub runner the dispatch resolves to, or the Codemagic instance
type, or the Bitrise machine type and stack.
The machine fields push CIConfig past gocritic's hugeParam limit, so
NewCodemagic, NewBitrise (internal and pkg), ProviderFiles and
WriteProviderFiles take *config.CIConfig.
A Windows checkout with core.autocrlf embeds the templates with CRLF
endings, so the line matches that included the LF found nothing. Match
the runs-on lines without their ending, and keep a \r on the provider
machine lines (and the inserted Bitrise stack) when the template has one.
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.

1 participant