@@ -20,18 +20,34 @@ defaults:
2020 shell : bash
2121
2222jobs :
23- docker :
24- runs-on : ubuntu-latest
23+ build :
24+ strategy :
25+ matrix :
26+ include :
27+ - platform : linux/amd64
28+ runs-on : ubuntu-latest
29+ arch : amd64
30+ - platform : linux/arm64
31+ runs-on : ubuntu-24.04-arm
32+ arch : arm64
33+ runs-on : ${{ matrix.runs-on }}
2534 permissions : {}
2635 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.
3136 - uses : actions/checkout@v6
3237 with :
33- ref : ${{ github.event_name == 'workflow_dispatch' && 'main' || github.ref_name }}
34- fetch-depth : 0
38+ ref : ${{ github.event_name == 'workflow_dispatch' && inputs.ref || github.ref }}
39+
40+ - name : Install build dependencies
41+ run : sudo apt-get update && sudo apt-get install -y --no-install-recommends libudev-dev libdbus-1-dev
42+
43+ - name : Cache Rust build
44+ uses : Swatinem/rust-cache@v2
45+
46+ - name : Build binary
47+ run : cargo build --package stellar-cli --release
48+
49+ - name : Copy binary for Docker context
50+ run : cp target/release/stellar stellar
3551
3652 - name : Set up Docker Buildx
3753 uses : docker/setup-buildx-action@v4
@@ -43,51 +59,98 @@ jobs:
4359 username : ${{ secrets.DOCKERHUB_USERNAME }}
4460 password : ${{ secrets.DOCKERHUB_TOKEN }}
4561
46- # Build only (no push) to validate the Dockerfile on changes to main .
47- - name : Setup vars (push)
62+ # Validation only — build without pushing .
63+ - name : Build
4864 if : github.event_name == 'push'
65+ uses : docker/build-push-action@v7
66+ with :
67+ context : .
68+ platforms : ${{ matrix.platform }}
69+ push : false
70+ cache-from : type=gha,scope=${{ matrix.arch }}
71+ cache-to : type=gha,mode=max,scope=${{ matrix.arch }}
72+
73+ # Publish — push by digest so the merge job can assemble the manifest.
74+ - name : Build and push by digest
75+ if : github.event_name != 'push'
76+ id : build
77+ uses : docker/build-push-action@v7
78+ with :
79+ context : .
80+ platforms : ${{ matrix.platform }}
81+ outputs : type=image,name=stellar/cli,push-by-digest=true,name-canonical=true,push=true
82+ cache-from : type=gha,scope=${{ matrix.arch }}
83+ cache-to : type=gha,mode=max,scope=${{ matrix.arch }}
84+
85+ - name : Upload digest
86+ if : github.event_name != 'push'
4987 run : |
50- echo "STELLAR_CLI_REF=${{ github.sha }}" >> $GITHUB_ENV
88+ mkdir -p /tmp/digests
89+ digest="${{ steps.build.outputs.digest }}"
90+ touch "/tmp/digests/${digest#sha256:}"
91+
92+ - name : Upload digest artifact
93+ if : github.event_name != 'push'
94+ uses : actions/upload-artifact@v4
95+ with :
96+ name : digest-${{ matrix.arch }}
97+ path : /tmp/digests/*
98+ if-no-files-found : error
99+ retention-days : 1
100+
101+ merge :
102+ needs : build
103+ if : github.event_name != 'push'
104+ runs-on : ubuntu-latest
105+ permissions : {}
106+ steps :
107+ - uses : actions/checkout@v6
108+ with :
109+ ref : ${{ github.event_name == 'workflow_dispatch' && inputs.ref || github.ref }}
110+ fetch-depth : 0
51111
52- # Use the published tag as the ref; set both the versioned and `latest` tags.
53- - name : Setup vars (release)
54- if : github.event_name == 'release'
112+ # Compute Docker tags from the ref.
113+ # - Version tag (e.g. v1.2.3): push versioned + latest tags.
114+ # - Any other ref: push a tag for the resolved commit SHA.
115+ - name : Compute tags
55116 run : |
56- ref="${{ github.ref_name }}"
117+ ref="${{ github.event_name == 'workflow_dispatch' && inputs.ref || github.ref_name }}"
118+
57119 if [[ "$ref" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
58120 version="${ref#v}"
59- echo "STELLAR_CLI_REF=${ref}" >> $GITHUB_ENV
60121 echo "DOCKER_TAGS=stellar/cli:${version},stellar/cli:latest" >> $GITHUB_ENV
61- else
122+ elif [[ "${{ github.event_name }}" == "release" ]]; then
62123 echo "::error::Release tag '${ref}' is not a valid version tag (expected vX.Y.Z)."
63124 exit 1
125+ else
126+ commit="$(git rev-parse HEAD)"
127+ echo "DOCKER_TAGS=stellar/cli:${commit}" >> $GITHUB_ENV
64128 fi
65129
66- # If the ref looks like a version tag (e.g. v1.2.3), treat it like a
67- # release and include the `latest` tag. Otherwise, resolve the ref to a
68- # commit SHA via git rev-parse, which handles branch names, tags, full
69- # SHAs, and partial SHAs.
70- - name : Setup vars (workflow_dispatch)
71- if : github.event_name == 'workflow_dispatch'
72- run : |
73- ref="${{ inputs.ref }}"
130+ - name : Download digests
131+ uses : actions/download-artifact@v4
132+ with :
133+ path : /tmp/digests
134+ pattern : digest-*
135+ merge-multiple : true
74136
75- if [[ "$ref" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
76- echo "STELLAR_CLI_REF=${ref}" >> $GITHUB_ENV
77- echo "DOCKER_TAGS=stellar/cli:${ref#v},stellar/cli:latest" >> $GITHUB_ENV
78- elif commit="$(git rev-parse --verify "$ref^{commit}" 2>/dev/null)"; then
79- echo "STELLAR_CLI_REF=${commit}" >> $GITHUB_ENV
80- echo "DOCKER_TAGS=stellar/cli:${commit}" >> $GITHUB_ENV
81- else
82- echo "::error::Could not resolve ref '${ref}' to a commit."
83- exit 1
84- fi
137+ - name : Set up Docker Buildx
138+ uses : docker/setup-buildx-action@v4
85139
86- - name : Build and push
87- uses : docker/build-push- action@v7
140+ - name : Log in to Docker Hub
141+ uses : docker/login- action@v4
88142 with :
89- 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 }}
143+ username : ${{ secrets.DOCKERHUB_USERNAME }}
144+ password : ${{ secrets.DOCKERHUB_TOKEN }}
145+
146+ - name : Create and push manifest
147+ working-directory : /tmp/digests
148+ run : |
149+ tag_args=""
150+ IFS=',' read -ra tag_list <<< "$DOCKER_TAGS"
151+ for tag in "${tag_list[@]}"; do
152+ tag_args+=" --tag ${tag}"
153+ done
154+
155+ docker buildx imagetools create $tag_args \
156+ $(printf 'stellar/cli@sha256:%s ' *)
0 commit comments