Skip to content

Commit 4d60793

Browse files
authored
Fix: [AEA-0000] - initial pipelines for building images (#5)
1 parent c3a5846 commit 4d60793

61 files changed

Lines changed: 2387 additions & 198 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitallowed

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
id-token: write
2+
password: \${{secrets\.GITHUB_TOKEN}}
3+
\.gitallowed

.github/config/settings.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
TAG_FORMAT: "v${version}"

.github/dependabot.yml

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#########################################################################
2+
# Dependabot configuration file
3+
#########################################################################
4+
5+
version: 2
6+
7+
updates:
8+
- package-ecosystem: "github-actions"
9+
# Workflow files stored in the
10+
# default location of `.github/workflows`
11+
directory: "/"
12+
schedule:
13+
interval: "weekly"
14+
day: "friday"
15+
time: "18:00" # UTC
16+
open-pull-requests-limit: 20
17+
commit-message:
18+
prefix: "Upgrade: [dependabot] - "
19+
20+
###################################
21+
# NPM workspace ##################
22+
###################################
23+
- package-ecosystem: "npm"
24+
directory: "/"
25+
schedule:
26+
interval: "weekly"
27+
day: "friday"
28+
time: "18:00"
29+
open-pull-requests-limit: 20
30+
versioning-strategy: increase
31+
commit-message:
32+
prefix: "Upgrade: [dependabot] - "
33+
34+
###################################
35+
# Poetry #########################
36+
###################################
37+
- package-ecosystem: "pip"
38+
directory: "/"
39+
schedule:
40+
interval: "weekly"
41+
day: "friday"
42+
time: "18:00"
43+
open-pull-requests-limit: 20
44+
versioning-strategy: increase
45+
commit-message:
46+
prefix: "Upgrade: [dependabot] - "

.github/pull_request_template.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
## Summary
2+
3+
**Remove items from this list if they are not relevant. Remove this line once this has been done**
4+
5+
- Routine Change
6+
- :exclamation: Breaking Change
7+
- :robot: Operational or Infrastructure Change
8+
- :sparkles: New Feature
9+
- :warning: Potential issues that might be caused by this change
10+
11+
### Details
12+
13+
Add any summary information of what is in the change. **Remove this line if you have nothing to add.**
14+
15+
## Pull Request Naming
16+
17+
Pull requests should be named using the following format:
18+
19+
```text
20+
Tag: [AEA-NNNN] - Short description
21+
```
22+
23+
Tag can be one of:
24+
25+
- `Fix` - for a bug fix. (Patch release)
26+
- `Update` - either for a backwards-compatible enhancement or for a rule change that adds reported problems. (Patch release)
27+
- `New` - implemented a new feature. (Minor release)
28+
- `Breaking` - for a backwards-incompatible enhancement or feature. (Major release)
29+
- `Docs` - changes to documentation only. (Patch release)
30+
- `Build` - changes to build process only. (No release)
31+
- `Upgrade` - for a dependency upgrade. (Patch release)
32+
- `Chore` - for refactoring, adding tests, etc. (anything that isn't user-facing). (Patch release)
33+
34+
If the current release is x.y.z then
35+
- a patch release increases z by 1
36+
- a minor release increases y by 1
37+
- a major release increases x by 1
38+
39+
Correct tagging is necessary for our automated versioning and release process.
40+
41+
The description of your pull request will be used as the commit message for the merge, and also be included in the changelog. Please ensure that your title is sufficiently descriptive.
42+
43+
### Rerunning Checks
44+
45+
If you need to rename your pull request, you can restart the checks by either:
46+
47+
- Closing and reopening the pull request
48+
- pushing an empty commit
49+
```bash
50+
git commit --allow-empty -m 'trigger build'
51+
git push
52+
```
53+
- Amend your last commit and force push to the branch
54+
```bash
55+
git commit --amend --no-edit
56+
git push --force
57+
```
58+
59+
Rerunning the checks from within the pull request will not use the updated title.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
name: build_all_images
2+
'on':
3+
workflow_call:
4+
inputs:
5+
docker_tag:
6+
required: true
7+
type: string
8+
tag_latest:
9+
required: true
10+
type: boolean
11+
env:
12+
BRANCH_NAME: '${{ github.event.pull_request.head.ref }}'
13+
jobs:
14+
discover_folders:
15+
runs-on: ubuntu-latest
16+
outputs:
17+
language_folders: ${{ steps.find-folders.outputs.languages }}
18+
project_folders: ${{ steps.find-folders.outputs.projects }}
19+
steps:
20+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
21+
22+
- id: find-folders
23+
run: |
24+
language_folders=$(find src/languages -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | jq -R -s -c 'split("\n")[:-1]')
25+
project_folders=$(find src/projects -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | jq -R -s -c 'split("\n")[:-1]')
26+
echo "languages=$language_folders" >> "$GITHUB_OUTPUT"
27+
echo "projects=$project_folders" >> "$GITHUB_OUTPUT"
28+
package_base_docker_image:
29+
uses: ./.github/workflows/build_multi_arch_image.yml
30+
with:
31+
tag_latest: ${{ inputs.tag_latest }}
32+
docker_tag: ${{ inputs.docker_tag }}
33+
container_name: base
34+
base_folder: "."
35+
package_language_docker_images:
36+
needs:
37+
- package_base_docker_image
38+
- discover_folders
39+
strategy:
40+
fail-fast: false
41+
matrix:
42+
container_name: ${{ fromJson(needs.discover_folders.outputs.language_folders) }}
43+
uses: ./.github/workflows/build_multi_arch_image.yml
44+
with:
45+
tag_latest: ${{ inputs.tag_latest }}
46+
docker_tag: ${{ inputs.docker_tag }}
47+
container_name: ${{ matrix.container_name }}
48+
base_folder: "languages"
49+
package_project_docker_images:
50+
needs:
51+
- package_language_docker_images
52+
53+
- discover_folders
54+
strategy:
55+
fail-fast: false
56+
matrix:
57+
container_name: ${{ fromJson(needs.discover_folders.outputs.project_folders) }}
58+
uses: ./.github/workflows/build_multi_arch_image.yml
59+
with:
60+
tag_latest: ${{ inputs.tag_latest }}
61+
docker_tag: ${{ inputs.docker_tag }}
62+
container_name: ${{ matrix.container_name }}
63+
base_folder: "projects"
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
name: Build and push docker image
2+
'on':
3+
workflow_call:
4+
inputs:
5+
tag_latest:
6+
required: true
7+
type: boolean
8+
docker_tag:
9+
required: true
10+
type: string
11+
container_name:
12+
required: true
13+
type: string
14+
base_folder:
15+
required: true
16+
type: string
17+
18+
jobs:
19+
build_and_push_image:
20+
name: Build image for ${{ inputs.container_name }} on ${{ matrix.arch }}
21+
permissions:
22+
contents: read
23+
packages: write
24+
attestations: write
25+
id-token: write
26+
runs-on: '${{ matrix.runner }}'
27+
strategy:
28+
fail-fast: false
29+
matrix:
30+
include:
31+
- arch: amd64
32+
runner: ubuntu-22.04
33+
- arch: arm64
34+
runner: ubuntu-22.04-arm
35+
steps:
36+
- name: Free Disk Space for Docker
37+
uses: endersonmenezes/free-disk-space@e6ed9b02e683a3b55ed0252f1ee469ce3b39a885
38+
with:
39+
remove_android: true
40+
remove_dotnet: true
41+
remove_haskell: true
42+
remove_tool_cache: true
43+
rm_cmd: rm
44+
remove_packages: >-
45+
azure-cli google-cloud-cli microsoft-edge-stable
46+
google-chrome-stable firefox postgresql* temurin-* *llvm* mysql*
47+
dotnet-sdk-*
48+
remove_packages_one_command: true
49+
- name: Login to github container registry
50+
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9
51+
with:
52+
registry: ghcr.io
53+
username: ${{github.actor}}
54+
password: ${{secrets.GITHUB_TOKEN}}
55+
- name: Checkout code
56+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8
57+
with:
58+
fetch-depth: 0
59+
- name: setup node
60+
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f
61+
with:
62+
node-version-file: .tool-versions
63+
64+
- name: make install
65+
run: |
66+
make install-node
67+
68+
- name: Build container
69+
run: |
70+
echo "Building image..."
71+
make build-image
72+
73+
echo "Creating combined trivy ignore file"
74+
# create combined trivy ignore file for use in trivy scan, combining common and specific ignore files if they exist
75+
combined="src/${BASE_FOLDER}/${CONTAINER_NAME}/.trivyignore_combined.yaml"
76+
common="src/common/.trivyignore.yaml"
77+
specific="src/${BASE_FOLDER}/${CONTAINER_NAME}/.trivyignore.yaml"
78+
echo "vulnerabilities:" > "$combined"
79+
if [ -f "$common" ]; then sed -n '2,$p' "$common" >> "$combined"; fi
80+
if [ -f "$specific" ]; then sed -n '2,$p' "$specific" >> "$combined"; fi
81+
echo "Combined trivy ignore file created at $combined"
82+
83+
env:
84+
ARCHITECTURE: '${{ matrix.arch }}'
85+
DOCKER_TAG: '${{ inputs.docker_tag }}'
86+
CONTAINER_NAME: '${{ inputs.container_name }}'
87+
BASE_VERSION: ${{ inputs.docker_tag}}
88+
IMAGE_TAG: ":${{ inputs.docker_tag }}-${{ matrix.arch }}"
89+
BASE_FOLDER: "${{ inputs.base_folder }}"
90+
- name: Check docker vulnerabilities - json output
91+
uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8
92+
with:
93+
scan-type: "image"
94+
image-ref: "ghcr.io/nhsdigital/eps-devcontainers/${{ inputs.container_name }}:${{ inputs.docker_tag }}-${{ matrix.arch }}"
95+
severity: "CRITICAL,HIGH"
96+
scanners: "vuln"
97+
vuln-type: "os,library"
98+
format: "json"
99+
output: "scan_results_docker.json"
100+
exit-code: "0"
101+
trivy-config: src/${{ inputs.base_folder }}/${{ inputs.container_name }}/trivy.yaml
102+
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f
103+
name: Upload scan results
104+
with:
105+
name: "scan_results_docker_${{ inputs.container_name }}_${{ matrix.arch }}.json"
106+
path: scan_results_docker.json
107+
- name: Check docker vulnerabilities - table output
108+
uses: aquasecurity/trivy-action@b6643a29fecd7f34b3597bc6acb0a98b03d33ff8
109+
with:
110+
scan-type: "image"
111+
image-ref: "ghcr.io/nhsdigital/eps-devcontainers/${{ inputs.container_name }}:${{ inputs.docker_tag }}-${{ matrix.arch }}"
112+
severity: "CRITICAL,HIGH"
113+
scanners: "vuln"
114+
vuln-type: "os,library"
115+
format: "table"
116+
output: "scan_results_docker.txt"
117+
exit-code: "1"
118+
trivy-config: src/${{ inputs.base_folder }}/${{ inputs.container_name }}/trivy.yaml
119+
120+
- name: Show docker vulnerability output
121+
if: always()
122+
run: |
123+
echo "Scan output for ghcr.io/nhsdigital/eps-devcontainers/base:${DOCKER_TAG}-${ARCHITECTURE}"
124+
if [ -f scan_results_docker.txt ]; then
125+
cat scan_results_docker.txt
126+
fi
127+
env:
128+
ARCHITECTURE: '${{ matrix.arch }}'
129+
DOCKER_TAG: '${{ inputs.docker_tag }}'
130+
- name: Push tagged image
131+
run: |
132+
echo "Pushing image..."
133+
docker push "ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:${DOCKER_TAG}-${ARCHITECTURE}"
134+
env:
135+
DOCKER_TAG: ${{ inputs.docker_tag }}
136+
CONTAINER_NAME: '${{ inputs.container_name }}'
137+
ARCHITECTURE: '${{ matrix.arch }}'
138+
- name: Push latest image
139+
if: ${{ inputs.tag_latest }}
140+
run: |
141+
docker tag "ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:${DOCKER_TAG}-${ARCHITECTURE}" "ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:latest-${ARCHITECTURE}"
142+
echo "Pushing image..."
143+
docker push "ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:latest-${ARCHITECTURE}"
144+
env:
145+
DOCKER_TAG: ${{ inputs.docker_tag }}
146+
CONTAINER_NAME: '${{ inputs.container_name }}'
147+
ARCHITECTURE: '${{ matrix.arch }}'
148+
publish_combined_image:
149+
name: Publish combined image for ${{ inputs.container_name }}
150+
runs-on: ubuntu-22.04
151+
needs: build_and_push_image
152+
permissions:
153+
contents: read
154+
packages: write
155+
attestations: write
156+
id-token: write
157+
steps:
158+
- name: Login to github container registry
159+
uses: docker/login-action@c94ce9fb468520275223c153574b00df6fe4bcc9
160+
with:
161+
registry: ghcr.io
162+
username: ${{github.actor}}
163+
password: ${{secrets.GITHUB_TOKEN}}
164+
165+
- name: Push multi-arch tagged image
166+
run: |
167+
docker buildx imagetools create -t "ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:${DOCKER_TAG}" \
168+
"ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:${DOCKER_TAG}-amd64" \
169+
"ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:${DOCKER_TAG}-arm64"
170+
echo "## PUSHED IMAGE : ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:${DOCKER_TAG}" >> "$GITHUB_STEP_SUMMARY"
171+
env:
172+
DOCKER_TAG: ${{ inputs.docker_tag }}
173+
CONTAINER_NAME: '${{ inputs.container_name }}'
174+
175+
- name: Push multi-arch latest image
176+
if: ${{ inputs.tag_latest }}
177+
run: |
178+
docker buildx imagetools create -t "ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:latest" \
179+
"ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:latest-amd64" \
180+
"ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:latest-arm64"
181+
echo "## PUSHED COMBINED IMAGE : ghcr.io/nhsdigital/eps-devcontainers/${CONTAINER_NAME}:latest" >> "$GITHUB_STEP_SUMMARY"
182+
env:
183+
DOCKER_TAG: ${{ inputs.docker_tag }}
184+
CONTAINER_NAME: '${{ inputs.container_name }}'

0 commit comments

Comments
 (0)