-
Notifications
You must be signed in to change notification settings - Fork 1
[GPCAPIM-289]-[Pass integration tests through APIM proxy (with mock CIS2)]-[RP] #101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| name: "Run test suite" | ||
| description: | | ||
| Composite action that runs a single test type (unit/contract/schema/integration/acceptance), | ||
| uploads the test artefacts, and publishes a JUnit summary to the GitHub Actions job. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. junit and html |
||
| Delegates to `make test-<type>` which invokes scripts/tests/run-test.sh. | ||
| For remote tests, pass apigee-access-token to authenticate with the APIM proxy. | ||
|
|
||
| inputs: | ||
| test-type: | ||
| description: "Type of test to run" | ||
| required: true | ||
| apigee-access-token: | ||
| description: "Apigee access token" | ||
| required: false | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if the env defaults to remote: env: as you have further down - should this 'apigee-access-token' default to true as you say above that this token is required for a remote run? |
||
| base-url: | ||
| description: "The URL of the environment to test" | ||
| required: false | ||
| mtls-cert: | ||
| description: "Path to mTLS certificate" | ||
| required: false | ||
| mtls-key: | ||
| description: "Path to mTLS key" | ||
| required: false | ||
| stub-sds: | ||
| description: "Whether to stub SDS" | ||
| required: false | ||
| default: "false" | ||
| stub-pds: | ||
| description: "Whether to stub PDS" | ||
| required: false | ||
| default: "false" | ||
| stub-provider: | ||
| description: "Whether to stub Provider" | ||
| required: false | ||
| default: "false" | ||
| env: | ||
| description: "Environment: local or remote" | ||
| required: false | ||
| default: "remote" | ||
|
|
||
| runs: | ||
| using: composite | ||
| steps: | ||
| - name: "Run ${{ inputs.test-type }} tests" | ||
| shell: bash | ||
| env: | ||
| APIGEE_ACCESS_TOKEN: ${{ inputs.apigee-access-token }} | ||
| BASE_URL: ${{ inputs.base-url }} | ||
| MTLS_CERT: ${{ inputs.mtls-cert }} | ||
| MTLS_KEY: ${{ inputs.mtls-key }} | ||
| STUB_SDS: ${{ inputs.stub-sds }} | ||
| STUB_PDS: ${{ inputs.stub-pds }} | ||
| STUB_PROVIDER: ${{ inputs.stub-provider }} | ||
| ENV: ${{ inputs.env }} | ||
| run: | | ||
| if [[ -n "${APIGEE_ACCESS_TOKEN}" ]]; then | ||
| echo "::add-mask::${APIGEE_ACCESS_TOKEN}" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what does this do? if it masks the log when why log it out? |
||
| fi | ||
| make test-${{ inputs.test-type }} | ||
|
|
||
| - name: "Upload ${{ inputs.test-type }} test results" | ||
| if: always() | ||
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | ||
| with: | ||
| name: ${{ inputs.test-type }}-test-results | ||
| path: gateway-api/test-artefacts/ | ||
| retention-days: 30 | ||
|
|
||
| - name: "Check ${{ inputs.test-type }}-tests.xml exists" | ||
| id: check | ||
| if: always() | ||
| shell: bash | ||
| run: | | ||
| if [[ -f "gateway-api/test-artefacts/${{ inputs.test-type }}-tests.xml" ]]; then | ||
| echo "exists=true" >> "$GITHUB_OUTPUT" | ||
| else | ||
| echo "exists=false" >> "$GITHUB_OUTPUT" | ||
| fi | ||
|
|
||
| - name: "Publish ${{ inputs.test-type }} test results to summary" | ||
| if: ${{ always() && steps.check.outputs.exists == 'true' }} | ||
| uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 | ||
| with: | ||
| paths: gateway-api/test-artefacts/${{ inputs.test-type }}-tests.xml | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,130 @@ | ||
| name: SBOM Scan | ||
| description: Performs SBOM scanning and reporting with optional dependency graph upload | ||
|
|
||
| inputs: | ||
| image-ref: | ||
| description: 'Docker image reference to scan' | ||
| required: false | ||
| repo-path: | ||
| description: "Path to git repo to scan (local or remote)" | ||
| required: false | ||
| fs-path: | ||
| description: 'Path to filesystem to scan' | ||
| required: false | ||
| github-token: | ||
| description: 'GitHub token for dependency graph upload' | ||
| required: false | ||
| publish-to-dependency-graph: | ||
| description: 'Whether to publish SBOM to GitHub Dependency Graph' | ||
| required: false | ||
| default: 'false' | ||
| artifact-name: | ||
| description: 'Name for the uploaded SBOM artifact' | ||
| required: false | ||
| default: 'sbom' | ||
|
|
||
| outputs: | ||
| sbom-path: | ||
| description: 'Path to the generated SBOM file' | ||
| value: 'sbom.spdx.json' | ||
|
|
||
| runs: | ||
| using: "composite" | ||
| steps: | ||
| - name: Validate inputs | ||
| shell: bash | ||
| env: | ||
| IMAGE_REF: ${{ inputs.image-ref }} | ||
| REPO_PATH: ${{ inputs.repo-path }} | ||
| FS_PATH: ${{ inputs.fs-path }} | ||
| run: | | ||
| echo "IMAGE_REF:" $IMAGE_REF | ||
| echo "REPO_PATH:" $REPO_PATH | ||
| echo "FS_PATH:" $FS_PATH | ||
| if [[ -z $IMAGE_REF && -z $REPO_PATH && -z $FS_PATH ]]; then | ||
| echo "Must define one of IMAGE_REF or REPO_PATH or FS_PATH" | ||
| exit 1 | ||
| elif [[ -n $IMAGE_REF && -n $REPO_PATH && -n $FS_PATH ]]; then | ||
| echo "Must define only one of IMAGE_REF or REPO_PATH or FS_PATH, not multiple." | ||
| exit 1 | ||
| fi | ||
| ls -l $FS_PATH || true | ||
|
|
||
| - name: Trivy SBOM SPDX Scan - Docker Image | ||
| if: ${{ inputs.image-ref != '' }} | ||
| uses: aquasecurity/trivy-action@0.34.2 | ||
| with: | ||
| scan-type: image | ||
| image-ref: ${{ inputs.image-ref }} | ||
| format: spdx-json | ||
| output: sbom.spdx.json | ||
|
|
||
| - name: Trivy SBOM SPDX Scan - Repo | ||
| if: ${{ inputs.repo-path != '' }} | ||
| uses: aquasecurity/trivy-action@0.34.2 | ||
| with: | ||
| scan-type: repo | ||
| scan-ref: ${{ inputs.repo-path }} | ||
| format: spdx-json | ||
| output: sbom.spdx.json | ||
|
|
||
| - name: Trivy SBOM SPDX Scan - Filesystem | ||
| if: ${{ inputs.fs-path != '' }} | ||
| uses: aquasecurity/trivy-action@0.34.2 | ||
| with: | ||
| scan-type: fs | ||
| scan-ref: ${{ inputs.fs-path }} | ||
| format: spdx-json | ||
| output: sbom.spdx.json | ||
|
|
||
| - name: Trivy SBOM Dependency Graph Upload | ||
| if: ${{ inputs.publish-to-dependency-graph == 'true' && inputs.github-token != '' }} | ||
| uses: aquasecurity/trivy-action@0.34.2 | ||
| with: | ||
| scan-type: image | ||
| image-ref: ${{ inputs.image-ref }} | ||
| format: github | ||
| output: sbom.github.json | ||
| github-pat: ${{ inputs.github-token }} | ||
|
|
||
| - name: Upload SBOM artifact | ||
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | ||
| with: | ||
| name: ${{ inputs.artifact-name }} | ||
| path: sbom.spdx.json | ||
|
|
||
| - name: Append SBOM inventory to summary | ||
| if: always() | ||
| shell: bash | ||
| run: | | ||
| cat > sbom_to_summary.jq <<'JQ' | ||
| def clean: (.|tostring) | gsub("\\|"; "\\|") | gsub("\r?\n"; " "); | ||
| def purl: ((.externalRefs[]? | select(.referenceType=="purl") | .referenceLocator) // ""); | ||
| def license: (.licenseConcluded // .licenseDeclared // ""); | ||
| def supplier: ((.supplier // "") | sub("^Person: *|^Organization: *";"")); | ||
|
|
||
| if (has("spdxVersion") | not) then | ||
| "### SBOM Inventory (SPDX)\n\nSBOM is not SPDX JSON." | ||
| else | ||
| .packages as $pkgs | ||
| | "### SBOM Inventory (SPDX)\n\n" | ||
| + "| Metric | Value |\n|---|---|\n" | ||
| + "| Packages | " + ($pkgs|length|tostring) + " |\n\n" | ||
| + "<details><summary>Full inventory</summary>\n\n" | ||
| + "| Package | Version | Supplier | License | PURL |\n|---|---|---|---|---|\n" | ||
| + ( | ||
| $pkgs | ||
| | map("| " | ||
| + ((.name // .SPDXID) | clean) | ||
| + " | " + ((.versionInfo // "") | clean) | ||
| + " | " + (supplier | clean) | ||
| + " | " + (license | clean) | ||
| + " | " + (purl | clean) | ||
| + " |") | ||
| | join("\n") | ||
| ) | ||
| + "\n\n</details>\n" | ||
| end | ||
| JQ | ||
|
|
||
| jq -r -f sbom_to_summary.jq sbom.spdx.json >> "$GITHUB_STEP_SUMMARY" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,143 @@ | ||
| name: Trivy fs Scan | ||
| description: Performs Trivy security scanning for filesystems with comprehensive reporting | ||
|
|
||
| inputs: | ||
| filesystem-ref: | ||
| description: 'Filesystem reference to scan (e.g., /path/to/filesystem)' | ||
| required: true | ||
| severity: | ||
| description: 'Comma-separated list of severity levels to report' | ||
| required: false | ||
| default: 'HIGH,CRITICAL,MEDIUM,LOW,UNKNOWN' | ||
| trivy-config: | ||
| description: 'Path to Trivy configuration file' | ||
| required: false | ||
| default: 'trivy.yaml' | ||
| artifact-name: | ||
| description: 'Name for the uploaded artifact' | ||
| required: false | ||
| default: 'trivy-fs-scan-results' | ||
| fail-on-critical-high: | ||
| description: 'Whether to fail the action on critical/high findings' | ||
| required: false | ||
| default: 'true' | ||
| ignore-unfixed: | ||
| description: 'Ignore unfixed vulnerabilities' | ||
| required: false | ||
| default: 'true' | ||
|
|
||
| outputs: | ||
| critical-count: | ||
| description: 'Number of critical severity findings' | ||
| value: ${{ steps.report.outputs.crit }} | ||
| high-count: | ||
| description: 'Number of high severity findings' | ||
| value: ${{ steps.report.outputs.high }} | ||
| report-path: | ||
| description: 'Path to the generated markdown report' | ||
| value: 'trivy_fs_report.md' | ||
|
|
||
| runs: | ||
| using: "composite" | ||
| steps: | ||
| - name: Check if Trivy config exists | ||
| id: trivy-config-check | ||
| shell: bash | ||
| run: | | ||
| if [[ -f "${{ inputs.trivy-config }}" ]]; then | ||
| echo "config-exists=true" >> "$GITHUB_OUTPUT" | ||
| echo "config-arg=${{ inputs.trivy-config }}" >> "$GITHUB_OUTPUT" | ||
| else | ||
| echo "config-exists=false" >> "$GITHUB_OUTPUT" | ||
| echo "config-arg=" >> "$GITHUB_OUTPUT" | ||
| fi | ||
|
|
||
| - name: Trivy fs scan | ||
| uses: aquasecurity/trivy-action@0.34.2 | ||
| with: | ||
| scan-type: 'fs' | ||
| scan-ref: ${{ inputs.filesystem-ref }} | ||
| format: json | ||
| output: trivy-fs-scan.json | ||
| exit-code: 0 | ||
| ignore-unfixed: ${{ inputs.ignore-unfixed }} | ||
| severity: ${{ inputs.severity }} | ||
| trivy-config: ${{ steps.trivy-config-check.outputs.config-arg }} | ||
|
|
||
| - name: Upload Trivy Scan Artifact | ||
| uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 | ||
| with: | ||
| name: ${{ inputs.artifact-name }} | ||
| path: trivy-fs-scan.json | ||
|
|
||
| - name: Build summary & counts | ||
| id: report | ||
| shell: bash | ||
| run: | | ||
| # Filesystem scan report | ||
| jq -r ' | ||
| def clean: (.|tostring) | gsub("\\|";"\\|") | gsub("\r?\n";" "); | ||
| def sev: ["CRITICAL","HIGH","MEDIUM","LOW","UNKNOWN"]; | ||
| def counts: | ||
| ([.Results[]? | .Vulnerabilities[]? | .Severity // "UNKNOWN"] | ||
| | reduce .[] as $s ({CRITICAL:0,HIGH:0,MEDIUM:0,LOW:0,UNKNOWN:0}; .[$s]+=1)); | ||
| . as $root | ||
| | (counts) as $c | ||
| | | ||
| # ---- TOP BANNER (only if High/Critical present) ---- | ||
| ( | ||
| if (($c.CRITICAL + $c.HIGH) > 0) then | ||
| "🚫 **Trivy gate:** **\($c.CRITICAL) Critical**, **\($c.HIGH) High** vulnerability(s) found.\n\n" | ||
| else | ||
| "✅ **Trivy gate:** no Critical/High vulnerabilities.\n\n" | ||
| end | ||
| ) | ||
| # ---- SUMMARY REPORT ---- | ||
| + "### Trivy Filesystem Scan Summary\n\n" | ||
| + "**Filesystem:** " + ($root.ArtifactName // "'"'"'${{ inputs.filesystem-ref }}'"'"'") + "\n\n" | ||
| + "| Severity | Count |\n|---|---|\n" | ||
| + (sev | map("| " + . + " | " + ($c[.]|tostring) + " |") | join("\n")) | ||
| + (if ([.Results[]? | .Vulnerabilities[]?] | length) == 0 | ||
| then "\n\n✅ No vulnerabilities found.\n" | ||
| else | ||
| "\n\n<details><summary>Findings (top 50)</summary>\n\n" | ||
| + "| Severity | ID | Package | Installed | Fixed | Source |\n|---|---|---|---|---|---|\n" | ||
| + ( | ||
| [ .Results[]? as $r | ||
| | $r.Vulnerabilities[]? | ||
| | "| \(.Severity) | \(.VulnerabilityID) | \(.PkgName) | \(.InstalledVersion) | \((.FixedVersion // "") | clean) | \(($r.Target) | clean) |" | ||
| ] | .[:50] | join("\n") | ||
| ) | ||
| + "\n\n</details>\n" | ||
| end) | ||
| ' trivy-fs-scan.json > trivy_fs_report.md | ||
|
|
||
| # Extract counts for gating/other steps | ||
| read CRIT HIGH < <(jq -r ' | ||
| [.Results[]? | .Vulnerabilities[]? | .Severity // "UNKNOWN"] | ||
| | reduce .[] as $s ({CRITICAL:0,HIGH:0,MEDIUM:0,LOW:0,UNKNOWN:0}; .[$s]+=1) | ||
| | "\(.CRITICAL) \(.HIGH)" | ||
| ' trivy-fs-scan.json) | ||
|
|
||
| echo "crit=$CRIT" >> "$GITHUB_OUTPUT" | ||
| echo "high=$HIGH" >> "$GITHUB_OUTPUT" | ||
|
|
||
| - name: Publish Trivy Summary | ||
| if: always() | ||
| shell: bash | ||
| run: cat trivy_fs_report.md >> "$GITHUB_STEP_SUMMARY" | ||
|
|
||
| - name: Update Trivy PR comment | ||
| if: ${{ github.event_name == 'pull_request' && !github.event.pull_request.head.repo.fork }} | ||
| uses: marocchino/sticky-pull-request-comment@v2 | ||
| with: | ||
| header: ${{ inputs.artifact-name }} | ||
| path: trivy_fs_report.md | ||
|
|
||
| - name: Check Trivy Issue Thresholds | ||
| if: ${{ inputs.fail-on-critical-high == 'true' && (steps.report.outputs.crit != '0' || steps.report.outputs.high != '0') }} | ||
| shell: bash | ||
| run: | | ||
| echo "Critical vulnerabilities detected: ${{ steps.report.outputs.crit }}" | ||
| echo "High vulnerabilities detected: ${{ steps.report.outputs.high }}" | ||
| exit 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Composite action that can run any one of the test types: unit/contract/schema/integration/acceptance
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or
Composite action that is used to run the test types: