Skip to content

Commit 54ddd90

Browse files
committed
ci(nestjs-trpc): add build script and simplify release workflow
Extract multi-platform Rust CLI build into scripts/build-cli.sh, simplify release.yml from 4 jobs to 2, add tag-triggered releases, add shellcheck linting for shell scripts, and scope git-cliff changelog to packages/nestjs-trpc changes only.
1 parent a5e991c commit 54ddd90

File tree

5 files changed

+338
-3
lines changed

5 files changed

+338
-3
lines changed

.github/workflows/release.yml

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
tags: ['v*']
6+
workflow_dispatch:
7+
inputs:
8+
dry_run:
9+
description: 'Dry run (skip publish)'
10+
type: boolean
11+
default: false
12+
13+
env:
14+
CARGO_TERM_COLOR: always
15+
RUST_BACKTRACE: 1
16+
17+
jobs:
18+
build-cli:
19+
strategy:
20+
fail-fast: false
21+
matrix:
22+
include:
23+
- { target: x86_64-apple-darwin, os: macos-13 }
24+
- { target: aarch64-apple-darwin, os: macos-14 }
25+
- { target: x86_64-unknown-linux-gnu, os: ubuntu-latest }
26+
- { target: aarch64-unknown-linux-gnu, os: ubuntu-latest }
27+
- { target: x86_64-pc-windows-msvc, os: windows-latest }
28+
29+
runs-on: ${{ matrix.os }}
30+
steps:
31+
- name: Checkout
32+
uses: actions/checkout@v4
33+
34+
- name: Setup Rust
35+
uses: actions-rust-lang/setup-rust-toolchain@v1
36+
with:
37+
toolchain: stable
38+
target: ${{ matrix.target }}
39+
cache-workspaces: packages/nestjs-trpc/cli -> target
40+
41+
- name: Install cross (Linux ARM64)
42+
if: matrix.target == 'aarch64-unknown-linux-gnu'
43+
run: cargo install cross --git https://github.com/cross-rs/cross
44+
45+
- name: Build CLI
46+
shell: bash
47+
run: ./scripts/build-cli.sh --target ${{ matrix.target }}
48+
49+
- name: Upload artifact
50+
uses: actions/upload-artifact@v4
51+
with:
52+
name: cli-${{ matrix.target }}
53+
path: packages/nestjs-trpc/native/${{ matrix.target }}/
54+
retention-days: 1
55+
56+
publish:
57+
needs: build-cli
58+
runs-on: ubuntu-latest
59+
permissions:
60+
contents: write
61+
id-token: write
62+
steps:
63+
- name: Checkout
64+
uses: actions/checkout@v4
65+
with:
66+
fetch-depth: 0
67+
68+
- name: Setup Bun
69+
uses: oven-sh/setup-bun@v2
70+
71+
- name: Setup Node.js
72+
uses: actions/setup-node@v4
73+
with:
74+
node-version: '20'
75+
registry-url: 'https://registry.npmjs.org'
76+
77+
- name: Install git-cliff
78+
uses: taiki-e/install-action@v2
79+
with:
80+
tool: git-cliff
81+
82+
- name: Install dependencies
83+
run: bun install --frozen-lockfile
84+
85+
- name: Build TypeScript
86+
run: bun run build
87+
88+
- name: Download all CLI binaries
89+
uses: actions/download-artifact@v4
90+
with:
91+
path: packages/nestjs-trpc/native/
92+
pattern: cli-*
93+
merge-multiple: true
94+
95+
- name: Verify binaries
96+
run: |
97+
for target in x86_64-apple-darwin aarch64-apple-darwin x86_64-unknown-linux-gnu aarch64-unknown-linux-gnu; do
98+
test -f "packages/nestjs-trpc/native/$target/nestjs-trpc" || { echo "Missing: $target"; exit 1; }
99+
done
100+
test -f "packages/nestjs-trpc/native/x86_64-pc-windows-msvc/nestjs-trpc.exe" || { echo "Missing: windows"; exit 1; }
101+
chmod +x packages/nestjs-trpc/native/x86_64-unknown-linux-gnu/nestjs-trpc
102+
packages/nestjs-trpc/native/x86_64-unknown-linux-gnu/nestjs-trpc --help
103+
104+
- name: Extract version from tag
105+
id: version
106+
run: |
107+
if [[ "$GITHUB_REF" == refs/tags/v* ]]; then
108+
VERSION="${GITHUB_REF#refs/tags/v}"
109+
else
110+
VERSION=$(jq -r '.version' packages/nestjs-trpc/package.json)
111+
fi
112+
echo "version=$VERSION" >> $GITHUB_OUTPUT
113+
echo "Version: $VERSION"
114+
115+
- name: Update package.json version
116+
working-directory: packages/nestjs-trpc
117+
run: npm version ${{ steps.version.outputs.version }} --no-git-tag-version
118+
119+
- name: Update Cargo.toml version
120+
run: |
121+
sed -i 's/^version = ".*"/version = "${{ steps.version.outputs.version }}"/' packages/nestjs-trpc/cli/Cargo.toml
122+
123+
- name: Generate changelog
124+
id: changelog
125+
run: |
126+
git-cliff --tag "v${{ steps.version.outputs.version }}" -o CHANGELOG.md
127+
git-cliff --unreleased --tag "v${{ steps.version.outputs.version }}" > RELEASE_NOTES.md
128+
129+
{
130+
echo 'changelog<<EOF'
131+
cat RELEASE_NOTES.md
132+
echo EOF
133+
} >> $GITHUB_OUTPUT
134+
135+
- name: Publish to npm
136+
if: ${{ github.event_name == 'push' || !inputs.dry_run }}
137+
working-directory: packages/nestjs-trpc
138+
run: npm publish --provenance --access public
139+
env:
140+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
141+
142+
- name: Publish to npm (dry run)
143+
if: ${{ github.event_name != 'push' && inputs.dry_run }}
144+
working-directory: packages/nestjs-trpc
145+
run: |
146+
echo "DRY RUN: Would publish to npm"
147+
npm pack
148+
149+
- name: Prepare release assets
150+
run: |
151+
mkdir -p release-assets
152+
cp packages/nestjs-trpc/native/x86_64-apple-darwin/nestjs-trpc release-assets/nestjs-trpc-macos-x64
153+
cp packages/nestjs-trpc/native/aarch64-apple-darwin/nestjs-trpc release-assets/nestjs-trpc-macos-arm64
154+
cp packages/nestjs-trpc/native/x86_64-unknown-linux-gnu/nestjs-trpc release-assets/nestjs-trpc-linux-x64
155+
cp packages/nestjs-trpc/native/aarch64-unknown-linux-gnu/nestjs-trpc release-assets/nestjs-trpc-linux-arm64
156+
cp packages/nestjs-trpc/native/x86_64-pc-windows-msvc/nestjs-trpc.exe release-assets/nestjs-trpc-windows-x64.exe
157+
158+
cd release-assets && sha256sum * > checksums.txt
159+
cat checksums.txt
160+
161+
- name: Create GitHub Release
162+
if: ${{ github.event_name == 'push' || !inputs.dry_run }}
163+
uses: softprops/action-gh-release@v2
164+
with:
165+
tag_name: v${{ steps.version.outputs.version }}
166+
name: v${{ steps.version.outputs.version }}
167+
body: ${{ steps.changelog.outputs.changelog }}
168+
draft: false
169+
prerelease: ${{ contains(steps.version.outputs.version, '-') }}
170+
files: |
171+
release-assets/nestjs-trpc-macos-x64
172+
release-assets/nestjs-trpc-macos-arm64
173+
release-assets/nestjs-trpc-linux-x64
174+
release-assets/nestjs-trpc-linux-arm64
175+
release-assets/nestjs-trpc-windows-x64.exe
176+
release-assets/checksums.txt
177+

