1+ ---
2+
3+ name : 📦 Build Linux binary
4+
5+ on : # yamllint disable-line rule:truthy
6+ release :
7+ types :
8+ - published
9+
10+ jobs :
11+ build-linux :
12+ runs-on : ubuntu-latest
13+ name : 📦 Build Linux Executables
14+ strategy :
15+ fail-fast : false
16+ matrix :
17+ platform :
18+ - os : linux
19+ arch : amd64
20+ - os : linux
21+ arch : arm64
22+
23+ steps :
24+ - name : Checkout code
25+ uses : actions/checkout@v3
26+
27+ - name : Set up QEMU
28+ uses : docker/setup-qemu-action@v2
29+ with :
30+ platforms : arm64,amd64
31+
32+ - name : Set up Docker Buildx
33+ uses : docker/setup-buildx-action@v2
34+
35+ - name : Extract version from tag
36+ id : get_version
37+ run : |
38+ if [[ "$GITHUB_REF_NAME" == refs/pull/* ]]; then
39+ # For pull requests, use "dev" as version
40+ VERSION="dev"
41+ else
42+ # For releases, extract version from tag (remove 'v' prefix if present)
43+ VERSION=${GITHUB_REF_NAME#v}
44+ fi
45+ echo "VERSION=$VERSION" >> $GITHUB_ENV
46+ echo "{\"version\": \"$VERSION\", \"type\":\"bin\"}" > version.json
47+
48+ - name : Build Docker image for ${{ matrix.platform.os }}-${{ matrix.platform.arch }}
49+ uses : docker/build-push-action@v4
50+ with :
51+ context : .
52+ push : false
53+ load : true
54+ tags : ctx-builder-${{ matrix.platform.os }}-${{ matrix.platform.arch }}:latest
55+ platforms : linux/${{ matrix.platform.arch }}
56+ build-args : |
57+ TARGET_OS=${{ matrix.platform.os }}
58+ TARGET_ARCH=${{ matrix.platform.arch }}
59+ VERSION=${{ env.VERSION }}
60+ cache-from : type=gha,scope=${{ matrix.platform.os }}-${{ matrix.platform.arch }}
61+ cache-to : type=gha,mode=max,scope=${{ matrix.platform.os }}-${{ matrix.platform.arch }}
62+
63+ - name : Extract executable
64+ run : |
65+ mkdir -p dist
66+ container_id=$(docker create ctx-builder-${{ matrix.platform.os }}-${{ matrix.platform.arch }}:latest)
67+ docker cp $container_id:/.output/ctx ./dist/ctx-${{ env.VERSION }}-${{ matrix.platform.os }}-${{ matrix.platform.arch }}
68+ docker rm $container_id
69+
70+ - name : 📤 Upload build artifact
71+ uses : actions/upload-artifact@v4
72+ with :
73+ name : ctx-${{ env.VERSION }}-${{ matrix.platform.os }}-${{ matrix.platform.arch }}
74+ path : dist/ctx-${{ env.VERSION }}-${{ matrix.platform.os }}-${{ matrix.platform.arch }}
75+
76+ - name : 📤 Upload release assets
77+ 78+ if : startsWith(github.ref, 'refs/tags/')
79+ with :
80+ token : " ${{ secrets.RELEASE_TOKEN }}"
81+ files : |
82+ ./dist/ctx-${{ env.VERSION }}-${{ matrix.platform.os }}-${{ matrix.platform.arch }}
83+
84+ build-alpine-docker :
85+ needs : [ build-linux ]
86+ runs-on : ubuntu-latest
87+ name : 📦 Build Alpine Docker Container
88+ strategy :
89+ fail-fast : false
90+ matrix :
91+ platform :
92+ - os : linux
93+ arch : amd64
94+ - os : linux
95+ arch : arm64
96+ steps :
97+ - name : Checkout code
98+ uses : actions/checkout@v3
99+
100+ - name : Set up QEMU
101+ uses : docker/setup-qemu-action@v3
102+
103+ - name : Set up Docker Buildx
104+ uses : docker/setup-buildx-action@v3
105+
106+ - name : Extract version from tag
107+ id : get_version
108+ run : |
109+ if [[ "$GITHUB_REF_NAME" == refs/pull/* ]]; then
110+ # For pull requests, use "dev" as version
111+ VERSION="dev"
112+ else
113+ # For releases, extract version from tag (remove 'v' prefix if present)
114+ VERSION=${GITHUB_REF_NAME#v}
115+ fi
116+ echo "VERSION=$VERSION" >> $GITHUB_ENV
117+
118+ - name : Download Linux ${{ matrix.platform.arch }} binary
119+ uses : actions/download-artifact@v4
120+ with :
121+ name : ctx-${{ env.VERSION }}-${{ matrix.platform.os }}-${{ matrix.platform.arch }}
122+ path : ./tmp
123+
124+ - name : Make binary executable
125+ run : |
126+ chmod +x ./tmp/ctx-${{ env.VERSION }}-${{ matrix.platform.os }}-${{ matrix.platform.arch }}
127+
128+ - name : Create Docker context directory
129+ run : |
130+ mkdir -p ./docker
131+ cp ./tmp/ctx-${{ env.VERSION }}-${{ matrix.platform.os }}-${{ matrix.platform.arch }} ./docker/ctx
132+
133+ # Create Dockerfile for Alpine
134+ cat > ./docker/Dockerfile << 'EOF'
135+ FROM alpine:3.21
136+
137+ # Install dependencies
138+ RUN apk add --no-cache libstdc++ libgcc
139+
140+ WORKDIR /app
141+
142+ COPY ctx /usr/local/bin/ctx
143+ RUN chmod +x /usr/local/bin/ctx
144+
145+ ENTRYPOINT ["ctx"]
146+ EOF
147+
148+ - name : Extract metadata for Docker Image
149+ id : docker-metadata
150+ uses : docker/metadata-action@v5
151+ with :
152+ images : ghcr.io/context-hub/ctx
153+
154+ - name : Login to GitHub Container Registry
155+ uses : docker/login-action@v3
156+ with :
157+ registry : ghcr.io
158+ username : ${{ secrets.GHCR_LOGIN }}
159+ password : ${{ secrets.GHCR_PASSWORD }}
160+
161+ - name : Build and push Docker image
162+ id : build
163+ uses : docker/build-push-action@v6
164+ with :
165+ context : ./docker
166+ push : true
167+ tags : ghcr.io/context-hub/ctx
168+ labels : ${{ steps.docker-metadata.outputs.labels }}
169+ platforms : linux/${{ matrix.platform.arch }}
170+ outputs : type=image,push-by-digest=true,name-canonical=true,push=true
171+
172+ - name : Export digest
173+ run : |
174+ mkdir -p ${{ runner.temp }}/digests
175+ digest="${{ steps.build.outputs.digest }}"
176+ touch "${{ runner.temp }}/digests/${digest#sha256:}"
177+
178+ - name : Upload digest
179+ uses : actions/upload-artifact@v4
180+ with :
181+ name : digests-${{ matrix.platform.arch }}
182+ path : ${{ runner.temp }}/digests/*
183+ if-no-files-found : error
184+ retention-days : 1
185+
186+ merge :
187+ runs-on : ubuntu-latest
188+ needs :
189+ - build-alpine-docker
190+ steps :
191+ - name : Download digests
192+ uses : actions/download-artifact@v4
193+ with :
194+ path : ${{ runner.temp }}/digests
195+ pattern : digests-*
196+ merge-multiple : true
197+
198+ - name : Login to Docker Hub
199+ uses : docker/login-action@v3
200+ with :
201+ registry : ghcr.io
202+ username : ${{ secrets.GHCR_LOGIN }}
203+ password : ${{ secrets.GHCR_PASSWORD }}
204+
205+ - name : Set up Docker Buildx
206+ uses : docker/setup-buildx-action@v3
207+
208+ - name : Docker meta
209+ id : meta
210+ uses : docker/metadata-action@v5
211+ with :
212+ images : ghcr.io/context-hub/ctx
213+ tags : |
214+ type=ref,event=branch
215+ type=ref,event=pr
216+ type=semver,pattern={{version}}
217+ type=raw,value=latest
218+
219+ - name : Create manifest list and push
220+ working-directory : ${{ runner.temp }}/digests
221+ run : |
222+ docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
223+ $(printf 'ghcr.io/context-hub/ctx@sha256:%s ' *)
224+
225+ - name : Inspect image
226+ run : |
227+ docker buildx imagetools inspect ghcr.io/context-hub/ctx:${{ steps.meta.outputs.version }}
0 commit comments