1- name : Build and Push Docker Image
1+ name : Build and Push Docker Image for Multiple Architectures
22
33on :
4- # To enable manual triggering of this workflow
5- workflow_dispatch :
6-
7- # Trigger for pushes to master and tags
4+ pull_request :
85 push :
96 branches :
107 - master
8+ - develop
119 tags :
1210 - ' v*.*.*'
1311
@@ -16,38 +14,162 @@ concurrency:
1614 cancel-in-progress : true
1715
1816env :
19- IMAGE_NAME : index.docker.io/metacall/core
17+ DOCKER_REGISTRY : index.docker.io
18+ DOCKER_USERNAME : metacall
19+ IMAGE_NAME : core
20+ BUILDKIT_VERSION : 0.13.0
2021
2122jobs :
2223 build :
23- runs-on : ubuntu-latest
2424 name : Build
25+ runs-on : ubuntu-latest
26+ strategy :
27+ fail-fast : false
28+ matrix :
29+ platform :
30+ - linux/amd64
31+ - linux/386
32+ - linux/arm64
33+ - linux/riscv64
34+ - linux/ppc64le
35+ - linux/s390x
36+ - linux/arm/v7
37+ - linux/arm/v6
2538 steps :
26- - name : Checkout the code
39+ - name : Checkout Repository
2740 uses : actions/checkout@v4
2841 with :
2942 fetch-depth : 0
3043
31- - name : Login to DockerHub
32- run : docker login -u "${{ secrets.DOCKER_HUB_USERNAME }}" -p "${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}"
44+ - name : Set up QEMU
45+ uses : docker/setup-qemu-action@v3
46+
47+ - name : Set up Docker BuildX
48+ uses : docker/setup-buildx-action@v3
49+ with :
50+ version : v${{ env.BUILDKIT_VERSION }}
3351
34- - name : Pull MetaCall Docker Images
35- run : bash ./docker-compose.sh pull
52+ - name : Login to Docker Hub
53+ uses : docker/login-action@v3
54+ with :
55+ username : ${{ secrets.DOCKER_HUB_USERNAME }}
56+ password : ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
3657
3758 - name : Build MetaCall Docker Images
38- run : bash ./docker-compose.sh build
59+ env :
60+ METACALL_PLATFORM : ${{ matrix.platform }}
61+ run : |
62+ ./docker-compose.sh platform
63+
64+ - name : Tag Platform Images
65+ run : |
66+ platform_tag=$(echo "${{ matrix.platform }}" | tr '/' '-')
67+ echo "Platform Tag: ${platform_tag}"
68+ for tag in "deps" "dev" "runtime" "cli"; do
69+ docker tag metacall/${IMAGE_NAME}:${tag} \
70+ ${DOCKER_REGISTRY}/${DOCKER_USERNAME}/${IMAGE_NAME}:${tag}-${platform_tag}
71+ done
72+
73+ - name : Push Platform Images
74+ run : |
75+ platform_tag=$(echo "${{ matrix.platform }}" | tr '/' '-')
76+ for tag in "deps" "dev" "runtime" "cli"; do
77+ echo "Pushing image for tag: ${tag} with platform: ${platform_tag}"
78+ docker push ${DOCKER_REGISTRY}/${DOCKER_USERNAME}/${IMAGE_NAME}:${tag}-${platform_tag}
79+ done
3980
40- # TODO: Build with alpine and provide multiple tags (debian & alpine) once all tests pass
41- - name : Push MetaCall Docker Image to DockerHub
81+ - name : Run Tests
4282 run : |
43- if [[ "${{ github.ref == 'refs/heads/master' }}" = true ]]; then
44- bash ./docker-compose.sh push
45- elif [[ "${{ contains(github.ref, 'refs/tags/') }}" = true ]]; then
46- bash ./docker-compose.sh version
47- else
48- echo "Failed to push the docker images"
49- exit 1
83+ set -exuo pipefail
84+ platform_tag=$(echo "${{ matrix.platform }}" | tr '/' '-')
85+ cat <<EOF > Dockerfile.test
86+ FROM ${DOCKER_REGISTRY}/${DOCKER_USERNAME}/${IMAGE_NAME}:cli-${platform_tag}
87+ RUN echo "console.log('abcde')" > script.js
88+ RUN metacallcli script.js
89+ EOF
90+
91+ docker build --platform ${{ matrix.platform }} -f Dockerfile.test -t test-image .
92+ docker run --rm --platform=${{ matrix.platform }} test-image
93+
94+ manifest :
95+ name : Create and Push Manifest Lists
96+ needs : build
97+ # Only run when master or when tagging a version
98+ if : (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/')) && github.event_name != 'pull_request'
99+ runs-on : ubuntu-latest
100+ steps :
101+ - name : Login to Docker Hub
102+ uses : docker/login-action@v3
103+ with :
104+ username : ${{ secrets.DOCKER_HUB_USERNAME }}
105+ password : ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
106+
107+ - name : Create and Push Manifest Lists
108+ run : |
109+ tags=("deps" "dev" "runtime" "cli")
110+ platforms=("linux/amd64" "linux/386" "linux/arm64" "linux/riscv64" "linux/ppc64le" "linux/s390x" "linux/arm/v7" "linux/arm/v6")
111+
112+ echo "Create all the tags by platform"
113+
114+ for tag in "${tags[@]}"; do
115+ echo "Creating manifest for tag: $tag"
116+ platform_tags=""
117+ for platform in "${platforms[@]}"; do
118+ platform_tag=$(echo "${platform}" | tr '/' '-')
119+ platform_tags="${platform_tags} ${DOCKER_REGISTRY}/${DOCKER_USERNAME}/${IMAGE_NAME}:${tag}-${platform_tag}"
120+ done
121+ echo "Creating manifest with tags: ${platform_tags}"
122+ docker manifest create ${DOCKER_REGISTRY}/${DOCKER_USERNAME}/${IMAGE_NAME}:${tag} ${platform_tags} --amend
123+ docker manifest push ${DOCKER_REGISTRY}/${DOCKER_USERNAME}/${IMAGE_NAME}:${tag}
124+ done
125+
126+ echo "Create the latest tag"
127+
128+ cli_platform_tags=""
129+ for platform in ${platforms[@]}"; do
130+ platform_tag=$(echo "${platform}" | tr '/' '-')
131+ cli_platform_tags="${cli_platform_tags} ${DOCKER_USERNAME}/${IMAGE_NAME}:cli-${platform_tag}"
132+ done
133+ docker manifest create ${DOCKER_REGISTRY}/${DOCKER_USERNAME}/${IMAGE_NAME}:latest ${cli_platform_tags} --amend
134+ docker manifest push ${DOCKER_REGISTRY}/${DOCKER_USERNAME}/${IMAGE_NAME}:latest
135+
136+ if [[ "${{ startsWith(github.ref, 'refs/tags/') }}" = true ]]; then
137+ VERSION=${GITHUB_REF#refs/tags/v}
138+
139+ echo "Create the version ${VERSION} tag"
140+
141+ for tag in "${tags[@]}"; do
142+ platform_tags=""
143+ for platform in "${platforms[@]}"; do
144+ platform_tag=$(echo "${platform}" | tr '/' '-')
145+ platform_tags="${platform_tags} ${DOCKER_REGISTRY}/${DOCKER_USERNAME}/${IMAGE_NAME}:${tag}-${platform_tag}"
146+ done
147+ docker manifest create ${DOCKER_REGISTRY}/${DOCKER_USERNAME}/${IMAGE_NAME}:${VERSION}-${tag} ${platform_tags} --amend
148+ docker manifest push ${DOCKER_REGISTRY}/${DOCKER_USERNAME}/${IMAGE_NAME}:${VERSION}-${tag}
149+ done
50150 fi
51151
52- - name : Logout from DockerHub
53- run : docker logout
152+ cleanup :
153+ name : Cleanup Platform Specific Tags
154+ needs : [build, manifest]
155+ runs-on : ubuntu-latest
156+ if : always()
157+ steps :
158+ - name : Remove Platform-Specific Tags
159+ run : |
160+ tags=("deps" "dev" "runtime" "cli")
161+ platforms=("linux/amd64" "linux/386" "linux/arm64" "linux/riscv64" "linux/ppc64le" "linux/s390x" "linux/arm/v7" "linux/arm/v6")
162+
163+ for tag in "${tags[@]}"; do
164+ for platform in "${platforms[@]}"; do
165+ platform_tag=$(echo "${platform}" | tr '/' '-')
166+ tag_to_delete="${tag}-${platform_tag}"
167+
168+ echo "Deleting tag: ${tag_to_delete}"
169+ echo "https://hub.docker.com/v2/repositories/${DOCKER_USERNAME}/${IMAGE_NAME}/tags/${tag_to_delete}/"
170+
171+ curl -X DELETE \
172+ -H "Authorization: Bearer ${{ secrets.DOCKER_HUB_ACCESS_TOKEN_DELETE }}" \
173+ "https://hub.docker.com/v2/repositories/${DOCKER_USERNAME}/${IMAGE_NAME}/tags/${tag_to_delete}/"
174+ done
175+ done
0 commit comments