[GPCAPIM-260]-[Steel Thread integration testing]-[RP] #383
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: Preview Environment | |
| on: | |
| pull_request: | |
| types: [opened, reopened, synchronize, closed] | |
| env: | |
| AWS_REGION: eu-west-2 | |
| AWS_ACCOUNT_ID: "900119715266" | |
| ECR_REPOSITORY_NAME: "whoami" | |
| TF_STATE_BUCKET: "cds-cdg-dev-tfstate-900119715266" | |
| PREVIEW_STATE_PREFIX: "dev/preview/" | |
| python_version: "3.14" | |
| jobs: | |
| preview: | |
| name: Manage preview environment | |
| runs-on: ubuntu-latest | |
| # Needed for OIDC → AWS (recommended) | |
| permissions: | |
| id-token: write | |
| contents: read | |
| pull-requests: write | |
| # One job per branch at a time | |
| concurrency: | |
| group: preview-${{ github.head_ref || github.ref_name }} | |
| cancel-in-progress: true | |
| env: | |
| AWS_ROLE_ARN: ${{ secrets.DEV_AWS_CREDENTIALS }} | |
| steps: | |
| - name: Checkout repo | |
| uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 | |
| # Configure AWS credentials (OIDC recommended) | |
| - name: Configure AWS credentials | |
| uses: aws-actions/configure-aws-credentials@4c2b9cc816c86555b61460789ac95da17d7e829b | |
| with: | |
| role-to-assume: ${{ env.AWS_ROLE_ARN }} | |
| aws-region: ${{ env.AWS_REGION }} | |
| - name: Login to Amazon ECR | |
| id: ecr-login | |
| uses: aws-actions/amazon-ecr-login@062b18b96a7aff071d4dc91bc00c4c1a7945b076 | |
| - name: Compute branch metadata | |
| id: meta | |
| run: | | |
| # For PRs, head_ref is the source branch name | |
| RAW_BRANCH="${GITHUB_HEAD_REF:-${GITHUB_REF_NAME}}" | |
| # Sanitize branch name for tags / hostnames (lowercase, only allowed chars) | |
| SANITIZED_BRANCH=$( | |
| printf '%s' "$RAW_BRANCH" \ | |
| | tr '[:upper:]' '[:lower:]' \ | |
| | tr '._' '-' \ | |
| | tr -c 'a-z0-9-' '-' \ | |
| | sed -E 's/-{2,}/-/g; s/^-+//; s/-+$//' | |
| ) | |
| # Last resort fallback if everything got stripped | |
| if [ -z "$SANITIZED_BRANCH" ]; then | |
| SANITIZED_BRANCH="invalid-branch-name" | |
| fi | |
| echo "raw_branch=$RAW_BRANCH" >> $GITHUB_OUTPUT | |
| echo "branch_name=$SANITIZED_BRANCH" >> $GITHUB_OUTPUT | |
| # ECR repo URL (must match core stack's ECR repo) | |
| ECR_URL="${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPOSITORY_NAME}" | |
| echo "ecr_url=$ECR_URL" >> $GITHUB_OUTPUT | |
| # Terraform state key for this preview env | |
| TF_STATE_KEY="${PREVIEW_STATE_PREFIX}${SANITIZED_BRANCH}.tfstate" | |
| echo "tf_state_key=$TF_STATE_KEY" >> $GITHUB_OUTPUT | |
| # ALB listener rule priority - derive from PR number (must be unique per listener) | |
| if [ -n "${{ github.event.number }}" ]; then | |
| PRIORITY=$(( 1000 + ${{ github.event.number }} )) | |
| else | |
| PRIORITY=1999 | |
| fi | |
| echo "alb_rule_priority=$PRIORITY" >> $GITHUB_OUTPUT | |
| - name: Setup Python project | |
| if: github.event.action != 'closed' | |
| uses: ./.github/actions/setup-python-project | |
| with: | |
| python-version: ${{ env.python_version }} | |
| - name: Build Docker image | |
| if: github.event.action != 'closed' | |
| env: | |
| PYTHON_VERSION: ${{ env.python_version }} | |
| run: | | |
| IMAGE_TAG="${{ steps.meta.outputs.branch_name }}" | |
| ECR_URL="${{ steps.meta.outputs.ecr_url }}" | |
| make build IMAGE_TAG="${IMAGE_TAG}" ECR_URL="${ECR_URL}" | |
| - name: Push Docker image to ECR | |
| if: github.event.action != 'closed' | |
| run: | | |
| IMAGE_TAG="${{ steps.meta.outputs.branch_name }}" | |
| ECR_URL="${{ steps.meta.outputs.ecr_url }}" | |
| docker push "${ECR_URL}:${IMAGE_TAG}" | |
| - name: Setup Terraform | |
| uses: hashicorp/setup-terraform@b9cd54a3c349d3f38e8881555d616ced269862dd | |
| with: | |
| terraform_version: 1.14.0 | |
| # ---------- APPLY (PR opened / updated) ---------- | |
| - name: Terraform init (apply) | |
| if: github.event.action != 'closed' | |
| working-directory: infrastructure/environments/preview | |
| run: | | |
| terraform init \ | |
| -backend-config="bucket=${TF_STATE_BUCKET}" \ | |
| -backend-config="key=${{ steps.meta.outputs.tf_state_key }}" \ | |
| -backend-config="region=${AWS_REGION}" | |
| - name: Terraform apply preview env | |
| if: github.event.action != 'closed' | |
| working-directory: infrastructure/environments/preview | |
| env: | |
| TF_VAR_branch_name: ${{ steps.meta.outputs.branch_name }} | |
| TF_VAR_image_tag: ${{ steps.meta.outputs.branch_name }} | |
| TF_VAR_alb_rule_priority: ${{ steps.meta.outputs.alb_rule_priority }} | |
| run: | | |
| terraform apply \ | |
| -auto-approve | |
| - name: Capture preview TF outputs | |
| if: github.event.action != 'closed' | |
| id: tf-output | |
| working-directory: infrastructure/environments/preview | |
| run: | | |
| terraform output -json > tf-output.json | |
| URL=$(jq -r '.url.value' tf-output.json) | |
| echo "preview_url=$URL" >> $GITHUB_OUTPUT | |
| TG=$(jq -r '.target_group_arn.value' tf-output.json) | |
| echo "target_group=$TG" >> $GITHUB_OUTPUT | |
| ECS_SERVICE=$(jq -r '.ecs_service_name.value' tf-output.json) | |
| echo "ecs_service=$ECS_SERVICE" >> $GITHUB_OUTPUT | |
| ECS_CLUSTER=$(jq -r '.ecs_cluster_name.value' tf-output.json) | |
| echo "ecs_cluster=$ECS_CLUSTER" >> $GITHUB_OUTPUT | |
| - name: Compute preview host | |
| id: set-host | |
| if: github.event.action != 'closed' | |
| run: | | |
| PREVIEW_URL='${{ steps.tf-output.outputs.preview_url }}' | |
| if [ -z "$PREVIEW_URL" ] || [ "$PREVIEW_URL" = "null" ]; then | |
| echo "host=missing" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| HOST=$(printf '%s' "$PREVIEW_URL" | sed -E 's#^https?://##' | sed -E 's#/.*$##') | |
| echo "host=${HOST}" >> "$GITHUB_OUTPUT" | |
| - name: Get proxygen machine user details | |
| id: proxygen-machine-user | |
| uses: aws-actions/aws-secretsmanager-get-secrets@a9a7eb4e2f2871d30dc5b892576fde60a2ecc802 | |
| with: | |
| secret-ids: /cds/gateway/dev/proxygen/proxygen-key-secret | |
| name-transformation: lowercase | |
| - name: Deploy preview API proxy | |
| if: github.event.action != 'closed' | |
| uses: ./.github/actions/proxy/deploy-proxy | |
| with: | |
| mtls-secret-name: ${{ vars.PREVIEW_ENV_MTLS_SECRET_NAME}} | |
| target-url: ${{ steps.tf-output.outputs.preview_url }} | |
| proxy-base-path: "clinical-data-gateway-api-poc-pr-${{ github.event.pull_request.number }}" | |
| proxygen-key-secret: ${{ env._cds_gateway_dev_proxygen_proxygen_key_secret }} | |
| proxygen-key-id: ${{ vars.PREVIEW_ENV_PROXYGEN_KEY_ID }} | |
| proxygen-api-name: ${{ vars.PROXYGEN_API_NAME }} | |
| proxygen-client-id: ${{ vars.PREVIEW_ENV_PROXYGEN_CLIENT_ID }} | |
| - name: Tear down preview API proxy | |
| if: github.event.action == 'closed' | |
| uses: ./.github/actions/proxy/tear-down-proxy | |
| with: | |
| proxy-base-path: "clinical-data-gateway-api-poc-pr-${{ github.event.pull_request.number }}" | |
| proxygen-key-secret: ${{ env._cds_gateway_dev_proxygen_proxygen_key_secret }} | |
| proxygen-key-id: ${{ vars.PREVIEW_ENV_PROXYGEN_KEY_ID }} | |
| proxygen-api-name: ${{ vars.PROXYGEN_API_NAME }} | |
| proxygen-client-id: ${{ vars.PREVIEW_ENV_PROXYGEN_CLIENT_ID }} | |
| # ---------- Ensure re-deployment (PR updated) ---------- | |
| - name: Force ECS service redeployment | |
| if: github.event.action == 'synchronize' | |
| id: await-redeployment | |
| run: | | |
| aws ecs update-service \ | |
| --cluster ${{ steps.tf-output.outputs.ecs_cluster }} \ | |
| --service ${{ steps.tf-output.outputs.ecs_service }} \ | |
| --force-new-deployment \ | |
| --region ${{ env.AWS_REGION }} | |
| # ---------- DESTROY (PR closed) ---------- | |
| - name: Terraform init (destroy) | |
| if: github.event.action == 'closed' | |
| working-directory: infrastructure/environments/preview | |
| run: | | |
| terraform init \ | |
| -backend-config="bucket=${TF_STATE_BUCKET}" \ | |
| -backend-config="key=${{ steps.meta.outputs.tf_state_key }}" \ | |
| -backend-config="region=${AWS_REGION}" | |
| - name: Terraform destroy preview env | |
| if: github.event.action == 'closed' | |
| working-directory: infrastructure/environments/preview | |
| env: | |
| TF_VAR_branch_name: ${{ steps.meta.outputs.branch_name }} | |
| TF_VAR_image_tag: ${{ steps.meta.outputs.branch_name }} | |
| TF_VAR_alb_rule_priority: ${{ steps.meta.outputs.alb_rule_priority }} | |
| run: | | |
| terraform destroy -auto-approve | |
| # ---------- Wait on AWS tasks and notify ---------- | |
| - name: Await deployment completion | |
| if: github.event.action != 'closed' | |
| run: | | |
| aws ecs wait services-stable \ | |
| --cluster ${{ steps.tf-output.outputs.ecs_cluster }} \ | |
| --services ${{ steps.tf-output.outputs.ecs_service }} \ | |
| --region ${{ env.AWS_REGION }} | |
| - name: Get mTLS certs for testing | |
| if: github.event.action != 'closed' | |
| id: mtls-certs | |
| uses: aws-actions/aws-secretsmanager-get-secrets@a9a7eb4e2f2871d30dc5b892576fde60a2ecc802 | |
| with: | |
| secret-ids: | | |
| /cds/gateway/dev/mtls/client1-key-secret | |
| /cds/gateway/dev/mtls/client1-key-public | |
| name-transformation: lowercase | |
| # Prepare cert files for the following test suites | |
| - name: Prepare mTLS cert files for tests | |
| if: github.event.action != 'closed' | |
| run: | | |
| printf '%s' "$_cds_gateway_dev_mtls_client1_key_secret" > /tmp/client1-key.pem | |
| printf '%s' "$_cds_gateway_dev_mtls_client1_key_public" > /tmp/client1-cert.pem | |
| chmod 600 /tmp/client1-key.pem /tmp/client1-cert.pem | |
| - name: Smoke test preview URL | |
| if: github.event.action != 'closed' | |
| id: smoke-test | |
| env: | |
| PREVIEW_URL: ${{ steps.tf-output.outputs.preview_url }} | |
| run: | | |
| if [ -z "$PREVIEW_URL" ] || [ "$PREVIEW_URL" = "null" ]; then | |
| echo "Preview URL missing" | |
| echo "http_status=missing" >> "$GITHUB_OUTPUT" | |
| echo "http_result=missing-url" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| STATUS=$(curl \ | |
| --cert /tmp/client1-cert.pem \ | |
| --key /tmp/client1-key.pem \ | |
| --silent \ | |
| --output /tmp/preview.headers \ | |
| --write-out '%{http_code}' \ | |
| --head \ | |
| --max-time 30 "$PREVIEW_URL"/health || true) | |
| if [ "$STATUS" = "404" ]; then | |
| echo "Preview responded with expected 404" | |
| echo "http_status=404" >> "$GITHUB_OUTPUT" | |
| echo "http_result=allowed-404" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| if [[ "$STATUS" =~ ^[0-9]{3}$ ]] && [ "$STATUS" -ge 200 ] && [ "$STATUS" -lt 400 ]; then | |
| echo "Preview responded with status $STATUS" | |
| echo "http_status=$STATUS" >> "$GITHUB_OUTPUT" | |
| echo "http_result=success" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| fi | |
| echo "Preview responded with unexpected status $STATUS" | |
| if [ -f /tmp/preview.headers ]; then | |
| echo "Response headers:" | |
| cat /tmp/preview.headers | |
| fi | |
| echo "http_status=$STATUS" >> "$GITHUB_OUTPUT" | |
| echo "http_result=unexpected-status" >> "$GITHUB_OUTPUT" | |
| exit 0 | |
| # ---------- QUALITY CHECKS (Test Suites) ---------- | |
| # UNIT TESTS | |
| - name: Run unit tests against preview | |
| if: github.event.action != 'closed' | |
| env: | |
| MTLS_CERT: /tmp/client1-cert.pem | |
| MTLS_KEY: /tmp/client1-key.pem | |
| run: | | |
| make test-unit | |
| - name: Upload unit test results | |
| if: always() | |
| uses: actions/upload-artifact@v5 | |
| with: | |
| name: unit-test-results | |
| path: gateway-api/test-artefacts/ | |
| retention-days: 30 | |
| - name: Check unit-tests.xml exists | |
| id: check-unit | |
| if: always() | |
| run: | | |
| TARGET="gateway-api/test-artefacts/unit-tests.xml" | |
| echo "Checking for $TARGET" | |
| if [ -f "$TARGET" ]; then | |
| echo "exists=true" >> "$GITHUB_OUTPUT" | |
| echo "Found $TARGET" | |
| else | |
| echo "exists=false" >> "$GITHUB_OUTPUT" | |
| echo "Missing $TARGET" >&2 | |
| echo "Listing gateway-api/test-artefacts for debugging:" | |
| ls -la gateway-api/test-artefacts || true | |
| fi | |
| - name: Publish unit test results to summary | |
| if: ${{ always() && steps.check-unit.outputs.exists == 'true' }} | |
| uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 | |
| with: | |
| paths: gateway-api/test-artefacts/unit-tests.xml | |
| # CONTRACT TESTS | |
| - name: Run contract tests | |
| if: github.event.action != 'closed' | |
| env: | |
| BASE_URL: ${{ steps.tf-output.outputs.preview_url }} | |
| MTLS_CERT: /tmp/client1-cert.pem | |
| MTLS_KEY: /tmp/client1-key.pem | |
| run: | | |
| make test-contract | |
| - name: Upload contract test results | |
| if: always() | |
| uses: actions/upload-artifact@v5 | |
| with: | |
| name: contract-test-results | |
| path: gateway-api/test-artefacts/ | |
| retention-days: 30 | |
| - name: Check contract-tests.xml exists | |
| id: check-contract | |
| if: always() | |
| run: | | |
| TARGET="gateway-api/test-artefacts/contract-tests.xml" | |
| echo "Checking for $TARGET" | |
| if [ -f "$TARGET" ]; then | |
| echo "exists=true" >> "$GITHUB_OUTPUT" | |
| echo "Found $TARGET" | |
| else | |
| echo "exists=false" >> "$GITHUB_OUTPUT" | |
| echo "Missing $TARGET" >&2 | |
| echo "Listing gateway-api/test-artefacts for debugging:" | |
| ls -la gateway-api/test-artefacts || true | |
| fi | |
| - name: Publish contract test results to summary | |
| if: ${{ always() && steps.check-contract.outputs.exists == 'true' }} | |
| uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 | |
| with: | |
| paths: gateway-api/test-artefacts/contract-tests.xml | |
| # SCHEMA TESTS | |
| - name: Run schema validation tests against preview | |
| if: github.event.action != 'closed' | |
| env: | |
| BASE_URL: ${{ steps.tf-output.outputs.preview_url }} | |
| MTLS_CERT: /tmp/client1-cert.pem | |
| MTLS_KEY: /tmp/client1-key.pem | |
| run: | | |
| make test-schema | |
| - name: Upload schema test results | |
| if: always() | |
| uses: actions/upload-artifact@v5 | |
| with: | |
| name: schema-test-results | |
| path: gateway-api/test-artefacts/ | |
| retention-days: 30 | |
| - name: Check schema-tests.xml exists | |
| id: check-schema | |
| if: always() | |
| run: | | |
| TARGET="gateway-api/test-artefacts/schema-tests.xml" | |
| echo "Checking for $TARGET" | |
| if [ -f "$TARGET" ]; then | |
| echo "exists=true" >> "$GITHUB_OUTPUT" | |
| echo "Found $TARGET" | |
| else | |
| echo "exists=false" >> "$GITHUB_OUTPUT" | |
| echo "Missing $TARGET" >&2 | |
| echo "Listing gateway-api/test-artefacts for debugging:" | |
| ls -la gateway-api/test-artefacts || true | |
| fi | |
| - name: Publish schema test results to summary | |
| if: ${{ always() && steps.check-schema.outputs.exists == 'true' }} | |
| uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 | |
| with: | |
| paths: gateway-api/test-artefacts/schema-tests.xml | |
| # INTEGRATION TESTS | |
| - name: Run integration tests against preview | |
| if: github.event.action != 'closed' | |
| env: | |
| BASE_URL: ${{ steps.tf-output.outputs.preview_url }} | |
| MTLS_CERT: /tmp/client1-cert.pem | |
| MTLS_KEY: /tmp/client1-key.pem | |
| run: | | |
| make test-integration | |
| - name: Upload integration test results | |
| if: always() | |
| uses: actions/upload-artifact@v5 | |
| with: | |
| name: integration-test-results | |
| path: gateway-api/test-artefacts/ | |
| retention-days: 30 | |
| - name: Check integration-tests.xml exists | |
| id: check-integration | |
| if: always() | |
| run: | | |
| TARGET="gateway-api/test-artefacts/integration-tests.xml" | |
| echo "Checking for $TARGET" | |
| if [ -f "$TARGET" ]; then | |
| echo "exists=true" >> "$GITHUB_OUTPUT" | |
| echo "Found $TARGET" | |
| else | |
| echo "exists=false" >> "$GITHUB_OUTPUT" | |
| echo "Missing $TARGET" >&2 | |
| echo "Listing gateway-api/test-artefacts for debugging:" | |
| ls -la gateway-api/test-artefacts || true | |
| fi | |
| - name: Publish integration test results to summary | |
| if: ${{ always() && steps.check-integration.outputs.exists == 'true' }} | |
| uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 | |
| with: | |
| paths: gateway-api/test-artefacts/integration-tests.xml | |
| # ACCEPTANCE TESTS | |
| - name: Run acceptance tests against preview | |
| if: github.event.action != 'closed' | |
| env: | |
| BASE_URL: ${{ steps.tf-output.outputs.preview_url }} | |
| HOST: ${{ steps.set-host.outputs.host }} | |
| MTLS_CERT: /tmp/client1-cert.pem | |
| MTLS_KEY: /tmp/client1-key.pem | |
| run: | | |
| make test-acceptance | |
| - name: Upload acceptance test results | |
| if: always() | |
| uses: actions/upload-artifact@v5 | |
| with: | |
| name: acceptance-test-results | |
| path: gateway-api/test-artefacts/ | |
| retention-days: 30 | |
| - name: Check acceptance-tests.xml exists | |
| id: check-acceptance | |
| if: always() | |
| run: | | |
| TARGET="gateway-api/test-artefacts/acceptance-tests.xml" | |
| echo "Checking for $TARGET" | |
| if [ -f "$TARGET" ]; then | |
| echo "exists=true" >> "$GITHUB_OUTPUT" | |
| echo "Found $TARGET" | |
| else | |
| echo "exists=false" >> "$GITHUB_OUTPUT" | |
| echo "Missing $TARGET" >&2 | |
| echo "Listing gateway-api/test-artefacts for debugging:" | |
| ls -la gateway-api/test-artefacts || true | |
| fi | |
| - name: Publish acceptance test results to summary | |
| if: ${{ always() && steps.check-acceptance.outputs.exists == 'true' }} | |
| uses: test-summary/action@31493c76ec9e7aa675f1585d3ed6f1da69269a86 | |
| with: | |
| paths: gateway-api/test-artefacts/acceptance-tests.xml | |
| # Cleanup after tests | |
| - name: Remove mTLS temp files | |
| if: github.event.action != 'closed' | |
| run: | | |
| rm -f /tmp/client1-key.pem /tmp/client1-cert.pem || true | |
| - name: Comment function name on PR | |
| if: github.event_name == 'pull_request' && github.event.action != 'closed' | |
| uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd | |
| with: | |
| script: | | |
| const alb = '${{ steps.tf-output.outputs.target_group }}'; | |
| const url = '${{ steps.tf-output.outputs.preview_url }}'; | |
| const proxy_url = 'https://internal-dev.api.service.nhs.uk/clinical-data-gateway-api-poc-pr-${{ github.event.pull_request.number }}'; | |
| const cluster = '${{ steps.tf-output.outputs.ecs_cluster }}'; | |
| const service = '${{ steps.tf-output.outputs.ecs_service }}'; | |
| const owner = context.repo.owner; | |
| const repo = context.repo.repo; | |
| const issueNumber = context.issue.number; | |
| const smokeStatus = '${{ steps.smoke-test.outputs.http_status }}' || 'n/a'; | |
| const smokeResult = '${{ steps.smoke-test.outputs.http_result }}' || 'not-run'; | |
| const smokeLabels = { | |
| success: ':white_check_mark: Passed', | |
| 'allowed-404': ':white_check_mark: Allowed 404', | |
| 'unexpected-status': ':x: Unexpected status', | |
| 'missing-url': ':x: Missing URL', | |
| }; | |
| const smokeReadable = smokeLabels[smokeResult] ?? smokeResult; | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner, | |
| repo, | |
| issue_number: issueNumber, | |
| per_page: 100, | |
| }); | |
| for (const comment of comments) { | |
| const isBot = comment.user?.login === 'github-actions[bot]'; | |
| const isPreviewUpdate = comment.body?.includes('Deployment Complete'); | |
| if (isBot && isPreviewUpdate) { | |
| await github.rest.issues.deleteComment({ | |
| owner, | |
| repo, | |
| comment_id: comment.id, | |
| }); | |
| } | |
| } | |
| const lines = [ | |
| '**Deployment Complete**', | |
| `- Preview URL: [${url}](${url}) — [Health endpoint](${url}/health)`, | |
| ` - Smoke Test: ${smokeReadable} (HTTP ${smokeStatus})`, | |
| `- Proxy URL: [${proxy_url}](${proxy_url})`, | |
| `- ECS Cluster: \`${cluster}\``, | |
| `- ECS Service: \`${service}\``, | |
| `- ALB Target: \`${alb}\``, | |
| ]; | |
| await github.rest.issues.createComment({ | |
| owner, | |
| repo, | |
| issue_number: issueNumber, | |
| body: lines.join('\n'), | |
| }); | |
| # ---------- Security scanning ---------- | |
| - name: Trivy IaC scan | |
| if: github.event.action != 'closed' | |
| uses: nhs-england-tools/trivy-action/iac-scan@3456c1657a37d500027fd782e6b08911725392da | |
| with: | |
| scan-ref: infrastructure/environments/preview | |
| artifact-name: trivy-iac-scan-${{ steps.meta.outputs.branch_name }} | |
| - name: Trivy filesystem scan | |
| if: github.event.action != 'closed' | |
| uses: nhs-england-tools/trivy-action/image-scan@3456c1657a37d500027fd782e6b08911725392da | |
| with: | |
| image-ref: ${{steps.meta.outputs.ecr_url}}:${{steps.meta.outputs.branch_name}} | |
| artifact-name: trivy-scan-${{ steps.meta.outputs.branch_name }} | |
| - name: Generate SBOM | |
| uses: nhs-england-tools/trivy-action/sbom-scan@3456c1657a37d500027fd782e6b08911725392da | |
| if: github.event.action != 'closed' | |
| with: | |
| image-ref: ${{steps.meta.outputs.ecr_url}}:${{steps.meta.outputs.branch_name}} | |
| artifact-name: trivy-sbom-${{ steps.meta.outputs.branch_name }} |