diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bfd5cba..a384aab 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,6 +16,12 @@ on: type: boolean default: true +# Single source of truth for the Homebrew tap location: the token-minting step +# scopes itself to it, and .goreleaser.yaml reads both from the environment. +env: + HOMEBREW_TAP_OWNER: ${{ github.repository_owner }} + HOMEBREW_TAP_REPO: homebrew-tap + jobs: release: runs-on: ubuntu-latest @@ -57,6 +63,17 @@ jobs: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + # Short-lived token scoped to the tap repository only, for the brews + # section. Skipped on a dry run, where GoReleaser never publishes it. + - name: Mint a Homebrew tap token + id: tap_token + if: ${{ github.event.inputs.dry_run != 'true' }} + uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 + with: + app-id: ${{ secrets.TAP_APP_ID }} + private-key: ${{ secrets.TAP_APP_PRIVATE_KEY }} + owner: ${{ env.HOMEBREW_TAP_OWNER }} + repositories: ${{ env.HOMEBREW_TAP_REPO }} - name: Execute GoReleaser uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # goreleaser-action v7 with: @@ -65,6 +82,10 @@ jobs: args: release --clean ${{ steps.resolve_tag.outputs.extra_flags }} --release-notes changes/${{ steps.resolve_tag.outputs.tag }}.md env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # Always defined: {{ .Env.HOMEBREW_TAP_TOKEN }} fails to render if the + # variable is missing. On a dry run the minting step is skipped, and the + # placeholder is never used because --snapshot publishes nothing. + HOMEBREW_TAP_TOKEN: ${{ steps.tap_token.outputs.token || 'dry-run' }} - name: Upload assets if: ${{ github.event.inputs.dry_run != 'true' }} uses: actions/upload-artifact@v7 diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 7ea5be1..9d155cf 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -24,10 +24,10 @@ builds: archives: - id: devcloud - format: tar.gz + formats: [ tar.gz ] format_overrides: - goos: windows - format: zip + formats: [ zip ] files: - LICENSE - README.md @@ -40,6 +40,27 @@ checksum: algorithm: sha256 name_template: 'CHECKSUMS' +# Publishes Formula/devcloud.rb to the tap repo named by HOMEBREW_TAP_OWNER and +# HOMEBREW_TAP_REPO (set in .github/workflows/release.yml). The token comes from +# a GitHub App installed only on that repository: the job's own GITHUB_TOKEN +# cannot write to another repo. +brews: +- ids: + - devcloud + repository: + owner: "{{ .Env.HOMEBREW_TAP_OWNER }}" + name: "{{ .Env.HOMEBREW_TAP_REPO }}" + token: "{{ .Env.HOMEBREW_TAP_TOKEN }}" + homepage: "https://github.com/{{ .Env.GITHUB_REPOSITORY_OWNER }}/{{ .ProjectName }}" + description: "Local development companion for cloud-native apps" + license: "Apache-2.0" + install: | + bin.install "devcloud" + # devcloud is a long-running server with no subcommands, so the test only + # asserts the flag usage text -- starting it would hang the test. + test: | + assert_match "-config", shell_output("#{bin}/devcloud -h 2>&1") + dockers_v2: - images: - ghcr.io/{{ .Env.GITHUB_REPOSITORY_OWNER }}/{{ .ProjectName }} diff --git a/changes/unreleased/Added-20260731-001220.yaml b/changes/unreleased/Added-20260731-001220.yaml new file mode 100644 index 0000000..75c30b4 --- /dev/null +++ b/changes/unreleased/Added-20260731-001220.yaml @@ -0,0 +1,5 @@ +kind: Added +body: Homebrew installation via `brew install skyoo2003/tap/devcloud`, published to the tap on each release +time: 2026-07-31T00:12:20.839744+09:00 +custom: + Issue: "121"