feat: add HMAC-SHA256 cryptographic signing for audit log integrity #131
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: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| jobs: | |
| docs: | |
| name: Docs Checks | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| - name: Changelog guard (docs-only PRs) | |
| if: github.event_name == 'pull_request' | |
| run: | | |
| set -euo pipefail | |
| CHANGED_FILES="$(git diff --name-only "${{ github.event.pull_request.base.sha }}" "${{ github.sha }}")" | |
| if [ -z "$CHANGED_FILES" ]; then | |
| exit 0 | |
| fi | |
| docs_only=true | |
| changelog_updated=false | |
| while IFS= read -r file; do | |
| [ -z "$file" ] && continue | |
| # Check if root CHANGELOG.md was updated | |
| if [ "$file" = "CHANGELOG.md" ]; then | |
| changelog_updated=true | |
| fi | |
| # Determine if this PR is docs-only | |
| case "$file" in | |
| docs/*|README.md) | |
| ;; | |
| *) | |
| docs_only=false | |
| ;; | |
| esac | |
| done <<EOF | |
| $CHANGED_FILES | |
| EOF | |
| if [ "$docs_only" = true ] && [ "$changelog_updated" = false ]; then | |
| echo "Documentation-only PRs must update CHANGELOG.md" | |
| exit 1 | |
| fi | |
| - name: API docs consistency guard (PRs) | |
| if: github.event_name == 'pull_request' | |
| run: | | |
| set -euo pipefail | |
| # Requires Bash 4.0+ for ** glob patterns (GitHub Actions uses Bash 5.2.21) | |
| CHANGED_FILES="$(git diff --name-only "${{ github.event.pull_request.base.sha }}" "${{ github.sha }}")" | |
| if [ -z "$CHANGED_FILES" ]; then | |
| exit 0 | |
| fi | |
| api_changed=false | |
| docs_changed=false | |
| while IFS= read -r file; do | |
| [ -z "$file" ] && continue | |
| # API/runtime implementation changes | |
| case "$file" in | |
| internal/*/http/*.go|cmd/app/commands/*.go|migrations/*/*.sql) | |
| api_changed=true | |
| ;; | |
| esac | |
| # Documentation files that should be updated when API changes | |
| # Note: docs/api/*.md matches root files, docs/api/**/*.md matches subdirectories | |
| case "$file" in | |
| docs/api/*.md|docs/api/**/*.md|\ | |
| docs/openapi.yaml|\ | |
| docs/examples/*.md|\ | |
| docs/operations/*.md|docs/operations/**/*.md|\ | |
| docs/getting-started/*.md|\ | |
| docs/cli-commands.md|\ | |
| docs/releases/*.md|\ | |
| docs/configuration.md|\ | |
| docs/README.md|\ | |
| docs/metadata.json|\ | |
| CHANGELOG.md|\ | |
| README.md) | |
| docs_changed=true | |
| ;; | |
| esac | |
| done <<EOF | |
| $CHANGED_FILES | |
| EOF | |
| if [ "$api_changed" = true ] && [ "$docs_changed" = false ]; then | |
| echo "API/runtime changes detected but no related docs updates found" | |
| echo "Update docs/api/*/, openapi.yaml, examples/, operations/*/, or release notes/changelog as needed" | |
| exit 1 | |
| fi | |
| - name: Release docs link guard (PRs) | |
| if: github.event_name == 'pull_request' | |
| env: | |
| GITHUB_EVENT_NAME: ${{ github.event_name }} | |
| PR_BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| PR_HEAD_SHA: ${{ github.sha }} | |
| run: python3 docs/tools/check_release_docs_links.py | |
| - name: Markdown lint | |
| uses: DavidAnson/markdownlint-cli2-action@v20 | |
| with: | |
| config: .markdownlint.json | |
| globs: | | |
| README.md | |
| docs/**/*.md | |
| .github/pull_request_template.md | |
| - name: Example shape checks | |
| run: python3 docs/tools/check_example_shapes.py | |
| - name: Docs metadata checks | |
| run: | | |
| set -euo pipefail | |
| if [ "${{ github.event_name }}" = "pull_request" ]; then | |
| export DOCS_CHANGED_FILES="$(git diff --name-only "${{ github.event.pull_request.base.sha }}" "${{ github.sha }}")" | |
| else | |
| export DOCS_CHANGED_FILES="" | |
| fi | |
| python3 docs/tools/check_docs_metadata.py | |
| - name: Docs release image tag checks | |
| run: python3 docs/tools/check_release_image_tags.py | |
| - name: OpenAPI validation | |
| run: | | |
| set -euo pipefail | |
| python3 -m pip install --disable-pip-version-check --no-cache-dir openapi-spec-validator==0.7.1 | |
| python3 -m openapi_spec_validator docs/openapi.yaml | |
| - name: Markdown link check (offline) | |
| uses: lycheeverse/lychee-action@v2 | |
| with: | |
| args: --offline --include-fragments --no-progress "README.md" "docs/**/*.md" ".github/pull_request_template.md" | |
| test: | |
| name: Test | |
| runs-on: ubuntu-latest | |
| services: | |
| postgres: | |
| image: postgres:16-alpine | |
| env: | |
| POSTGRES_USER: testuser | |
| POSTGRES_PASSWORD: testpassword | |
| POSTGRES_DB: testdb | |
| options: >- | |
| --health-cmd pg_isready | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 5 | |
| ports: | |
| - 5433:5432 | |
| mysql: | |
| image: mysql:8.0 | |
| env: | |
| MYSQL_ROOT_PASSWORD: rootpassword | |
| MYSQL_DATABASE: testdb | |
| MYSQL_USER: testuser | |
| MYSQL_PASSWORD: testpassword | |
| options: >- | |
| --health-cmd="mysqladmin ping -h localhost -u testuser -ptestpassword" | |
| --health-interval=10s | |
| --health-timeout=5s | |
| --health-retries=5 | |
| ports: | |
| - 3307:3306 | |
| steps: | |
| - name: Checkout code | |
| uses: actions/checkout@v6 | |
| - name: Set up Go | |
| uses: actions/setup-go@v6 | |
| with: | |
| go-version: "1.25.5" | |
| cache: true | |
| - name: Download dependencies | |
| run: go mod download | |
| - name: golangci-lint | |
| uses: golangci/golangci-lint-action@v9 | |
| with: | |
| version: latest | |
| - name: Run tests | |
| run: make test |