Switch to go releaser

This commit is contained in:
2025-12-08 02:32:46 +00:00
parent 66b9ed0861
commit 91f0fc9ab8
4 changed files with 93 additions and 622 deletions
-622
View File
@@ -1,622 +0,0 @@
name: PR Validation
on:
pull_request:
branches: [ main ]
push:
branches: [ main ]
permissions:
contents: read
pull-requests: write
checks: write
security-events: write
jobs:
# Fast feedback - format and basic checks
quick-checks:
name: Quick Checks
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: '1.24'
cache: true
- name: Format check
run: |
# Exclude vendor directory from format checks
UNFORMATTED=$(gofmt -s -l . | grep -v "^vendor/" || true)
if [ -n "$UNFORMATTED" ]; then
echo "Code is not formatted. Run: gofmt -s -w ."
echo "Unformatted files:"
echo "$UNFORMATTED"
gofmt -s -d $(echo "$UNFORMATTED")
exit 1
fi
- name: Go vet
run: go vet ./...
- name: Go mod verify
run: go mod verify
- name: Go mod tidy check
run: |
go mod tidy
git diff --exit-code go.mod go.sum
# Static analysis with golangci-lint (advisory - will not fail the build)
golangci-lint:
name: golangci-lint
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: '1.24'
cache: true
- name: golangci-lint
uses: golangci/golangci-lint-action@v8
with:
version: latest
args: --timeout=10m
continue-on-error: true # Allow pipeline to continue even with linting warnings
# Staticcheck analysis
staticcheck:
name: Staticcheck
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: '1.24'
cache: true
- name: Install staticcheck
run: go install honnef.co/go/tools/cmd/staticcheck@latest
- name: Run staticcheck
run: staticcheck ./...
# Security scanning with gosec
gosec:
name: Gosec Security Scanner
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: '1.24'
cache: true
- name: Run Gosec Security Scanner
run: |
go install github.com/securego/gosec/v2/cmd/gosec@latest
gosec -no-fail -fmt sarif -out results.sarif ./... || echo "Gosec completed with warnings"
continue-on-error: true
- name: Upload SARIF file
if: always() && hashFiles('results.sarif') != ''
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif
continue-on-error: true
# Vulnerability scanning
govulncheck:
name: Vulnerability Scan
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: '1.24'
cache: true
- name: Install govulncheck
run: go install golang.org/x/vuln/cmd/govulncheck@latest
- name: Run govulncheck
run: govulncheck ./...
# CodeQL analysis
codeql:
name: CodeQL Analysis
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: '1.24'
cache: true
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: go
continue-on-error: true
- name: Autobuild
uses: github/codeql-action/autobuild@v3
continue-on-error: true
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
continue-on-error: true
# Unit tests with race detection
test-race:
name: Unit Tests (Race Detector)
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: '1.24'
cache: true
- name: Run tests with race detector
run: go test -race -timeout=15m -count=1 -v ./...
env:
GOMAXPROCS: 4
# Coverage analysis with threshold check
test-coverage:
name: Test Coverage
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: '1.24'
cache: true
- name: Run tests with coverage
run: |
go test -coverprofile=coverage.out -covermode=atomic -timeout=15m ./...
go tool cover -func=coverage.out -o=coverage.txt
- name: Calculate coverage
id: coverage
run: |
COVERAGE=$(go tool cover -func=coverage.out | grep total | awk '{print $3}' | sed 's/%//')
echo "coverage=$COVERAGE" >> $GITHUB_OUTPUT
echo "Total Coverage: $COVERAGE%"
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
file: ./coverage.out
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false
continue-on-error: true
- name: Comment coverage on PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v8
with:
script: |
const coverage = '${{ steps.coverage.outputs.coverage }}';
const threshold = 70;
const coverageNum = parseFloat(coverage);
const emoji = coverageNum >= threshold ? '✅' : '⚠️';
const status = coverageNum >= threshold ? 'meets' : 'below';
const body = `## ${emoji} Test Coverage Report
| Metric | Value |
|--------|-------|
| **Total Coverage** | ${coverage}% |
| **Threshold** | ${threshold}% |
| **Status** | ${emoji} Coverage ${status} threshold |`;
// Find existing comment
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
});
const botComment = comments.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('Test Coverage Report')
);
if (botComment) {
await github.rest.issues.updateComment({
comment_id: botComment.id,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
}
- name: Check coverage threshold
run: |
COVERAGE=${{ steps.coverage.outputs.coverage }}
THRESHOLD=70
echo "Coverage: $COVERAGE%"
echo "Threshold: $THRESHOLD%"
if (( $(echo "$COVERAGE < $THRESHOLD" | bc -l) )); then
echo "⚠️ Coverage $COVERAGE% is below threshold $THRESHOLD%"
exit 1
fi
echo "✅ Coverage $COVERAGE% meets threshold $THRESHOLD%"
# Memory leak detection
test-memory-leaks:
name: Memory Leak Detection
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: '1.24'
cache: true
- name: Run goroutine leak tests
run: |
echo "Running goroutine leak detection tests..."
go test -v -timeout=20m -run='.*[Gg]oroutine.*[Ll]eak.*' ./... || echo "No goroutine leak tests found"
- name: Run memory leak tests
run: |
echo "Running memory leak detection tests..."
go test -v -timeout=20m -run='.*[Mm]emory.*[Ll]eak.*' ./... || echo "No memory leak tests found"
- name: Run cleanup tests
run: |
echo "Running cleanup and resource management tests..."
go test -v -timeout=20m -run='.*[Cc]leanup.*' ./... || echo "No cleanup tests found"
# Integration tests
test-integration:
name: Integration Tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: '1.24'
cache: true
- name: Run integration tests
run: |
if [ -d "./integration" ]; then
go test -v -timeout=20m ./integration/...
else
echo "Running integration tests from all packages..."
go test -v -timeout=20m -run='.*[Ii]ntegration.*' ./...
fi
# Regression tests
test-regression:
name: Regression Tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: '1.24'
cache: true
- name: Run regression tests
run: |
echo "Running regression tests..."
go test -v -timeout=20m -run='.*[Rr]egression.*' ./...
# Provider-specific tests (parallel matrix)
test-providers:
name: Provider Tests (${{ matrix.provider }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
provider:
- google
- azure
- auth0
- okta
- keycloak
- cognito
- gitlab
- github
- generic
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: '1.24'
cache: true
- name: Run ${{ matrix.provider }} provider tests
run: |
PROVIDER_CAP=$(echo "${{ matrix.provider }}" | sed 's/.*/\u&/')
echo "Testing $PROVIDER_CAP provider..."
go test -v -timeout=10m -run=".*$PROVIDER_CAP.*" ./internal/providers/... || true
go test -v -timeout=10m -run=".*${{ matrix.provider }}.*" ./... || true
# Benchmark tests with performance tracking
benchmark:
name: Benchmark Tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: '1.24'
cache: true
- name: Run benchmarks
run: |
echo "Running benchmark tests..."
go test -bench=. -benchmem -benchtime=1s -run=^$ ./... | tee benchmark.txt
- name: Upload benchmark results
uses: actions/upload-artifact@v4
with:
name: benchmark-results
path: benchmark.txt
retention-days: 30
- name: Compare benchmarks
if: github.event_name == 'pull_request'
continue-on-error: true
run: |
echo "Benchmark results available in artifacts"
echo "To compare with main branch, download previous benchmark results"
# Build validation across platforms
build:
name: Build (${{ matrix.os }}/${{ matrix.arch }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
os: [linux, darwin]
arch: [amd64, arm64]
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: '1.24'
cache: true
- name: Build for ${{ matrix.os }}/${{ matrix.arch }}
env:
GOOS: ${{ matrix.os }}
GOARCH: ${{ matrix.arch }}
run: |
echo "Building for $GOOS/$GOARCH..."
go build -v -ldflags="-s -w" ./...
# Security-specific edge case tests
test-security-edge-cases:
name: Security Edge Cases
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: '1.24'
cache: true
- name: Run security edge case tests
run: |
echo "Running security edge case tests..."
go test -v -timeout=15m -run='.*[Ss]ecurity.*' ./...
# Session management tests
test-session:
name: Session Management Tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: '1.24'
cache: true
- name: Run session tests
run: |
echo "Running session management tests..."
go test -v -timeout=15m -run='.*[Ss]ession.*' ./...
# Token validation tests
test-token:
name: Token Validation Tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: '1.24'
cache: true
- name: Run token validation tests
run: |
echo "Running token validation tests..."
go test -v -timeout=15m -run='.*[Tt]oken.*' ./...
# CSRF and security tests
test-csrf:
name: CSRF and Security Tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Setup Go
uses: actions/setup-go@v6
with:
go-version: '1.24'
cache: true
- name: Run CSRF tests
run: |
echo "Running CSRF and security tests..."
go test -v -timeout=15m -run='.*[Cc][Ss][Rr][Ff].*' ./...
# Multi-Go version compatibility
test-go-versions:
name: Go ${{ matrix.go-version }} Compatibility
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
go-version: ['1.24']
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Setup Go ${{ matrix.go-version }}
uses: actions/setup-go@v6
with:
go-version: ${{ matrix.go-version }}
cache: true
- name: Run tests on Go ${{ matrix.go-version }}
run: go test -short -timeout=10m ./...
# Final validation - all checks must pass (golangci-lint is advisory)
all-checks-passed:
name: ✅ All Checks Passed
runs-on: ubuntu-latest
needs:
- quick-checks
- golangci-lint
- staticcheck
- gosec
- govulncheck
- codeql
- test-race
- test-coverage
- test-memory-leaks
- test-integration
- test-regression
- test-providers
- benchmark
- build
- test-security-edge-cases
- test-session
- test-token
- test-csrf
- test-go-versions
if: always()
steps:
- name: Check all jobs status
run: |
echo "Checking status of all jobs..."
# Check critical jobs (excluding golangci-lint which is advisory)
CRITICAL_FAILURES=false
if [ "${{ needs.quick-checks.result }}" == "failure" ] || \
[ "${{ needs.staticcheck.result }}" == "failure" ] || \
[ "${{ needs.test-race.result }}" == "failure" ] || \
[ "${{ needs.test-coverage.result }}" == "failure" ] || \
[ "${{ needs.build.result }}" == "failure" ]; then
CRITICAL_FAILURES=true
fi
if [ "$CRITICAL_FAILURES" == "true" ]; then
echo "❌ Critical checks failed"
exit 1
elif [ "${{ contains(needs.*.result, 'cancelled') }}" == "true" ]; then
echo "⚠️ Some checks were cancelled"
exit 1
else
echo "✅ All critical checks passed successfully!"
if [ "${{ needs.golangci-lint.result }}" != "success" ]; then
echo "️ Note: golangci-lint reported issues (advisory only)"
fi
fi
- name: Post summary
if: always()
run: |
echo "# PR Validation Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "## Job Status" >> $GITHUB_STEP_SUMMARY
echo "- Quick Checks: ${{ needs.quick-checks.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Linting (advisory): ${{ needs.golangci-lint.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Static Analysis: ${{ needs.staticcheck.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Security Scan (gosec): ${{ needs.gosec.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Vulnerability Scan: ${{ needs.govulncheck.result }}" >> $GITHUB_STEP_SUMMARY
echo "- CodeQL: ${{ needs.codeql.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Race Detection: ${{ needs.test-race.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Coverage: ${{ needs.test-coverage.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Memory Leaks: ${{ needs.test-memory-leaks.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Integration Tests: ${{ needs.test-integration.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Regression Tests: ${{ needs.test-regression.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Provider Tests: ${{ needs.test-providers.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Benchmarks: ${{ needs.benchmark.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Build: ${{ needs.build.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Security Edge Cases: ${{ needs.test-security-edge-cases.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Session Tests: ${{ needs.test-session.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Token Tests: ${{ needs.test-token.result }}" >> $GITHUB_STEP_SUMMARY
echo "- CSRF Tests: ${{ needs.test-csrf.result }}" >> $GITHUB_STEP_SUMMARY
echo "- Go Version Compatibility: ${{ needs.test-go-versions.result }}" >> $GITHUB_STEP_SUMMARY
+23
View File
@@ -0,0 +1,23 @@
name: Pull Request
on:
pull_request:
branches:
- main
push:
branches:
- "**"
- "!main"
permissions:
contents: read
pull-requests: write
security-events: write
jobs:
pr-checks:
uses: lukaszraczylo/shared-actions/.github/workflows/go-pr.yaml@main
with:
go-version: "1.24"
coverage-threshold: 70
secrets: inherit
+21
View File
@@ -0,0 +1,21 @@
name: Release
on:
push:
branches:
- main
paths:
- "**.go"
- "go.mod"
- "go.sum"
workflow_dispatch:
permissions:
contents: write
jobs:
release:
uses: lukaszraczylo/shared-actions/.github/workflows/go-release.yaml@main
with:
go-version: "1.24"
secrets: inherit
+49
View File
@@ -0,0 +1,49 @@
version: 2
# Traefik plugins are source-only - no binary builds
# Traefik loads plugins via Yaegi interpreter at runtime
builds:
- skip: true
# Create source archive for GitHub releases
archives:
- format: tar.gz
name_template: "{{ .ProjectName }}_{{ .Version }}_source"
files:
- "*.go"
- "**/*.go"
- go.mod
- go.sum
- .traefik.yml
- LICENSE*
- README*
# Exclude test files and vendor from release archive
- "!**/*_test.go"
- "!vendor/**"
- "!docker/**"
- "!integration/**"
- "!regression/**"
- "!examples/**"
- "!docs/**"
checksum:
name_template: "{{ .ProjectName }}_{{ .Version }}_checksums.txt"
algorithm: sha256
changelog:
sort: asc
filters:
exclude:
- "^docs:"
- "^test:"
- "^Merge"
- "^WIP"
- "^chore:"
release:
github:
owner: lukaszraczylo
name: traefikoidc
name_template: "v{{ .Version }}"
draft: false
prerelease: auto