@@ -20,34 +20,22 @@ defaults:
2020 shell : bash
2121
2222jobs :
23- docker :
23+ vars :
2424 runs-on : ubuntu-latest
2525 permissions : {}
26+ outputs :
27+ stellar_cli_ref : ${{ steps.set.outputs.stellar_cli_ref }}
28+ docker_tags : ${{ steps.set.outputs.docker_tags }}
2629 steps :
27- # Check out the repository at a known ref with full history so that git
28- # can resolve branch names, tags, full SHAs, and partial SHAs correctly.
29- # For workflow_dispatch, this uses the default branch; for release events,
30- # this uses the published tag.
3130 - uses : actions/checkout@v6
3231 with :
3332 ref : ${{ github.event_name == 'workflow_dispatch' && 'main' || github.ref_name }}
3433 fetch-depth : 0
3534
36- - name : Set up Docker Buildx
37- uses : docker/setup-buildx-action@v4
38-
39- - name : Log in to Docker Hub
40- if : github.event_name != 'push'
41- uses : docker/login-action@v4
42- with :
43- username : ${{ secrets.DOCKERHUB_USERNAME }}
44- password : ${{ secrets.DOCKERHUB_TOKEN }}
45-
4635 # Build only (no push) to validate the Dockerfile on changes to main.
4736 - name : Setup vars (push)
4837 if : github.event_name == 'push'
49- run : |
50- echo "STELLAR_CLI_REF=${{ github.sha }}" >> $GITHUB_ENV
38+ run : echo "STELLAR_CLI_REF=${{ github.sha }}" >> $GITHUB_ENV
5139
5240 # Use the published tag as the ref; set both the versioned and `latest` tags.
5341 - name : Setup vars (release)
@@ -83,11 +71,121 @@ jobs:
8371 exit 1
8472 fi
8573
86- - name : Build and push
74+ - id : set
75+ run : |
76+ echo "stellar_cli_ref=${STELLAR_CLI_REF}" >> $GITHUB_OUTPUT
77+ echo "docker_tags=${DOCKER_TAGS}" >> $GITHUB_OUTPUT
78+
79+ build :
80+ needs : vars
81+ permissions : {}
82+ strategy :
83+ matrix :
84+ include :
85+ - platform : linux/amd64
86+ runs-on : ubuntu-latest
87+ - platform : linux/arm64
88+ runs-on : ubuntu-24.04-arm
89+ runs-on : ${{ matrix.runs-on }}
90+ # For push events (validation only), skip arm64 — amd64 is sufficient.
91+ if : github.event_name != 'push' || matrix.platform == 'linux/amd64'
92+ steps :
93+ - uses : actions/checkout@v6
94+ with :
95+ ref : ${{ needs.vars.outputs.stellar_cli_ref }}
96+
97+ - name : Install build dependencies
98+ run : sudo apt-get update && sudo apt-get install -y --no-install-recommends libudev-dev libdbus-1-dev
99+
100+ - name : Cache Rust build
101+ uses : Swatinem/rust-cache@v2
102+
103+ - name : Build binary
104+ run : cargo build --package stellar-cli --release
105+
106+ - name : Set up Docker Buildx
107+ uses : docker/setup-buildx-action@v4
108+
109+ - name : Log in to Docker Hub
110+ if : github.event_name != 'push'
111+ uses : docker/login-action@v4
112+ with :
113+ username : ${{ secrets.DOCKERHUB_USERNAME }}
114+ password : ${{ secrets.DOCKERHUB_TOKEN }}
115+
116+ - name : Copy binary for Docker context
117+ run : cp target/release/stellar stellar
118+
119+ # Validation only — build without pushing.
120+ - name : Build
121+ if : github.event_name == 'push'
122+ uses : docker/build-push-action@v7
123+ with :
124+ context : .
125+ platforms : ${{ matrix.platform }}
126+ push : false
127+ cache-from : type=gha,scope=${{ matrix.platform }}
128+ cache-to : type=gha,mode=max,scope=${{ matrix.platform }}
129+
130+ # Publish — push by digest so the merge job can assemble the manifest.
131+ - name : Build and push by digest
132+ if : github.event_name != 'push'
133+ id : build
87134 uses : docker/build-push-action@v7
88135 with :
89136 context : .
90- platforms : linux/amd64,linux/arm64
91- push : ${{ github.event_name != 'push' }}
92- build-args : STELLAR_CLI_REF=${{ env.STELLAR_CLI_REF }}
93- tags : ${{ env.DOCKER_TAGS }}
137+ platforms : ${{ matrix.platform }}
138+ outputs : type=image,name=stellar/cli,push-by-digest=true,name-canonical=true,push=true
139+ cache-from : type=gha,scope=${{ matrix.platform }}
140+ cache-to : type=gha,mode=max,scope=${{ matrix.platform }}
141+
142+ - name : Export digest
143+ if : github.event_name != 'push'
144+ run : |
145+ mkdir -p /tmp/digests
146+ digest="${{ steps.build.outputs.digest }}"
147+ touch "/tmp/digests/${digest#sha256:}"
148+
149+ - name : Upload digest
150+ if : github.event_name != 'push'
151+ uses : actions/upload-artifact@v4
152+ with :
153+ name : digest-${{ matrix.platform == 'linux/amd64' && 'amd64' || 'arm64' }}
154+ path : /tmp/digests/*
155+ if-no-files-found : error
156+ retention-days : 1
157+
158+ merge :
159+ needs : [vars, build]
160+ if : github.event_name != 'push'
161+ runs-on : ubuntu-latest
162+ permissions : {}
163+ steps :
164+ - name : Download digests
165+ uses : actions/download-artifact@v4
166+ with :
167+ path : /tmp/digests
168+ pattern : digest-*
169+ merge-multiple : true
170+
171+ - name : Set up Docker Buildx
172+ uses : docker/setup-buildx-action@v4
173+
174+ - name : Log in to Docker Hub
175+ uses : docker/login-action@v4
176+ with :
177+ username : ${{ secrets.DOCKERHUB_USERNAME }}
178+ password : ${{ secrets.DOCKERHUB_TOKEN }}
179+
180+ - name : Create and push manifest
181+ working-directory : /tmp/digests
182+ run : |
183+ tags="${{ needs.vars.outputs.docker_tags }}"
184+ tag_args=""
185+ IFS=',' read -ra tag_list <<< "$tags"
186+ for tag in "${tag_list[@]}"; do
187+ tag_args+=" --tag ${tag}"
188+ done
189+
190+ docker buildx imagetools create $tag_args \
191+ $(printf 'stellar/cli@sha256:%s ' *)
0 commit comments