Skip to content

release.yml: pin busbar sibling at the v1.5.0 release SHA #5

release.yml: pin busbar sibling at the v1.5.0 release SHA

release.yml: pin busbar sibling at the v1.5.0 release SHA #5

Workflow file for this run

# Release: on a version tag (e.g. v1.0.0), build the store-mysql plugin cdylib for all 5
# supported targets, pack + sign each into a loadable busbar plugin tarball, and publish them to
# THIS repo's own GitHub Release.
#
# Same 5-target matrix, same busbar-plugin-pack pack/sign step (built from a sibling busbar
# checkout), same BUSBAR_SIGN_KEY-or-`--allow-unsigned` fallback, same `gh release upload` +
# build-provenance attestation pattern busbar's own plugins use — but every plugin (including this
# one) now releases from its own repo; busbarAI no longer has a combined `store-plugins` release
# job to mirror.
#
# This plugin's own version (the `v*` tag pushed here) is NOT tied to busbar's version number —
# it is independently versioned starting at 0.5.0 (see README), separate from whichever busbar
# commit it happens to build against via BUSBAR_REF below.
name: release
on:
push:
tags:
- "v*"
permissions:
contents: write # create the Release + upload assets
id-token: write # OIDC identity for keyless Sigstore signing (provenance)
attestations: write # record the build-provenance attestation
env:
# Which busbar commit to check out as the sibling path dependency (used only to build
# busbar-plugin-pack, which then packs + signs this plugin under BUSBAR_SIGN_KEY) — same
# BUSBAR_REF convention ci.yml / plugin-ci.yml already established. Pinned to a commit SHA on
# the 1.5.0-dev branch, not the branch name itself, since a mutable branch checked out while
# holding the signing key is a supply-chain foot-gun. To bump deliberately: confirm the new SHA
# builds busbar-plugin-pack cleanly, then update this value in a reviewed PR — never track the
# branch automatically. Update to a `main` SHA once busbar 1.5.0 actually ships; until then the
# plugin ABI surface this crate depends on only exists on 1.5.0-dev.
BUSBAR_REF: 5b78db9fe0059a08907978f15bcde67e8cd757f9 # v1.5.0 release SHA (GetBusbar/busbar main, 2026-08-02)
jobs:
# Create the Release first so the parallel per-target upload jobs have something to attach to
# (uploading from a matrix without a pre-existing release races -> "release not found").
create-release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Create GitHub Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
if ! out=$(gh release create "${GITHUB_REF_NAME}" \
--repo "${GITHUB_REPOSITORY}" \
--title "busbar-store-mysql ${GITHUB_REF_NAME}" \
--verify-tag --generate-notes 2>&1); then
if echo "$out" | grep -qi "already exists"; then
echo "$out"
echo "Release ${GITHUB_REF_NAME} already exists — reusing it (parallel matrix re-run or race)."
gh release view "${GITHUB_REF_NAME}" --repo "${GITHUB_REPOSITORY}"
else
echo "$out" >&2
exit 1
fi
else
echo "$out"
fi
# One signed .tar.gz per target: {cdylib + manifest.json}, packed by busbar-plugin-pack and
# signed with the busbar release PRIVATE key (BUSBAR_SIGN_KEY secret) so it verifies as
# first-party against the PUBLIC key embedded in busbar's own release binaries. If that secret
# isn't provisioned on this repo, falls back to an UNSIGNED tarball (loadable only under
# plugins.trust.allow_unsigned) rather than blocking the release — same seam busbarAI's own
# release.yml documents (TODO(release-keys)).
store-plugin:
needs: create-release
name: store-plugin (${{ matrix.target }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- target: x86_64-unknown-linux-gnu
os: ubuntu-latest
libext: so
libprefix: lib
- target: aarch64-unknown-linux-gnu
os: ubuntu-24.04-arm
libext: so
libprefix: lib
- target: x86_64-apple-darwin
os: macos-latest
libext: dylib
libprefix: lib
- target: aarch64-apple-darwin
os: macos-latest
libext: dylib
libprefix: lib
- target: x86_64-pc-windows-msvc
os: windows-latest
libext: dll
libprefix: ""
steps:
- name: Checkout store-mysql
uses: actions/checkout@v7
with:
path: store-mysql
- name: Checkout busbar (sibling path dependency)
uses: actions/checkout@v7
with:
repository: GetBusbar/busbar
ref: ${{ env.BUSBAR_REF }}
path: busbarAI
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- uses: Swatinem/rust-cache@v2
- name: Build the store-mysql plugin cdylib
working-directory: store-mysql
run: cargo build --release --target ${{ matrix.target }}
shell: bash
- name: Build busbar-plugin-pack (from the sibling busbar checkout)
working-directory: busbarAI
run: cargo build --release --target ${{ matrix.target }} -p busbar-plugin-pack
shell: bash
- name: Package + sign the plugin tarball
env:
BUSBAR_SIGN_KEY: ${{ secrets.BUSBAR_SIGN_KEY }}
run: |
set -euo pipefail
ver="${GITHUB_REF_NAME#v}"
target="${{ matrix.target }}"
outdir="plugin-dist"; mkdir -p "$outdir"
pack="busbarAI/target/${target}/release/busbar-plugin-pack"
[ -x "$pack" ] || pack="busbarAI/target/${target}/release/busbar-plugin-pack.exe"
unsigned_flag=""
if [ -z "${BUSBAR_SIGN_KEY:-}" ]; then
echo "::warning::BUSBAR_SIGN_KEY secret is not provisioned — packaging an UNSIGNED plugin tarball (loadable only under plugins.trust.allow_unsigned). See busbarAI's release.yml TODO(release-keys) seam."
unsigned_flag="--allow-unsigned"
fi
lib="store-mysql/target/${target}/release/${{ matrix.libprefix }}busbar_store_mysql_plugin.${{ matrix.libext }}"
"$pack" pack \
--lib "$lib" \
--name "busbar-store-mysql-plugin" --alias "mysql" --kind store \
--version "$ver" --publisher busbar \
--description "First-party signed kind:store plugin cdylib: the MySQL/MariaDB backend for busbar's durable governance store, exported over the store C ABI. Drop the built library into the plugins folder and set store.module: mysql to share virtual keys, budgets, and usage across a fleet of busbar nodes." \
--license Apache-2.0 \
--out "${outdir}/busbar-store-mysql-${ver}-${target}.tar.gz" \
$unsigned_flag
ls -l "$outdir"
shell: bash
- name: Attach plugin tarball to Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh release upload "${GITHUB_REF_NAME}" plugin-dist/*.tar.gz --repo "${GITHUB_REPOSITORY}" --clobber
shell: bash
# Keyless (Sigstore/OIDC) build-provenance attestation binding this tarball's digest to this
# workflow run + commit — `gh attestation verify <tarball> --repo ${{ github.repository }}`.
- name: Attest plugin build provenance
uses: actions/attest-build-provenance@v4
with:
subject-path: "plugin-dist/*.tar.gz"
# Instant marketing-site rebuild the moment this plugin ships a real release -- marketing's
# deploy.yml listens for this exact repository_dispatch event type (plus its own daily-poll
# fallback, so a missed/failed dispatch here is never a permanent gap). Same RELEASE_DISPATCH_TOKEN
# pattern busbar core's own release.yml uses for its downstream fan-out -- see that file's
# notify-downstream job for the template this mirrors. Fails loud (not a silent no-op) if the
# secret isn't provisioned, so a missing secret can't masquerade as "nothing to notify."
notify-marketing:
needs: [store-plugin]
runs-on: ubuntu-latest
steps:
- name: Dispatch upstream-release to the marketing site
env:
GH_TOKEN: ${{ secrets.RELEASE_DISPATCH_TOKEN }}
run: |
set -euo pipefail
if [ -z "${GH_TOKEN:-}" ]; then
echo "::error::RELEASE_DISPATCH_TOKEN is not provisioned on this repo -- cannot notify" \
"marketing instantly. marketing's own daily poll will still pick this release up" \
"within 24h (self-healing fallback intact)." >&2
exit 1
fi
gh api "repos/GetBusbar/marketing/dispatches" \
-f event_type=upstream-release \
-f "client_payload[repo]=${GITHUB_REPOSITORY}" \
-f "client_payload[tag]=${GITHUB_REF_NAME}"