1+ name : Release Client Binaries
2+
3+ on :
4+ workflow_dispatch :
5+ inputs :
6+ version :
7+ description : ' Release version without v prefix (e.g. 1.20.5)'
8+ required : true
9+ type : string
10+ release_tag :
11+ description : ' GitHub release tag (e.g. v1.20.5)'
12+ required : true
13+ type : string
14+ target_repo :
15+ description : ' GitHub repo to attach binaries to'
16+ required : false
17+ default : terraphim-ai
18+ type : string
19+
20+ permissions :
21+ contents : write
22+
23+ env :
24+ CARGO_TERM_COLOR : always
25+
26+ jobs :
27+ build-binaries :
28+ name : Build client binaries for ${{ matrix.target }}
29+ strategy :
30+ fail-fast : false
31+ matrix :
32+ include :
33+ # GitHub-hosted Linux: terraphim-ai self-hosted runners are repo-scoped.
34+ - os : ubuntu-22.04
35+ target : x86_64-unknown-linux-gnu
36+ use_cross : false
37+ - os : ubuntu-22.04
38+ target : x86_64-unknown-linux-musl
39+ use_cross : true
40+ - os : ubuntu-22.04
41+ target : aarch64-unknown-linux-musl
42+ use_cross : true
43+ - os : macos-latest
44+ target : x86_64-apple-darwin
45+ use_cross : false
46+ - os : macos-latest
47+ target : aarch64-apple-darwin
48+ use_cross : false
49+ - os : windows-latest
50+ target : x86_64-pc-windows-msvc
51+ use_cross : false
52+ runs-on : ${{ matrix.os }}
53+ env :
54+ CARGO_REGISTRIES_TERRAPHIM_TOKEN : ${{ secrets.CARGO_REGISTRIES_TERRAPHIM_TOKEN }}
55+ steps :
56+ - uses : actions/checkout@v4
57+ - uses : dtolnay/rust-toolchain@stable
58+ with :
59+ targets : ${{ matrix.target }}
60+ - name : Install zig
61+ if : contains(matrix.target, 'apple-darwin') || contains(matrix.target, 'windows')
62+ shell : bash
63+ run : |
64+ if command -v zig &>/dev/null; then exit 0; fi
65+ if command -v brew &>/dev/null; then brew install zig; fi
66+ if command -v choco &>/dev/null; then choco install zig -y; fi
67+ - name : Install cross
68+ if : matrix.use_cross
69+ run : |
70+ if command -v cross &>/dev/null; then
71+ cross --version
72+ exit 0
73+ fi
74+ rustup run stable cargo install cross --locked --git https://github.com/cross-rs/cross
75+ - uses : Swatinem/rust-cache@v2
76+ if : matrix.target != 'x86_64-unknown-linux-gnu'
77+ with :
78+ key : clients-${{ matrix.target }}
79+ - name : Build client binaries
80+ shell : bash
81+ run : |
82+ if [ "${{ matrix.use_cross }}" = "true" ]; then
83+ BUILD="rustup run stable cross"
84+ else
85+ BUILD="rustup run stable cargo"
86+ fi
87+ $BUILD build --release --target ${{ matrix.target }} -p terraphim_agent --bin terraphim-agent
88+ $BUILD build --release --target ${{ matrix.target }} -p terraphim-cli --bin terraphim-cli
89+ $BUILD build --release --target ${{ matrix.target }} -p terraphim_grep --bin terraphim-grep --features "code-search openrouter"
90+ - name : Package artifacts (Unix)
91+ if : matrix.os != 'windows-latest'
92+ env :
93+ VERSION : ${{ inputs.version }}
94+ run : |
95+ mkdir -p artifacts
96+ tar -czf "artifacts/terraphim-agent-${VERSION}-${{ matrix.target }}.tar.gz" -C "target/${{ matrix.target }}/release" terraphim-agent
97+ tar -czf "artifacts/terraphim-cli-${VERSION}-${{ matrix.target }}.tar.gz" -C "target/${{ matrix.target }}/release" terraphim-cli
98+ tar -czf "artifacts/terraphim-grep-${VERSION}-${{ matrix.target }}.tar.gz" -C "target/${{ matrix.target }}/release" terraphim-grep
99+ cp target/${{ matrix.target }}/release/terraphim-agent artifacts/terraphim-agent-${{ matrix.target }}
100+ cp target/${{ matrix.target }}/release/terraphim-cli artifacts/terraphim-cli-${{ matrix.target }}
101+ cp target/${{ matrix.target }}/release/terraphim-grep artifacts/terraphim-grep-${{ matrix.target }}
102+ chmod +x artifacts/*
103+ - name : Package artifacts (Windows)
104+ if : matrix.os == 'windows-latest'
105+ shell : bash
106+ env :
107+ VERSION : ${{ inputs.version }}
108+ run : |
109+ mkdir -p artifacts
110+ cd "target/${{ matrix.target }}/release"
111+ 7z a -tzip "../../../artifacts/terraphim-agent-${VERSION}-${{ matrix.target }}.zip" terraphim-agent.exe
112+ 7z a -tzip "../../../artifacts/terraphim-cli-${VERSION}-${{ matrix.target }}.zip" terraphim-cli.exe
113+ 7z a -tzip "../../../artifacts/terraphim-grep-${VERSION}-${{ matrix.target }}.zip" terraphim-grep.exe
114+ cd -
115+ cp target/${{ matrix.target }}/release/terraphim-agent.exe artifacts/terraphim-agent-${{ matrix.target }}.exe
116+ cp target/${{ matrix.target }}/release/terraphim-cli.exe artifacts/terraphim-cli-${{ matrix.target }}.exe
117+ cp target/${{ matrix.target }}/release/terraphim-grep.exe artifacts/terraphim-grep-${{ matrix.target }}.exe
118+ - uses : actions/upload-artifact@v4
119+ with :
120+ name : client-binaries-${{ matrix.target }}
121+ path : artifacts/*
122+
123+ create-universal-macos :
124+ name : Create macOS universal client binaries
125+ needs : build-binaries
126+ if : always() && needs.build-binaries.result != 'cancelled'
127+ runs-on : macos-latest
128+ steps :
129+ - uses : actions/download-artifact@v4
130+ with :
131+ name : client-binaries-x86_64-apple-darwin
132+ path : x86_64
133+ - uses : actions/download-artifact@v4
134+ with :
135+ name : client-binaries-aarch64-apple-darwin
136+ path : aarch64
137+ - run : |
138+ mkdir -p universal
139+ lipo -create x86_64/terraphim-agent-x86_64-apple-darwin aarch64/terraphim-agent-aarch64-apple-darwin -output universal/terraphim-agent-universal-apple-darwin
140+ lipo -create x86_64/terraphim-grep-x86_64-apple-darwin aarch64/terraphim-grep-aarch64-apple-darwin -output universal/terraphim-grep-universal-apple-darwin
141+ chmod +x universal/*
142+ - uses : actions/upload-artifact@v4
143+ with :
144+ name : client-binaries-universal-apple-darwin
145+ path : universal/*
146+
147+ sign-and-notarize-macos :
148+ name : Sign and notarize macOS client binaries
149+ needs : create-universal-macos
150+ if : always() && needs.create-universal-macos.result == 'success'
151+ runs-on : macos-latest
152+ steps :
153+ - uses : actions/checkout@v4
154+ - uses : actions/download-artifact@v4
155+ with :
156+ name : client-binaries-universal-apple-darwin
157+ path : universal
158+ - uses : 1password/install-cli-action@v2
159+ - name : Load signing credentials
160+ env :
161+ OP_SERVICE_ACCOUNT_TOKEN : ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
162+ run : |
163+ echo "APPLE_ID=$(op read 'op://TerraphimPlatform/apple.developer.credentials/username' --no-newline)" >> $GITHUB_ENV
164+ echo "APPLE_TEAM_ID=$(op read 'op://TerraphimPlatform/apple.developer.credentials/APPLE_TEAM_ID' --no-newline)" >> $GITHUB_ENV
165+ echo "APPLE_APP_PASSWORD=$(op read 'op://TerraphimPlatform/apple.developer.credentials/APPLE_APP_SPECIFIC_PASSWORD' --no-newline)" >> $GITHUB_ENV
166+ echo "CERT_BASE64=$(op read 'op://TerraphimPlatform/apple.developer.certificate/base64' --no-newline)" >> $GITHUB_ENV
167+ echo "CERT_PASSWORD=$(op read 'op://TerraphimPlatform/apple.developer.certificate/password' --no-newline)" >> $GITHUB_ENV
168+ - name : Sign and notarize agent and grep
169+ env :
170+ RUNNER_TEMP : ${{ runner.temp }}
171+ run : |
172+ chmod +x scripts/sign-macos-binary.sh
173+ ./scripts/sign-macos-binary.sh universal/terraphim-agent-universal-apple-darwin "$APPLE_ID" "$APPLE_TEAM_ID" "$APPLE_APP_PASSWORD" "$CERT_BASE64" "$CERT_PASSWORD"
174+ ./scripts/sign-macos-binary.sh universal/terraphim-grep-universal-apple-darwin "$APPLE_ID" "$APPLE_TEAM_ID" "$APPLE_APP_PASSWORD" "$CERT_BASE64" "$CERT_PASSWORD"
175+ - uses : actions/upload-artifact@v4
176+ with :
177+ name : client-binaries-signed-universal-apple-darwin
178+ path : universal/*
179+
180+ upload-to-target-release :
181+ name : Attach client binaries to terraphim-ai release
182+ needs : [build-binaries, sign-and-notarize-macos]
183+ # Attach when macOS sign succeeded; do not require full matrix (Windows is optional).
184+ if : >-
185+ always() &&
186+ !cancelled() &&
187+ needs.sign-and-notarize-macos.result == 'success' &&
188+ needs.build-binaries.result != 'cancelled'
189+ runs-on : ubuntu-latest
190+ steps :
191+ - uses : actions/download-artifact@v4
192+ with :
193+ pattern : client-binaries*
194+ path : release-assets
195+ merge-multiple : true
196+ - name : Upload to target GitHub release
197+ env :
198+ GH_TOKEN : ${{ secrets.TERRAPHIM_AI_RELEASE_TOKEN || secrets.GITHUB_TOKEN }}
199+ run : |
200+ TAG="${{ inputs.release_tag }}"
201+ REPO="terraphim/${{ inputs.target_repo }}"
202+ find release-assets -type f | sort
203+ gh release upload "$TAG" release-assets/* --repo "$REPO" --clobber
0 commit comments