Skip to content

Commit b8158b2

Browse files
committed
Add inference runtime workspace with CI and release automation
1 parent 666088a commit b8158b2

25 files changed

Lines changed: 4465 additions & 0 deletions

‎.cargo/config.toml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[alias]
2+
dev-clippy = "clippy --workspace --all-targets -- -D warnings"
3+
dev-test-fast = "nextest run"

‎.github/workflows/ci.yml‎

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
branches:
6+
- main
7+
paths:
8+
- ".cargo/config.toml"
9+
- "Cargo.toml"
10+
- "Cargo.lock"
11+
- "crates/**"
12+
- ".github/workflows/**"
13+
push:
14+
branches:
15+
- main
16+
paths:
17+
- ".cargo/config.toml"
18+
- "Cargo.toml"
19+
- "Cargo.lock"
20+
- "crates/**"
21+
- ".github/workflows/**"
22+
23+
permissions:
24+
contents: read
25+
26+
concurrency:
27+
group: ci-${{ github.workflow }}-${{ github.ref }}
28+
cancel-in-progress: true
29+
30+
jobs:
31+
fmt:
32+
name: Format
33+
runs-on: ubuntu-latest
34+
steps:
35+
- uses: actions/checkout@v5
36+
- uses: dtolnay/rust-toolchain@stable
37+
with:
38+
components: rustfmt
39+
- name: cargo fmt
40+
run: cargo fmt --all --check
41+
42+
clippy:
43+
name: Clippy
44+
runs-on: ubuntu-latest
45+
steps:
46+
- uses: actions/checkout@v5
47+
- uses: dtolnay/rust-toolchain@stable
48+
with:
49+
components: clippy
50+
- uses: Swatinem/rust-cache@v2
51+
with:
52+
workspaces: . -> target
53+
shared-key: ci
54+
cache-workspace-crates: true
55+
- name: cargo dev-clippy
56+
run: cargo dev-clippy
57+
58+
test:
59+
name: Nextest
60+
runs-on: ubuntu-latest
61+
steps:
62+
- uses: actions/checkout@v5
63+
- uses: dtolnay/rust-toolchain@stable
64+
- uses: taiki-e/install-action@nextest
65+
- uses: Swatinem/rust-cache@v2
66+
with:
67+
workspaces: . -> target
68+
shared-key: ci
69+
cache-workspace-crates: true
70+
- name: cargo dev-test-fast
71+
run: cargo dev-test-fast
72+
73+
build-smoke:
74+
name: Release build smoke (${{ matrix.os }})
75+
runs-on: ${{ matrix.os }}
76+
strategy:
77+
fail-fast: false
78+
matrix:
79+
os:
80+
- ubuntu-latest
81+
- macos-latest
82+
- windows-latest
83+
84+
steps:
85+
- uses: actions/checkout@v5
86+
- uses: dtolnay/rust-toolchain@stable
87+
- uses: Swatinem/rust-cache@v2
88+
with:
89+
workspaces: . -> target
90+
shared-key: ci-build-smoke-${{ matrix.os }}
91+
cache-workspace-crates: true
92+
93+
- name: Build release binary
94+
run: cargo build --release -p bitloops-inference
95+
96+
- name: Smoke test (Unix)
97+
if: runner.os != 'Windows'
98+
run: ./target/release/bitloops-inference --help >/dev/null
99+
100+
- name: Smoke test (Windows)
101+
if: runner.os == 'Windows'
102+
shell: pwsh
103+
run: |
104+
& "target/release/bitloops-inference.exe" --help | Out-Null

