chore(deps): bump the actions group with 4 updates #743
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] | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| jobs: | |
| # Detect what files changed to skip unnecessary CI for docs-only PRs | |
| changes: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| code: ${{ steps.filter.outputs.code }} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 | |
| id: filter | |
| with: | |
| filters: | | |
| code: | |
| - 'src/**' | |
| - 'tests/**' | |
| - '*.sln' | |
| - 'Directory.*.props' | |
| - 'Directory.Packages.props' | |
| - '.github/workflows/**' | |
| build: | |
| needs: changes | |
| if: needs.changes.outputs.code == 'true' | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, windows-latest, macos-latest] | |
| runs-on: ${{ matrix.os }} | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| fetch-depth: 0 # Full history for MinVer | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5 | |
| with: | |
| dotnet-version: '10.0.x' | |
| - name: Cache NuGet packages | |
| uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v4 | |
| with: | |
| path: ~/.nuget/packages | |
| key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }} | |
| restore-keys: | | |
| ${{ runner.os }}-nuget- | |
| - name: Restore dependencies | |
| run: dotnet restore --locked-mode | |
| - name: Restore local tools | |
| run: dotnet tool restore | |
| - name: Audit NuGet dependencies for vulnerabilities | |
| if: matrix.os == 'ubuntu-latest' | |
| run: | | |
| OUTPUT=$(dotnet list package --vulnerable --include-transitive 2>&1) | |
| echo "$OUTPUT" | |
| if echo "$OUTPUT" | grep -q "has the following vulnerable packages"; then | |
| echo "::error::Vulnerable NuGet packages detected. Update affected packages to secure versions." | |
| exit 1 | |
| fi | |
| echo "::notice::No known vulnerabilities found in NuGet dependencies" | |
| - name: Scan for secrets | |
| # Only scan on PRs - on pushes to main, base and HEAD are the same commit | |
| if: github.event_name == 'pull_request' && matrix.os == 'ubuntu-latest' | |
| uses: trufflesecurity/trufflehog@6c05c4a00b91aa542267d8e32a8254774799d68d # v3.93.8 | |
| with: | |
| path: ./ | |
| base: ${{ github.event.repository.default_branch }} | |
| head: HEAD | |
| extra_args: --only-verified | |
| - name: Build | |
| run: dotnet build --no-restore -c Release | |
| - name: Verify code formatting | |
| run: dotnet format --no-restore --verify-no-changes --verbosity diagnostic | |
| - name: Run tests with coverage | |
| timeout-minutes: 15 | |
| run: | | |
| dotnet run --project tests/DraftSpec.Tests -c Release -- --coverage --coverage-output-format cobertura --coverage-output coverage.cobertura.xml --report-trx --report-trx-filename test-results.trx | |
| - name: Convert TRX to JUnit | |
| if: ${{ !cancelled() && matrix.os == 'ubuntu-latest' }} | |
| run: | | |
| dotnet tool run trx2junit tests/DraftSpec.Tests/bin/Release/net10.0/TestResults/test-results.trx --output tests/DraftSpec.Tests/bin/Release/net10.0/TestResults | |
| - name: Run CLI integration tests | |
| timeout-minutes: 10 | |
| run: | | |
| dotnet run --project tests/DraftSpec.Cli.IntegrationTests -c Release -- --coverage --coverage-output-format cobertura --coverage-output integration-coverage.cobertura.xml | |
| - name: Upload test results on failure | |
| if: always() | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: test-results-${{ matrix.os }} | |
| path: | | |
| tests/**/TestResults/*.trx | |
| tests/**/TestResults/*.xml | |
| retention-days: 14 | |
| if-no-files-found: ignore | |
| - name: Generate coverage report | |
| if: matrix.os == 'ubuntu-latest' | |
| run: | | |
| dotnet tool run reportgenerator -reports:"tests/DraftSpec.Tests/bin/Release/net10.0/TestResults/coverage.cobertura.xml;tests/DraftSpec.Cli.IntegrationTests/bin/Release/net10.0/TestResults/integration-coverage.cobertura.xml" -targetdir:./coverage-report -reporttypes:Html | |
| - name: Enforce coverage threshold | |
| if: matrix.os == 'ubuntu-latest' | |
| run: | | |
| COVERAGE_FILE="tests/DraftSpec.Tests/bin/Release/net10.0/TestResults/coverage.cobertura.xml" | |
| THRESHOLD=88 | |
| # Extract line-rate from Cobertura XML (value between 0 and 1) | |
| LINE_RATE=$(grep -oP 'line-rate="\K[0-9.]+' "$COVERAGE_FILE" | head -1) | |
| COVERAGE=$(echo "$LINE_RATE * 100" | bc -l | xargs printf "%.2f") | |
| echo "Current coverage: ${COVERAGE}%" | |
| echo "Threshold: ${THRESHOLD}%" | |
| # Compare using bc for floating point | |
| if (( $(echo "$COVERAGE < $THRESHOLD" | bc -l) )); then | |
| echo "::error::Coverage ${COVERAGE}% is below threshold ${THRESHOLD}%" | |
| exit 1 | |
| fi | |
| echo "::notice::Coverage ${COVERAGE}% meets threshold ${THRESHOLD}%" | |
| - name: Upload coverage to Codecov | |
| if: matrix.os == 'ubuntu-latest' | |
| uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: tests/DraftSpec.Tests/bin/Release/net10.0/TestResults/coverage.cobertura.xml,tests/DraftSpec.Cli.IntegrationTests/bin/Release/net10.0/TestResults/integration-coverage.cobertura.xml | |
| fail_ci_if_error: true | |
| verbose: true | |
| - name: Upload test results to Codecov | |
| if: ${{ !cancelled() && matrix.os == 'ubuntu-latest' }} | |
| uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: tests/DraftSpec.Tests/bin/Release/net10.0/TestResults/test-results.xml | |
| report_type: test_results | |
| - name: Upload coverage report artifact | |
| if: matrix.os == 'ubuntu-latest' | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: coverage-report | |
| path: ./coverage-report | |
| retention-days: 7 | |
| - name: Pack | |
| if: matrix.os == 'ubuntu-latest' | |
| run: dotnet pack --no-build -c Release | |
| - name: Upload packages | |
| if: matrix.os == 'ubuntu-latest' | |
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | |
| with: | |
| name: nuget-packages | |
| path: | | |
| src/*/bin/Release/*.nupkg | |
| src/*/bin/Release/*.snupkg | |
| retention-days: 7 | |
| # Lean coverage job for docs-only PRs - just enough to satisfy codecov requirement | |
| coverage-baseline: | |
| needs: changes | |
| if: needs.changes.outputs.code != 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 | |
| with: | |
| fetch-depth: 0 # Full history for git-dependent tests | |
| - name: Setup .NET | |
| uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5 | |
| with: | |
| dotnet-version: '10.0.x' | |
| - name: Cache NuGet packages | |
| uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v4 | |
| with: | |
| path: ~/.nuget/packages | |
| key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }} | |
| restore-keys: | | |
| ${{ runner.os }}-nuget- | |
| - name: Restore and build | |
| run: | | |
| dotnet restore --locked-mode | |
| dotnet build -c Release --no-restore | |
| - name: Run tests with coverage | |
| run: | | |
| dotnet run --project tests/DraftSpec.Tests -c Release --no-build -- --coverage --coverage-output-format cobertura --coverage-output coverage.cobertura.xml | |
| - name: Upload coverage to Codecov | |
| uses: codecov/codecov-action@671740ac38dd9b0130fbe1cec585b89eea48d3de # v5 | |
| with: | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| files: tests/DraftSpec.Tests/bin/Release/net10.0/TestResults/coverage.cobertura.xml | |
| fail_ci_if_error: false # Don't fail docs PRs on coverage issues | |
| # Summary job for branch protection - provides single "build-summary" status | |
| build-summary: | |
| if: always() | |
| needs: [changes, build, coverage-baseline] | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check build matrix status | |
| run: | | |
| # If no code changes, build was skipped - that's OK | |
| if [[ "${{ needs.changes.outputs.code }}" != "true" ]]; then | |
| echo "No code changes detected - build skipped (docs-only PR)" | |
| exit 0 | |
| fi | |
| # Otherwise, build must have succeeded | |
| if [[ "${{ needs.build.result }}" == "success" ]]; then | |
| echo "All build jobs passed" | |
| exit 0 | |
| else | |
| echo "One or more build jobs failed: ${{ needs.build.result }}" | |
| exit 1 | |
| fi |