build(deps): bump the github-actions group across 2 directories with 10 updates #326
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
| # SPDX-License-Identifier: Apache-2.0 | |
| # © Crown Copyright 2025. This work has been developed by the National Digital Twin Programme and is legally attributed to the Department for Business and Trade (UK) as the governing entity. | |
| name: CI | |
| on: | |
| push: | |
| branches: | |
| - main | |
| - develop | |
| pull_request: | |
| branches: | |
| - main | |
| - develop | |
| - 'release/**' | |
| - 'hotfix/**' | |
| workflow_dispatch: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| detect-changes: | |
| name: Detect Changes | |
| runs-on: ubuntu-latest | |
| permissions: | |
| pull-requests: read | |
| outputs: | |
| run_pac_ci: >- | |
| ${{ (github.event_name == 'pull_request' && steps.changes.outputs.pac == 'true') || | |
| github.event_name == 'workflow_dispatch' || | |
| (github.event_name == 'push' && (github.ref_name == 'main' || github.ref_name == 'develop')) }} | |
| run_conventional_commits_ci: >- | |
| ${{ (github.event_name == 'pull_request' && steps.changes.outputs.conventional_commits == 'true') || | |
| github.event_name == 'workflow_dispatch' || | |
| (github.event_name == 'push' && (github.ref_name == 'main' || github.ref_name == 'develop')) }} | |
| run_sbom_aggregation_ci: >- | |
| ${{ (github.event_name == 'pull_request' && steps.changes.outputs.sbom_aggregation == 'true') || | |
| github.event_name == 'workflow_dispatch' || | |
| (github.event_name == 'push' && (github.ref_name == 'main' || github.ref_name == 'develop')) }} | |
| steps: | |
| - name: Checkout code | |
| if: github.event_name == 'pull_request' | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3 | |
| name: detect changes | |
| if: github.event_name == 'pull_request' | |
| id: changes | |
| with: | |
| filters: | | |
| pac: | |
| - 'tools/policy-as-code/**' | |
| conventional_commits: | |
| - 'tools/conventional-commits/respository-ruleset/**' | |
| sbom_aggregation: | |
| - 'tools/sbom-aggregation/**' | |
| lint-policies: | |
| permissions: | |
| contents: read | |
| name: Lint Policies | |
| runs-on: ubuntu-latest | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.run_pac_ci == 'true' | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Setup OPA | |
| uses: open-policy-agent/setup-opa@b2b258e089860efaadaaf71bf6e3aecb4a3eeff1 # v2.4.0 | |
| with: | |
| version: latest | |
| - name: Setup Regal | |
| uses: open-policy-agent/setup-regal@761188c3b435761fa254beca508a44875619648f # v2.0.0 | |
| with: | |
| version: latest | |
| - name: OPA Check (Strict) | |
| run: | | |
| opa check --strict tools/policy-as-code/policy | |
| - name: Regal Lint (github format) | |
| run: | | |
| mkdir -p test-results | |
| regal lint -f github tools/policy-as-code/policy | |
| - name: Regal Lint (sarif format) | |
| if: success() || failure() | |
| run: | | |
| mkdir -p test-results | |
| regal lint -f sarif tools/policy-as-code/policy -o test-results/lint-results.sarif | |
| - name: Upload linting results | |
| if: success() || failure() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: pac-linting-report | |
| path: test-results/lint-results.sarif | |
| test-policies: | |
| permissions: | |
| contents: read | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.run_pac_ci == 'true' | |
| name: Test Policies | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Setup OPA | |
| uses: open-policy-agent/setup-opa@b2b258e089860efaadaaf71bf6e3aecb4a3eeff1 # v2.4.0 | |
| with: | |
| version: latest | |
| - name: Run OPA Tests and Generate Reports | |
| run: | | |
| # Create output directory | |
| mkdir -p test-results | |
| mkdir -p test-results/coverage | |
| mkdir -p tmp | |
| opa test --format=json tools/policy-as-code/policy > tmp/test-results.json | |
| # 1. GENERATE TEST RESULTS (JUnit XML) | |
| # Convert JSON results to JUnit XML using jq | |
| jq -r ' | |
| "<testsuites time=\"\((map(.duration) | add // 0) / 1000000000)\"> | |
| <testsuite name=\"OPA\" tests=\"\(length)\" failures=\"\(map(select(.fail)) | length)\" time=\"\((map(.duration) | add // 0) / 1000000000)\"> | |
| \(map("<testcase name=\"\(.name)\" classname=\"\(.package)\" time=\"\(.duration/1000000000)\">\(if .fail then "<failure message=\"Test failed\"/>" else "" end)</testcase>") | join("")) | |
| </testsuite> | |
| </testsuites>" | |
| ' tmp/test-results.json > test-results/test-results-junit.xml | |
| # 2. GENERATE TEST EXECUTION REPORT (Generic Test Data for SonarQube) | |
| # Convert OPA JSON test results to Sonar Generic Execution XML format | |
| jq -r ' | |
| "<testExecutions version=\"1\">" + | |
| ( | |
| [ | |
| group_by(.location.file)[] | | |
| "<file path=\"\(.[0].location.file)\">" + | |
| ( | |
| map( | |
| "<testCase name=\"\(.name)\" duration=\"\((.duration / 1000000) | floor)\">" + | |
| (if .fail then "<failure message=\"Test failed\"/>" else "" end) + | |
| "</testCase>" | |
| ) | join("") | |
| ) + | |
| "</file>" | |
| ] | join("") | |
| ) + | |
| "</testExecutions>" | |
| ' tmp/test-results.json > test-results/test-results.xml | |
| # 3. GENERATE COVERAGE REPORT (Generic Test Data) | |
| # Convert OPA JSON coverage to Sonar Generic XML format | |
| opa test --coverage --format=json tools/policy-as-code/policy | jq -r ' | |
| "<coverage version=\"1\">" + | |
| ( | |
| [ | |
| .files | to_entries[] | | |
| "<file path=\"\(.key)\">" + | |
| ( | |
| [ | |
| (.value.covered[]? | range(.start.row; .end.row + 1) | "<lineToCover lineNumber=\"\(.)\" covered=\"true\"/>"), | |
| (.value.not_covered[]? | range(.start.row; .end.row + 1) | "<lineToCover lineNumber=\"\(.)\" covered=\"false\"/>") | |
| ] | join("") | |
| ) + | |
| "</file>" | |
| ] | join("") | |
| ) + | |
| "</coverage>" | |
| ' > test-results/coverage/coverage.xml | |
| - name: Upload test reports | |
| if: success() || failure() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: pac-test-report | |
| path: test-results/ | |
| test-conventional-commits: | |
| permissions: | |
| contents: read | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.run_conventional_commits_ci == 'true' | |
| name: Test Conventional Commits | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Setup Python | |
| uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| python-version: '3.12' | |
| cache: 'pip' | |
| - name: Install dependencies | |
| run: | | |
| pip install --only-binary :all: --require-hashes -r tools/conventional-commits/respository-ruleset/requirements.txt | |
| - name: Run Tests | |
| run: | | |
| # Create output directory | |
| mkdir -p test-results | |
| pytest --junitxml=test-results/test-results-conventional-commits.xml \ | |
| -- tools/conventional-commits/respository-ruleset/test_commit_regex.py | |
| - name: Upload test reports | |
| if: success() || failure() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: conventional-commits-test-report | |
| path: test-results/ | |
| test-sbom-aggregation: | |
| permissions: | |
| contents: read | |
| needs: detect-changes | |
| if: needs.detect-changes.outputs.run_sbom_aggregation_ci == 'true' | |
| name: Test SBOM Aggregation | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| - name: Setup Python | |
| uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0 | |
| with: | |
| python-version: '3.12' | |
| cache: 'pip' | |
| - name: Install dependencies | |
| run: | | |
| pip install --only-binary :all: --require-hashes -r tools/sbom-aggregation/requirements.txt | |
| - name: Run Tests | |
| run: | | |
| # Create output directory | |
| mkdir -p test-results/coverage | |
| pytest --cov-config=tools/sbom-aggregation/.coveragerc \ | |
| --cov=merge_sboms \ | |
| --cov-report xml:test-results/coverage/sbom-cov.xml \ | |
| --junitxml=test-results/test-results-sbom-aggregation.xml \ | |
| -- tools/sbom-aggregation/test_merge_sboms.py | |
| - name: Upload test reports | |
| if: success() || failure() | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: sbom-aggregation-test-report | |
| path: test-results/ | |
| publish-results: | |
| permissions: | |
| contents: read | |
| security-events: write | |
| needs: | |
| - lint-policies | |
| - test-policies | |
| - test-conventional-commits | |
| - test-sbom-aggregation | |
| if: always() | |
| name: Publish Reports | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| fetch-depth: 0 | |
| - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| pattern: '*-report' | |
| path: test-results | |
| merge-multiple: true | |
| - name: Detect reports exist | |
| id: results-check | |
| uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0 | |
| with: | |
| script: | | |
| const fs = require('fs'); | |
| const args = []; | |
| const hasSarif = fs.existsSync('test-results/lint-results.sarif'); | |
| const hasUnit = fs.existsSync('test-results/test-results.xml'); | |
| const hasConventionalCommits = fs.existsSync('test-results/test-results-conventional-commits.xml'); | |
| const hasSbomUnit = fs.existsSync('test-results/test-results-sbom-aggregation.xml'); | |
| const hasCoverage = fs.existsSync('test-results/coverage/coverage.xml'); | |
| const hasSbomCoverage = fs.existsSync('test-results/coverage/sbom-cov.xml'); | |
| core.setOutput('sarif-reports', hasSarif); | |
| core.setOutput('unit-reports', hasUnit || hasConventionalCommits || hasSbomUnit); | |
| core.setOutput('coverage-reports', hasCoverage || hasSbomCoverage); | |
| // Check for lint report | |
| if (hasSarif) { | |
| args.push('-Dsonar.sarifReportPaths=test-results/lint-results.sarif'); | |
| } | |
| // Check for Test Execution reports | |
| if (hasUnit) { | |
| args.push('-Dsonar.testExecutionReportPaths=test-results/test-results.xml'); | |
| } | |
| // Check for Python test reports | |
| const pythonTestReports = []; | |
| if (hasConventionalCommits) { | |
| pythonTestReports.push('test-results/test-results-conventional-commits.xml'); | |
| } | |
| if (hasSbomUnit) { | |
| pythonTestReports.push('test-results/test-results-sbom-aggregation.xml'); | |
| } | |
| if (pythonTestReports.length > 0) { | |
| args.push(`-Dsonar.python.xunit.reportPath=${pythonTestReports.join(',')}`); | |
| } | |
| // Check for coverage report | |
| if (hasCoverage) { | |
| args.push('-Dsonar.coverageReportPaths=test-results/coverage/coverage.xml'); | |
| } | |
| if (hasSbomCoverage) { | |
| args.push('-Dsonar.python.coverage.reportPaths=test-results/coverage/sbom-cov.xml'); | |
| } | |
| // Join with spaces and set as output | |
| core.setOutput('sonar-args', args.join(' ')); | |
| - name: Upload SARIF file | |
| if: | | |
| github.event.repository.visibility == 'public' && | |
| steps.results-check.outputs.sarif-reports == 'true' | |
| uses: github/codeql-action/upload-sarif@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 | |
| with: | |
| sarif_file: test-results/lint-results.sarif | |
| category: regal-lint | |
| - name: SonarQube Scan | |
| uses: SonarSource/sonarqube-scan-action@22918119ff8e1ca75a623e15c8296b6ea4fbe28f # v8.2.1 | |
| if: github.actor != 'dependabot[bot]' | |
| env: | |
| SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} | |
| with: | |
| args: > | |
| ${{ steps.results-check.outputs.sonar-args }} | |
| - name: Publish Test Results | |
| uses: dorny/test-reporter@a43b3a5f7366b97d083190328d2c652e1a8b6aa2 # v3.0.0 | |
| if: | | |
| always() && | |
| steps.results-check.outputs.unit-reports == 'true' | |
| with: | |
| name: OPA Test Results | |
| path: 'test-results/test-results-*.xml' | |
| reporter: java-junit |