CI #102
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: CI | |
| on: | |
| pull_request: | |
| branches: | |
| - main | |
| merge_group: | |
| permissions: | |
| contents: read | |
| # pull-requests: read is needed so dorny/paths-filter can diff the PR. | |
| pull-requests: read | |
| jobs: | |
| # changes detects whether this PR touches code or build config. Docs-only | |
| # PRs skip the heavy jobs entirely but still produce a green CI Complete | |
| # so the branch ruleset lets them merge. | |
| # | |
| # merge_group doesn't pass a useful base ref to dorny; the action falls | |
| # back to treating every file as changed, which is exactly what we want — | |
| # the merge queue should always run the full suite. | |
| changes: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| code: ${{ steps.filter.outputs.code }} | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 | |
| id: filter | |
| with: | |
| filters: | | |
| code: | |
| - '**/*.go' | |
| - 'go.mod' | |
| - 'go.sum' | |
| - 'Makefile' | |
| - '.goreleaser.yml' | |
| - '.github/workflows/**' | |
| - 'install.sh' | |
| lint: | |
| needs: changes | |
| if: needs.changes.outputs.code == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - name: Set up Go | |
| uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 | |
| with: | |
| go-version: "1.25" | |
| - name: Check formatting | |
| run: | | |
| if [ -n "$(gofmt -l .)" ]; then | |
| echo "Code is not formatted. Run 'go fmt ./...'" | |
| gofmt -d . | |
| exit 1 | |
| fi | |
| - name: Install staticcheck | |
| run: go install honnef.co/go/tools/cmd/staticcheck@2025.1.1 | |
| - name: Run go vet | |
| run: go vet ./... | |
| - name: Run staticcheck | |
| run: staticcheck ./... | |
| test: | |
| needs: changes | |
| if: needs.changes.outputs.code == 'true' | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - name: Set up Go | |
| uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 | |
| with: | |
| go-version: "1.25" | |
| - name: Run tests | |
| run: go test -race -vet=off ./... | |
| cover: | |
| needs: changes | |
| if: needs.changes.outputs.code == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - name: Set up Go | |
| uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 | |
| with: | |
| go-version: "1.25" | |
| - name: Enforce 100% internal coverage | |
| run: make cover | |
| build: | |
| needs: changes | |
| if: needs.changes.outputs.code == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - name: Set up Go | |
| uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 | |
| with: | |
| go-version: "1.25" | |
| - name: Build binary | |
| run: make build | |
| goreleaser-check: | |
| needs: changes | |
| if: needs.changes.outputs.code == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - name: Set up Go | |
| uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 | |
| with: | |
| go-version: "1.25" | |
| - name: Install GoReleaser | |
| uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7.2.3 | |
| with: | |
| distribution: goreleaser | |
| version: "~> v2" | |
| install-only: true | |
| - name: Validate GoReleaser config | |
| run: goreleaser check | |
| # Sentinel required-status-check consumed by the branch ruleset + merge queue. | |
| # Runs unconditionally so docs-only PRs still report green. Code-gated jobs | |
| # count as success when they ran AND succeeded, or when they were skipped | |
| # because no code changed; any other result (failure, cancelled) fails the | |
| # gate. | |
| ci-complete: | |
| name: CI Complete | |
| needs: [changes, lint, test, cover, build, goreleaser-check] | |
| if: always() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Aggregate job results | |
| env: | |
| CODE_CHANGED: ${{ needs.changes.outputs.code }} | |
| CHANGES_RESULT: ${{ needs.changes.result }} | |
| LINT_RESULT: ${{ needs.lint.result }} | |
| TEST_RESULT: ${{ needs.test.result }} | |
| COVER_RESULT: ${{ needs.cover.result }} | |
| BUILD_RESULT: ${{ needs.build.result }} | |
| GORELEASER_RESULT: ${{ needs.goreleaser-check.result }} | |
| run: | | |
| echo "code_changed=$CODE_CHANGED" | |
| echo "changes=$CHANGES_RESULT lint=$LINT_RESULT test=$TEST_RESULT cover=$COVER_RESULT build=$BUILD_RESULT goreleaser=$GORELEASER_RESULT" | |
| # Include changes in the validation loop: if the paths-filter job | |
| # itself fails (checkout error, dorny bug), every downstream job | |
| # reports `skipped` and the gate would otherwise pass despite no | |
| # actual verification having run. | |
| # Acceptable per-job results: | |
| # success — ran and passed | |
| # skipped — no code changed, so no work to do | |
| # Anything else (failure, cancelled) fails the gate. | |
| for r in "$CHANGES_RESULT" "$LINT_RESULT" "$TEST_RESULT" "$COVER_RESULT" "$BUILD_RESULT" "$GORELEASER_RESULT"; do | |
| case "$r" in | |
| success|skipped) ;; | |
| *) | |
| echo "one or more required jobs failed: $r" | |
| exit 1 | |
| ;; | |
| esac | |
| done | |
| echo "all required checks passed" |