Skip to content

Commit 514a9e9

Browse files
jgourmelenclaude
andcommitted
feat: build 3 images from single repo (mapping-service, fhir-simulator-r4, fhir-simulator-r5)
Same Docker image pushed under 3 names, differentiated by runtime configuration. Uses matrix strategy for parallel GitOps PR creation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent d696e9a commit 514a9e9

3 files changed

Lines changed: 77 additions & 55 deletions

File tree

.github/workflows/dev-build.yml

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ env:
1111
GCP_REGION: europe-west8
1212
ARTIFACT_REGISTRY: europe-west8-docker.pkg.dev
1313
REGISTRY_NAME: hapi-fhir
14-
IMAGE_NAME: mapping-service
1514

1615
permissions:
1716
id-token: write
@@ -45,16 +44,21 @@ jobs:
4544
target: default
4645
push: true
4746
tags: |
48-
${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
49-
${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/${{ env.IMAGE_NAME }}:latest
47+
${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/mapping-service:${{ github.sha }}
48+
${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/mapping-service:latest
49+
${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/fhir-simulator-r4:${{ github.sha }}
50+
${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/fhir-simulator-r4:latest
51+
${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/fhir-simulator-r5:${{ github.sha }}
52+
${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/fhir-simulator-r5:latest
5053
cache-from: type=gha
5154
cache-to: type=gha,mode=max
5255

5356
- name: Summary
5457
run: |
55-
echo "## Docker Image Built & Pushed" >> $GITHUB_STEP_SUMMARY
58+
echo "## Docker Images Built & Pushed" >> $GITHUB_STEP_SUMMARY
5659
echo "" >> $GITHUB_STEP_SUMMARY
57-
echo "**Image:** \`${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/${{ env.IMAGE_NAME }}\`" >> $GITHUB_STEP_SUMMARY
60+
echo "**Registry:** \`${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}\`" >> $GITHUB_STEP_SUMMARY
61+
echo "**Images:** mapping-service, fhir-simulator-r4, fhir-simulator-r5" >> $GITHUB_STEP_SUMMARY
5862
echo "**Tags:** \`${{ github.sha }}\`, \`latest\`" >> $GITHUB_STEP_SUMMARY
5963
6064
cve-scan:
@@ -77,22 +81,29 @@ jobs:
7781
run: gcloud auth configure-docker ${{ env.ARTIFACT_REGISTRY }} --quiet
7882

7983
- name: Pull image
80-
run: docker pull ${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
84+
run: docker pull ${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/mapping-service:${{ github.sha }}
8185

8286
- name: Trivy CVE Scan
8387
uses: ./.github/actions/trivy-scan
8488
with:
85-
image: ${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
89+
image: ${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/mapping-service:${{ github.sha }}
8690
fail-on-critical: 'true'
8791
max-high-cves: '5'
8892
block: 'false'
8993

9094
create-sandbox-pr:
91-
name: Create Sandbox GitOps PR
95+
name: Create Sandbox GitOps PR (${{ matrix.service }})
9296
needs: build-push
9397
runs-on: ubuntu-latest
98+
strategy:
99+
fail-fast: false
100+
matrix:
101+
service:
102+
- mapping-service
103+
- fhir-simulator-r4
104+
- fhir-simulator-r5
94105
concurrency:
95-
group: gitops-sandbox-mapping-service
106+
group: gitops-sandbox-${{ matrix.service }}
96107
cancel-in-progress: false
97108
steps:
98109
- name: Checkout code
@@ -102,8 +113,8 @@ jobs:
102113
uses: ./.github/actions/argocd-pr
103114
with:
104115
env-name: sandbox
105-
component-name: mapping-service
106-
gitops-folder: sandbox/mapping-service
116+
component-name: ${{ matrix.service }}
117+
gitops-folder: sandbox/${{ matrix.service }}
107118
gitops-values-file: values.yaml
108119
image-tag-paths: '["deployment.imageRef.tag"]'
109120
github-app-id: ${{ vars.GITOPS_APP_ID }}

.github/workflows/production-deploy.yml

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ on:
99
type: string
1010

1111
env:
12-
IMAGE_NAME: mapping-service
1312
STAGING_PROJECT_ID: s3ns-staging-okeiro
1413
STAGING_REGISTRY: europe-west9-docker.pkg.dev
1514
STAGING_REGISTRY_NAME: preproduction-okeiro
@@ -72,25 +71,28 @@ jobs:
7271
run: |
7372
gcloud auth configure-docker ${{ env.STAGING_REGISTRY }} --quiet
7473
75-
- name: Retag image from staging to production
74+
- name: Retag all images from staging to production
7675
env:
7776
VERSION: ${{ github.event.inputs.version }}
7877
run: |
79-
STAGING_IMAGE="${{ env.STAGING_REGISTRY }}/${{ env.STAGING_PROJECT_ID }}/${{ env.STAGING_REGISTRY_NAME }}/${{ env.IMAGE_NAME }}:${VERSION}"
80-
PROD_IMAGE_BASE="${{ env.PROD_REGISTRY }}/${{ env.PROD_PROJECT_ID }}/${{ env.PROD_REGISTRY_NAME }}/${{ env.IMAGE_NAME }}"
78+
SERVICES="mapping-service fhir-simulator-r4 fhir-simulator-r5"
8179
82-
echo "Pulling staging image: $STAGING_IMAGE"
83-
docker pull "$STAGING_IMAGE"
80+
for SERVICE in $SERVICES; do
81+
STAGING_IMAGE="${{ env.STAGING_REGISTRY }}/${{ env.STAGING_PROJECT_ID }}/${{ env.STAGING_REGISTRY_NAME }}/${SERVICE}:${VERSION}"
82+
PROD_IMAGE_BASE="${{ env.PROD_REGISTRY }}/${{ env.PROD_PROJECT_ID }}/${{ env.PROD_REGISTRY_NAME }}/${SERVICE}"
8483
85-
echo "Tagging for production:"
86-
docker tag "$STAGING_IMAGE" "${PROD_IMAGE_BASE}:${VERSION}"
87-
docker tag "$STAGING_IMAGE" "${PROD_IMAGE_BASE}:latest"
84+
echo "--- Retagging ${SERVICE} ---"
85+
echo "Pulling: $STAGING_IMAGE"
86+
docker pull "$STAGING_IMAGE"
8887
89-
echo "Pushing to production registry:"
90-
docker push "${PROD_IMAGE_BASE}:${VERSION}"
91-
docker push "${PROD_IMAGE_BASE}:latest"
88+
docker tag "$STAGING_IMAGE" "${PROD_IMAGE_BASE}:${VERSION}"
89+
docker tag "$STAGING_IMAGE" "${PROD_IMAGE_BASE}:latest"
9290
93-
echo "Successfully retagged ${IMAGE_NAME}:${VERSION} to production"
91+
docker push "${PROD_IMAGE_BASE}:${VERSION}"
92+
docker push "${PROD_IMAGE_BASE}:latest"
93+
94+
echo "Done: ${SERVICE}:${VERSION}"
95+
done
9496
9597
cve-scan:
9698
name: CVE Scan Before Production Deploy
@@ -111,22 +113,29 @@ jobs:
111113

112114
- name: Pull image from registry
113115
run: |
114-
docker pull "${{ env.PROD_REGISTRY }}/${{ env.PROD_PROJECT_ID }}/${{ env.PROD_REGISTRY_NAME }}/${{ env.IMAGE_NAME }}:${{ github.event.inputs.version }}"
116+
docker pull "${{ env.PROD_REGISTRY }}/${{ env.PROD_PROJECT_ID }}/${{ env.PROD_REGISTRY_NAME }}/mapping-service:${{ github.event.inputs.version }}"
115117
116118
- name: Trivy CVE Scan
117119
uses: ./.github/actions/trivy-scan
118120
with:
119-
image: "${{ env.PROD_REGISTRY }}/${{ env.PROD_PROJECT_ID }}/${{ env.PROD_REGISTRY_NAME }}/${{ env.IMAGE_NAME }}:${{ github.event.inputs.version }}"
121+
image: "${{ env.PROD_REGISTRY }}/${{ env.PROD_PROJECT_ID }}/${{ env.PROD_REGISTRY_NAME }}/mapping-service:${{ github.event.inputs.version }}"
120122
fail-on-critical: 'true'
121123
max-high-cves: '5'
122124
block: 'true'
123125

124126
create-gitops-pr:
125-
name: Create Production GitOps PR
127+
name: Create Production GitOps PR (${{ matrix.service }})
126128
needs: retag-and-push
127129
runs-on: ubuntu-latest
130+
strategy:
131+
fail-fast: false
132+
matrix:
133+
service:
134+
- mapping-service
135+
- fhir-simulator-r4
136+
- fhir-simulator-r5
128137
concurrency:
129-
group: gitops-production-mapping-service
138+
group: gitops-production-${{ matrix.service }}
130139
cancel-in-progress: false
131140
steps:
132141
- name: Checkout code
@@ -136,8 +145,8 @@ jobs:
136145
uses: ./.github/actions/argocd-pr
137146
with:
138147
env-name: production
139-
component-name: mapping-service
140-
gitops-folder: production/mapping-service
148+
component-name: ${{ matrix.service }}
149+
gitops-folder: production/${{ matrix.service }}
141150
gitops-values-file: values.yaml
142151
image-tag-paths: '["deployment.imageRef.tag"]'
143152
image-tag: ${{ github.event.inputs.version }}
@@ -149,12 +158,6 @@ jobs:
149158
run: |
150159
echo "## Production Deployment Initiated" >> $GITHUB_STEP_SUMMARY
151160
echo "" >> $GITHUB_STEP_SUMMARY
152-
echo "**Component:** mapping-service" >> $GITHUB_STEP_SUMMARY
161+
echo "**Component:** ${{ matrix.service }}" >> $GITHUB_STEP_SUMMARY
153162
echo "**Version:** ${{ github.event.inputs.version }}" >> $GITHUB_STEP_SUMMARY
154163
echo "**Triggered by:** @${{ github.actor }}" >> $GITHUB_STEP_SUMMARY
155-
echo "" >> $GITHUB_STEP_SUMMARY
156-
echo "### Next Steps" >> $GITHUB_STEP_SUMMARY
157-
echo "1. Review the GitOps PR in the helm-charts repository" >> $GITHUB_STEP_SUMMARY
158-
echo "2. **IMPORTANT:** Manually approve and merge the PR to deploy to production" >> $GITHUB_STEP_SUMMARY
159-
echo "3. Monitor the deployment in the production cluster" >> $GITHUB_STEP_SUMMARY
160-
echo "4. Validate production functionality after deployment" >> $GITHUB_STEP_SUMMARY

.github/workflows/staging-build.yml

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ env:
99
GCP_REGION: europe-west9
1010
ARTIFACT_REGISTRY: europe-west9-docker.pkg.dev
1111
REGISTRY_NAME: preproduction-okeiro
12-
IMAGE_NAME: mapping-service
1312

1413
permissions:
1514
id-token: write
@@ -61,17 +60,24 @@ jobs:
6160
target: default
6261
push: true
6362
tags: |
64-
${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
65-
${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/${{ env.IMAGE_NAME }}:${{ needs.parse-version.outputs.version }}
66-
${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/${{ env.IMAGE_NAME }}:latest
63+
${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/mapping-service:${{ github.sha }}
64+
${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/mapping-service:${{ needs.parse-version.outputs.version }}
65+
${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/mapping-service:latest
66+
${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/fhir-simulator-r4:${{ github.sha }}
67+
${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/fhir-simulator-r4:${{ needs.parse-version.outputs.version }}
68+
${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/fhir-simulator-r4:latest
69+
${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/fhir-simulator-r5:${{ github.sha }}
70+
${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/fhir-simulator-r5:${{ needs.parse-version.outputs.version }}
71+
${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/fhir-simulator-r5:latest
6772
cache-from: type=gha
6873
cache-to: type=gha,mode=max
6974

7075
- name: Summary
7176
run: |
72-
echo "## Docker Image Built & Pushed to Staging" >> $GITHUB_STEP_SUMMARY
77+
echo "## Docker Images Built & Pushed to Staging" >> $GITHUB_STEP_SUMMARY
7378
echo "" >> $GITHUB_STEP_SUMMARY
74-
echo "**Image:** \`${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/${{ env.IMAGE_NAME }}\`" >> $GITHUB_STEP_SUMMARY
79+
echo "**Registry:** \`${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}\`" >> $GITHUB_STEP_SUMMARY
80+
echo "**Images:** mapping-service, fhir-simulator-r4, fhir-simulator-r5" >> $GITHUB_STEP_SUMMARY
7581
echo "**Tags:** \`${{ needs.parse-version.outputs.version }}\`, \`${{ github.sha }}\`, \`latest\`" >> $GITHUB_STEP_SUMMARY
7682
7783
cve-scan:
@@ -93,22 +99,29 @@ jobs:
9399

94100
- name: Pull image from registry
95101
run: |
96-
docker pull "${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/${{ env.IMAGE_NAME }}:${{ needs.parse-version.outputs.version }}"
102+
docker pull "${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/mapping-service:${{ needs.parse-version.outputs.version }}"
97103
98104
- name: Trivy CVE Scan
99105
uses: ./.github/actions/trivy-scan
100106
with:
101-
image: "${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/${{ env.IMAGE_NAME }}:${{ needs.parse-version.outputs.version }}"
107+
image: "${{ env.ARTIFACT_REGISTRY }}/${{ env.GCP_PROJECT_ID }}/${{ env.REGISTRY_NAME }}/mapping-service:${{ needs.parse-version.outputs.version }}"
102108
fail-on-critical: 'true'
103109
max-high-cves: '5'
104110
block: 'true'
105111

106112
create-gitops-pr:
107-
name: Create Staging GitOps PR
113+
name: Create Staging GitOps PR (${{ matrix.service }})
108114
needs: [parse-version, build-push, cve-scan]
109115
runs-on: ubuntu-latest
116+
strategy:
117+
fail-fast: false
118+
matrix:
119+
service:
120+
- mapping-service
121+
- fhir-simulator-r4
122+
- fhir-simulator-r5
110123
concurrency:
111-
group: gitops-staging-mapping-service
124+
group: gitops-staging-${{ matrix.service }}
112125
cancel-in-progress: false
113126
steps:
114127
- name: Checkout code
@@ -118,8 +131,8 @@ jobs:
118131
uses: ./.github/actions/argocd-pr
119132
with:
120133
env-name: preproduction
121-
component-name: mapping-service
122-
gitops-folder: preproduction/mapping-service
134+
component-name: ${{ matrix.service }}
135+
gitops-folder: preproduction/${{ matrix.service }}
123136
gitops-values-file: values.yaml
124137
image-tag-paths: '["deployment.imageRef.tag"]'
125138
image-tag: ${{ needs.parse-version.outputs.version }}
@@ -131,11 +144,6 @@ jobs:
131144
run: |
132145
echo "## Staging Deployment Initiated" >> $GITHUB_STEP_SUMMARY
133146
echo "" >> $GITHUB_STEP_SUMMARY
134-
echo "**Component:** mapping-service" >> $GITHUB_STEP_SUMMARY
147+
echo "**Component:** ${{ matrix.service }}" >> $GITHUB_STEP_SUMMARY
135148
echo "**Version:** ${{ needs.parse-version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
136149
echo "**Tag:** ${{ github.event.release.tag_name }}" >> $GITHUB_STEP_SUMMARY
137-
echo "" >> $GITHUB_STEP_SUMMARY
138-
echo "### Next Steps" >> $GITHUB_STEP_SUMMARY
139-
echo "1. Review the GitOps PR in the helm-charts repository" >> $GITHUB_STEP_SUMMARY
140-
echo "2. Merge the PR to deploy to staging" >> $GITHUB_STEP_SUMMARY
141-
echo "3. Validate the deployment on staging environment" >> $GITHUB_STEP_SUMMARY

0 commit comments

Comments
 (0)