Skip to content

Commit cce5584

Browse files
authored
Merge pull request #282 from NHSDigital/PPHA-588-Create-the-Review-environment-and-pr-trigger
PPHA-588: create the review environment and pr trigger
2 parents 2ae990b + cea9607 commit cce5584

24 files changed

Lines changed: 356 additions & 93 deletions

File tree

.azuredevops/pipelines/deploy.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ stages:
4747
- task: AzureCLI@2
4848
displayName: Run terraform
4949
inputs:
50-
azureSubscription: lung-${{ parameters.environment }}
50+
azureSubscription: sc-lungcs-${{ parameters.environment }}-spoke
5151
scriptType: bash
5252
scriptLocation: inlineScript
5353
addSpnToEnvironment: true
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Delete review app
2+
3+
on:
4+
pull_request:
5+
types: [closed]
6+
7+
jobs:
8+
destroy:
9+
if: contains(github.event.pull_request.labels.*.name, 'deploy')
10+
name: Delete review app pr-${{ github.event.pull_request.number }}
11+
permissions:
12+
id-token: write
13+
pull-requests: write
14+
runs-on: ubuntu-latest
15+
environment: review
16+
# Prevent concurrent jobs on the same environment and between deploy and delete workflows
17+
concurrency: deploy-review-${{ github.event.pull_request.number }}
18+
19+
steps:
20+
- name: Checkout code
21+
uses: actions/checkout@v6
22+
23+
- uses: azure/login@v2
24+
with:
25+
client-id: ${{ secrets.AZURE_CLIENT_ID }}
26+
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
27+
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
28+
29+
- name: Call delete review app pipeline
30+
run: |
31+
echo "Starting Azure devops pipeline \"Delete review app\"..."
32+
RUN_ID=$(az pipelines run \
33+
--commit-id ${{ github.event.pull_request.head.sha }}\
34+
--name "Delete review app"\
35+
--org https://dev.azure.com/nhse-dtos \
36+
--project lung-cancer-risk-check \
37+
--parameters commitSHA=${{ github.event.pull_request.head.sha }} prNumber=${{ github.event.pull_request.number }} \
38+
--output tsv --query id)
39+
40+
echo "See pipeline run in Azure devops: https://dev.azure.com/nhse-dtos/lung-cancer-risk-check/_build/results?buildId=${RUN_ID}&view=results"
41+
42+
scripts/bash/wait_ado_pipeline.sh "$RUN_ID" https://dev.azure.com/nhse-dtos lung_cancer_screening
43+
44+
- name: Post URL to PR comments
45+
uses: marocchino/sticky-pull-request-comment@5060d4700a91de252c87eeddd2da026382d9298a
46+
with:
47+
message: |
48+
The review app at this URL has been deleted:
49+
https://pr-${{ github.event.pull_request.number }}.non-live.digital-lung-cancer-screening.nhs.uk
Lines changed: 66 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
1-
name: "CI/CD pull request"
2-
3-
# The total recommended execution time for the "CI/CD Pull Request" workflow is around 20 minutes.
1+
name: 'CI/CD pull request'
42

53
on:
6-
push:
7-
branches:
8-
- "**"
9-
- "!main"
104
pull_request:
11-
types: [opened, reopened]
5+
types: [opened, reopened, synchronize, labeled]
126

