Skip to content

Commit bfc085f

Browse files
authored
Merge pull request #3 from terraphim/task/release-binaries-v1.20.5
feat(ci): release-binaries for terraphim-ai v1.20.5
2 parents 50285ad + d5dcf15 commit bfc085f

7 files changed

Lines changed: 296 additions & 4 deletions

File tree

.cargo/config.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
[registry]
22
global-credential-providers = ["cargo:token"]
33

4+
[registries.terraphim]
5+
index = "sparse+https://git.terraphim.cloud/api/packages/terraphim/cargo/"
6+
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
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+
- os: [self-hosted, bigbox]
34+
target: x86_64-unknown-linux-gnu
35+
use_cross: false
36+
- os: [self-hosted, bigbox]
37+
target: x86_64-unknown-linux-musl
38+
use_cross: true
39+
- os: [self-hosted, bigbox]
40+
target: aarch64-unknown-linux-musl
41+
use_cross: true
42+
- os: [self-hosted, macOS]
43+
target: x86_64-apple-darwin
44+
use_cross: false
45+
- os: [self-hosted, macOS]
46+
target: aarch64-apple-darwin
47+
use_cross: false
48+
- os: windows-latest
49+
target: x86_64-pc-windows-msvc
50+
use_cross: false
51+
runs-on: ${{ matrix.os }}
52+
steps:
53+
- uses: actions/checkout@v4
54+
- uses: dtolnay/rust-toolchain@stable
55+
with:
56+
targets: ${{ matrix.target }}
57+
- name: Install zig
58+
if: contains(matrix.target, 'apple-darwin') || contains(matrix.target, 'windows')
59+
shell: bash
60+
run: |
61+
if command -v zig &>/dev/null; then exit 0; fi
62+
if command -v brew &>/dev/null; then brew install zig; fi
63+
if command -v choco &>/dev/null; then choco install zig -y; fi
64+
- name: Install cross
65+
if: matrix.use_cross
66+
run: cargo install cross
67+
- uses: Swatinem/rust-cache@v2
68+
if: matrix.target != 'x86_64-unknown-linux-gnu'
69+
with:
70+
key: clients-${{ matrix.target }}
71+
- name: Build client binaries
72+
env:
73+
CARGO_REGISTRIES_TERRAPHIM_TOKEN: ${{ secrets.CARGO_REGISTRIES_TERRAPHIM_TOKEN }}
74+
run: |
75+
BUILD="${{ matrix.use_cross && 'cross' || 'cargo' }}"
76+
$BUILD build --release --target ${{ matrix.target }} -p terraphim_agent --bin terraphim-agent
77+
$BUILD build --release --target ${{ matrix.target }} -p terraphim_cli --bin terraphim-cli
78+
$BUILD build --release --target ${{ matrix.target }} -p terraphim_grep --bin terraphim-grep --features "code-search openrouter"
79+
- name: Package artifacts (Unix)
80+
if: matrix.os != 'windows-latest'
81+
env:
82+
VERSION: ${{ inputs.version }}
83+
run: |
84+
mkdir -p artifacts
85+
tar -czf "artifacts/terraphim-agent-${VERSION}-${{ matrix.target }}.tar.gz" -C "target/${{ matrix.target }}/release" terraphim-agent
86+
tar -czf "artifacts/terraphim-cli-${VERSION}-${{ matrix.target }}.tar.gz" -C "target/${{ matrix.target }}/release" terraphim-cli
87+
tar -czf "artifacts/terraphim-grep-${VERSION}-${{ matrix.target }}.tar.gz" -C "target/${{ matrix.target }}/release" terraphim-grep
88+
cp target/${{ matrix.target }}/release/terraphim-agent artifacts/terraphim-agent-${{ matrix.target }}
89+
cp target/${{ matrix.target }}/release/terraphim-cli artifacts/terraphim-cli-${{ matrix.target }}
90+
cp target/${{ matrix.target }}/release/terraphim-grep artifacts/terraphim-grep-${{ matrix.target }}
91+
chmod +x artifacts/*
92+
- name: Package artifacts (Windows)
93+
if: matrix.os == 'windows-latest'
94+
shell: bash
95+
env:
96+
VERSION: ${{ inputs.version }}
97+
run: |
98+
mkdir -p artifacts
99+
cd "target/${{ matrix.target }}/release"
100+
7z a -tzip "../../../artifacts/terraphim-agent-${VERSION}-${{ matrix.target }}.zip" terraphim-agent.exe
101+
7z a -tzip "../../../artifacts/terraphim-cli-${VERSION}-${{ matrix.target }}.zip" terraphim-cli.exe
102+
7z a -tzip "../../../artifacts/terraphim-grep-${VERSION}-${{ matrix.target }}.zip" terraphim-grep.exe
103+
cd -
104+
cp target/${{ matrix.target }}/release/terraphim-agent.exe artifacts/terraphim-agent-${{ matrix.target }}.exe
105+
cp target/${{ matrix.target }}/release/terraphim-cli.exe artifacts/terraphim-cli-${{ matrix.target }}.exe
106+
cp target/${{ matrix.target }}/release/terraphim-grep.exe artifacts/terraphim-grep-${{ matrix.target }}.exe
107+
- uses: actions/upload-artifact@v4
108+
with:
109+
name: client-binaries-${{ matrix.target }}
110+
path: artifacts/*
111+
112+
create-universal-macos:
113+
name: Create macOS universal client binaries
114+
needs: build-binaries
115+
if: always() && needs.build-binaries.result != 'cancelled'
116+
runs-on: [self-hosted, macOS]
117+
steps:
118+
- uses: actions/download-artifact@v4
119+
with:
120+
name: client-binaries-x86_64-apple-darwin
121+
path: x86_64
122+
- uses: actions/download-artifact@v4
123+
with:
124+
name: client-binaries-aarch64-apple-darwin
125+
path: aarch64
126+
- run: |
127+
mkdir -p universal
128+
lipo -create x86_64/terraphim-agent-x86_64-apple-darwin aarch64/terraphim-agent-aarch64-apple-darwin -output universal/terraphim-agent-universal-apple-darwin
129+
lipo -create x86_64/terraphim-grep-x86_64-apple-darwin aarch64/terraphim-grep-aarch64-apple-darwin -output universal/terraphim-grep-universal-apple-darwin
130+
chmod +x universal/*
131+
- uses: actions/upload-artifact@v4
132+
with:
133+
name: client-binaries-universal-apple-darwin
134+
path: universal/*
135+
136+
sign-and-notarize-macos:
137+
name: Sign and notarize macOS client binaries
138+
needs: create-universal-macos
139+
if: always() && needs.create-universal-macos.result == 'success'
140+
runs-on: [self-hosted, macOS]
141+
steps:
142+
- uses: actions/checkout@v4
143+
- uses: actions/download-artifact@v4
144+
with:
145+
name: client-binaries-universal-apple-darwin
146+
path: universal
147+
- uses: 1password/install-cli-action@v2
148+
- name: Load signing credentials
149+
env:
150+
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
151+
run: |
152+
echo "APPLE_ID=$(op read 'op://TerraphimPlatform/apple.developer.credentials/username' --no-newline)" >> $GITHUB_ENV
153+
echo "APPLE_TEAM_ID=$(op read 'op://TerraphimPlatform/apple.developer.credentials/APPLE_TEAM_ID' --no-newline)" >> $GITHUB_ENV
154+
echo "APPLE_APP_PASSWORD=$(op read 'op://TerraphimPlatform/apple.developer.credentials/APPLE_APP_SPECIFIC_PASSWORD' --no-newline)" >> $GITHUB_ENV
155+
echo "CERT_BASE64=$(op read 'op://TerraphimPlatform/apple.developer.certificate/base64' --no-newline)" >> $GITHUB_ENV
156+
echo "CERT_PASSWORD=$(op read 'op://TerraphimPlatform/apple.developer.certificate/password' --no-newline)" >> $GITHUB_ENV
157+
- name: Sign and notarize agent and grep
158+
env:
159+
RUNNER_TEMP: ${{ runner.temp }}
160+
run: |
161+
chmod +x scripts/sign-macos-binary.sh
162+
./scripts/sign-macos-binary.sh universal/terraphim-agent-universal-apple-darwin "$APPLE_ID" "$APPLE_TEAM_ID" "$APPLE_APP_PASSWORD" "$CERT_BASE64" "$CERT_PASSWORD"
163+
./scripts/sign-macos-binary.sh universal/terraphim-grep-universal-apple-darwin "$APPLE_ID" "$APPLE_TEAM_ID" "$APPLE_APP_PASSWORD" "$CERT_BASE64" "$CERT_PASSWORD"
164+
- uses: actions/upload-artifact@v4
165+
with:
166+
name: client-binaries-signed-universal-apple-darwin
167+
path: universal/*
168+
169+
upload-to-target-release:
170+
name: Attach client binaries to terraphim-ai release
171+
needs: [build-binaries, sign-and-notarize-macos]
172+
if: always() && needs.build-binaries.result == 'success'
173+
runs-on: ubuntu-latest
174+
steps:
175+
- uses: actions/download-artifact@v4
176+
with:
177+
pattern: client-binaries*
178+
path: release-assets
179+
merge-multiple: true
180+
- name: Upload to target GitHub release
181+
env:
182+
GH_TOKEN: ${{ secrets.TERRAPHIM_AI_RELEASE_TOKEN || secrets.GITHUB_TOKEN }}
183+
run: |
184+
TAG="${{ inputs.release_tag }}"
185+
REPO="terraphim/${{ inputs.target_repo }}"
186+
find release-assets -type f | sort
187+
gh release upload "$TAG" release-assets/* --repo "$REPO" --clobber

Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ members = [
1414
]
1515

1616
[workspace.package]
17-
version = "1.20.4"
17+
version = "1.20.5"
1818
edition = "2024"
1919
authors = ["Terraphim Team <team@terraphim.ai>"]
2020
documentation = "https://terraphim.ai"
@@ -23,6 +23,9 @@ repository = "https://git.terraphim.cloud/terraphim/terraphim-clients"
2323
license = "Apache-2.0"
2424
readme = "README.md"
2525

26+
[patch.crates-io]
27+
terraphim_service = { version = "1.20.5", registry = "terraphim" }
28+
2629
[workspace.dependencies]
2730
tokio = { version = "1.0", features = ["full"] }
2831
reqwest = { version = "0.12", features = ["json", "rustls-tls"], default-features = false }

crates/terraphim_agent/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ terraphim_persistence = { version = "1.0.0" }
7474
terraphim_config = { version = "1.0.0" }
7575
terraphim_command_runtime = { path = "../terraphim_command_runtime", version = "0.1.0" }
7676
terraphim_automata = { version = "1.19.2" }
77-
terraphim_service = { version = "1.0.0", default-features = false }
77+
terraphim_service = { version = "1.20.5", default-features = false, registry = "terraphim" }
7878
terraphim_middleware = { version = "1.0.0" }
7979
terraphim_rolegraph = { version = "1.0.0" }
8080
terraphim_hooks = { path = "../terraphim_hooks", version = "1.0.0" }

crates/terraphim_cli/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ path = "src/main.rs"
1818

1919
[dependencies]
2020
# Core terraphim crates
21-
terraphim_service = { version = "1.0.0" }
21+
terraphim_service = { version = "1.20.5", registry = "terraphim" }
2222
terraphim_config = { version = "1.0.0" }
2323
terraphim_command_runtime = { path = "../terraphim_command_runtime", version = "0.1.0" }
2424
terraphim_types = { version = "1.0.0" }

crates/terraphim_grep/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ log.workspace = true
2828
terraphim_types = { version = "1.15.0" }
2929
terraphim_rolegraph = { version = "1.15.0" }
3030
terraphim_automata = { version = "1.19.2" }
31-
terraphim_service = { version = "1.16.15", optional = true }
31+
terraphim_service = { version = "1.20.5", optional = true, registry = "terraphim" }
3232
terraphim_config = { version = "1.15.0" }
3333

3434
fff-search = { version = "0.8.4", optional = true }

scripts/sign-macos-binary.sh

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
# Sign and notarize a macOS binary
5+
# Usage: ./sign-macos-binary.sh <binary_path> <apple_id> <team_id> <app_password> <cert_base64> <cert_password>
6+
7+
# Parameters passed from workflow (not hardcoded secrets)
8+
BINARY_PATH="$1"
9+
APPLE_ID="$2"
10+
TEAM_ID="$3"
11+
APP_PASS="$4"
12+
CERT_BASE64="$5"
13+
CERT_PASS="$6"
14+
15+
echo "==> Signing and notarizing: $(basename "$BINARY_PATH")"
16+
17+
# Create temporary keychain
18+
KEYCHAIN_PATH="$RUNNER_TEMP/signing.keychain-db"
19+
KEYCHAIN_PASS=$(openssl rand -base64 32)
20+
21+
echo "==> Creating temporary keychain"
22+
security create-keychain -p "$KEYCHAIN_PASS" "$KEYCHAIN_PATH"
23+
security set-keychain-settings -lut 21600 "$KEYCHAIN_PATH"
24+
security unlock-keychain -p "$KEYCHAIN_PASS" "$KEYCHAIN_PATH"
25+
26+
# Import certificate
27+
echo "==> Importing certificate"
28+
CERT_PATH="$RUNNER_TEMP/certificate.p12"
29+
# Remove newlines from base64 before decoding (macOS base64 is strict)
30+
echo "$CERT_BASE64" | tr -d '\n' | base64 --decode > "$CERT_PATH"
31+
32+
security import "$CERT_PATH" \
33+
-k "$KEYCHAIN_PATH" \
34+
-P "$CERT_PASS" \
35+
-T /usr/bin/codesign \
36+
-T /usr/bin/security
37+
38+
# Set key partition list to allow codesign to access the key
39+
security set-key-partition-list \
40+
-S apple-tool:,apple: \
41+
-s -k "$KEYCHAIN_PASS" \
42+
"$KEYCHAIN_PATH"
43+
44+
# Add keychain to search list
45+
security list-keychains -d user -s "$KEYCHAIN_PATH" $(security list-keychains -d user | sed s/\"//g)
46+
47+
# Find signing identity
48+
SIGNING_IDENTITY=$(security find-identity -v -p codesigning "$KEYCHAIN_PATH" | grep "Developer ID Application" | head -1 | awk -F'"' '{print $2}')
49+
echo "==> Found signing identity: $SIGNING_IDENTITY"
50+
51+
# Sign the binary
52+
echo "==> Signing binary"
53+
codesign \
54+
--sign "$SIGNING_IDENTITY" \
55+
--options runtime \
56+
--timestamp \
57+
--verbose \
58+
"$BINARY_PATH"
59+
60+
# Verify signature
61+
echo "==> Verifying signature"
62+
codesign --verify --deep --strict --verbose=2 "$BINARY_PATH"
63+
64+
# Create ZIP for notarization
65+
ZIP_PATH="${BINARY_PATH}.zip"
66+
echo "==> Creating ZIP for notarization"
67+
ditto -c -k --keepParent "$BINARY_PATH" "$ZIP_PATH"
68+
69+
# Submit for notarization
70+
echo "==> Submitting for notarization"
71+
xcrun notarytool submit "$ZIP_PATH" \
72+
--apple-id "$APPLE_ID" \
73+
--team-id "$TEAM_ID" \
74+
--password "$APP_PASS" \
75+
--wait
76+
77+
# Check notarization status
78+
echo "==> Checking notarization status"
79+
SUBMISSION_ID=$(xcrun notarytool history \
80+
--apple-id "$APPLE_ID" \
81+
--team-id "$TEAM_ID" \
82+
--password "$APP_PASS" \
83+
| grep -m1 "id:" | awk '{print $2}')
84+
85+
xcrun notarytool log "$SUBMISSION_ID" \
86+
--apple-id "$APPLE_ID" \
87+
--team-id "$TEAM_ID" \
88+
--password "$APP_PASS"
89+
90+
# Verify with spctl
91+
echo "==> Verifying Gatekeeper acceptance"
92+
spctl --assess --type execute --verbose "$BINARY_PATH" || true
93+
94+
# Cleanup
95+
echo "==> Cleaning up"
96+
rm -f "$CERT_PATH" "$ZIP_PATH"
97+
security delete-keychain "$KEYCHAIN_PATH" || true
98+
99+
echo "✅ Successfully signed and notarized: $(basename "$BINARY_PATH")"

0 commit comments

Comments
 (0)