Skip to content

Fix security review followups from #161 (#162) #623

Fix security review followups from #161 (#162)

Fix security review followups from #161 (#162) #623

Workflow file for this run

name: Test
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
jobs:
test:
name: Tests
runs-on: ubuntu-latest
env:
BASECAMP_NO_KEYRING: "1"
GOPRIVATE: github.com/basecamp/basecamp-sdk
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Generate token for private SDK access
id: app-token
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2
with:
app-id: ${{ vars.RELEASE_CLIENT_ID }}
private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
owner: basecamp
repositories: basecamp-sdk
- name: Set up Go
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6
with:
go-version-file: 'go.mod'
- name: Configure git for private modules
run: git config --global url."https://x-access-token:${{ steps.app-token.outputs.token }}@github.com/".insteadOf "https://github.com/"
- name: Check SDK provenance
run: make provenance-check
- name: Check naming (no stale legacy references)
run: make check-naming
- name: Run unit tests
run: go test -v ./...
- name: Build binary
run: go build -o bin/basecamp ./cmd/basecamp
- name: Smoke test
run: |
./bin/basecamp --version
./bin/basecamp --help | head -5
lint:
name: Lint
runs-on: ubuntu-latest
env:
GOPRIVATE: github.com/basecamp/basecamp-sdk
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Generate token for private SDK access
id: app-token
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2
with:
app-id: ${{ vars.RELEASE_CLIENT_ID }}
private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
owner: basecamp
repositories: basecamp-sdk
- name: Set up Go
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6
with:
go-version-file: 'go.mod'
- name: Configure git for private modules
run: git config --global url."https://x-access-token:${{ steps.app-token.outputs.token }}@github.com/".insteadOf "https://github.com/"
- name: Run golangci-lint
uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9
with:
version: v2.9.0
security:
name: Security
runs-on: ubuntu-latest
env:
GOPRIVATE: github.com/basecamp/basecamp-sdk
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Generate token for private SDK access
id: app-token
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2
with:
app-id: ${{ vars.RELEASE_CLIENT_ID }}
private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
owner: basecamp
repositories: basecamp-sdk
- name: Set up Go
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6
with:
go-version-file: 'go.mod'
- name: Configure git for private modules
run: git config --global url."https://x-access-token:${{ steps.app-token.outputs.token }}@github.com/".insteadOf "https://github.com/"
- name: Run govulncheck
# @latest intentional — pinning delays scanning improvements and
# new Go version support for no meaningful reproducibility gain.
run: |
go install golang.org/x/vuln/cmd/govulncheck@latest
govulncheck ./...
race-check:
name: Race Detection
runs-on: ubuntu-latest
env:
BASECAMP_NO_KEYRING: "1"
GOPRIVATE: github.com/basecamp/basecamp-sdk
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Generate token for private SDK access
id: app-token
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2
with:
app-id: ${{ vars.RELEASE_CLIENT_ID }}
private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
owner: basecamp
repositories: basecamp-sdk
- name: Set up Go
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6
with:
go-version-file: 'go.mod'
- name: Configure git for private modules
run: git config --global url."https://x-access-token:${{ steps.app-token.outputs.token }}@github.com/".insteadOf "https://github.com/"
- name: Run tests with race detector
run: go test -race -v ./...
integration:
name: Integration Tests
runs-on: ubuntu-latest
env:
BASECAMP_NO_KEYRING: "1"
GOPRIVATE: github.com/basecamp/basecamp-sdk
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Generate token for private SDK access
id: app-token
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2
with:
app-id: ${{ vars.RELEASE_CLIENT_ID }}
private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
owner: basecamp
repositories: basecamp-sdk
- name: Set up Go
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6
with:
go-version-file: 'go.mod'
- name: Configure git for private modules
run: git config --global url."https://x-access-token:${{ steps.app-token.outputs.token }}@github.com/".insteadOf "https://github.com/"
- name: Cache BATS
id: cache-bats
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: /usr/local/libexec/bats-core
key: bats-1.11.0
- name: Install BATS
if: steps.cache-bats.outputs.cache-hit != 'true'
run: |
git clone --depth 1 --branch v1.11.0 https://github.com/bats-core/bats-core.git /tmp/bats-core
sudo /tmp/bats-core/install.sh /usr/local
- name: Run BATS integration tests
run: make test-e2e
benchmarks:
name: Benchmarks
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
continue-on-error: true
env:
BASECAMP_NO_KEYRING: "1"
GOPRIVATE: github.com/basecamp/basecamp-sdk
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
fetch-depth: 2
- name: Generate token for private SDK access
id: app-token
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2
with:
app-id: ${{ vars.RELEASE_CLIENT_ID }}
private-key: ${{ secrets.RELEASE_APP_PRIVATE_KEY }}
owner: basecamp
repositories: basecamp-sdk
- name: Check for benchmark-relevant changes
id: filter
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3
with:
filters: |
bench:
- 'internal/api/**'
- 'internal/names/**'
- 'internal/dateparse/**'
- 'internal/output/**'
- 'go.mod'
- 'go.sum'
- name: Set up Go
if: steps.filter.outputs.bench == 'true'
uses: actions/setup-go@4b73464bb391d4059bd26b0524d20df3927bd417 # v6
with:
go-version-file: 'go.mod'
- name: Configure git for private modules
if: steps.filter.outputs.bench == 'true'
run: git config --global url."https://x-access-token:${{ steps.app-token.outputs.token }}@github.com/".insteadOf "https://github.com/"
- name: Run benchmarks
if: steps.filter.outputs.bench == 'true'
run: go test -bench=. -benchmem -count=3 ./internal/... | tee benchmarks.txt
- name: Download previous benchmark baseline
if: steps.filter.outputs.bench == 'true'
uses: actions/cache/restore@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: benchmarks-baseline.txt
key: benchmarks-baseline-${{ github.sha }}
restore-keys: |
benchmarks-baseline-
- name: Install benchstat
if: steps.filter.outputs.bench == 'true'
run: go install golang.org/x/perf/cmd/benchstat@latest
- name: Compare benchmarks
if: steps.filter.outputs.bench == 'true' && hashFiles('benchmarks-baseline.txt') != ''
run: |
echo "## Benchmark Comparison" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
benchstat benchmarks-baseline.txt benchmarks.txt >> $GITHUB_STEP_SUMMARY 2>&1 || true
echo '```' >> $GITHUB_STEP_SUMMARY
- name: Check for significant regression
if: steps.filter.outputs.bench == 'true' && hashFiles('benchmarks-baseline.txt') != ''
run: |
benchstat benchmarks-baseline.txt benchmarks.txt > comparison.txt 2>&1 || true
if grep -E '\+[2-9][0-9]\.[0-9]+%|\+[1-9][0-9][0-9]+' comparison.txt; then
echo "::error::Performance regression detected (>20% slower). See benchmark comparison in step summary."
exit 1
fi
- name: Save benchmark baseline
if: steps.filter.outputs.bench == 'true'
run: cp benchmarks.txt benchmarks-baseline.txt
- name: Cache benchmark baseline
if: steps.filter.outputs.bench == 'true'
uses: actions/cache/save@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5
with:
path: benchmarks-baseline.txt
key: benchmarks-baseline-${{ github.sha }}
- name: Upload benchmark results
if: steps.filter.outputs.bench == 'true'
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: benchmarks
path: benchmarks.txt
retention-days: 30