Skip to content

Commit 573b6ae

Browse files
committed
feat: standardize CI/CD workflow to match zlib pattern
1 parent 6eaae9e commit 573b6ae

File tree

1 file changed

+216
-0
lines changed

1 file changed

+216
-0
lines changed

.github/workflows/wasm-ci.yml

Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
name: CI/CD Pipeline
2+
3+
on:
4+
push:
5+
branches: [ wasm ]
6+
tags: [ 'v*' ]
7+
pull_request:
8+
branches: [ wasm ]
9+
10+
jobs:
11+
test:
12+
name: Test Suite (Deno)
13+
runs-on: [self-hosted, docker, wasm, emscripten]
14+
container:
15+
image: ghcr.io/discere-os/wasm-builder:main-b23d443
16+
credentials:
17+
username: ${{ github.actor }}
18+
password: ${{ secrets.GITHUB_TOKEN }}
19+
20+
steps:
21+
- name: Checkout code
22+
uses: actions/checkout@v4
23+
24+
- name: Type check
25+
run: deno check src/lib/index.ts
26+
27+
- name: Build WASM modules with Meson
28+
run: deno task build:wasm
29+
30+
- name: Run Deno tests
31+
run: deno task test
32+
33+
- name: Run benchmarks
34+
run: deno task bench
35+
36+
- name: Upload build artifacts
37+
uses: actions/upload-artifact@v4
38+
with:
39+
name: wasm-modules
40+
path: |
41+
install/wasm/
42+
retention-days: 7
43+
44+
build:
45+
name: Build Distribution
46+
runs-on: [self-hosted, docker, wasm, emscripten]
47+
needs: test
48+
container:
49+
image: ghcr.io/discere-os/wasm-builder:main-b23d443
50+
credentials:
51+
username: ${{ github.actor }}
52+
password: ${{ secrets.GITHUB_TOKEN }}
53+
54+
steps:
55+
- name: Checkout code
56+
uses: actions/checkout@v4
57+
58+
- name: Build WASM modules
59+
run: deno task build:wasm
60+
61+
- name: Fix artifact permissions
62+
run: |
63+
# Ensure artifacts are readable by runner (files created as root in container)
64+
sudo chown -R $(id -u):$(id -g) install/ || chown -R $(id -u):$(id -g) install/
65+
chmod -R u+rw,go+r install/
66+
67+
- name: Generate WASM Build Summary
68+
run: |
69+
echo "# 📦 WASM Build Results" >> $GITHUB_STEP_SUMMARY
70+
echo "" >> $GITHUB_STEP_SUMMARY
71+
72+
# Build artifacts analysis
73+
if [[ -f "install/wasm/libffi-side.wasm" && -f "install/wasm/libffi-main" ]]; then
74+
SIDE_SIZE=$(stat -c%s "install/wasm/libffi-side.wasm" 2>/dev/null || stat -f%z "install/wasm/libffi-side.wasm")
75+
76+
echo "## File Sizes" >> $GITHUB_STEP_SUMMARY
77+
echo "| Module | Size |" >> $GITHUB_STEP_SUMMARY
78+
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
79+
echo "| SIDE_MODULE | $(numfmt --to=iec $SIDE_SIZE 2>/dev/null || echo "${SIDE_SIZE} bytes") |" >> $GITHUB_STEP_SUMMARY
80+
echo "" >> $GITHUB_STEP_SUMMARY
81+
else
82+
echo "⚠️ Build artifacts not found" >> $GITHUB_STEP_SUMMARY
83+
echo "" >> $GITHUB_STEP_SUMMARY
84+
fi
85+
86+
# Build environment info
87+
echo "## Build Environment" >> $GITHUB_STEP_SUMMARY
88+
echo "- **Emscripten**: \`$(emcc --version | head -n1 | cut -d' ' -f2)\`" >> $GITHUB_STEP_SUMMARY
89+
echo "- **Meson**: \`$(meson --version)\`" >> $GITHUB_STEP_SUMMARY
90+
echo "- **Deno**: \`$(deno --version | head -n1 | cut -d' ' -f2)\`" >> $GITHUB_STEP_SUMMARY
91+
echo "- **Runner**: \`$(uname -m)\` $(uname -s)" >> $GITHUB_STEP_SUMMARY
92+
echo "" >> $GITHUB_STEP_SUMMARY
93+
94+
- name: Upload dist artifacts
95+
uses: actions/upload-artifact@v4
96+
with:
97+
name: dist-package
98+
path: |
99+
install/
100+
retention-days: 7
101+
102+
deploy-cloudflare-release:
103+
name: Deploy Release to Cloudflare R2
104+
runs-on: [self-hosted, docker, wasm, emscripten]
105+
needs: [build]
106+
if: startsWith(github.ref, 'refs/tags/v')
107+
container:
108+
image: ghcr.io/discere-os/wasm-builder:main-b23d443
109+
credentials:
110+
username: ${{ github.actor }}
111+
password: ${{ secrets.GITHUB_TOKEN }}
112+
113+
steps:
114+
- name: Checkout code
115+
uses: actions/checkout@v4
116+
117+
- name: Download build artifacts
118+
uses: actions/download-artifact@v4
119+
with:
120+
name: dist-package
121+
path: ./install
122+
123+
- name: Set release version
124+
id: release-version
125+
run: echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
126+
127+
- name: Calculate SHA-256
128+
id: sha
129+
run: |
130+
WASM_FILE="install/wasm/libffi-side.wasm"
131+
SHA=$(sha256sum "$WASM_FILE" | awk '{print $1}')
132+
echo "sha=${SHA}" >> $GITHUB_OUTPUT
133+
echo "${SHA}" > "${WASM_FILE}.sha256"
134+
echo "🔒 SHA-256: ${SHA}"
135+
136+
- name: Deploy to Cloudflare R2
137+
run: |
138+
VERSION="${{ steps.release-version.outputs.VERSION }}"
139+
SHA="${{ steps.sha.outputs.sha }}"
140+
141+
# Deploy SIDE_MODULE to versioned path (immutable)
142+
wrangler r2 object put discere-os-wasm-production/libffi@${VERSION}/side.wasm \
143+
--remote \
144+
--file=install/wasm/libffi-side.wasm \
145+
--content-type=application/wasm \
146+
--cache-control="public, max-age=31536000, immutable"
147+
148+
# Deploy to SHA path (content-addressable)
149+
wrangler r2 object put discere-os-wasm-production/libffi@sha-${SHA:0:7}/side.wasm \
150+
--remote \
151+
--file=install/wasm/libffi-side.wasm \
152+
--content-type=application/wasm \
153+
--cache-control="public, max-age=31536000, immutable"
154+
env:
155+
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
156+
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
157+
158+
- name: Verify deployment
159+
run: |
160+
sleep 15
161+
VERSION="${{ steps.release-version.outputs.VERSION }}"
162+
curl -I "https://wasm.discere.cloud/libffi@${VERSION}/side.wasm" || exit 1
163+
echo "✅ Cloudflare R2 deployment verified"
164+
165+
deploy-cloudflare-snapshot:
166+
name: Deploy Snapshot to Cloudflare R2
167+
runs-on: [self-hosted, docker, wasm, emscripten]
168+
needs: [build]
169+
if: github.ref == 'refs/heads/wasm' && github.event_name == 'push'
170+
container:
171+
image: ghcr.io/discere-os/wasm-builder:main-b23d443
172+
credentials:
173+
username: ${{ github.actor }}
174+
password: ${{ secrets.GITHUB_TOKEN }}
175+
176+
steps:
177+
- name: Checkout code
178+
uses: actions/checkout@v4
179+
180+
- name: Download build artifacts
181+
uses: actions/download-artifact@v4
182+
with:
183+
name: dist-package
184+
path: ./install
185+
186+
- name: Set snapshot version
187+
id: version
188+
run: echo "VERSION=sha-$(echo $GITHUB_SHA | cut -c1-7)" >> $GITHUB_OUTPUT
189+
190+
- name: Calculate SHA-256 and generate metadata
191+
id: metadata
192+
run: |
193+
WASM_FILE="install/wasm/libffi-side.wasm"
194+
SHA=$(sha256sum "$WASM_FILE" | awk '{print $1}')
195+
SIZE=$(stat -c%s "$WASM_FILE")
196+
197+
echo "sha=${SHA}" >> $GITHUB_OUTPUT
198+
echo "size=${SIZE}" >> $GITHUB_OUTPUT
199+
echo "${SHA}" > "${WASM_FILE}.sha256"
200+
201+
echo "🔒 SHA-256: ${SHA}"
202+
echo "📦 Size: $((SIZE / 1024)) KB"
203+
204+
- name: Deploy snapshot to Cloudflare R2
205+
run: |
206+
VERSION="${{ steps.version.outputs.VERSION }}"
207+
208+
# Deploy SIDE_MODULE only (MAIN_MODULE for testing/NPM only)
209+
wrangler r2 object put discere-os-wasm-production/libffi@${VERSION}/side.wasm \
210+
--remote \
211+
--file=install/wasm/libffi-side.wasm \
212+
--content-type=application/wasm \
213+
--cache-control="public, max-age=31536000, immutable"
214+
env:
215+
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
216+
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}

0 commit comments

Comments
 (0)