Files
git.stella-ops.org/.gitea/workflows/spec-diff-gate.yml

181 lines
6.0 KiB
YAML

# Spec-Diff Gate - Contract Verification Workflow
# Sprint: Testing Enhancement Advisory - Phase 1.1
# Verifies that OpenAPI specifications match code implementations
name: spec-diff-gate
on:
pull_request:
branches: [main, develop]
paths:
- 'src/**/WebService/**'
- 'src/**/Endpoints/**'
- 'src/**/Controllers/**'
- 'docs/api/**'
- 'docs/contracts/**'
- 'docs/db/**'
push:
branches: [main]
workflow_dispatch:
concurrency:
group: spec-diff-${{ github.ref }}
cancel-in-progress: true
jobs:
# ==========================================================================
# Contract Spec Diff Tests
# ==========================================================================
spec-diff:
name: Contract Spec Diff
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: "10.0.100"
- name: Restore dependencies
run: dotnet restore src/__Tests/Architecture/StellaOps.Architecture.Contracts.Tests/StellaOps.Architecture.Contracts.Tests.csproj
- name: Build spec-diff tests
run: dotnet build src/__Tests/Architecture/StellaOps.Architecture.Contracts.Tests/StellaOps.Architecture.Contracts.Tests.csproj --configuration Release --no-restore
- name: Run OpenAPI spec validation
run: |
dotnet test src/__Tests/Architecture/StellaOps.Architecture.Contracts.Tests \
--configuration Release \
--no-build \
--filter "Category=Architecture&Category=Contract" \
--logger "trx;LogFileName=spec-diff.trx" \
--results-directory ./TestResults
- name: Generate spec-diff report
if: always()
run: |
dotnet test src/__Tests/Architecture/StellaOps.Architecture.Contracts.Tests \
--configuration Release \
--no-build \
--filter "FullyQualifiedName~SpecDiff_GeneratesReport" \
--logger "console;verbosity=detailed" \
2>&1 | tee ./TestResults/spec-diff-report.txt || true
- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: spec-diff-results
path: TestResults/**
- name: Publish test summary
uses: dorny/test-reporter@v1
if: always()
with:
name: Spec Diff Test Results
path: TestResults/**/*.trx
reporter: dotnet-trx
# ==========================================================================
# Schema Compliance Tests
# ==========================================================================
schema-compliance:
name: Schema Compliance
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: "10.0.100"
- name: Restore dependencies
run: dotnet restore src/__Tests/Architecture/StellaOps.Architecture.Contracts.Tests/StellaOps.Architecture.Contracts.Tests.csproj
- name: Build schema tests
run: dotnet build src/__Tests/Architecture/StellaOps.Architecture.Contracts.Tests/StellaOps.Architecture.Contracts.Tests.csproj --configuration Release --no-restore
- name: Run schema compliance tests
run: |
dotnet test src/__Tests/Architecture/StellaOps.Architecture.Contracts.Tests \
--configuration Release \
--no-build \
--filter "FullyQualifiedName~SchemaCompliance" \
--logger "trx;LogFileName=schema-compliance.trx" \
--results-directory ./TestResults
- name: Upload schema test results
uses: actions/upload-artifact@v4
if: always()
with:
name: schema-compliance-results
path: TestResults/**
# ==========================================================================
# API Governance Check (existing, enhanced)
# ==========================================================================
api-governance:
name: API Governance
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install spectral
run: npm install -g @stoplight/spectral-cli
- name: Lint OpenAPI specs
run: |
find docs/api -name "*.yaml" -o -name "*.yml" | while read spec; do
echo "Linting: $spec"
spectral lint "$spec" --ruleset .spectral.yaml || true
done
- name: Check for breaking changes
run: |
if [ -f ".gitea/scripts/validate/api-compat-diff.mjs" ]; then
node .gitea/scripts/validate/api-compat-diff.mjs --baseline docs/contracts/api-aggregate-*.yaml
else
echo "API compat diff script not found, skipping"
fi
# ==========================================================================
# Combined Gate Status
# ==========================================================================
gate-status:
name: Spec Diff Gate Status
runs-on: ubuntu-latest
needs: [spec-diff, schema-compliance, api-governance]
if: always()
steps:
- name: Check gate status
run: |
if [ "${{ needs.spec-diff.result }}" == "failure" ]; then
echo "::error::Spec diff tests failed - specs and code are out of sync"
exit 1
fi
if [ "${{ needs.schema-compliance.result }}" == "failure" ]; then
echo "::error::Schema compliance tests failed - migrations may not comply with specifications"
exit 1
fi
if [ "${{ needs.api-governance.result }}" == "failure" ]; then
echo "::warning::API governance checks had issues - review API lint results"
fi
echo "All spec-diff checks passed!"