‎.github/workflows/release.yml‎

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*"
7+
8+
permissions:
9+
contents: read
10+
11+
concurrency:
12+
group: release-${{ github.ref }}
13+
cancel-in-progress: false
14+
15+
jobs:
16+
build:
17+
name: Build ${{ matrix.target }}
18+
runs-on: ${{ matrix.os }}
19+
strategy:
20+
fail-fast: false
21+
matrix:
22+
include:
23+
- os: macos-14
24+
target: aarch64-apple-darwin
25+
- os: macos-13
26+
target: x86_64-apple-darwin
27+
- os: ubuntu-latest
28+
target: x86_64-unknown-linux-musl
29+
- os: ubuntu-latest
30+
target: aarch64-unknown-linux-musl
31+
- os: windows-latest
32+
target: x86_64-pc-windows-msvc
33+
- os: windows-latest
34+
target: aarch64-pc-windows-msvc
35+
36+
steps:
37+
- uses: actions/checkout@v5
38+
39+
- uses: dtolnay/rust-toolchain@stable
40+
with:
41+
targets: ${{ matrix.target }}
42+
43+
- uses: Swatinem/rust-cache@v2
44+
with:
45+
workspaces: . -> target
46+
shared-key: release-${{ matrix.target }}
47+
cache-workspace-crates: true
48+
49+
- name: Install cross
50+
if: ${{ contains(matrix.target, 'unknown-linux-musl') }}
51+
run: cargo install cross --locked
52+
53+
- name: Install musl-tools
54+
if: contains(matrix.target, 'unknown-linux-musl')
55+
run: |
56+
sudo apt-get update
57+
sudo apt-get install -y musl-tools
58+
59+
- name: Install qemu for Linux arm64 smoke test
60+
if: matrix.target == 'aarch64-unknown-linux-musl'
61+
run: |
62+
sudo apt-get update
63+
sudo apt-get install -y qemu-user
64+
65+
- name: Configure Windows arm64 linker
66+
if: matrix.target == 'aarch64-pc-windows-msvc'
67+
shell: pwsh
68+
run: |
69+
"CARGO_TARGET_AARCH64_PC_WINDOWS_MSVC_LINKER=rust-lld" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
70+
71+
- name: Build (musl targets)
72+
if: ${{ contains(matrix.target, 'unknown-linux-musl') }}
73+
run: cross build --release -p bitloops-inference --target ${{ matrix.target }}
74+
75+
- name: Build (non-musl targets)
76+
if: ${{ !contains(matrix.target, 'unknown-linux-musl') }}
77+
run: cargo build --release -p bitloops-inference --target ${{ matrix.target }}
78+
79+
- name: Smoke test (Unix)
80+
if: runner.os != 'Windows' && matrix.target != 'aarch64-unknown-linux-musl'
81+
run: ./target/${{ matrix.target }}/release/bitloops-inference --help >/dev/null
82+
83+
- name: Smoke test (Linux arm64 via qemu)
84+
if: matrix.target == 'aarch64-unknown-linux-musl'
85+
run: qemu-aarch64 ./target/${{ matrix.target }}/release/bitloops-inference --help >/dev/null
86+
87+
- name: Smoke test (Windows)
88+
if: matrix.target == 'x86_64-pc-windows-msvc'
89+
shell: pwsh
90+
run: |
91+
& "target/${{ matrix.target }}/release/bitloops-inference.exe" --help | Out-Null
92+
93+
- name: Validate Windows arm64 build output
94+
if: matrix.target == 'aarch64-pc-windows-msvc'
95+
shell: pwsh
96+
run: |
97+
$exe = "target/${{ matrix.target }}/release/bitloops-inference.exe"
98+
if (-not (Test-Path $exe)) {
99+
throw "Missing expected binary: $exe"
100+
}
101+
102+
- name: Import Apple signing certificate
103+
if: runner.os == 'macOS'
104+
env:
105+
APPLE_CERT_P12_BASE64: ${{ secrets.APPLE_CERT_P12_BASE64 }}
106+
APPLE_CERT_PASSWORD: ${{ secrets.APPLE_CERT_PASSWORD }}
107+
run: |
108+
echo "$APPLE_CERT_P12_BASE64" | base64 --decode > apple-cert.p12
109+
110+
security create-keychain -p temp123 build.keychain
111+
security default-keychain -s build.keychain
112+
security unlock-keychain -p temp123 build.keychain
113+
security set-keychain-settings -lut 21600 build.keychain
114+
115+
security import apple-cert.p12 \
116+
-k build.keychain \
117+
-P "$APPLE_CERT_PASSWORD" \
118+
-T /usr/bin/codesign \
119+
-T /usr/bin/security
120+
121+
security set-key-partition-list \
122+
-S apple-tool:,apple: \
123+
-s \
124+
-k temp123 \
125+
build.keychain
126+
127+
- name: Sign macOS binary
128+
if: runner.os == 'macOS'
129+
env:
130+
APPLE_SIGNING_IDENTITY: ${{ vars.APPLE_SIGNING_IDENTITY }}
131+
run: |
132+
codesign --force --options runtime --timestamp \
133+
--sign "$APPLE_SIGNING_IDENTITY" \
134+
"target/${{ matrix.target }}/release/bitloops-inference"
135+
136+
- name: Verify macOS signature
137+
if: runner.os == 'macOS'
138+
run: |
139+
codesign --verify --verbose=4 "target/${{ matrix.target }}/release/bitloops-inference"
140+
codesign --display --verbose=4 "target/${{ matrix.target }}/release/bitloops-inference"
141+
spctl -a -t exec -vv "target/${{ matrix.target }}/release/bitloops-inference" || true
142+
143+
- name: Package (Linux)
144+
if: runner.os == 'Linux'
145+
run: |
146+
mkdir -p dist/package
147+
cp "target/${{ matrix.target }}/release/bitloops-inference" dist/package/bitloops-inference
148+
tar -C dist/package -czf "dist/bitloops-inference-${{ matrix.target }}.tar.gz" bitloops-inference
149+
150+
- name: Package (macOS)
151+
if: runner.os == 'macOS'
152+
run: |
153+
mkdir -p dist/package
154+
cp "target/${{ matrix.target }}/release/bitloops-inference" dist/package/bitloops-inference
155+
ditto -c -k --keepParent dist/package "dist/bitloops-inference-${{ matrix.target }}.zip"
156+
157+
- name: Restore App Store Connect key
158+
if: runner.os == 'macOS'
159+
env:
160+
APPSTORE_CONNECT_API_KEY_P8_BASE64: ${{ secrets.APPSTORE_CONNECT_API_KEY_P8_BASE64 }}
161+
run: |
162+
echo "$APPSTORE_CONNECT_API_KEY_P8_BASE64" | base64 --decode > AuthKey.p8
163+
164+
- name: Notarise macOS archive
165+
if: runner.os == 'macOS'
166+
env:
167+
APPSTORE_CONNECT_KEY_ID: ${{ vars.APPSTORE_CONNECT_KEY_ID }}
168+
APPSTORE_CONNECT_ISSUER_ID: ${{ vars.APPSTORE_CONNECT_ISSUER_ID }}
169+
run: |
170+
xcrun notarytool submit "dist/bitloops-inference-${{ matrix.target }}.zip" \
171+
--key AuthKey.p8 \
172+
--key-id "$APPSTORE_CONNECT_KEY_ID" \
173+
--issuer "$APPSTORE_CONNECT_ISSUER_ID" \
174+
--wait
175+
176+
- name: Package (Windows)
177+
if: runner.os == 'Windows'
178+
shell: pwsh
179+
run: |
180+
New-Item -ItemType Directory -Path dist/package -Force | Out-Null
181+
Copy-Item "target/${{ matrix.target }}/release/bitloops-inference.exe" "dist/package/bitloops-inference.exe" -Force
182+
Compress-Archive -Path dist/package/* -DestinationPath "dist/bitloops-inference-${{ matrix.target }}.zip"
183+
184+
- name: Upload build artefact
185+
uses: actions/upload-artifact@v4
186+
with:
187+
name: release-${{ matrix.target }}
188+
path: dist/bitloops-inference-${{ matrix.target }}.*
189+
190+
publish:
191+
name: Publish release
192+
runs-on: ubuntu-latest
193+
needs: build
194+
permissions:
195+
contents: write
196+
env:
197+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
198+
steps:
199+
- name: Download packaged artefacts
200+
uses: actions/download-artifact@v4
201+
with:
202+
path: dist
203+
merge-multiple: true
204+
205+
- name: Generate checksums
206+
run: |
207+
cd dist
208+
sha256sum bitloops-inference-* > checksums-sha256.txt
209+
210+
- name: Publish to GitHub Releases
211+
uses: softprops/action-gh-release@v2
212+
with:
213+
generate_release_notes: true
214+
files: |
215+
dist/bitloops-inference-*
216+
dist/checksums-sha256.txt
217+
218+
- name: Send Slack notification
219+
if: env.SLACK_WEBHOOK_URL != ''
220+
uses: slackapi/slack-github-action@v2.1.1
221+
with:
222+
webhook: ${{ env.SLACK_WEBHOOK_URL }}
223+
webhook-type: incoming-webhook
224+
payload: |
225+
text: "🚀 bitloops-inference ${{ github.ref_name }} has been released!"

0 commit comments

Comments
 (0)