v0.30.15 #566
Workflow file for this run
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
| name: Publish | |
| on: | |
| release: | |
| types: [published] | |
| workflow_dispatch: | |
| inputs: | |
| tag: | |
| description: "Git tag to publish (e.g. v0.4.6)" | |
| required: true | |
| type: string | |
| dry_run: | |
| description: "Dry run — build everything but skip registry publishes" | |
| required: false | |
| default: false | |
| type: boolean | |
| force_republish: | |
| description: "Force publish even if version already exists" | |
| required: false | |
| default: false | |
| type: boolean | |
| targets: | |
| description: "Comma-separated targets (empty = all). Values: crates,cli,homebrew" | |
| required: false | |
| default: "" | |
| type: string | |
| repository_dispatch: | |
| types: [publish-release] | |
| concurrency: | |
| group: publish-${{ github.event.inputs.tag || github.ref_name || github.run_id }} | |
| cancel-in-progress: false | |
| permissions: | |
| contents: read | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| prepare: | |
| name: Prepare release | |
| runs-on: runner-medium | |
| outputs: | |
| tag: ${{ steps.meta.outputs.tag }} | |
| version: ${{ steps.meta.outputs.version }} | |
| checkout_ref: ${{ steps.meta.outputs.checkout_ref }} | |
| dry_run: ${{ steps.meta.outputs.dry_run }} | |
| force_republish: ${{ steps.meta.outputs.force_republish }} | |
| release_crates: ${{ steps.meta.outputs.release_crates }} | |
| release_cli: ${{ steps.meta.outputs.release_cli }} | |
| release_homebrew: ${{ steps.meta.outputs.release_homebrew }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 | |
| - name: Prepare release metadata | |
| id: meta | |
| uses: xberg-io/actions/prepare-release-metadata@v1 | |
| with: | |
| available-targets: crates,cli,homebrew | |
| # Bootstrap alef from main (build from source) so this step doesn't | |
| # try to download a binary from the just-created release tag — those | |
| # binaries don't exist yet (they're built later in this same run). | |
| alef-version: main | |
| validate-versions: | |
| name: Validate versions | |
| needs: prepare | |
| runs-on: runner-medium | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| ref: ${{ needs.prepare.outputs.checkout_ref }} | |
| - name: Validate manifest versions | |
| uses: xberg-io/actions/validate-versions@v1 | |
| with: | |
| version: ${{ needs.prepare.outputs.version }} | |
| alef-version: main | |
| check-cratesio: | |
| name: Check crates.io | |
| needs: prepare | |
| if: needs.prepare.outputs.release_crates == 'true' | |
| runs-on: runner-medium | |
| outputs: | |
| exists: ${{ steps.check.outputs.exists }} | |
| steps: | |
| - name: Check crates.io for alef | |
| id: check | |
| uses: xberg-io/actions/check-registry@v1 | |
| with: | |
| registry: cratesio | |
| package: alef | |
| version: ${{ needs.prepare.outputs.version }} | |
| alef-version: main | |
| check-github-release: | |
| name: Check GitHub release | |
| needs: prepare | |
| if: needs.prepare.outputs.release_cli == 'true' | |
| runs-on: runner-medium | |
| outputs: | |
| exists: ${{ steps.check.outputs.exists }} | |
| steps: | |
| - name: Check GitHub release assets | |
| id: check | |
| uses: xberg-io/actions/check-registry@v1 | |
| with: | |
| registry: github-release | |
| package: alef | |
| version: ${{ needs.prepare.outputs.version }} | |
| tag: ${{ needs.prepare.outputs.tag }} | |
| asset-prefix: alef- | |
| repo: xberg-io/alef | |
| alef-version: main | |
| check-homebrew: | |
| name: Check Homebrew tap | |
| needs: prepare | |
| if: needs.prepare.outputs.release_homebrew == 'true' | |
| runs-on: runner-medium | |
| outputs: | |
| exists: ${{ steps.check.outputs.exists }} | |
| steps: | |
| - name: Check Homebrew formula | |
| id: check | |
| uses: xberg-io/actions/check-registry@v1 | |
| with: | |
| registry: homebrew | |
| package: alef | |
| version: ${{ needs.prepare.outputs.version }} | |
| tap-repo: xberg-io/homebrew-tap | |
| alef-version: main | |
| build-cli: | |
| name: Build CLI (${{ matrix.label }}) | |
| needs: [prepare, validate-versions, check-github-release] | |
| if: | | |
| always() && | |
| needs.prepare.outputs.release_cli == 'true' && | |
| needs.validate-versions.result == 'success' && | |
| (needs.check-github-release.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - label: linux-x86_64 | |
| runner: runner-medium | |
| target: x86_64-unknown-linux-gnu | |
| - label: linux-aarch64 | |
| runner: runner-medium-arm64 | |
| target: aarch64-unknown-linux-gnu | |
| - label: macos-arm64 | |
| runner: macos-latest | |
| target: aarch64-apple-darwin | |
| runs-on: ${{ matrix.runner }} | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| ref: ${{ needs.prepare.outputs.checkout_ref }} | |
| - name: Setup Rust | |
| uses: xberg-io/actions/setup-rust@v1 | |
| with: | |
| target: ${{ matrix.target }} | |
| cache-key-prefix: publish-cli-${{ matrix.label }} | |
| install-llvm-cov: "false" | |
| macos-dynamic-lookup: "false" | |
| disable-cache: ${{ runner.os == 'Windows' && 'true' || 'false' }} | |
| - name: Build CLI | |
| id: build | |
| uses: xberg-io/actions/build-rust-cli@v1 | |
| with: | |
| package-name: alef | |
| binary-name: alef | |
| target: ${{ matrix.target }} | |
| - name: Create release archive | |
| id: archive | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| ARCHIVE_DIR="alef-${{ matrix.target }}" | |
| mkdir -p "${ARCHIVE_DIR}" | |
| cp "${{ steps.build.outputs.binary-path }}" "${ARCHIVE_DIR}/" | |
| if [[ "${{ runner.os }}" == "Windows" ]]; then | |
| ARCHIVE_NAME="alef-${{ matrix.target }}.zip" | |
| 7z a "${ARCHIVE_NAME}" "${ARCHIVE_DIR}" | |
| else | |
| ARCHIVE_NAME="alef-${{ matrix.target }}.tar.gz" | |
| tar -czf "${ARCHIVE_NAME}" "${ARCHIVE_DIR}" | |
| fi | |
| echo "path=${ARCHIVE_NAME}" >> "$GITHUB_OUTPUT" | |
| echo "name=${ARCHIVE_NAME}" >> "$GITHUB_OUTPUT" | |
| - name: Upload CLI artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: cli-${{ matrix.label }} | |
| path: ${{ steps.archive.outputs.path }} | |
| retention-days: 14 | |
| publish-homebrew-formula: | |
| name: Update Homebrew formula | |
| needs: [prepare, validate-versions, check-homebrew, publish-crates] | |
| if: | | |
| always() && | |
| needs.prepare.outputs.release_homebrew == 'true' && | |
| needs.prepare.outputs.dry_run != 'true' && | |
| needs.validate-versions.result == 'success' && | |
| (needs.check-homebrew.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') && | |
| needs.publish-crates.result != 'failure' | |
| runs-on: runner-medium | |
| steps: | |
| - uses: actions/create-github-app-token@v3 | |
| id: tap-token | |
| with: | |
| app-id: ${{ secrets.BOT_APP_ID }} | |
| private-key: ${{ secrets.BOT_APP_PRIVATE_KEY }} | |
| owner: xberg-io | |
| repositories: homebrew-tap | |
| - uses: actions/checkout@v7 | |
| with: | |
| ref: ${{ needs.prepare.outputs.checkout_ref }} | |
| - uses: actions/checkout@v7 | |
| with: | |
| repository: xberg-io/homebrew-tap | |
| token: ${{ steps.tap-token.outputs.token }} | |
| path: homebrew-tap | |
| - name: Update formula | |
| env: | |
| TAG: ${{ needs.prepare.outputs.tag }} | |
| VERSION: ${{ needs.prepare.outputs.version }} | |
| TAP_DIR: ${{ github.workspace }}/homebrew-tap | |
| run: scripts/publish/update-homebrew-formula.sh | |
| - name: Commit and push formula | |
| working-directory: homebrew-tap | |
| env: | |
| GH_TOKEN: ${{ steps.tap-token.outputs.token }} | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| if git diff --quiet Formula/alef.rb; then | |
| echo "No formula changes; skipping commit." | |
| exit 0 | |
| fi | |
| git add Formula/alef.rb | |
| git commit -m "alef ${{ needs.prepare.outputs.version }}" | |
| git push origin HEAD | |
| homebrew-bottles: | |
| name: Build Homebrew bottle (${{ matrix.bottle_tag }}) | |
| needs: [prepare, publish-homebrew-formula] | |
| if: | | |
| always() && | |
| needs.prepare.outputs.release_homebrew == 'true' && | |
| needs.prepare.outputs.dry_run != 'true' && | |
| needs.publish-homebrew-formula.result == 'success' | |
| runs-on: ${{ matrix.os }} | |
| timeout-minutes: 90 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: macos-latest | |
| bottle_tag: arm64_sequoia | |
| install_brew: false | |
| - os: macos-15-intel | |
| bottle_tag: sequoia | |
| install_brew: false | |
| - os: ubuntu-latest | |
| bottle_tag: x86_64_linux | |
| install_brew: true | |
| - os: ubuntu-24.04-arm | |
| bottle_tag: arm64_linux | |
| install_brew: true | |
| steps: | |
| - uses: actions/create-github-app-token@v3 | |
| id: app-token | |
| with: | |
| app-id: ${{ secrets.BOT_APP_ID }} | |
| private-key: ${{ secrets.BOT_APP_PRIVATE_KEY }} | |
| owner: xberg-io | |
| - uses: actions/checkout@v7 | |
| with: | |
| ref: ${{ needs.prepare.outputs.checkout_ref }} | |
| - name: Install Homebrew (Linux) | |
| if: ${{ matrix.install_brew }} | |
| uses: xberg-io/actions/install-homebrew-linux@v1 | |
| - name: Build bottles | |
| uses: xberg-io/actions/homebrew-build-bottles@v1 | |
| with: | |
| tag: ${{ needs.prepare.outputs.tag }} | |
| version: ${{ needs.prepare.outputs.version }} | |
| tap: xberg-io/homebrew-tap | |
| formulas: alef | |
| out-dir: ${{ github.workspace }}/bottle-json | |
| github-repo: xberg-io/alef | |
| token: ${{ steps.app-token.outputs.token }} | |
| - name: Upload bottle JSON manifests | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: homebrew-bottle-json-${{ matrix.bottle_tag }} | |
| path: ${{ github.workspace }}/bottle-json/*.json | |
| if-no-files-found: error | |
| retention-days: 14 | |
| publish-homebrew-bottles: | |
| name: Merge Homebrew bottle DSL | |
| needs: [prepare, publish-homebrew-formula, homebrew-bottles] | |
| if: | | |
| always() && | |
| needs.prepare.outputs.release_homebrew == 'true' && | |
| needs.prepare.outputs.dry_run != 'true' && | |
| needs.publish-homebrew-formula.result == 'success' && | |
| needs.homebrew-bottles.result == 'success' | |
| runs-on: runner-medium | |
| steps: | |
| - uses: actions/create-github-app-token@v3 | |
| id: tap-token | |
| with: | |
| app-id: ${{ secrets.BOT_APP_ID }} | |
| private-key: ${{ secrets.BOT_APP_PRIVATE_KEY }} | |
| owner: xberg-io | |
| repositories: homebrew-tap | |
| - uses: actions/checkout@v7 | |
| with: | |
| ref: ${{ needs.prepare.outputs.checkout_ref }} | |
| - uses: actions/checkout@v7 | |
| with: | |
| repository: xberg-io/homebrew-tap | |
| token: ${{ steps.tap-token.outputs.token }} | |
| path: homebrew-tap | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| pattern: homebrew-bottle-json-* | |
| path: ${{ github.workspace }}/bottle-json | |
| merge-multiple: true | |
| - name: Merge bottle DSL into formula | |
| uses: xberg-io/actions/homebrew-merge-bottles@v1 | |
| with: | |
| tag: ${{ needs.prepare.outputs.tag }} | |
| version: ${{ needs.prepare.outputs.version }} | |
| tap-dir: ${{ github.workspace }}/homebrew-tap | |
| json-dir: ${{ github.workspace }}/bottle-json | |
| formulas: alef | |
| github-repo: xberg-io/alef | |
| - name: Commit and push bottle DSL | |
| working-directory: homebrew-tap | |
| env: | |
| GH_TOKEN: ${{ steps.tap-token.outputs.token }} | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| if git diff --quiet Formula/alef.rb; then | |
| echo "No bottle DSL changes; skipping commit." | |
| exit 0 | |
| fi | |
| git add Formula/alef.rb | |
| git commit -m "alef ${{ needs.prepare.outputs.version }}: add bottle DSL" | |
| git push origin HEAD | |
| upload-release-assets: | |
| name: Upload release assets | |
| needs: [prepare, validate-versions, check-github-release, build-cli] | |
| if: | | |
| always() && | |
| needs.prepare.outputs.release_cli == 'true' && | |
| needs.validate-versions.result == 'success' && | |
| needs.build-cli.result == 'success' && | |
| (needs.check-github-release.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') | |
| runs-on: runner-medium | |
| steps: | |
| - uses: actions/create-github-app-token@v3 | |
| id: app-token | |
| with: | |
| app-id: ${{ secrets.BOT_APP_ID }} | |
| private-key: ${{ secrets.BOT_APP_PRIVATE_KEY }} | |
| owner: xberg-io | |
| - uses: actions/checkout@v7 | |
| with: | |
| ref: ${{ needs.prepare.outputs.checkout_ref }} | |
| - name: Download all CLI artifacts | |
| uses: actions/download-artifact@v8 | |
| with: | |
| pattern: cli-* | |
| path: dist/cli | |
| merge-multiple: true | |
| - name: Upload CLI artifacts to release | |
| uses: xberg-io/actions/publish-github-release@v1 | |
| with: | |
| tag: ${{ needs.prepare.outputs.tag }} | |
| title: ${{ needs.prepare.outputs.tag }} | |
| artifacts: "dist/cli/*" | |
| generate-notes: "false" | |
| draft: "false" | |
| dry-run: ${{ needs.prepare.outputs.dry_run }} | |
| token: ${{ steps.app-token.outputs.token }} | |
| publish-crates: | |
| name: Publish crates.io | |
| needs: [prepare, validate-versions, check-cratesio] | |
| if: | | |
| always() && | |
| needs.prepare.outputs.release_crates == 'true' && | |
| needs.validate-versions.result == 'success' && | |
| (needs.check-cratesio.outputs.exists != 'true' || needs.prepare.outputs.force_republish == 'true') | |
| runs-on: runner-medium | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| ref: ${{ needs.prepare.outputs.checkout_ref }} | |
| - name: Setup Rust | |
| uses: xberg-io/actions/setup-rust@v1 | |
| with: | |
| install-llvm-cov: "false" | |
| - name: Publish to crates.io | |
| uses: xberg-io/actions/publish-crates@v1 | |
| with: | |
| crates: alef | |
| version: ${{ needs.prepare.outputs.version }} | |
| dry-run: ${{ needs.prepare.outputs.dry_run }} | |
| finalize: | |
| name: Finalize release | |
| needs: [prepare, upload-release-assets, publish-crates, publish-homebrew-bottles] | |
| if: always() | |
| runs-on: runner-medium | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| ref: ${{ needs.prepare.outputs.checkout_ref }} | |
| - name: Publish summary | |
| if: always() | |
| run: | | |
| { | |
| echo "## Release ${{ needs.prepare.outputs.tag }}" | |
| echo "" | |
| echo "| Registry | Status |" | |
| echo "|----------|--------|" | |
| } >> "$GITHUB_STEP_SUMMARY" | |
| report() { | |
| local name="$1" result="$2" | |
| case "$result" in | |
| success) echo "| $name | :white_check_mark: Published |" ;; | |
| skipped) echo "| $name | :fast_forward: Skipped |" ;; | |
| *) echo "| $name | :x: $result |" ;; | |
| esac | |
| } | |
| { | |
| report "crates.io" "${{ needs.publish-crates.result }}" | |
| report "GitHub Release" "${{ needs.upload-release-assets.result }}" | |
| report "Homebrew" "${{ needs.publish-homebrew-bottles.result }}" | |
| } >> "$GITHUB_STEP_SUMMARY" |