Merge pull request #22 from REPPL/bughunt-6 #70
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 | |
| # Lightweight checks on every push and pull request: format, build, vet, and | |
| # test on Linux, plus a smoke test of the merge → report pipeline on the bundled | |
| # sample, full-history secret scanning, and a workflow audit. Also runs on | |
| # `merge_group` so the same jobs gate each entry the merge queue builds — the | |
| # queue tests every PR against the exact main it will land on, and its required | |
| # checks are these same contexts, so they MUST trigger here or the queue hangs. | |
| on: | |
| push: | |
| branches: ['**'] | |
| pull_request: | |
| merge_group: | |
| # Cancel superseded runs of the same ref (PRs and non-default branch pushes). | |
| # Never cancel a merge-queue run (each queue entry must complete to merge) or a | |
| # default-branch push; each already has its own ref, so this only affects | |
| # rapidly-superseded PR/branch pushes. | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: ${{ github.event_name != 'merge_group' && github.ref != format('refs/heads/{0}', github.event.repository.default_branch) }} | |
| permissions: | |
| contents: read | |
| jobs: | |
| # Build + vet + test + pipeline smoke, race-enabled. Ubuntu-only: the darwin | |
| # build is covered by the release cross-compile, and a macos-latest leg aborts | |
| # the demo/record race binaries with a runner-specific dyld "missing LC_UUID" | |
| # trap (a GitHub image + race-detector issue, not our code — the suite is green | |
| # on a real Mac). A single job named "check" is also the context branch | |
| # protection requires; a matrix would rename it and never report that context. | |
| check: | |
| timeout-minutes: 10 | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| with: | |
| persist-credentials: false | |
| - name: Set up Go | |
| uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6 | |
| with: | |
| go-version-file: go.mod | |
| # Any file gofmt lists needs `gofmt -w` and fails the job. | |
| - name: Format (gofmt) | |
| run: | | |
| set -euo pipefail | |
| unformatted="$(gofmt -l .)" | |
| if [ -n "$unformatted" ]; then | |
| echo "gofmt: these files are not formatted (run gofmt -w .):" >&2 | |
| echo "$unformatted" >&2 | |
| exit 1 | |
| fi | |
| - name: Build | |
| run: go build -o testimony ./cmd/testimony | |
| - name: Vet | |
| run: go vet ./... | |
| - name: Test | |
| run: go test -race ./... | |
| # The full pipeline against the bundled sample session: merge must produce | |
| # a timeline, report must render it, and both outputs must be non-empty. | |
| # Runs on both OSes — it also proves the freshly built binary actually runs | |
| # the pipeline on each host. | |
| - name: Pipeline smoke test | |
| run: | | |
| set -euo pipefail | |
| ./testimony merge -session examples/sample-session | |
| ./testimony report -session examples/sample-session | |
| test -s examples/sample-session/timeline.jsonl | |
| test -s examples/sample-session/report.md | |
| grep -q "## Timeline" examples/sample-session/report.md | |
| grep -q "save button" examples/sample-session/report.md | |
| # The bundled findings.jsonl renders the Findings section with the | |
| # confirmed save-feedback bug (F-001). | |
| grep -q "## Findings" examples/sample-session/report.md | |
| grep -q "### Confirmed (1)" examples/sample-session/report.md | |
| grep -q "\*\*F-001\*\* bug" examples/sample-session/report.md | |
| # Secrets never land in history: full-history scan on every push/PR. Run as a | |
| # pinned, checksum-verified CLI (no PR-comment / SARIF GitHub-API integration | |
| # and no marketplace-action licence caveat), so it is self-contained. A | |
| # non-zero exit means gitleaks found a secret. | |
| gitleaks: | |
| timeout-minutes: 10 | |
| runs-on: ubuntu-latest | |
| env: | |
| GITLEAKS_VERSION: 8.24.3 | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| with: | |
| fetch-depth: 0 | |
| persist-credentials: false | |
| - name: Install gitleaks (pinned, checksum-verified) | |
| run: | | |
| set -euo pipefail | |
| cd "$RUNNER_TEMP" | |
| base="gitleaks_${GITLEAKS_VERSION}_linux_x64.tar.gz" | |
| url="https://github.com/gitleaks/gitleaks/releases/download/v${GITLEAKS_VERSION}" | |
| curl -sSLf -o "$base" "$url/$base" | |
| curl -sSLf -o checksums.txt "$url/gitleaks_${GITLEAKS_VERSION}_checksums.txt" | |
| grep " $base\$" checksums.txt | sha256sum -c - | |
| tar -xzf "$base" gitleaks | |
| sudo install gitleaks /usr/local/bin/gitleaks | |
| gitleaks version | |
| - name: Scan full history | |
| run: gitleaks git --redact --no-banner . | |
| # Audit the workflows themselves (pwn requests, template injection, cache | |
| # poisoning, unpinned uses). The action runs zizmor and gates on its findings | |
| # (a non-zero exit means a finding); SARIF upload to Code Scanning is off — see | |
| # the advanced-security note below. | |
| zizmor: | |
| timeout-minutes: 10 | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| with: | |
| persist-credentials: false | |
| - uses: zizmorcore/zizmor-action@192e21d79ab29983730a13d1382995c2307fbcaa # v0.5.7 | |
| with: | |
| # advanced-security: false — Code Scanning is not enabled on this repo, | |
| # so a SARIF upload would fail the job even with zero findings. The | |
| # action still runs zizmor and fails on any finding above its threshold; | |
| # findings surface in the job log. Flip to true (and add | |
| # security-events: write) if Code Scanning default setup is enabled later. | |
| advanced-security: false |