Release Ruby custom-build (bt-publishing-test) #20
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # | |
| # Reference implementation of the v2 Ruby CUSTOM-BUILD ("build-ownership") shape, using | |
| # bt-publishing-test. This does NOT release a real gem. | |
| # | |
| # Same pipeline as turnkey, cut at the build⟷publish seam: | |
| # configure (facts + manifest) → validate (gate) → pack (unprivileged build) → | |
| # request-approval → [gate] → ship-package | |
| # pack builds + attests the gem with NO publish credentials and uploads it; ship-package | |
| # (gated) verifies its attestations and `gem push`es THAT exact gem. | |
| # | |
| # SETUP: RubyGems Trusted Publishing must list THIS workflow filename | |
| # (release-ruby-custom.yml) + the `publish` environment. Only ship-package publishes. | |
| name: Release Ruby custom-build (bt-publishing-test) | |
| on: | |
| pull_request: | |
| paths: | |
| - 'actions/**' | |
| - '.github/workflows/**' | |
| workflow_dispatch: | |
| inputs: | |
| release_type: | |
| description: "Release type — maps to the github_release default" | |
| type: choice | |
| default: stable | |
| options: [stable, prerelease] | |
| sha: | |
| description: "Commit SHA (of the version bump) to release" | |
| required: true | |
| type: string | |
| prev_release: | |
| description: "Anchor for release notes: a tag name or commit SHA." | |
| type: string | |
| required: false | |
| default: '58a397193105516446c3042361913655bcece509' | |
| dry_run: | |
| description: "Dry run: build + pack (no attest, no publish)" | |
| type: boolean | |
| default: false | |
| jobs: | |
| bump: | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 5 | |
| permissions: {} | |
| outputs: | |
| version: ${{ steps.bump.outputs.version }} | |
| steps: | |
| - name: Bump version | |
| id: bump | |
| run: | | |
| CURRENT=$(curl -sf https://rubygems.org/api/v1/gems/bt-publishing-test.json 2>/dev/null | jq -r '.version // empty' 2>/dev/null || true) | |
| CURRENT=${CURRENT:-0.0.0} | |
| IFS='.' read -r major minor patch <<< "$CURRENT" | |
| echo "version=$major.$minor.$((patch + 1))" >> $GITHUB_OUTPUT | |
| configure: | |
| needs: bump | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 5 | |
| permissions: | |
| contents: write | |
| outputs: | |
| version: ${{ steps.configure.outputs.version }} | |
| release_tag: ${{ steps.configure.outputs.release_tag }} | |
| prev_release: ${{ steps.configure.outputs.prev_release }} | |
| branch: ${{ steps.configure.outputs.branch }} | |
| on_release_branch: ${{ steps.configure.outputs.on_release_branch }} | |
| already_published: ${{ steps.configure.outputs.already_published }} | |
| notes: ${{ steps.configure.outputs.notes }} | |
| package: ${{ steps.configure.outputs.package }} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: Configure release | |
| id: configure | |
| uses: ./actions/release/lang/ruby/configure | |
| with: | |
| version: ${{ needs.bump.outputs.version }} | |
| sha: ${{ inputs.sha || github.event.pull_request.head.sha }} | |
| working_directory: test/release/ruby | |
| release_type: ${{ inputs.release_type || 'stable' }} | |
| rubygems_package_name: bt-publishing-test | |
| package_label: 'bt-publishing-test' | |
| emoji: ':ruby:' | |
| prev_release: ${{ inputs.prev_release || github.event.pull_request.head.sha }} | |
| validate: | |
| needs: [bump, configure] | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 10 | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: Validate release | |
| uses: ./actions/release/lang/ruby/validate | |
| with: | |
| sha: ${{ inputs.sha || github.event.pull_request.head.sha }} | |
| dry_run: ${{ inputs.dry_run || github.event_name == 'pull_request' }} | |
| working_directory: test/release/ruby | |
| release_tag: ${{ needs.configure.outputs.release_tag }} | |
| on_release_branch: ${{ needs.configure.outputs.on_release_branch }} | |
| notes: ${{ needs.configure.outputs.notes }} | |
| already_published: ${{ needs.configure.outputs.already_published }} | |
| build: 'false' # the pack job owns the build (lint still runs) | |
| sbom: 'false' # pack generates + attests the SBOM | |
| # BUILD side — unprivileged: NO publish credentials. | |
| pack: | |
| needs: [bump, configure, validate] | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 15 | |
| permissions: | |
| contents: read | |
| id-token: write | |
| attestations: write | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| ref: ${{ inputs.sha || github.event.pull_request.head.sha }} | |
| fetch-depth: 0 | |
| # bt-publishing-test: write the resolved version into version.rb + Gemfile.lock. | |
| - name: Apply version to version.rb and Gemfile.lock | |
| env: | |
| VERSION: ${{ needs.configure.outputs.version }} | |
| run: | | |
| sed -i "s|VERSION = \".*\"|VERSION = \"$VERSION\"|" \ | |
| test/release/ruby/lib/bt_publishing_test/version.rb | |
| sed -i "s|bt-publishing-test ([0-9]*\.[0-9]*\.[0-9]*)|bt-publishing-test ($VERSION)|" \ | |
| test/release/ruby/Gemfile.lock | |
| - name: Pack + attest | |
| uses: ./actions/release/lang/ruby/pack | |
| with: | |
| sha: ${{ inputs.sha || github.event.pull_request.head.sha }} | |
| checkout: 'false' | |
| working_directory: test/release/ruby | |
| dry_run: ${{ inputs.dry_run || github.event_name == 'pull_request' }} | |
| # Stage the exact built gem + SBOM for the gated ship job. | |
| - name: Stage artifact | |
| run: | | |
| mkdir -p artifact | |
| cp test/release/ruby/pkg/*.gem artifact/ | |
| cp test/release/ruby/sbom.json artifact/ 2>/dev/null || true | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: release-package | |
| path: artifact/ | |
| retention-days: 1 | |
| if-no-files-found: error | |
| request-approval: | |
| needs: [configure, validate, pack] | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 5 | |
| permissions: {} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: Request release approval | |
| uses: ./actions/release/request-approval | |
| with: | |
| packages: '[${{ needs.configure.outputs.package }}]' | |
| sha: ${{ inputs.sha || github.event.pull_request.head.sha }} | |
| branch: ${{ needs.configure.outputs.branch }} | |
| on_release_branch: ${{ needs.configure.outputs.on_release_branch }} | |
| commit_message: ${{ needs.configure.outputs.commit_message }} | |
| dry_run: ${{ inputs.dry_run || github.event_name == 'pull_request' }} | |
| slack_token: ${{ github.event_name != 'pull_request' && secrets.SLACK_BOT_TOKEN || '' }} | |
| slack_channel: ${{ github.event_name != 'pull_request' && vars.SLACK_SDK_RELEASE_CHANNEL || '' }} | |
| # PUBLISH side — gated. | |
| ship-package: | |
| needs: [configure, validate, pack, request-approval] | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 15 | |
| environment: >- | |
| ${{ github.event_name != 'pull_request' | |
| && (inputs.dry_run && 'publish-dry-run' || 'publish') | |
| || '' }} | |
| permissions: | |
| contents: write | |
| id-token: write # OIDC trusted publishing | |
| attestations: read # gh attestation verify | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| - name: Download artifact | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: release-package | |
| path: dl | |
| - name: Ship package | |
| uses: ./actions/release/lang/ruby/ship-package | |
| with: | |
| working_directory: dl # holds the .gem + sbom.json | |
| sha: ${{ inputs.sha || github.event.pull_request.head.sha }} | |
| dry_run: ${{ inputs.dry_run || github.event_name == 'pull_request' }} | |
| release_tag: ${{ needs.configure.outputs.release_tag }} | |
| already_published: ${{ needs.configure.outputs.already_published }} | |
| # ⚠️ TEST-BED EXCEPTION — do NOT copy. Real consumers wire the derived value: | |
| # github_release: ${{ needs.configure.outputs.github_release }} | |
| github_release: 'false' | |
| gem_name: bt-publishing-test | |
| version: ${{ needs.configure.outputs.version }} | |
| label: bt-publishing-test | |
| notes: ${{ needs.configure.outputs.notes }} | |
| prev_release: ${{ needs.configure.outputs.prev_release }} | |
| branch: ${{ needs.configure.outputs.branch }} | |
| on_release_branch: ${{ needs.configure.outputs.on_release_branch }} | |
| slack_token: ${{ github.event_name != 'pull_request' && secrets.SLACK_BOT_TOKEN || '' }} | |
| slack_channel: ${{ github.event_name != 'pull_request' && vars.SLACK_SDK_RELEASE_CHANNEL || '' }} | |
| emoji: ':ruby:' |