generated from nhs-england-tools/repository-template
-
Notifications
You must be signed in to change notification settings - Fork 0
240 lines (203 loc) · 8.95 KB
/
stage-3-build-images.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
name: Docker Image CI
on:
push:
branches:
- main
workflow_call:
inputs:
environment_tag:
description: Environment of the deployment
required: true
type: string
default: development
docker_compose_file:
description: The path of the compose.yaml file needed to build docker images
required: true
type: string
function_app_source_code_path:
description: The source path of the function app source code for the docker builds
required: true
type: string
project_name:
description: The name of the project
required: true
type: string
excluded_containers_csv_list:
description: Excluded containers in a comma separated list
required: true
type: string
jobs:
get-functions:
runs-on: ubuntu-latest
permissions:
id-token: write
outputs:
FUNC_NAMES: ${{ steps.get-function-names.outputs.FUNC_NAMES }}
steps:
- uses: actions/checkout@v4
- uses: tj-actions/changed-files@v45
id: changed-files
with:
path: ${{ inputs.function_app_source_code_path }}
dir_names: true
- name: Checkout dtos-devops-templates repository
uses: actions/checkout@v4
with:
repository: NHSDigital/dtos-devops-templates
path: templates
ref: main
- name: Get docker compose function name(s)
id: get-function-names
env:
CHANGED_FOLDERS: ${{ steps.changed-files.outputs.all_changed_files }}
run: |
DOCKER_COMPOSE_DIR="$(dirname "${{ inputs.docker_compose_file }}")"
bash ./templates/scripts/deployments/get-docker-names.sh ${{ inputs.docker_compose_file }} ${{ inputs.excluded_containers_csv_list }}
echo "DOCKER_COMPOSE_DIR=$DOCKER_COMPOSE_DIR" >> ${GITHUB_OUTPUT}
- name: Print function names
run: |
echo "The branch is: " ${{ github.ref }}
echo "FUNC_NAMES before setting output: ${{ steps.get-function-names.outputs.FUNC_NAMES }}"
echo "FUNC_NAMES=${FUNC_NAMES}" >> ${GITHUB_OUTPUT}
build-and-push:
runs-on: ubuntu-latest
permissions:
id-token: write
contents: read
needs: get-functions
strategy:
matrix:
function: ${{ fromJSON(needs.get-functions.outputs.FUNC_NAMES) }}
if: needs.get-functions.outputs.FUNC_NAMES != '["null"]' && needs.get-functions.outputs.FUNC_NAMES != '[]' && needs.get-functions.outputs.FUNC_NAMES != '[""]'
outputs:
pr_num_tag: ${{ env.PR_NUM_TAG }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 1
submodules: 'true'
- name: Checkout dtos-devops-templates repository
uses: actions/checkout@v4
with:
repository: NHSDigital/dtos-devops-templates
path: templates
ref: main
- name: Az CLI login
if: github.ref == 'refs/heads/main'
uses: azure/login@v2
with:
client-id: ${{ secrets.AZURE_CLIENT_ID }}
tenant-id: ${{ secrets.AZURE_TENANT_ID }}
subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
- name: Azure Container Registry login
if: github.ref == 'refs/heads/main'
run: az acr login --name ${{ secrets.ACR_NAME }}
- name: Create Tags
env:
GH_TOKEN: ${{ github.token }}
continue-on-error: false
run: |
echo "GITHUB_REF: ${GITHUB_REF}"
echo "The branch is: ${{ github.ref }}"
if [[ "${GITHUB_REF}" == refs/pull/*/merge ]]; then
PR_NUM_TAG=$(echo "${GITHUB_REF}" | sed 's/refs\/pull\/\([0-9]*\)\/merge/\1/')
else
PULLS_JSON=$(gh api /repos/{owner}/{repo}/commits/${GITHUB_SHA}/pulls)
ORIGINATING_BRANCH=$(echo ${PULLS_JSON} | jq -r '.[].head.ref' | python3 -c "import sys, urllib.parse; print(urllib.parse.quote_plus(sys.stdin.read().strip()))")
echo "ORIGINATING_BRANCH: ${ORIGINATING_BRANCH}"
PR_NUM_TAG=$(echo ${PULLS_JSON} | jq -r '.[].number')
fi
echo "PR_NUM_TAG: pr${PR_NUM_TAG}"
echo "PR_NUM_TAG=pr${PR_NUM_TAG}" >> ${GITHUB_ENV}
SHORT_COMMIT_HASH=$(git rev-parse --short ${GITHUB_SHA})
echo "Commit hash tag: ${SHORT_COMMIT_HASH}"
echo "COMMIT_HASH_TAG=${SHORT_COMMIT_HASH}" >> ${GITHUB_ENV}
echo "ENVIRONMENT_TAG=${{ inputs.environment_tag }}" >> ${GITHUB_ENV}
- name: Build and Push Image
working-directory: ${{ steps.get-function-names.outputs.DOCKER_COMPOSE_DIR }}
continue-on-error: false
run: |
function=${{ matrix.function }}
project_name=${{ inputs.project_name }}
echo project_name: $project_name
if [ -z "${function}" ]; then
echo "Function variable is empty. Skipping Docker build."
exit 0
fi
# Build the image
docker compose -f ${{ inputs.docker_compose_file }} build ${function}
repo_name="${{ secrets.ACR_NAME }}.azurecr.io/${project_name}-$function"
# Tag the image
docker tag ${project_name}-${function}:latest "$repo_name:${COMMIT_HASH_TAG}"
docker tag ${project_name}-${function}:latest "$repo_name:${PR_NUM_TAG}"
docker tag ${project_name}-${function}:latest "$repo_name:${ENVIRONMENT_TAG}"
# If this variable is set, the create-sbom-report.sh script will scan this docker image instead.
export CHECK_DOCKER_IMAGE=${project_name}-${function}:latest
export FORCE_USE_DOCKER=true
export PR_NUM_TAG=${PR_NUM_TAG}
echo "PR_NUM_TAG=${PR_NUM_TAG}" >> ${GITHUB_ENV}
# Push the image to the repository
if [ "${GITHUB_REF}" == 'refs/heads/main' ]; then
docker push "${repo_name}:${COMMIT_HASH_TAG}"
if [ "${PR_NUM_TAG}" != 'pr' ]; then
docker push "${repo_name}:${PR_NUM_TAG}"
fi
docker push "${repo_name}:${ENVIRONMENT_TAG}"
fi
export SBOM_REPOSITORY_REPORT="sbom-${function}-repository-report"
echo "SBOM_REPOSITORY_REPORT=$SBOM_REPOSITORY_REPORT" >> $GITHUB_ENV
${GITHUB_WORKSPACE}/templates/scripts/reports/create-sbom-report.sh
export VULNERABILITIES_REPOSITORY_REPORT="vulnerabilities-${function}-repository-report"
echo "VULNERABILITIES_REPOSITORY_REPORT=$VULNERABILITIES_REPOSITORY_REPORT" >> $GITHUB_ENV
${GITHUB_WORKSPACE}/templates/scripts/reports/scan-vulnerabilities.sh
# Remove the image
docker rmi "${repo_name}:${COMMIT_HASH_TAG}"
docker rmi "${repo_name}:${PR_NUM_TAG}"
docker rmi "${repo_name}:${ENVIRONMENT_TAG}"
docker rmi ${project_name}-${function}:latest
- name: Compress SBOM report
shell: bash
run: |
echo SBOM_REPOSITORY_REPORT: ${SBOM_REPOSITORY_REPORT}
zip "${SBOM_REPOSITORY_REPORT}.json.zip" "${SBOM_REPOSITORY_REPORT}.json"
- name: Upload SBOM report as an artefact
uses: actions/upload-artifact@v4
with:
name: ${{ env.SBOM_REPOSITORY_REPORT }}.json.zip
path: ./${{ env.SBOM_REPOSITORY_REPORT }}.json.zip
retention-days: 21
- name: Compress vulnerabilities report
shell: bash
run: |
echo VULNERABILITIES_REPOSITORY_REPORT: ${VULNERABILITIES_REPOSITORY_REPORT}
zip ${VULNERABILITIES_REPOSITORY_REPORT}.json.zip ${VULNERABILITIES_REPOSITORY_REPORT}.json
- name: Upload vulnerabilities report as an artefact
uses: actions/upload-artifact@v4
with:
name: ${{ env.VULNERABILITIES_REPOSITORY_REPORT }}.json.zip
path: ./${{ env.VULNERABILITIES_REPOSITORY_REPORT }}.json.zip
retention-days: 21
aggregate-json:
runs-on: ubuntu-latest
needs: build-and-push
steps:
- name: Download SBOM JSON artifacts
uses: actions/download-artifact@v4
with:
path: ./downloaded-artifacts
- name: Combine sbom report JSON files
run: |
zip sbom-repository-report-${{ needs.build-and-push.outputs.PR_NUM_TAG }}.zip downloaded-artifacts/**/sbom*.json.zip
- name: Combine vulnerabilities report JSON files
run: |
zip vulnerabilities-repository-report-${{ needs.build-and-push.outputs.PR_NUM_TAG }}.zip downloaded-artifacts/**/vulnerabilities*.json.zip
- name: Upload sbom zip file
uses: actions/upload-artifact@v4
with:
name: aggregated-sbom-repository-report-${{ needs.build-and-push.outputs.PR_NUM_TAG }}.zip
path: sbom-repository-report-${{ needs.build-and-push.outputs.PR_NUM_TAG }}.zip
- name: Upload repository zip file
uses: actions/upload-artifact@v4
with:
name: aggregated-vulnerabilities-repository-report-${{ needs.build-and-push.outputs.PR_NUM_TAG }}.zip
path: vulnerabilities-repository-report-${{ needs.build-and-push.outputs.PR_NUM_TAG }}.zip