Skip to content

chore(deps): bump the actions group with 4 updates #743

chore(deps): bump the actions group with 4 updates

chore(deps): bump the actions group with 4 updates #743

Workflow file for this run

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