forked from argoproj-labs/argocd-image-updater
-
Notifications
You must be signed in to change notification settings - Fork 0
143 lines (126 loc) · 5.31 KB
/
Copy pathbuild-push-images.yaml
File metadata and controls
143 lines (126 loc) · 5.31 KB
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
name: docker-build-and-push-images
on:
workflow_dispatch:
inputs:
runners:
description: 'Runners to use (JSON array, e.g., ["ubuntu-latest", "ubuntu-24.04-arm"] or ["ubuntu-latest"])'
required: true
type: string
default: '["ubuntu-latest", "ubuntu-24.04-arm"]'
jobs:
build-push-images:
name: Build and push images (${{ matrix.runner }})
runs-on: ${{ matrix.runner }}
timeout-minutes: 30
strategy:
matrix:
runner: ${{ fromJSON(inputs.runners) }}
steps:
- name: Delete tool cache to preserve space
run: rm -rf /opt/hostedtoolcache || true
- name: Checkout code
uses: actions/checkout@v6
- name: Get version-tag
id: version-tag
run: |
VERSION=$(cat VERSION)
if [ "$VERSION" = "99.9.9" ]; then
VERSION_TAG="latest"
else
VERSION_TAG="v${VERSION}"
fi
echo version-tag=${VERSION_TAG} >> $GITHUB_OUTPUT
- name: Detect platform
id: platform
run: |
if [[ "${{ matrix.runner }}" == *"arm"* ]]; then
echo "platform=linux/arm64" >> $GITHUB_OUTPUT
echo "arch-tag=arm64" >> $GITHUB_OUTPUT
else
echo "platform=linux/amd64" >> $GITHUB_OUTPUT
echo "arch-tag=amd64" >> $GITHUB_OUTPUT
fi
- name: Setup Golang
uses: actions/setup-go@v6
with:
go-version-file: go.mod
- name: Build and push platform-specific image
run: |
set -euo pipefail
echo "${DOCKER_PASSWORD}" | docker login --username "${DOCKER_USERNAME}" --password-stdin quay.io
IMAGE_TAG="${{ steps.version-tag.outputs.version-tag }}-${{ steps.platform.outputs.arch-tag }}" make docker-build docker-push
env:
DOCKER_USERNAME: ${{ secrets.QUAY_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.QUAY_TOKEN }}
create-manifest:
name: Create multi-arch manifest
needs: build-push-images
runs-on: ubuntu-latest
timeout-minutes: 30
if: needs.build-push-images.result == 'success'
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Get version-tag
id: version-tag
run: |
VERSION=$(cat VERSION)
if [ "$VERSION" = "99.9.9" ]; then
VERSION_TAG="latest"
else
VERSION_TAG="v${VERSION}"
fi
echo version-tag=${VERSION_TAG} >> $GITHUB_OUTPUT
- name: Login to registry
run: |
set -euo pipefail
echo "${DOCKER_PASSWORD}" | docker login --username "${DOCKER_USERNAME}" --password-stdin quay.io
env:
DOCKER_USERNAME: ${{ secrets.QUAY_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.QUAY_TOKEN }}
- name: Create and push multi-arch manifest
run: |
set -ex
IMAGE_NAME="quay.io/argoprojlabs/argocd-image-updater"
VERSION_TAG="${{ steps.version-tag.outputs.version-tag }}"
# Resolve each platform tag to a single-image digest reference (image@sha256:...).
# Registry or build may expose -amd64/-arm64 as manifest lists; we take the platform digest.
# We must use digest refs only; mixing tag refs in the list can make Quay reject the push.
get_platform_ref() {
local tag=$1
local arch=$2
local inspect
inspect=$(docker manifest inspect "${IMAGE_NAME}:${tag}" 2>/dev/null) || return 1
if echo "${inspect}" | jq -e '.manifests' >/dev/null 2>&1; then
# Manifest list: extract the digest for the requested platform
local digest
digest=$(echo "${inspect}" | jq -r --arg a "${arch}" '.manifests[] | select(.platform.architecture == $a) | .digest' | head -n1)
[ -n "${digest}" ] && echo "${IMAGE_NAME}@${digest}" || return 1
else
# Single-platform image: get digest from verbose inspect descriptor
local digest
digest=$(docker manifest inspect --verbose "${IMAGE_NAME}:${tag}" 2>/dev/null | jq -r '.Descriptor.digest')
[ -n "${digest}" ] && [ "${digest}" != "null" ] && echo "${IMAGE_NAME}@${digest}" || return 1
fi
}
# Resolve each platform once (used for create and annotate)
REF_AMD64=""
REF_ARM64=""
if ref=$(get_platform_ref "${VERSION_TAG}-amd64" amd64); then
REF_AMD64="${ref}"
fi
if ref=$(get_platform_ref "${VERSION_TAG}-arm64" arm64); then
REF_ARM64="${ref}"
fi
REFS=$(echo "${REF_AMD64} ${REF_ARM64}" | sed 's/^ *//;s/ *$//')
if [ -z "${REFS}" ]; then
echo "No platform-specific images found, skipping manifest creation"
exit 0
fi
# Create manifest list from single-image refs
docker manifest create ${IMAGE_NAME}:${VERSION_TAG} ${REFS}
# Annotate each platform (reuse refs from above)
[ -n "${REF_AMD64}" ] && docker manifest annotate ${IMAGE_NAME}:${VERSION_TAG} "${REF_AMD64}" --os linux --arch amd64
[ -n "${REF_ARM64}" ] && docker manifest annotate ${IMAGE_NAME}:${VERSION_TAG} "${REF_ARM64}" --os linux --arch arm64
# Push the manifest
docker manifest push ${IMAGE_NAME}:${VERSION_TAG}