cliff.toml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# git-cliff configuration
2+
# https://git-cliff.org/docs/configuration
3+
4+
[changelog]
5+
header = """
6+
# Changelog
7+
8+
All notable changes to this project will be documented in this file.
9+
10+
"""
11+
body = """
12+
{% if version %}\
13+
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
14+
{% else %}\
15+
## [Unreleased]
16+
{% endif %}\
17+
{% for group, commits in commits | group_by(attribute="group") %}
18+
### {{ group | striptags | trim | upper_first }}
19+
{% for commit in commits %}
20+
- {% if commit.scope %}**{{ commit.scope }}:** {% endif %}\
21+
{{ commit.message | upper_first }}\
22+
{% if commit.breaking %} (**BREAKING**){% endif %}\
23+
{% endfor %}
24+
{% endfor %}\n
25+
"""
26+
footer = """
27+
<!-- generated by git-cliff -->
28+
"""
29+
trim = true
30+
31+
[git]
32+
include_paths = ["packages/nestjs-trpc/**"]
33+
conventional_commits = true
34+
filter_unconventional = true
35+
split_commits = false
36+
commit_parsers = [
37+
{ message = "^feat", group = "Features" },
38+
{ message = "^fix", group = "Bug Fixes" },
39+
{ message = "^doc", group = "Documentation" },
40+
{ message = "^perf", group = "Performance" },
41+
{ message = "^refactor", group = "Refactor" },
42+
{ message = "^style", group = "Styling" },
43+
{ message = "^test", group = "Testing" },
44+
{ message = "^chore\\(release\\)", skip = true },
45+
{ message = "^chore\\(deps.*\\)", skip = true },
46+
{ message = "^chore\\(pr\\)", skip = true },
47+
{ message = "^chore\\(pull\\)", skip = true },
48+
{ message = "^chore|^ci", group = "Miscellaneous Tasks" },
49+
{ body = ".*security", group = "Security" },
50+
{ message = "^revert", group = "Revert" },
51+
]
52+
protect_breaking_commits = false
53+
filter_commits = false
54+
topo_order = false
55+
sort_commits = "oldest"
56+
57+
[bump]
58+
features_always_bump_minor = true
59+
breaking_always_bump_major = true

