1+ name : ' Multi-Architecture Docker Build'
2+ on :
3+ workflow_call :
4+ inputs :
5+ images :
6+ description : ' Name of images to build'
7+ required : true
8+ type : string
9+ acr-username :
10+ description : ' Username to use when logging into ACR'
11+ required : true
12+ type : string
13+ acr-password :
14+ description : ' Password to use when logging into ACR'
15+ required : true
16+ type : string
17+ acr-registry-url :
18+ description : ' The url of the ACR registry to fetch credentials from'
19+ required : false
20+ type : string
21+ default : ' tignis.azurecr.io'
22+ pip-extra-index-url :
23+ description : ' The PIP_EXTRA_INDEX_URL for private pip packages'
24+ required : true
25+ type : string
26+ push :
27+ description : ' Also push the image to the remote repository'
28+ required : false
29+ type : string
30+ default : ' true'
31+ docker-build-context :
32+ description : ' Build context for docker'
33+ required : false
34+ type : string
35+ default : ' .'
36+ dockerfile :
37+ description : ' Name of the docker file to use'
38+ required : false
39+ type : string
40+ default : ' Dockerfile'
41+ GITHUB_TOKEN :
42+ description : ' Github token of the repository'
43+ required : false
44+ type : string
45+ default : ' '
46+ outputs :
47+ tag :
48+ description : ' Final tag used for the multi-architecture docker image'
49+ value : ${{ jobs.docker-manifest.outputs.tag }}
50+
51+ jobs :
52+ docker-amd64 :
53+ runs-on : ubuntu-latest
54+ outputs :
55+ tag : ${{ steps.docker.outputs.tag }}
56+ digest : ${{ steps.digest.outputs.digest }}
57+ image : ${{ inputs.images }}
58+ clean-tag : ${{ steps.clean-tag.outputs.value }}
59+ steps :
60+ - name : Checkout
61+ uses : actions/checkout@v4
62+
63+ - name : Build and Push docker image (AMD64)
64+ id : docker
65+ uses : tignis/docker-github-action/action.yaml@v2.3.1
66+ with :
67+ images : ${{ inputs.images }}
68+ acr-username : ${{ inputs.acr-username }}
69+ acr-password : ${{ inputs.acr-password }}
70+ acr-registry-url : ${{ inputs.acr-registry-url }}
71+ pip-extra-index-url : ${{ inputs.pip-extra-index-url }}
72+ push : ${{ inputs.push }}
73+ docker-build-context : ${{ inputs.docker-build-context }}
74+ dockerfile : ${{ inputs.dockerfile }}
75+ platforms : ' linux/amd64'
76+ tag-prefix : ' amd64-'
77+ GITHUB_TOKEN : ${{ inputs.GITHUB_TOKEN }}
78+
79+ - name : Extract clean tag
80+ id : clean-tag
81+ run : |
82+ TAG=${{ steps.docker.outputs.tag }}
83+ CLEAN_TAG=${TAG#*:amd64-}
84+ echo "value=${CLEAN_TAG}" >> $GITHUB_OUTPUT
85+ shell : bash
86+
87+ - name : Get image digest
88+ id : digest
89+ run : |
90+ echo "digest=$(docker inspect ${{ steps.docker.outputs.tag }} --format='{{index .RepoDigests 0}}' | cut -d'@' -f2)" >> $GITHUB_OUTPUT
91+ shell : bash
92+
93+ docker-arm64 :
94+ runs-on : [self-hosted, linux, ARM64]
95+ outputs :
96+ tag : ${{ steps.docker.outputs.tag }}
97+ digest : ${{ steps.digest.outputs.digest }}
98+ image : ${{ inputs.images }}
99+ steps :
100+ - name : Checkout
101+ uses : actions/checkout@v4
102+
103+ - name : Build and Push docker image (ARM64)
104+ id : docker
105+ uses : tignis/docker-github-action/action.yaml@v2.3.1
106+ with :
107+ images : ${{ inputs.images }}
108+ acr-username : ${{ inputs.acr-username }}
109+ acr-password : ${{ inputs.acr-password }}
110+ acr-registry-url : ${{ inputs.acr-registry-url }}
111+ pip-extra-index-url : ${{ inputs.pip-extra-index-url }}
112+ push : ${{ inputs.push }}
113+ docker-build-context : ${{ inputs.docker-build-context }}
114+ dockerfile : ${{ inputs.dockerfile }}
115+ platforms : ' linux/arm64'
116+ tag-prefix : ' arm64-'
117+ GITHUB_TOKEN : ${{ inputs.GITHUB_TOKEN }}
118+
119+ - name : Get image digest
120+ id : digest
121+ run : |
122+ echo "digest=$(docker inspect ${{ steps.docker.outputs.tag }} --format='{{index .RepoDigests 0}}' | cut -d'@' -f2)" >> $GITHUB_OUTPUT
123+ shell : bash
124+
125+ docker-manifest :
126+ needs : [docker-amd64, docker-arm64]
127+ runs-on : ubuntu-latest
128+ outputs :
129+ tag : ${{ steps.manifest.outputs.tag }}
130+ steps :
131+ - name : Login to ACR
132+ uses : docker/login-action@v3
133+ with :
134+ registry : ${{ inputs.acr-registry-url }}
135+ username : ${{ inputs.acr-username }}
136+ password : ${{ inputs.acr-password }}
137+
138+ - name : Create and push manifest
139+ id : manifest
140+ run : |
141+ IMAGE=${{ needs.docker-amd64.outputs.image }}
142+ CLEAN_TAG=${{ needs.docker-amd64.outputs.clean-tag }}
143+ FINAL_TAG="${IMAGE}:${CLEAN_TAG}"
144+
145+ # Enable experimental features for manifest command
146+ export DOCKER_CLI_EXPERIMENTAL=enabled
147+
148+ echo "Creating manifest for ${FINAL_TAG}"
149+
150+ # Create the manifest
151+ docker manifest create ${FINAL_TAG} \
152+ ${IMAGE}@${{ needs.docker-amd64.outputs.digest }} \
153+ ${IMAGE}@${{ needs.docker-arm64.outputs.digest }}
154+
155+ # Add architecture annotations
156+ docker manifest annotate ${FINAL_TAG} \
157+ ${IMAGE}@${{ needs.docker-amd64.outputs.digest }} --arch amd64
158+ docker manifest annotate ${FINAL_TAG} \
159+ ${IMAGE}@${{ needs.docker-arm64.outputs.digest }} --arch arm64
160+
161+ # Push the manifest
162+ docker manifest push ${FINAL_TAG}
163+
164+ echo "tag=${FINAL_TAG}" >> $GITHUB_OUTPUT
165+ echo "Multi-arch manifest created and pushed: ${FINAL_TAG}"
166+ shell : bash
0 commit comments