From 38ec8280814ad7d0a65f5f7b278ae37eacc570ea Mon Sep 17 00:00:00 2001 From: Ryan L'Italien Date: Wed, 9 Sep 2026 17:09:28 -0400 Subject: [PATCH] ci: tag-driven GitHub Releases Add a release workflow triggered only by pushing a v* tag, matching the house pattern already used in butterstack-connector. The tag run re-runs the same marketplace lint as lint.yml (so a release can never be cut from a broken manifest) and then cuts a GitHub Release with generated notes. This repo has no build artifact, so the release step is the whole job. Per-plugin versions in each plugin.json are untouched and keep moving on their own independent cadence; the tag only versions the collection. Also documents the strategy in a short README Releases section. --- .github/workflows/release.yml | 55 +++++++++++++++++++++++++++++++++++ README.md | 10 +++++++ 2 files changed, 65 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..8386272 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,55 @@ +# Cut a release by pushing a tag: `git tag v0.3.0 && git push origin v0.3.0`. +# Produces: a GitHub Release on this repo, titled and noted from the commits +# since the previous tag. There is no build artifact to publish - this repo +# is a Claude Code plugin marketplace manifest, not a binary or package - so +# cutting the release is the workflow's only job, gated by the same lint the +# `lint.yml` workflow runs on every push and PR, so a tag can never cut a +# release from a broken marketplace manifest. +# Plugin versions move independently of this tag: each plugin carries its own +# version in its own `.claude-plugin/plugin.json` (perforce at 0.2.0, unreal +# at 0.1.0, and so on) and releases on its own cadence. This tag versions the +# collection, not any individual plugin - do not bump a plugin's version to +# match it. +# Merging to main publishes nothing; only a `v*` tag push triggers this. +name: release +on: + push: + tags: ["v*"] +permissions: + contents: write +jobs: + release: + runs-on: ubuntu-latest + timeout-minutes: 10 + env: + CI: "true" + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + + - name: Install Claude Code CLI (provides `claude plugin validate`) + run: npm install -g @anthropic-ai/claude-code + + - name: Ensure shellcheck is available + run: | + if ! command -v shellcheck >/dev/null 2>&1; then + sudo apt-get update && sudo apt-get install -y shellcheck + fi + shellcheck --version + + - name: Lint plugins + run: ./scripts/lint-plugins.sh + + - name: Publish release + env: + GH_TOKEN: ${{ github.token }} + run: | + gh release create "${GITHUB_REF_NAME}" \ + --title "${GITHUB_REF_NAME}" \ + --generate-notes \ + --verify-tag diff --git a/README.md b/README.md index 376f3a6..faa65aa 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,16 @@ are especially valuable - behavior varies a lot by server/engine version and set This repo's own content is kept current from ButterStack's private working repo on a standing basis - see [DISTILLING.md](./DISTILLING.md) for the process. +## Releases + +The repo tag versions the collection, not any individual plugin. Each plugin +carries its own version in its own `.claude-plugin/plugin.json` and moves on +its own cadence - perforce and unity can sit at 0.2.0 while unreal, lore, +godot, and jenkins are still at 0.1.0, and that's expected. + +Cut a release by pushing a tag: `git tag v0.3.0 && git push origin v0.3.0`. +Merging to main publishes nothing. + ## License MIT. See [LICENSE](./LICENSE).