Skip to content

Update cli-plugins catalog on release; fix goreleaser double-run#66

Open
scotwells wants to merge 4 commits into
mainfrom
ci/plugin-index-update
Open

Update cli-plugins catalog on release; fix goreleaser double-run#66
scotwells wants to merge 4 commits into
mainfrom
ci/plugin-index-update

Conversation

@scotwells

@scotwells scotwells commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Two related release-pipeline changes.

Fix: goreleaser ran twice per release

Publishing a release through the GitHub UI creates the tag, which fires both push: tags and release: published. The plugin job was gated on the tag ref (startsWith(github.ref, refs/tags/v)), which is true for both events — so goreleaser ran twice concurrently, with two processes racing to upload the same release assets.

The plugin-publishing job is now gated on github.event_name == release, so it runs exactly once (on the release event) and has a real release to attach artifacts to. The validate-kustomize, publish-container-image, and publish-kustomize-bundle jobs are unchanged.

Feature: auto-update the datumctl plugin catalog

Adds an update-plugin-index job that runs after goreleaser attaches the archives + checksums.txt. In a single job it (1) mints a short-lived, repo-scoped installation token from the milo-os GitHub App, and (2) calls the datum-cloud/actions/update-plugin-index composite action, which opens a PR against milo-os/cli-plugins bumping plugins/ipam.yaml to the released version — refreshed per-platform URLs and checksums from checksums.txt, and a link back to the release. This replaces the manual manifest edit after each release.

Mint + call live in the same job on purpose: a GitHub App token minted in a separate job and passed via outputs is scrubbed to empty (masked values don't survive job-to-job hops), so a composite action — not a reusable workflow — is required. Verified end-to-end against the v0.2.0 assets.

Pinning

The update-plugin-index step pins datum-cloud/actions/update-plugin-index@feat/update-plugin-index-composite (datum-cloud/actions#85) until the composite action ships in a tagged release; switch to a version tag (e.g. @v1.18.0) once that release is cut.

Required setup — milo-os GitHub App

Cross-repo PRs need a token the built-in GITHUB_TOKEN can't provide (it only reaches this repo). This pipeline mints a short-lived, repo-scoped token from a GitHub App in the milo-os org — no long-lived PAT. One-time setup by an org admin:

  1. Create the App — milo-os org → Settings → Developer settings → GitHub Apps → New GitHub App.
    • Name: e.g. milo-plugin-index-updater.
    • Uncheck Active under Webhook (none needed).
    • Repository permissions: Contents → Read and write; Pull requests → Read and write.
    • Where can this App be installed: Only on this account.
    • Create it, note the App ID, and generate a private key (downloads a .pem).
  2. Install the App on the milo-os org, scoped to the cli-plugins repository (add other plugin index repos later as needed).
  3. Add secrets — org-level Actions secrets (shared by every milo plugin repo) or repo-level on milo-os/ipam:
    • PLUGIN_INDEX_APP_ID — the App ID
    • PLUGIN_INDEX_APP_PRIVATE_KEY — the full contents of the .pem

The workflow's generate-index-token job exchanges these for an installation token scoped to milo-os/cli-plugins (expires ~1h), which the catalog-update job uses to open the PR.

Related work

Gate the plugin-publishing jobs on the release event instead of the tag
ref. Publishing a release creates the tag, firing both push:tags and
release:published; keying off the tag ref ran goreleaser twice
concurrently with two processes racing to upload the same assets. The
release-event gate makes it run exactly once.

Add an update-plugin-index job that, after goreleaser attaches the
archives and checksums.txt, opens a PR against milo-os/cli-plugins
bumping plugins/ipam.yaml to the released version with refreshed URLs
and checksums. Pinned to the datum-cloud/actions branch until that
workflow ships in a tagged release.
Mint a short-lived, repo-scoped installation token from a milo-os GitHub
App and pass it to the catalog-update job, instead of relying on a
long-lived PAT secret. The token is scoped to milo-os/cli-plugins and
expires in ~1 hour; the App's ID and private key are stored as secrets.
The reusable update-plugin-index workflow has shipped in a tagged release,
so pin to it instead of the development branch.
Collapse the token-mint and catalog-update jobs into a single job that mints
the GitHub App token and calls the composite action in the same job, so the
token isn't scrubbed crossing a job boundary.
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