diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2082dc8..7bcb818 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,4 +1,16 @@ name: Release Go binaries + +# Two paths land here: +# pull_request — runs the test job (vet + race-detector tests across the +# whole module) so every PR proves the binary still builds and passes +# all tests, not just cmd/molecule. +# push tags v* — runs test + GoReleaser to cut multi-OS binaries (linux/ +# darwin/windows × amd64/arm64), checksums, and a GitHub Release. The +# release config lives in .goreleaser.yaml. +# +# Why GoReleaser over inline `go build`: checksums, release notes from +# git commits, and one config file that future channels (Homebrew tap, +# scoop bucket, Chocolatey) hook into without adding new workflow steps. on: push: tags: ['v*'] @@ -7,6 +19,8 @@ on: - '**.go' - 'go.mod' - 'go.sum' + - '.github/workflows/release.yml' + - '.goreleaser.yaml' permissions: contents: write @@ -17,40 +31,45 @@ jobs: steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 - with: { go-version: '1.25' } + with: + go-version: '1.25' + cache: true - name: Tidy run: go mod tidy && git diff --exit-code go.sum + # Vet covers the whole module — was previously scoped to three + # packages, which silently let regressions in internal/backends/ + # or internal/connect/ ship. - name: Vet - run: go vet ./cmd/molecule/... ./internal/client/... ./internal/cmd/... + run: go vet ./... + # Race detector required: the connect orchestrator runs + # heartbeat + poll goroutines concurrently. A race here would + # corrupt cursor state. - name: Test - run: go test ./cmd/molecule/... + run: go test -race -count=1 ./... release: runs-on: ubuntu-latest needs: [test] - strategy: - matrix: - include: - - goos: linux - goarch: amd64 - - goos: linux - goarch: arm64 - - goos: darwin - goarch: amd64 - - goos: darwin - goarch: arm64 - - goos: windows - goarch: amd64 + if: startsWith(github.ref, 'refs/tags/v') steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: { go-version: '1.25' } - - name: Build - run: | - GOOS=${{ matrix.goos }} GOARCH=${{ matrix.goarch }} \ - go build -o molecule-${{ matrix.goos }}-${{ matrix.goarch }}${{ matrix.goos == 'windows' && '.exe' || '' }} \ - ./cmd/molecule - - uses: softprops/action-gh-release@v2 with: - files: molecule-* - if: startsWith(github.ref, 'refs/tags/v') + # GoReleaser needs full history for its commit-based + # changelog. fetch-depth: 0 pulls everything. + fetch-depth: 0 + - uses: actions/setup-go@v5 + with: + go-version: '1.25' + cache: true + - name: Validate goreleaser config + uses: goreleaser/goreleaser-action@v6 + with: + version: '~> v2' + args: check + - name: Run GoReleaser + uses: goreleaser/goreleaser-action@v6 + with: + version: '~> v2' + args: release --clean + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 1907f23..851ca25 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -1,16 +1,14 @@ # GoReleaser configuration for molecule-cli # https://goreleaser.com/install/ # -# .goreleaser.yaml is the main config file for GoReleaser. -# This file must be committed. GoReleaser reads it from the repo root. +# Used by .github/workflows/release.yml on tag push (refs/tags/v*). +# Produces multi-OS binaries (linux/darwin/windows × amd64/arm64), +# tar.gz/zip archives that include pre-generated shell completions, +# a sha256 checksums file, and a GitHub Release. # # Run locally: -# goreleaser check # validate the config -# goreleaser snapshot --clean --snapshot-dir ./.snapshot # dry-run build -# -# CI: GitHub Actions runs plain `go build` per target (see .github/workflows/release.yml). -# GoReleaser would be used for a more sophisticated release (changelog from commits, -# multiple formats, Homebrew formula update, checksum files). Wire it up here when ready. +# goreleaser check — validate the config +# goreleaser release --snapshot --clean — dry-run build (no upload) version: 2 @@ -20,6 +18,13 @@ env: before: hooks: - go mod tidy + # Pre-generate shell completions so the archive ships them. Users + # can drop completions/molecule.bash into ~/.bash_completion.d/, etc. + # `molecule completion ` also still works at runtime. + - mkdir -p completions + - sh -c 'go run ./cmd/molecule completion bash > completions/molecule.bash' + - sh -c 'go run ./cmd/molecule completion zsh > completions/_molecule' + - sh -c 'go run ./cmd/molecule completion fish > completions/molecule.fish' builds: - id: molecule @@ -40,15 +45,13 @@ builds: archives: - id: default - format: tar.gz + formats: [tar.gz] format_overrides: - goos: windows - format: zip + formats: [zip] files: - src: completions/**/* dst: completions - checksum: - name_template: 'molecule_{{.Os}}_{{.Arch}}_{{.Version}}_checksums.txt' snapshot: name_template: "{{.Tag}}-snapshot"