137
jobs:
148
metadata:
15-
name: "Set CI/CD metadata"
9+
name: 'Set CI/CD metadata'
1610
runs-on: ubuntu-latest
1711
timeout-minutes: 1
1812
outputs:
@@ -23,28 +17,23 @@ jobs:
2317
nodejs_version: ${{ steps.variables.outputs.nodejs_version }}
2418
python_version: ${{ steps.variables.outputs.python_version }}
2519
terraform_version: ${{ steps.variables.outputs.terraform_version }}
26-
version: ${{ steps.variables.outputs.version }}
2720
does_pull_request_exist: ${{ steps.pr_exists.outputs.does_pull_request_exist }}
28-
branch_name: ${{ steps.variables.outputs.branch_name }}
21+
version: ${{ steps.variables.outputs.version }}
2922
steps:
30-
- name: "Checkout code"
23+
- name: 'Checkout code'
3124
uses: actions/checkout@v6
32-
- name: "Set CI/CD variables"
25+
- name: 'Set CI/CD variables'
3326
id: variables
34-
env:
35-
BRANCH_NAME: ${{ github.head_ref }}
3627
run: |
3728
datetime=$(date -u +'%Y-%m-%dT%H:%M:%S%z')
38-
BUILD_DATETIME=$datetime make version-create-effective-file
3929
echo "build_datetime_london=$(TZ=Europe/London date --date=$datetime +'%Y-%m-%dT%H:%M:%S%z')" >> $GITHUB_OUTPUT
4030
echo "build_datetime=$datetime" >> $GITHUB_OUTPUT
4131
echo "build_timestamp=$(date --date=$datetime -u +'%Y%m%d%H%M%S')" >> $GITHUB_OUTPUT
4232
echo "build_epoch=$(date --date=$datetime -u +'%s')" >> $GITHUB_OUTPUT
43-
echo "nodejs_version=$(grep "^nodejs\s" .tool-versions | cut -f2 -d' ')" >> $GITHUB_OUTPUT
44-
echo "python_version=$(grep "^python\s" .tool-versions | cut -f2 -d' ')" >> $GITHUB_OUTPUT
45-
echo "terraform_version=$(grep "^terraform\s" .tool-versions | cut -f2 -d' ')" >> $GITHUB_OUTPUT
46-
echo "version=$(head -n 1 .version 2> /dev/null || echo unknown)" >> $GITHUB_OUTPUT
47-
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
33+
echo "nodejs_version=$(grep "^nodejs" .tool-versions | cut -f2 -d' ')" >> $GITHUB_OUTPUT
34+
echo "python_version=$(grep "^python" .tool-versions | cut -f2 -d' ')" >> $GITHUB_OUTPUT
35+
echo "terraform_version=$(grep "^terraform" .tool-versions | cut -f2 -d' ')" >> $GITHUB_OUTPUT
36+
echo "version=${GITHUB_REF}" >> $GITHUB_OUTPUT
4837
- name: "Check if pull request exists for this branch"
4938
id: pr_exists
5039
env:
@@ -72,45 +61,45 @@ jobs:
7261
export DOES_PULL_REQUEST_EXIST="${{ steps.pr_exists.outputs.does_pull_request_exist }}"
7362
export BRANCH_NAME="${{ steps.variables.outputs.branch_name }}"
7463
make list-variables
75-
commit-stage: # Recommended maximum execution time is 2 minutes
76-
name: "Commit stage"
64+
commit-stage:
65+
name: 'Commit stage'
7766
needs: [metadata]
7867
uses: ./.github/workflows/stage-1-commit.yaml
7968
with:
80-
build_datetime: "${{ needs.metadata.outputs.build_datetime }}"
81-
build_timestamp: "${{ needs.metadata.outputs.build_timestamp }}"
82-
build_epoch: "${{ needs.metadata.outputs.build_epoch }}"
83-
nodejs_version: "${{ needs.metadata.outputs.nodejs_version }}"
84-
python_version: "${{ needs.metadata.outputs.python_version }}"
85-
terraform_version: "${{ needs.metadata.outputs.terraform_version }}"
86-
version: "${{ needs.metadata.outputs.version }}"
69+
build_datetime: '${{ needs.metadata.outputs.build_datetime }}'
70+
build_timestamp: '${{ needs.metadata.outputs.build_timestamp }}'
71+
build_epoch: '${{ needs.metadata.outputs.build_epoch }}'
72+
nodejs_version: '${{ needs.metadata.outputs.nodejs_version }}'
73+
python_version: '${{ needs.metadata.outputs.python_version }}'
74+
terraform_version: '${{ needs.metadata.outputs.terraform_version }}'
75+
version: '${{ needs.metadata.outputs.version }}'
8776
secrets: inherit
88-
test-stage: # Recommended maximum execution time is 5 minutes
89-
name: "Test stage"
90-
needs: [metadata, commit-stage]
77+
test-stage:
78+
name: 'Test stage'
79+
needs: [metadata]
9180
uses: ./.github/workflows/stage-2-test.yaml
9281
with:
93-
build_datetime: "${{ needs.metadata.outputs.build_datetime }}"
94-
build_timestamp: "${{ needs.metadata.outputs.build_timestamp }}"
95-
build_epoch: "${{ needs.metadata.outputs.build_epoch }}"
96-
nodejs_version: "${{ needs.metadata.outputs.nodejs_version }}"
97-
python_version: "${{ needs.metadata.outputs.python_version }}"
98-
terraform_version: "${{ needs.metadata.outputs.terraform_version }}"
99-
version: "${{ needs.metadata.outputs.version }}"
82+
build_datetime: '${{ needs.metadata.outputs.build_datetime }}'
83+
build_timestamp: '${{ needs.metadata.outputs.build_timestamp }}'
84+
build_epoch: '${{ needs.metadata.outputs.build_epoch }}'
85+
nodejs_version: '${{ needs.metadata.outputs.nodejs_version }}'
86+
python_version: '${{ needs.metadata.outputs.python_version }}'
87+
terraform_version: '${{ needs.metadata.outputs.terraform_version }}'
88+
version: '${{ needs.metadata.outputs.version }}'
10089
secrets: inherit
101-
build-stage: # Recommended maximum execution time is 3 minutes
102-
name: "Build stage"
103-
needs: [metadata, test-stage]
90+
build-stage:
91+
name: 'Build stage'
92+
needs: [metadata]
10493
uses: ./.github/workflows/stage-3-build.yaml
105-
if: needs.metadata.outputs.does_pull_request_exist == 'true' || (github.event_name == 'pull_request' && (github.event.action == 'opened' || github.event.action == 'reopened'))
10694
with:
107-
build_datetime: "${{ needs.metadata.outputs.build_datetime }}"
108-
build_timestamp: "${{ needs.metadata.outputs.build_timestamp }}"
109-
build_epoch: "${{ needs.metadata.outputs.build_epoch }}"
110-
nodejs_version: "${{ needs.metadata.outputs.nodejs_version }}"
111-
python_version: "${{ needs.metadata.outputs.python_version }}"
112-
terraform_version: "${{ needs.metadata.outputs.terraform_version }}"
113-
version: "${{ needs.metadata.outputs.version }}"
95+
build_datetime: '${{ needs.metadata.outputs.build_datetime }}'
96+
build_timestamp: '${{ needs.metadata.outputs.build_timestamp }}'
97+
build_epoch: '${{ needs.metadata.outputs.build_epoch }}'
98+
nodejs_version: '${{ needs.metadata.outputs.nodejs_version }}'
99+
python_version: '${{ needs.metadata.outputs.python_version }}'
100+
terraform_version: '${{ needs.metadata.outputs.terraform_version }}'
101+
version: '${{ needs.metadata.outputs.version }}'
102+
commit_sha: '${{ github.event.pull_request.head.sha }}'
114103
secrets: inherit
115104
acceptance-stage: # Recommended maximum execution time is 10 minutes
116105
name: "Acceptance stage"
@@ -125,4 +114,30 @@ jobs:
125114
python_version: "${{ needs.metadata.outputs.python_version }}"
126115
terraform_version: "${{ needs.metadata.outputs.terraform_version }}"
127116
version: "${{ needs.metadata.outputs.version }}"
117+
deploy-stage:
118+
if: contains(github.event.pull_request.labels.*.name, 'deploy')
119+
name: Deploy review app pr-${{ github.event.pull_request.number }}
120+
needs: [build-stage]
121+
permissions:
122+
id-token: write
123+
uses: ./.github/workflows/stage-5-deploy.yaml
124+
with:
125+
environments: '["review"]'
126+
commit_sha: ${{ github.event.pull_request.head.sha }}
127+
pr_number: ${{ github.event.pull_request.number }}
128128
secrets: inherit
129+
post-url:
130+
if: contains(github.event.pull_request.labels.*.name, 'deploy')
131+
name: Post URL pr-${{ github.event.pull_request.number }} to PR comments
132+
runs-on: ubuntu-latest
133+
needs: [deploy-stage]
134+
permissions:
135+
pull-requests: write
136+
steps:
137+
- name: Post URL to PR comments
138+
uses: marocchino/sticky-pull-request-comment@5060d4700a91de252c87eeddd2da026382d9298a
139+
with:
140+
message: |
141+
The review app is available at this URL:
142+
https://pr-${{ github.event.pull_request.number }}.non-live.digital-lung-cancer-screening.nhs.uk/
143+
You must authenticate with HTTP basic authentication. Ask the team for credentials.

