Skip to main content
README.md6.5 KB
View on GitHub

Plugin multi-architecture releases

Build and test a native Go plugin on six platforms, then package and publish one signed OCI index. This is a workflow template for a separate plugin repository generated by atmos plugin create; it does not publish Atmos or include another plugin implementation.

Consumers configure authentication providers and a keyring to use the generated plugin and store its credentials.

Configure the plugin repository

  1. Copy release.yaml to .github/workflows/release.yaml in your plugin repository.
  2. Set the repository variable ATMOS_VERSION to an exact released Atmos tag containing plugin build --platform and platform-aware conformance tests. The workflow verifies the downloaded binary against that release's checksums.
  3. Set PLUGIN_REPOSITORY to your lowercase GHCR destination, for example oci://ghcr.io/acme/oidc. Grant the repository's GITHUB_TOKEN access to that package. Configure a protected plugin-release environment for publication.
  4. Use a released SDK dependency in go.mod and commit go.sum; a developer's local go.work replacement is not portable to release runners.
  5. Keep your manifest identity, schemas, capabilities, and tests. Replace its executable/platform declarations with these paths:
spec:
runtime:
type: native
protocol: 1
executable: bin/plugin.exe
platforms:
linux/amd64:
executable: bin/linux-amd64/plugin
linux/arm64:
executable: bin/linux-arm64/plugin
darwin/amd64:
executable: bin/darwin-amd64/plugin
darwin/arm64:
executable: bin/darwin-arm64/plugin
windows/amd64:
executable: bin/windows-amd64/plugin.exe
windows/arm64:
executable: bin/windows-arm64/plugin.exe

The scaffold embeds plugin.yaml in the executable. Commit the final manifest and release version before building; do not rewrite it separately in matrix jobs. Every artifact must describe the same release. The six mappings select source outputs for builds and conformance tests. Packing places each platform's selected bytes at the common spec.runtime.executable path inside that platform's package. The .exe suffix on this common path also works on Linux/macOS and makes the packaged file directly executable on Windows.

Run

Locally, cross-compile every declared platform with:

atmos plugin build . --all-platforms
atmos plugin test .
atmos plugin pack . --output dist/plugin

plugin test runs the current process's compatible binary only. Building all six outputs does not prove the other five execute successfully.

Run the workflow manually with publish left false to validate the complete matrix without uploading to a registry. Each job verifies its Go host target, runs author tests, explicitly builds its platform, runs Atmos conformance against that binary, and uploads it. The aggregate job restores the executable bits lost by artifact transfer and packs exactly once after all six jobs pass. It creates one test consumer and lockfile from that layout. A second six-runner matrix restores the same lock with --frozen --from-layout, executes the scaffold's about command through plugin run, and checks that the lockfile is unchanged. These jobs download only Atmos and the layout: no Go setup, source checkout, compilation, or registry access is needed. The synthetic example.invalid source identifies the local test release; offline policy prevents network fallback. Pre-publication smoke tests verify integrity; signed publisher verification requires the subsequently published signature. Adapt the smoke command if your plugin no longer exports the scaffold's about command.

Update metadata.version, commit, and push a v* release tag to publish. A manual publication must also run against a tag with publish: true. The manifest version determines the published OCI tag; use the matching Git tag for clarity. Registry credentials and OIDC signing permissions are scoped to the publish job, which requires all six packaged-release smoke tests to pass. publish --sign --yes signs the complete index digest, which binds every platform's child digest. Configure consumers to trust the workflow's exact GitHub signing identity and issuer. Publication and signing are separate writes; if signing fails, the command reports the already-published digest for recovery.

The matrix uses GitHub's native hosted runner labels: ubuntu-24.04, ubuntu-24.04-arm, macos-15-intel, macos-15, windows-2022, and windows-11-arm. Runner availability and billing depend on your repository. Replace unavailable labels with native runners for the same OS/architecture; do not treat emulated execution or cross-compilation as native verification. Add oldest/newest supported Atmos versions to the verification matrix when your plugin declares an Atmos compatibility range.

Architecture variants

Baseline amd64 and arm64 outputs provide the broadest compatibility. An explicit target such as linux/arm/v7 or linux/amd64/v3 needs its own manifest entry and unique executable path. Build it with the matching --platform value and add a runner capable of executing that instruction set to the workflow. Supported ARM64 variants are v8/v8.0 through v8.9 and v9/v9.0 through v9.5 (Go 1.26). Baselines are amd64 v1, ARM64 v8.0, and ARM v5 with software floating point.

Selection stays within the running Atmos process's OS/architecture and uses its compiled instruction-set requirements as a conservative compatibility ceiling. It prefers the highest compatible explicit variant, then the baseline; it never assumes an emulated binary or a more capable physical CPU. An optimized plugin may therefore require a correspondingly built Atmos executable even when the machine's CPU could execute it. Lockfiles retain every platform digest and caches include the selected variant, so sharing one lockfile does not share incompatible executables. See the distribution requirements.