Skip to content

Commit 16d3578

Browse files
committed
chore: add ci/cd
Signed-off-by: azjezz <[email protected]>
1 parent cd4530c commit 16d3578

File tree

39 files changed

+496
-82
lines changed

39 files changed

+496
-82
lines changed

.github/workflows/cd.yml

Lines changed: 351 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,351 @@
1+
name: Continuous Deployment
2+
3+
on:
4+
workflow_dispatch:
5+
pull_request:
6+
push:
7+
branches:
8+
- main
9+
tags:
10+
- "*"
11+
12+
env:
13+
CICD_INTERMEDIATES_DIR: "_cd-intermediates"
14+
15+
jobs:
16+
crate_metadata:
17+
name: extract crate metadata
18+
runs-on: ubuntu-latest
19+
steps:
20+
- uses: actions/checkout@v4
21+
- name: extract crate information
22+
id: crate_metadata
23+
run: |
24+
cargo metadata --no-deps --format-version 1 | jq -r '
25+
.packages[0] |
26+
[
27+
"version=" + .version,
28+
"maintainer=" + (.authors[0] // ""),
29+
"homepage=" + (.homepage // ""),
30+
"msrv=" + (.rust_version // "")
31+
] |
32+
join("\n")
33+
' | tee -a $GITHUB_OUTPUT
34+
outputs:
35+
name: "mago"
36+
bin-name: "mago"
37+
version: ${{ steps.crate_metadata.outputs.version }}
38+
maintainer: ${{ steps.crate_metadata.outputs.maintainer }}
39+
homepage: ${{ steps.crate_metadata.outputs.homepage }}
40+
msrv: ${{ steps.crate_metadata.outputs.msrv }}
41+
42+
ensure_cargo_fmt:
43+
name: Ensure 'cargo fmt' has been run
44+
runs-on: ubuntu-20.04
45+
steps:
46+
- uses: dtolnay/rust-toolchain@stable
47+
with:
48+
components: rustfmt
49+
- uses: actions/checkout@v4
50+
- run: cargo fmt -- --check
51+
52+
min_version:
53+
name: Minimum supported rust version
54+
runs-on: ubuntu-20.04
55+
needs: crate_metadata
56+
steps:
57+
- name: Checkout source code
58+
uses: actions/checkout@v4
59+
60+
- name: Install rust toolchain (v${{ needs.crate_metadata.outputs.msrv }})
61+
uses: dtolnay/rust-toolchain@master
62+
with:
63+
toolchain: ${{ needs.crate_metadata.outputs.msrv }}
64+
- name: Run tests
65+
run: cargo test --workspace --locked --all-targets
66+
67+
build:
68+
name: ${{ matrix.job.target }} (${{ matrix.job.os }})
69+
runs-on: ${{ matrix.job.os }}
70+
needs: crate_metadata
71+
strategy:
72+
fail-fast: false
73+
matrix:
74+
job:
75+
# Windows
76+
- { target: x86_64-pc-windows-msvc, os: windows-2019 }
77+
# macOS
78+
- { target: aarch64-apple-darwin, os: macos-15 }
79+
- { target: x86_64-apple-darwin, os: macos-13 }
80+
# Linux with cross
81+
- {
82+
target: aarch64-unknown-linux-gnu,
83+
os: ubuntu-20.04,
84+
use-cross: true,
85+
}
86+
- {
87+
target: arm-unknown-linux-gnueabihf,
88+
os: ubuntu-20.04,
89+
use-cross: true,
90+
}
91+
- {
92+
target: arm-unknown-linux-musleabihf,
93+
os: ubuntu-20.04,
94+
use-cross: true,
95+
}
96+
- {
97+
target: x86_64-unknown-linux-gnu,
98+
os: ubuntu-20.04,
99+
use-cross: true,
100+
}
101+
- {
102+
target: x86_64-unknown-linux-musl,
103+
os: ubuntu-20.04,
104+
use-cross: true,
105+
}
106+
107+
env:
108+
BUILD_CMD: cargo
109+
110+
steps:
111+
- name: checkout source code
112+
uses: actions/checkout@v4
113+
114+
- name: Determine tag version
115+
id: version
116+
shell: bash
117+
run: |
118+
CLEAN_TAG=${GITHUB_REF_NAME#v}
119+
echo "CLEAN_TAG=$CLEAN_TAG" >> $GITHUB_OUTPUT
120+
121+
- name: install prerequisites
122+
shell: bash
123+
run: |
124+
case ${{ matrix.job.target }} in
125+
arm-unknown-linux-*) sudo apt-get -y update && sudo apt-get -y install gcc-arm-linux-gnueabihf ;;
126+
aarch64-unknown-linux-gnu) sudo apt-get -y update && sudo apt-get -y install gcc-aarch64-linux-gnu ;;
127+
esac
128+
129+
- name: install Rust toolchain
130+
uses: dtolnay/rust-toolchain@stable
131+
with:
132+
targets: ${{ matrix.job.target }}
133+
134+
- name: install cross
135+
if: matrix.job.use-cross
136+
uses: taiki-e/install-action@v2
137+
with:
138+
tool: cross
139+
140+
- name: overwrite build command env variable (for cross)
141+
if: matrix.job.use-cross
142+
shell: bash
143+
run: echo "BUILD_CMD=cross" >> $GITHUB_ENV
144+
145+
- name: show version information (Rust, cargo, GCC)
146+
shell: bash
147+
run: |
148+
set -x
149+
gcc --version || true
150+
rustup -V
151+
rustup toolchain list
152+
rustup default
153+
cargo -V
154+
rustc -V
155+
156+
- name: build
157+
shell: bash
158+
run: $BUILD_CMD build --locked --release --target=${{ matrix.job.target }}
159+
160+
- name: set binary name
161+
id: bin
162+
shell: bash
163+
run: |
164+
EXE_suffix=""
165+
case ${{ matrix.job.target }} in
166+
*-pc-windows-*) EXE_suffix=".exe" ;;
167+
esac;
168+
169+
BIN_NAME="${{ needs.crate_metadata.outputs.bin-name }}${EXE_suffix}"
170+
BIN_PATH="target/${{ matrix.job.target }}/release/${BIN_NAME}"
171+
172+
echo "BIN_PATH=${BIN_PATH}" >> $GITHUB_OUTPUT
173+
echo "BIN_NAME=${BIN_NAME}" >> $GITHUB_OUTPUT
174+
175+
- name: set testing options
176+
id: test-options
177+
shell: bash
178+
run: |
179+
unset CARGO_TEST_OPTIONS
180+
case ${{ matrix.job.target }} in
181+
arm-* | aarch64-*)
182+
CARGO_TEST_OPTIONS="--bin ${{ steps.bin.outputs.BIN_NAME }}"
183+
;;
184+
esac;
185+
echo "CARGO_TEST_OPTIONS=${CARGO_TEST_OPTIONS}" >> $GITHUB_OUTPUT
186+
187+
- name: run tests
188+
shell: bash
189+
run: $BUILD_CMD test --locked --target=${{ matrix.job.target }} ${{ steps.test-options.outputs.CARGO_TEST_OPTIONS}}
190+
191+
# Build the WASM artifacts only for x86_64-unknown-linux-gnu
192+
- name: Install wasm-pack and build WASM
193+
if: matrix.job.target == 'x86_64-unknown-linux-gnu'
194+
run: |
195+
cargo install wasm-pack --version 0.13.1 --locked
196+
cd crates/wasm
197+
wasm-pack build --target web --no-typescript -d pkg --no-pack --release
198+
cd ../..
199+
WASM_STAGING="${{ env.CICD_INTERMEDIATES_DIR }}/wasm"
200+
mkdir -p "${WASM_STAGING}"
201+
cp crates/wasm/pkg/mago_wasm_bg.wasm crates/wasm/pkg/mago_wasm.js "${WASM_STAGING}/"
202+
203+
- name: create tarball (main binary)
204+
id: package
205+
shell: bash
206+
run: |
207+
CLEAN_TAG="${{ steps.version.outputs.CLEAN_TAG }}"
208+
TARGET="${{ matrix.job.target }}"
209+
PKG_SUFFIX=".tar.gz"
210+
case "$TARGET" in
211+
*-pc-windows-msvc) PKG_SUFFIX=".zip" ;;
212+
esac
213+
214+
# Transform target naming:
215+
# 1) remove "unknown-" substrings
216+
# 2) replace "pc-windows-msvc" with "windows"
217+
# 3) replace "x86_64" with "x86-64"
218+
SHORT_TARGET=$(echo "$TARGET" | sed 's/unknown-//g; s/pc-windows-msvc/windows/; s/x86_64/x86-64/')
219+
220+
PKG_NAME="mago-${CLEAN_TAG}-${SHORT_TARGET}${PKG_SUFFIX}"
221+
echo "PKG_NAME=${PKG_NAME}" >> $GITHUB_OUTPUT
222+
223+
PKG_STAGING="${{ env.CICD_INTERMEDIATES_DIR }}/package"
224+
ARCHIVE_DIR="${PKG_STAGING}/mago-${CLEAN_TAG}-${SHORT_TARGET}/"
225+
mkdir -p "${ARCHIVE_DIR}"
226+
227+
# Binary
228+
cp "${{ steps.bin.outputs.BIN_PATH }}" "$ARCHIVE_DIR"
229+
230+
# Docs and licenses
231+
cp "README.md" "LICENSE-MIT" "LICENSE-APACHE" "$ARCHIVE_DIR" || true
232+
233+
pushd "${PKG_STAGING}/" >/dev/null
234+
case "$PKG_SUFFIX" in
235+
.zip)
236+
7z -y a "${PKG_NAME}" "mago-${CLEAN_TAG}-${SHORT_TARGET}/*"
237+
;;
238+
.tar.gz)
239+
tar czf "${PKG_NAME}" "mago-${CLEAN_TAG}-${SHORT_TARGET}"/*
240+
;;
241+
esac
242+
popd >/dev/null
243+
244+
echo "PKG_PATH=${PKG_STAGING}/${PKG_NAME}" >> $GITHUB_OUTPUT
245+
246+
- name: create WASM tarball
247+
id: wasm_package
248+
if: matrix.job.target == 'x86_64-unknown-linux-gnu'
249+
shell: bash
250+
run: |
251+
CLEAN_TAG="${{ steps.version.outputs.CLEAN_TAG }}"
252+
# Since WASM is universal, just name it 'mago-{CLEAN_TAG}-wasm.tar.gz'
253+
WASM_PKG_NAME="mago-${CLEAN_TAG}-wasm.tar.gz"
254+
echo "WASM_PKG_NAME=${WASM_PKG_NAME}" >> $GITHUB_OUTPUT
255+
256+
WASM_STAGING="${{ env.CICD_INTERMEDIATES_DIR }}/wasm"
257+
pushd "${WASM_STAGING}" >/dev/null
258+
tar czf "${WASM_PKG_NAME}" mago_wasm_bg.wasm mago_wasm.js
259+
popd >/dev/null
260+
261+
echo "WASM_PKG_PATH=${WASM_STAGING}/${WASM_PKG_NAME}" >> $GITHUB_OUTPUT
262+
263+
- name: create Debian package
264+
id: debian-package
265+
shell: bash
266+
if: startsWith(matrix.job.os, 'ubuntu')
267+
run: |
268+
CLEAN_TAG="${{ steps.version.outputs.CLEAN_TAG }}"
269+
TARGET="${{ matrix.job.target }}"
270+
271+
# Derive arch from target:
272+
case "$TARGET" in
273+
*x86_64*) DPKG_ARCH="amd64" ;;
274+
*i686*) DPKG_ARCH="i686" ;;
275+
*aarch64*|*arm64*) DPKG_ARCH="arm64" ;;
276+
*arm*hf*) DPKG_ARCH="armhf" ;;
277+
esac
278+
279+
# Check if musl in target
280+
if [[ "$TARGET" == *"musl"* ]]; then
281+
DPKG_NAME="mago-${CLEAN_TAG}-musl-${DPKG_ARCH}.deb"
282+
else
283+
DPKG_NAME="mago-${CLEAN_TAG}-${DPKG_ARCH}.deb"
284+
fi
285+
286+
echo "DPKG_NAME=${DPKG_NAME}" >> $GITHUB_OUTPUT
287+
288+
DPKG_STAGING="${{ env.CICD_INTERMEDIATES_DIR }}/debian-package"
289+
DPKG_DIR="${DPKG_STAGING}/dpkg"
290+
mkdir -p "${DPKG_DIR}"
291+
292+
install -Dm755 "${{ steps.bin.outputs.BIN_PATH }}" "${DPKG_DIR}/usr/bin/${{ steps.bin.outputs.BIN_NAME }}"
293+
294+
install -Dm644 "README.md" "${DPKG_DIR}/usr/share/doc/mago/README.md" || true
295+
install -Dm644 "LICENSE-MIT" "${DPKG_DIR}/usr/share/doc/mago/LICENSE-MIT" || true
296+
install -Dm644 "LICENSE-APACHE" "${DPKG_DIR}/usr/share/doc/mago/LICENSE-APACHE" || true
297+
298+
mkdir -p "${DPKG_DIR}/DEBIAN"
299+
cat > "${DPKG_DIR}/DEBIAN/control" <<EOF
300+
Package: mago
301+
Version: ${CLEAN_TAG}
302+
Section: utils
303+
Priority: optional
304+
Maintainer: ${{ needs.crate_metadata.outputs.maintainer }}
305+
Homepage: ${{ needs.crate_metadata.outputs.homepage }}
306+
Architecture: ${DPKG_ARCH}
307+
Description: A command-line benchmarking tool
308+
EOF
309+
310+
DPKG_PATH="${DPKG_STAGING}/${DPKG_NAME}"
311+
echo "DPKG_PATH=${DPKG_PATH}" >> $GITHUB_OUTPUT
312+
313+
fakeroot dpkg-deb --build "${DPKG_DIR}" "${DPKG_PATH}"
314+
315+
- name: "Artifact upload: tarball"
316+
uses: actions/upload-artifact@v3
317+
with:
318+
name: ${{ steps.package.outputs.PKG_NAME }}
319+
path: ${{ steps.package.outputs.PKG_PATH }}
320+
321+
- name: "Artifact upload: WASM"
322+
if: matrix.job.target == 'x86_64-unknown-linux-gnu' && steps.wasm_package.outputs.WASM_PKG_NAME
323+
uses: actions/upload-artifact@v3
324+
with:
325+
name: ${{ steps.wasm_package.outputs.WASM_PKG_NAME }}
326+
path: ${{ steps.wasm_package.outputs.WASM_PKG_PATH }}
327+
328+
- name: "Artifact upload: Debian package"
329+
uses: actions/upload-artifact@v3
330+
if: steps.debian-package.outputs.DPKG_NAME
331+
with:
332+
name: ${{ steps.debian-package.outputs.DPKG_NAME }}
333+
path: ${{ steps.debian-package.outputs.DPKG_PATH }}
334+
335+
- name: check for release
336+
id: is-release
337+
shell: bash
338+
run: |
339+
unset IS_RELEASE ; if [[ $GITHUB_REF =~ ^refs/tags/[0-9].* ]]; then IS_RELEASE='true' ; fi
340+
echo "IS_RELEASE=${IS_RELEASE}" >> $GITHUB_OUTPUT
341+
342+
- name: publish archives and packages
343+
uses: softprops/action-gh-release@v2
344+
if: steps.is-release.outputs.IS_RELEASE
345+
with:
346+
files: |
347+
${{ steps.package.outputs.PKG_PATH }}
348+
${{ steps.debian-package.outputs.DPKG_PATH }}
349+
${{ steps.wasm_package.outputs.WASM_PKG_PATH }}
350+
env:
351+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/ci.yml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,8 @@ jobs:
1010
strategy:
1111
fail-fast: false
1212
matrix:
13-
os: [ubuntu-latest, macos-latest, windows-latest]
13+
os: [ubuntu-latest]
1414
rust: [stable, nightly]
15-
exclude:
16-
- os: macos-latest
17-
rust: nightly
18-
- os: windows-latest
19-
rust: nightly
2015

2116
runs-on: ${{ matrix.os }}
2217

@@ -46,5 +41,4 @@ jobs:
4641
run: cargo test --workspace --locked --all-targets
4742

4843
- name: cargo build
49-
run: |
50-
cargo build --workspace --release --locked --all-targets
44+
run: cargo build --workspace --release --locked --all-targets

0 commit comments

Comments
 (0)