.github/workflows/cicd-2-main-branch.yaml

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -89,19 +89,8 @@ jobs:
8989
python_version: "${{ needs.metadata.outputs.python_version }}"
9090
terraform_version: "${{ needs.metadata.outputs.terraform_version }}"
9191
version: "${{ needs.metadata.outputs.version }}"
92+
commit_sha: '${{ github.sha }}'
9293
secrets: inherit
93-
94-
deploy-stage:
95-
name: Deploy stage
96-
needs: [build-stage]
97-
permissions:
98-
id-token: write
99-
uses: ./.github/workflows/stage-4-deploy.yaml
100-
with:
101-
environments: '["dev"]'
102-
commit_sha: ${{ github.sha }}
103-
secrets: inherit
104-
10594
acceptance-stage: # Recommended maximum execution time is 10 minutes
10695
name: "Acceptance stage"
10796
needs: [metadata, build-stage]
@@ -115,3 +104,13 @@ jobs:
115104
terraform_version: "${{ needs.metadata.outputs.terraform_version }}"
116105
version: "${{ needs.metadata.outputs.version }}"
117106
secrets: inherit
107+
deploy-stage:
108+
name: Deploy stage
109+
needs: [build-stage]
110+
permissions:
111+
id-token: write
112+
uses: ./.github/workflows/stage-5-deploy.yaml
113+
with:
114+
environments: '["review","dev","preprod","prod"]'
115+
commit_sha: ${{ github.sha }}
116+
secrets: inherit