package.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,16 @@
55
"private": true,
66
"scripts": {
77
"build": "tsc -b -v packages",
8-
"changelog": "lerna-changelog",
8+
"changelog": "git-cliff -o CHANGELOG.md",
9+
"changelog:unreleased": "git-cliff --unreleased",
10+
"changelog:next-version": "git-cliff --bumped-version",
911
"clean": "tsc -b --clean",
1012
"format": "prettier packages/**/*.ts --ignore-path ./.prettierignore --write",
1113
"lint": "eslint 'packages/**/*.ts' --fix",
14+
"lint:sh": "bash -c 'shopt -s globstar && shellcheck scripts/**/*.sh'",
1215
"test": "bun run --filter '*' test",
1316
"release": "release-it",
14-
"prepublish:npm": "bun run build && bun run changelog | pbcopy",
17+
"prepublish:npm": "bun run build && bun run changelog:unreleased | pbcopy",
1518
"publish:npm": "lerna publish",
1619
"prepublish:next": "bun run build",
1720
"publish:next": "lerna publish --dist-tag next",
@@ -72,6 +75,9 @@
7275
"prettier --write --ignore-path .prettierignore",
7376
"eslint --fix"
7477
],
78+
"scripts/**/*.sh": [
79+
"shellcheck"
80+
],
7581
"packages/nestjs-trpc/cli/**/*.rs": [
7682
"cargo fmt --manifest-path packages/nestjs-trpc/cli/Cargo.toml --",
7783
"bash -c 'cargo clippy --manifest-path packages/nestjs-trpc/cli/Cargo.toml --all-targets --all-features -- -D warnings'"

packages/nestjs-trpc/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
},
2929
"scripts": {
3030
"build": "rm -rf dist && tsc --project tsconfig.build.json && tsc --project config/tsconfig.json",
31-
"build:cli": "cd cli && cargo build --release",
31+
"build:cli": "../../scripts/build-cli.sh",
3232
"start:dev": "tsc --project tsconfig.json --watch --preserveWatchOutput",
3333
"debug:dev": "ts-node --inspect-brk lib/index.ts",
3434
"clean": "tsc -b --clean && rm -rf config/*.js config/*.d.ts",

scripts/build-cli.sh

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
5+
CLI_DIR="$SCRIPT_DIR/../packages/nestjs-trpc/cli"
6+
NATIVE_DIR="$SCRIPT_DIR/../packages/nestjs-trpc/native"
7+
8+
TARGET=""
9+
10+
while [[ $# -gt 0 ]]; do
11+
case $1 in
12+
--target)
13+
TARGET="$2"
14+
shift 2
15+
;;
16+
*)
17+
echo "Unknown option: $1" >&2
18+
exit 1
19+
;;
20+
esac
21+
done
22+
23+
if [[ -z "$TARGET" ]]; then
24+
ARCH="$(uname -m)"
25+
OS="$(uname -s)"
26+
27+
case "$OS" in
28+
Darwin)
29+
case "$ARCH" in
30+
arm64) TARGET="aarch64-apple-darwin" ;;
31+
x86_64) TARGET="x86_64-apple-darwin" ;;
32+
*) echo "Unsupported macOS architecture: $ARCH" >&2; exit 1 ;;
33+
esac
34+
;;
35+
Linux)
36+
case "$ARCH" in
37+
x86_64) TARGET="x86_64-unknown-linux-gnu" ;;
38+
aarch64) TARGET="aarch64-unknown-linux-gnu" ;;
39+
*) echo "Unsupported Linux architecture: $ARCH" >&2; exit 1 ;;
40+
esac
41+
;;
42+
*)
43+
echo "Unsupported OS: $OS (pass --target explicitly)" >&2
44+
exit 1
45+
;;
46+
esac
47+
48+
echo "Auto-detected target: $TARGET"
49+
fi
50+
51+
# Determine binary name (.exe for Windows targets)
52+
BINARY_NAME="nestjs-trpc"
53+
if [[ "$TARGET" == *"windows"* ]]; then
54+
BINARY_NAME="nestjs-trpc.exe"
55+
fi
56+
57+
# Determine whether to use cross-compilation
58+
HOST_TARGET=""
59+
if command -v rustc &>/dev/null; then
60+
HOST_TARGET="$(rustc -vV | awk '/^host:/ { print $2 }')"
61+
fi
62+
63+
BUILD_CMD="cargo"
64+
if [[ -n "$HOST_TARGET" && "$TARGET" != "$HOST_TARGET" ]]; then
65+
if command -v cross &>/dev/null; then
66+
BUILD_CMD="cross"
67+
echo "Cross-compiling: host=$HOST_TARGET, target=$TARGET"
68+
else
69+
echo "Target $TARGET differs from host $HOST_TARGET but 'cross' is not installed."
70+
echo "Falling back to cargo (make sure the target toolchain is installed)."
71+
fi
72+
fi
73+
74+
echo "Building CLI for $TARGET using $BUILD_CMD..."
75+
(cd "$CLI_DIR" && $BUILD_CMD build --release --target "$TARGET")
76+
77+
# Place binary in native/{target}/
78+
DEST_DIR="$NATIVE_DIR/$TARGET"
79+
mkdir -p "$DEST_DIR"
80+
81+
SOURCE="$CLI_DIR/target/$TARGET/release/$BINARY_NAME"
82+
if [[ ! -f "$SOURCE" ]]; then
83+
echo "Build succeeded but binary not found at: $SOURCE" >&2
84+
exit 1
85+
fi
86+
87+
cp "$SOURCE" "$DEST_DIR/$BINARY_NAME"
88+
89+
if [[ "$TARGET" != *"windows"* ]]; then
90+
chmod +x "$DEST_DIR/$BINARY_NAME"
91+
fi
92+
93+
echo "Binary placed at: $DEST_DIR/$BINARY_NAME"

0 commit comments

Comments
 (0)