diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 138fa55..770cd30 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,10 @@ jobs: plugin_kind: store plugin_alias: postgres service: postgres - busbar_ref: ${{ github.ref_name }} + busbar_ref: ${{ github.base_ref || github.ref_name }} + # base_ref FIRST: on a pull_request `github.ref_name` is '/merge', not a branch + # name, so this asked busbar for a branch called '5/merge' and the sibling checkout died + # with an unreadable git error on EVERY pull request to this repo. # NOTE: no extra_sibling_test_command here (unlike before this repo's 2-crate-workspace # restructure). `extra_sibling_test_command: cargo test -p busbar-store-postgres` used to # exercise the monorepo's own copy of the store logic against the sibling busbarAI checkout's diff --git a/.github/workflows/consumer-verify.yml b/.github/workflows/consumer-verify.yml new file mode 100644 index 0000000..f490bae --- /dev/null +++ b/.github/workflows/consumer-verify.yml @@ -0,0 +1,55 @@ +name: consumer-verify + +# Does what this repo PUBLISHED actually work when a user gets it? +# +# Every other workflow here reports on itself. ci.yml proves the code builds and its tests pass. +# release.yml's verify-assets proves the upload step believed it succeeded, asserted from inside the +# run that did the uploading. None of that is evidence about the artifact a user downloads, and the +# gap is not theoretical: webrequest-hook v1.0.4 published as a zero-asset phantom, and +# headroom-hook's published bundle could not boot the gateway because its shipped config used shapes +# busbar 1.5.3 retired. Both were green everywhere. Nothing anywhere noticed. +# +# The logic lives in ONE place for the whole fleet, exactly like plugin-ci.yml, so a fix reaches +# every plugin at once instead of being copied ten times and drifting nine. +# +# WHY BOTH TRIGGERS. release: published catches a broken publish immediately, and it fires whether or +# not the release workflow itself finished happy - which matters, because a verifier that only runs +# when everything already worked is not a verifier. The daily schedule catches ROT: an artifact that +# published fine can stop working later when nothing about it changed (a bundle that no longer boots +# against a newer engine, an asset deleted by hand, a release un-flagged as latest). A +# publish-time-only check structurally cannot see that class. +on: + release: + types: [published] + schedule: + - cron: " * * *" + workflow_dispatch: + inputs: + version: + description: "Version to verify (e.g. 1.0.4). Empty means the newest published release." + required: false + type: string + +permissions: + contents: read + issues: write + actions: read + +jobs: + consumer: + uses: GetBusbar/busbar/.github/workflows/plugin-consumer-verify.yml@dev + with: + version: ${{ inputs.version || '' }} + # Read off the PUBLISHED artifact, not guessed from the crate name: the filename prefix and the + # manifest name genuinely differ across this fleet (the store repos drop the trailing -plugin + # that the auth repos keep, and store-valkey publishes as busbar-store-redis). + asset_prefix: busbar-store-postgres + plugin_name: busbar-store-postgres-plugin + plugin_alias: postgres + plugin_kind: store + # This repo publishes a runnable bundle, so the check does not stop at 'the tarball exists': + # the image is pulled fresh and the container must BOOT and answer /healthz. That is the + # assertion that was missing when the published bundle shipped a config busbar had retired. + bundle_image: 43 9 + bundle_env: "" + secrets: inherit diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a016719..cc402da 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -249,3 +249,40 @@ jobs: -f event_type=upstream-release \ -f "client_payload[repo]=${GITHUB_REPOSITORY}" \ -f "client_payload[tag]=${GITHUB_REF_NAME}" + + # THE LAST STEP: does what we just published work for a user? + # + # Everything above verifies what THIS RUN produced, from inside this run. verify-assets asserts the + # assets it uploaded are present, which proves the run believed itself. It cannot prove the tarball + # downloads for a stranger, unpacks into a plugin busbar will load, or (where a bundle is + # published) boots. Those are the failures that shipped: a zero-asset phantom release, and a + # published bundle that exits 1 on startup. + # + # Consumer verification is POST-PUBLICATION by nature - you cannot download an asset that was never + # uploaded - so this cannot block the publish and does not pretend to. What it does is make the + # verdict impossible to miss: a failure is THIS release run's failure, and the shared workflow also + # opens or updates one labelled issue naming the failing check, expected, observed and the run URL. + # + # !cancelled() because a needs: on a FAILED job skips its dependent by default - the exact shape + # that skips a release's own guard precisely when the release is broken. + consumer-verification: + name: consumer verification (LAST STEP) + needs: [verify-assets] + if: ${{ !cancelled() }} + uses: GetBusbar/busbar/.github/workflows/plugin-consumer-verify.yml@dev + with: + version: ${{ github.ref_name }} + asset_prefix: busbar-store-postgres + plugin_name: busbar-store-postgres-plugin + plugin_alias: postgres + plugin_kind: store + # This repo publishes a runnable bundle, so the check does not stop at 'the tarball exists': + # the image is pulled fresh and the container must BOOT and answer /healthz. That is the + # assertion that was missing when the published bundle shipped a config busbar had retired. + bundle_image: 43 9 + bundle_env: "" + permissions: + contents: read + issues: write + actions: read + secrets: inherit