1+ name : Upload to ghcr.io
2+
3+ on :
4+ push :
5+ tags :
6+ - ' **'
7+ # GITHUB_SHA: Last commit in the tagged release
8+ # GITHUB_REF: Tag ref of release refs/tags/<tag_name>
9+ release :
10+ types :
11+ - published
12+ # GITHUB_SHA: Last commit on the GITHUB_REF branch or tag
13+ # GITHUB_REF: Branch or tag that received dispatch
14+ workflow_dispatch : {}
15+
16+ permissions :
17+ contents : read
18+ packages : write
19+
20+ env :
21+ # Only to avoid some repetition
22+ FLAKE_REF : github:${{ github.repository }}/${{ github.ref_name }}
23+ GH_TOKEN : ${{ github.token }}
24+
25+ jobs :
26+ wait-for-hydra :
27+ name : " Wait for hydra check-runs"
28+ runs-on : ubuntu-latest
29+
30+ steps :
31+ - name : Waiting for ci/hydra-build:required to complete
32+ run : |
33+ while [[ true ]]; do
34+ check_name='ci/hydra-build:required'
35+ conclusion=$(gh api "repos/$GITHUB_REPOSITORY/commits/$GITHUB_SHA/check-runs?check_name=$check_name" --paginate --jq '.check_runs[].conclusion')
36+ case "$conclusion" in
37+ success)
38+ echo "$check_name succeeded"
39+ exit 0;;
40+ '')
41+ echo "$check_name pending. Waiting 30s..."
42+ sleep 30;;
43+ *)
44+ echo "$check_name terminated unsuccessfully"
45+ exit 1;;
46+ esac
47+ done
48+
49+
50+ prepare :
51+ needs : [wait-for-hydra]
52+ name : " Prepare metadata"
53+ runs-on : ubuntu-latest
54+ outputs :
55+ LATEST_TAG : ${{ steps.latest-tag.outputs.LATEST_TAG }}
56+ LOCKED_URL : ${{ steps.flake-metadata.outputs.LOCKED_URL }}
57+
58+ steps :
59+ - name : Install Nix
60+ uses : cachix/install-nix-action@v31
61+
62+ - name : Display flake metadata
63+ id : flake-metadata
64+ run : |
65+ nix flake metadata ${{ env.FLAKE_REF }}
66+ nix flake metadata ${{ env.FLAKE_REF }} --json | jq -r '"LOCKED_URL=\(.url)"' >> "$GITHUB_OUTPUT"
67+
68+ - name : Obtaining latest release tag
69+ id : latest-tag
70+ run : |
71+ LATEST_TAG=$(gh api repos/$GITHUB_REPOSITORY/releases/latest --paginate --jq '.tag_name')
72+ echo "LATEST_TAG=$LATEST_TAG" >> "$GITHUB_OUTPUT"
73+ echo "Latest release tag is: $LATEST_TAG"
74+
75+
76+ build :
77+ needs : [prepare]
78+ name : " Upload to ghcr.io"
79+ runs-on : ubuntu-latest
80+ strategy :
81+ matrix :
82+ arch :
83+ - name : amd64
84+ system : x86_64-linux
85+ - name : arm64
86+ system : aarch64-linux
87+ image :
88+ - name : dmq-node
89+ nix_key : docker-hydra
90+
91+ steps :
92+ - name : Install Nix
93+ uses : cachix/install-nix-action@v31
94+
95+ - name : Log in to GitHub Container Registry
96+ uses : docker/login-action@v3
97+ with :
98+ registry : ghcr.io
99+ username : ${{ github.actor }}
100+ password : ${{ secrets.GITHUB_TOKEN }}
101+
102+ # NOTE We assume that hydra has already built the image, this is
103+ # reasonable since, before applying the tag, we must have already
104+ # pushed the tagged commit somewhere, and Hydra will have had the
105+ # change to build the image.
106+
107+ - name : Uploading ${{ matrix.image.name }} (${{ matrix.arch.name }})
108+ run : |
109+ echo "::group::Downloading from cache"
110+ nix build \
111+ --accept-flake-config \
112+ --print-out-paths \
113+ --builders "" \
114+ --max-jobs 0 \
115+ --out-link ./result-${{ matrix.image.name }}-${{ matrix.arch.name }} \
116+ ${{ needs.prepare.outputs.LOCKED_URL }}#packages.${{ matrix.arch.system }}.${{ matrix.image.nix_key }}
117+ echo "::endgroup::"
118+
119+ echo "::group::Uploading to registry"
120+ skopeo copy \
121+ docker-archive:./result-${{ matrix.image.name }}-${{ matrix.arch.name }} \
122+ docker://ghcr.io/intersectmbo/${{ matrix.image.name }}:$GITHUB_REF_NAME-${{ matrix.arch.name }}
123+ echo "::endgroup::"
124+
125+
126+ create-manifest :
127+ needs : [prepare, build]
128+ name : " Create Multi-Arch Manifest"
129+ runs-on : ubuntu-latest
130+
131+ steps :
132+ - name : Install Nix
133+ uses : cachix/install-nix-action@v31
134+
135+ # Regctl simplifies obtaining multi-arch digests
136+ - name : Install Nix Profile Commands
137+ run : nix profile install nixpkgs#regctl
138+
139+ # The docker buildx action has a tight coupling with GH runners
140+ - name : Setup Docker Buildx
141+ uses : docker/setup-buildx-action@v3
142+
143+ - name : Show buildx configuration
144+ run : docker buildx ls
145+
146+ - name : Log in to GitHub Container Registry
147+ uses : docker/login-action@v3
148+ with :
149+ registry : ghcr.io
150+ username : ${{ github.actor }}
151+ password : ${{ secrets.GITHUB_TOKEN }}
152+
153+ - name : Create Manifests
154+ run : |
155+ REPOS=(cardano-node cardano-submit-api cardano-tracer)
156+ ARCHES=(amd64 arm64)
157+
158+ for REPO in "${REPOS[@]}"; do
159+ IMAGE_REPO="ghcr.io/intersectmbo/$REPO"
160+ DIGESTS=()
161+
162+ echo "::group::Fetching digests for $REPO"
163+ for ARCH in "${ARCHES[@]}"; do
164+ DIGEST=$(skopeo inspect --no-tags "docker://$IMAGE_REPO:$GITHUB_REF_NAME-$ARCH" | jq -r .Digest)
165+ echo "$REPO $ARCH digest: $DIGEST"
166+ DIGESTS+=("$IMAGE_REPO@$DIGEST")
167+ done
168+ echo "::endgroup::"
169+
170+ echo "::group::Creating manifest for $REPO:$GITHUB_REF_NAME"
171+ docker buildx imagetools create --tag "$IMAGE_REPO:$GITHUB_REF_NAME" "${DIGESTS[@]}"
172+ echo "::endgroup::"
173+ done
174+
175+ - name : Verify multi-arch manifests
176+ run : |
177+ for REPO in cardano-node cardano-submit-api cardano-tracer; do
178+ IMAGE_REPO="ghcr.io/intersectmbo/$REPO"
179+ echo "::group::Inspecting $REPO:$GITHUB_REF_NAME"
180+
181+ DIGEST=$(regctl manifest head "$IMAGE_REPO:$GITHUB_REF_NAME")
182+ echo "$REPO multi-arch manifest digest: $DIGEST"
183+ skopeo inspect --raw "docker://$IMAGE_REPO:$GITHUB_REF_NAME" | jq
184+
185+ echo "::endgroup::"
186+ done
187+
188+ - name : Tag Containers as :latest
189+ # Github releases are checked for latest tag in the first `or` operand of
190+ # the if statement. However, promoted pre-releases or changed full
191+ # releases do not count as a `published` event and so won't trigger
192+ # this workflow. For those use cases a manual workflow must be run
193+ # from the matching release tag which the second `or` operand checks
194+ # for.
195+ if : |
196+ (github.event_name == 'release' && github.event.release.tag_name == needs.prepare.outputs.LATEST_TAG) ||
197+ (github.event_name == 'workflow_dispatch' && github.ref == format('refs/tags/{0}', needs.prepare.outputs.LATEST_TAG))
198+ run : |
199+ REPOS=(cardano-node cardano-submit-api cardano-tracer)
200+
201+ for REPO in "${REPOS[@]}"; do
202+ IMAGE_REPO="ghcr.io/intersectmbo/$REPO"
203+ DIGEST=$(regctl manifest head "$IMAGE_REPO:$GITHUB_REF_NAME")
204+
205+ echo "::group::Creating manifest for $IMAGE_REPO:latest"
206+ docker buildx imagetools create --tag "$IMAGE_REPO:latest" "$IMAGE_REPO@$DIGEST"
207+ echo "::endgroup::"
208+ done
0 commit comments