.github/workflows/stage-3-build.yaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ on:
3131
description: "Version of the software, set by the CI/CD pipeline workflow"
3232
required: true
3333
type: string
34+
commit_sha:
35+
description: 'Commit sha of the docker image'
36+
required: true
37+
type: string
3438

3539
env:
3640
REGISTRY: ghcr.io
@@ -69,7 +73,10 @@ jobs:
6973
type=raw,value=${{ github.event_name == 'pull_request' && github.event.pull_request.head.ref || '{{branch}}' }}
7074
type=raw,value=${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.pull_request.number) || '' }}
7175
type=sha,format=long,prefix=git-sha-
72-
76+
- name: Print commit SHA
77+
env:
78+
COMMIT_SHA: ${{ inputs.commit_sha }}
79+
run: echo "Commit SHA is ${COMMIT_SHA}"
7380
- name: Build and push Docker image
7481
id: push
7582
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8
@@ -78,6 +85,8 @@ jobs:
7885
push: true
7986
tags: ${{ steps.meta.outputs.tags }}
8087
labels: ${{ steps.meta.outputs.labels }}
88+
build-args: |
89+
COMMIT_SHA=${{ inputs.commit_sha }}
8190
8291
- name: Generate artifact attestation
8392
uses: actions/attest-build-provenance@v3
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
name: Deployment stage
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
environments:
7+
description: List of environments to deploy to (String array)
8+
required: true
9+
type: string
10+
commit_sha:
11+
description: Commit SHA used to fetch ADO pipeline and docker image
12+
required: true
13+
type: string
14+
pr_number:
15+
description: Pull request number when used in a pull request
16+
required: false
17+
type: string
18+
19+
jobs:
20+
deploy:
21+
name: Deploy
22+
runs-on: ubuntu-latest
23+
strategy:
24+
matrix:
25+
environment: ${{ fromJson(inputs.environments) }}
26+
max-parallel: 1
27+
environment: ${{ matrix.environment }}
28+
# Prevent concurrent jobs on the same environment and between deploy and delete workflows
29+
concurrency: deploy-${{ matrix.environment }}-${{inputs.pr_number}}
30+
31+
steps:
32+
- name: Checkout code
33+
uses: actions/checkout@v6
34+
35+
- uses: azure/login@v2
36+
with:
37+
client-id: ${{ secrets.AZURE_CLIENT_ID }}
38+
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
39+
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
40+
41+
- name: Call deployment pipeline
42+
env:
43+
COMMIT_SHA: ${{ inputs.commit_sha }}
44+
ENVIRONMENT: ${{ matrix.environment }}
45+
PR_NUMBER: ${{ inputs.pr_number }}
46+
run: |
47+
if [[ -n "$PR_NUMBER" ]]; then
48+
pr_argument="prNumber=$PR_NUMBER"
49+
else
50+
pr_argument=""
51+
fi
52+
53+
source infrastructure/environments/$ENVIRONMENT/variables.sh
54+
55+
echo "Starting Azure devops pipeline \"Deploy to Azure - $ENVIRONMENT\"..."
56+
RUN_ID=$(az pipelines run \
57+
--commit-id "$COMMIT_SHA" \
58+
--name "Deploy to Azure - $ENVIRONMENT" \
59+
--org https://dev.azure.com/nhse-dtos \
60+
--project lung-cancer-screening \
61+
--parameters commitSHA="$COMMIT_SHA" "$pr_argument" environment="$ENVIRONMENT" pool=${ADO_MANAGEMENT_POOL} \
62+
--output tsv --query id)
63+
64+
echo "See pipeline run in Azure devops: https://dev.azure.com/nhse-dtos/lung-cancer-screening/_build/results?buildId=${RUN_ID}&view=results"
65+
66+
scripts/bash/wait_ado_pipeline.sh "$RUN_ID" https://dev.azure.com/nhse-dtos lung-cancer-screening
67+
68+
- name: Basic application smoke test
69+
env:
70+
COMMIT_SHA: ${{ inputs.commit_sha }}
71+
ENVIRONMENT: ${{ matrix.environment }}
72+
PR_NUMBER: ${{ inputs.pr_number }}
73+
run: |
74+
dns_zone_name=$( grep dns_zone_name infrastructure/environments/$ENVIRONMENT/variables.tfvars | awk -F'"' '{print $2}' )
75+
use_apex_domain=$( grep use_apex_domain infrastructure/environments/$ENVIRONMENT/variables.tfvars | awk '{print $3}' || echo "false" )
76+
scripts/bash/container_app_smoke_test.sh "$ENVIRONMENT" "$COMMIT_SHA" "${dns_zone_name}" "$PR_NUMBER" "${use_apex_domain}"

.github/workflows/test-deploy.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ on:
99
type: choice
1010
options:
1111
- poc
12+
- review
13+
- dev
1214

1315
env:
1416
TARGET_ENV: ${{ inputs.target_env }}
@@ -40,4 +42,3 @@ jobs:
4042

4143
- name: Terraform plan
4244
run: make ${TARGET_ENV} ci poc-terraform-apply DOCKER_IMAGE_TAG=git-sha-${{ github.sha }}
43-

0 commit comments

Comments
 (0)