Skip to content

Commit 429faea

Browse files
committed
chore: add independent workflow to release
1 parent 05a6a2f commit 429faea

4 files changed

Lines changed: 238 additions & 172 deletions

File tree

.github/workflows/CI.yml

Lines changed: 15 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,26 @@ env:
55
MACOSX_DEPLOYMENT_TARGET: '10.13'
66
CARGO_INCREMENTAL: '1'
77
NODE_VERSION: '20'
8+
# CI:PR 与 main 的检查(lint / build / test),不包含发布
89
'on':
910
push:
1011
branches:
1112
- main
12-
tags-ignore:
13-
- '**'
1413
paths-ignore:
1514
- '**/*.md'
1615
- LICENSE
1716
- '**/*.gitignore'
1817
- .editorconfig
1918
- docs/**
20-
pull_request: null
19+
pull_request:
20+
branches:
21+
- main
22+
paths-ignore:
23+
- '**/*.md'
24+
- LICENSE
25+
- '**/*.gitignore'
26+
- .editorconfig
27+
- docs/**
2128
concurrency:
2229
group: ${{ github.workflow }}-${{ github.ref }}
2330
cancel-in-progress: true
@@ -67,6 +74,11 @@ jobs:
6774
runs-on: ${{ matrix.settings.host }}
6875
steps:
6976
- uses: actions/checkout@v4
77+
- name: Cache Rust toolchain
78+
uses: actions/cache@v4
79+
with:
80+
path: ~/.rustup
81+
key: rustup-${{ matrix.settings.host }}-${{ matrix.settings.target }}-stable
7082
- name: Install pnpm
7183
uses: pnpm/action-setup@v4
7284
- name: Setup node
@@ -232,68 +244,3 @@ jobs:
232244
--platform "${{ steps.docker.outputs.PLATFORM }}" \
233245
"${{ steps.docker.outputs.IMAGE }}" \
234246
sh -lc "corepack enable && pnpm test"
235-
publish:
236-
name: Publish
237-
runs-on: ubuntu-latest
238-
permissions:
239-
contents: write
240-
id-token: write
241-
needs:
242-
- lint
243-
- test-macOS-windows-binding
244-
- test-linux-binding
245-
steps:
246-
- uses: actions/checkout@v4
247-
- name: Install pnpm
248-
uses: pnpm/action-setup@v4
249-
- name: Setup node
250-
uses: actions/setup-node@v4
251-
with:
252-
node-version: ${{ env.NODE_VERSION }}
253-
cache: pnpm
254-
- name: Install dependencies
255-
run: pnpm install
256-
- name: create npm dirs
257-
run: pnpm napi create-npm-dirs
258-
- name: Download all artifacts
259-
uses: actions/download-artifact@v4
260-
with:
261-
path: artifacts
262-
- name: Move artifacts
263-
run: pnpm artifacts
264-
- name: List packages
265-
run: ls -R ./npm
266-
shell: bash
267-
- name: Add optionalDependencies for publish
268-
run: |
269-
node -e "
270-
const fs = require('fs');
271-
const p = JSON.parse(fs.readFileSync('package.json', 'utf8'));
272-
const v = p.version;
273-
p.optionalDependencies = {
274-
'rush-fs-win32-x64-msvc': v,
275-
'rush-fs-darwin-x64': v,
276-
'rush-fs-linux-x64-gnu': v,
277-
'rush-fs-darwin-arm64': v
278-
};
279-
fs.writeFileSync('package.json', JSON.stringify(p, null, 2));
280-
"
281-
- name: Publish platform packages and main package
282-
run: |
283-
COMMIT_MSG=$(git log -1 --pretty=%B)
284-
if echo "$COMMIT_MSG" | grep -qE "^[0-9]+\.[0-9]+\.[0-9]+$"; then
285-
npm config set provenance true
286-
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
287-
pnpm prepublishOnly
288-
npm publish --access public
289-
elif echo "$COMMIT_MSG" | grep -qE "[0-9]+\.[0-9]+\.[0-9]+"; then
290-
npm config set provenance true
291-
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
292-
pnpm prepublishOnly
293-
npm publish --tag next --access public
294-
else
295-
echo "Not a release (commit message is not a version), skipping publish"
296-
fi
297-
env:
298-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
299-
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

.github/workflows/Release.yml

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# Release:仅维护者触发,构建四平台并发布到 npm
2+
# 触发方式:
3+
# 1. 手动:Actions → Release → Run workflow(使用当前 main 的 package.json version)
4+
# 2. 打 tag:git tag v0.0.3 && git push origin v0.0.3(需先已把 package.json 改为 0.0.3 并 push)
5+
# 仓库需配置 Secrets → NPM_TOKEN(npm 的 Automation token,Publish 权限)
6+
name: Release
7+
env:
8+
DEBUG: napi:*
9+
APP_NAME: rush-fs
10+
MACOSX_DEPLOYMENT_TARGET: '10.13'
11+
CARGO_INCREMENTAL: '1'
12+
NODE_VERSION: '20'
13+
on:
14+
workflow_dispatch: {}
15+
push:
16+
tags:
17+
- 'v*'
18+
concurrency:
19+
group: ${{ github.workflow }}-${{ github.ref }}
20+
cancel-in-progress: true
21+
jobs:
22+
build:
23+
strategy:
24+
fail-fast: false
25+
matrix:
26+
settings:
27+
- host: macos-latest
28+
target: x86_64-apple-darwin
29+
build: pnpm build --target x86_64-apple-darwin
30+
- host: windows-latest
31+
build: pnpm build --target x86_64-pc-windows-msvc
32+
target: x86_64-pc-windows-msvc
33+
- host: ubuntu-latest
34+
target: x86_64-unknown-linux-gnu
35+
build: pnpm build --target x86_64-unknown-linux-gnu --use-napi-cross
36+
- host: macos-latest
37+
target: aarch64-apple-darwin
38+
build: pnpm build --target aarch64-apple-darwin
39+
name: build - ${{ matrix.settings.target }}
40+
runs-on: ${{ matrix.settings.host }}
41+
steps:
42+
- uses: actions/checkout@v4
43+
- name: Cache Rust toolchain
44+
uses: actions/cache@v4
45+
with:
46+
path: ~/.rustup
47+
key: rustup-${{ matrix.settings.host }}-${{ matrix.settings.target }}-stable
48+
- name: Install pnpm
49+
uses: pnpm/action-setup@v4
50+
- name: Setup node
51+
uses: actions/setup-node@v4
52+
with:
53+
node-version: ${{ env.NODE_VERSION }}
54+
cache: pnpm
55+
- name: Install
56+
uses: dtolnay/rust-toolchain@stable
57+
with:
58+
toolchain: stable
59+
targets: ${{ matrix.settings.target }}
60+
- name: Cache cargo
61+
uses: actions/cache@v4
62+
with:
63+
path: |
64+
~/.cargo/registry/index/
65+
~/.cargo/registry/cache/
66+
~/.cargo/git/db/
67+
~/.napi-rs
68+
.cargo-cache
69+
target/
70+
key: ${{ matrix.settings.target }}-cargo-${{ matrix.settings.host }}
71+
- uses: mlugg/setup-zig@v2
72+
if: ${{ contains(matrix.settings.target, 'musl') }}
73+
with:
74+
version: 0.14.1
75+
- name: Install cargo-zigbuild
76+
uses: taiki-e/install-action@v2
77+
if: ${{ contains(matrix.settings.target, 'musl') }}
78+
env:
79+
GITHUB_TOKEN: ${{ github.token }}
80+
with:
81+
tool: cargo-zigbuild
82+
- name: Setup toolchain
83+
run: ${{ matrix.settings.setup }}
84+
if: ${{ matrix.settings.setup }}
85+
shell: bash
86+
- name: Install dependencies
87+
run: pnpm install
88+
- name: Build
89+
run: ${{ matrix.settings.build }}
90+
shell: bash
91+
- name: Upload artifact
92+
uses: actions/upload-artifact@v5
93+
with:
94+
name: bindings-${{ matrix.settings.target }}
95+
path: |
96+
${{ env.APP_NAME }}.*.node
97+
${{ env.APP_NAME }}.*.wasm
98+
if-no-files-found: error
99+
publish:
100+
name: Publish to npm
101+
runs-on: ubuntu-latest
102+
permissions:
103+
contents: write
104+
id-token: write
105+
needs:
106+
- build
107+
steps:
108+
- uses: actions/checkout@v4
109+
- name: Install pnpm
110+
uses: pnpm/action-setup@v4
111+
- name: Setup node
112+
uses: actions/setup-node@v4
113+
with:
114+
node-version: ${{ env.NODE_VERSION }}
115+
cache: pnpm
116+
- name: Install dependencies
117+
run: pnpm install
118+
- name: Create npm dirs
119+
run: pnpm napi create-npm-dirs
120+
- name: Download all artifacts
121+
uses: actions/download-artifact@v4
122+
with:
123+
path: artifacts
124+
- name: Move artifacts
125+
run: pnpm artifacts
126+
- name: List packages
127+
run: ls -R ./npm
128+
shell: bash
129+
- name: Add optionalDependencies for publish
130+
run: |
131+
node -e "
132+
const fs = require('fs');
133+
const p = JSON.parse(fs.readFileSync('package.json', 'utf8'));
134+
const v = p.version;
135+
p.optionalDependencies = {
136+
'rush-fs-win32-x64-msvc': v,
137+
'rush-fs-darwin-x64': v,
138+
'rush-fs-linux-x64-gnu': v,
139+
'rush-fs-darwin-arm64': v
140+
};
141+
fs.writeFileSync('package.json', JSON.stringify(p, null, 2));
142+
"
143+
- name: Publish to npm
144+
run: |
145+
npm config set provenance true
146+
echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
147+
pnpm prepublishOnly
148+
npm publish --access public
149+
env:
150+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
151+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

README.md

Lines changed: 20 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -72,56 +72,6 @@ graph TD
7272
J -->|Return| K["JS Result"]
7373
```
7474

75-
## How does it works
76-
77-
For the original Node.js, it works serially and cost lots of memory to parse os object and string into JS style:
78-
79-
```mermaid
80-
graph TD
81-
A["JS: readdir"] -->|Call| B("Node.js C++ Binding")
82-
B -->|Submit Task| C{"Libuv Thread Pool"}
83-
84-
subgraph "Native Layer (Serial)"
85-
C -->|"Syscall: getdents"| D[OS Kernel]
86-
D -->|"Return File List"| C
87-
C -->|"Process Paths"| C
88-
end
89-
90-
C -->|"Results Ready"| E("V8 Main Thread")
91-
92-
subgraph "V8 Interaction (Heavy)"
93-
E -->|"Create JS String 1"| F[V8 Heap]
94-
E -->|"String 2"| F
95-
E -->|"String N..."| F
96-
F -->|"GC Pressure Rising"| F
97-
end
98-
99-
E -->|"Return Array"| G["JS Callback/Promise"]
100-
```
101-
102-
But, it's saved with Rust now:
103-
104-
```mermaid
105-
graph TD
106-
A["JS: readdir"] -->|"N-API Call"| B("Rust Wrapper")
107-
B -->|"Spawn Thread/Task"| C{"Rust Thread Pool"}
108-
109-
subgraph "Rust 'Black Box'"
110-
C -->|"Rayon: Parallel work"| D[OS Kernel]
111-
D -->|"Syscall: getdents"| C
112-
C -->|"Store as Rust Vec<String>"| H[Rust Heap]
113-
H -->|"No V8 Interaction yet"| H
114-
end
115-
116-
C -->|"All Done"| I("Convert to JS")
117-
118-
subgraph "N-API Bridge"
119-
I -->|"Batch Create JS Array"| J[V8 Heap]
120-
end
121-
122-
J -->|Return| K["JS Result"]
123-
```
124-
12575
## Status & Roadmap
12676

12777
We are rewriting `fs` APIs one by one.
@@ -533,12 +483,30 @@ See [CONTRIBUTING.md](./CONTRIBUTING.md) for the complete development guide —
533483
Then publish both the platform-specific packages and the main package **in order**:
534484

535485
1. Ensure you are logged in to npm (`npm login`).
536-
2. Bump the version via `pnpm version <patch|minor|major>`. This runs `pnpm preversion`, which builds the `.node` artifacts under `npm/` for each platform. **These files must exist before the next step can publish them.**
537-
3. Run `pnpm prepublishOnly` (which runs `napi prepublish -t npm`) to publish each built package from `npm/` (e.g. `rush-fs-darwin-arm64`, `rush-fs-win32-x64-msvc`). **If you see "doesn't exist" here, you skipped the build—run `pnpm build` or complete step 2 first.**
486+
2. Bump the version via `pnpm version <patch|minor|major>`. This runs `pnpm preversion`, which builds the `.node` for the **current platform only** (output is in the crate root, not under `npm/`). **To verify the Mac build:** after `pnpm build` or `preversion`, check that the crate root contains `rush-fs.darwin-arm64.node` (Apple Silicon) or `rush-fs.darwin-x64.node` (Intel Mac). For `prepublishOnly` to see it, you must have the file under `npm/<platform>/` (see "Local single-platform publish" below).
487+
3. Run `pnpm prepublishOnly` (which runs `napi prepublish -t npm`) to publish each built package from `npm/` (e.g. `rush-fs-darwin-arm64`, `rush-fs-win32-x64-msvc`). **If you see "doesn't exist" here,** the `.node` is not in `npm/` yet—either use CI to build all platforms, or for local Mac-only: run `napi create-npm-dirs`, then copy `rush-fs.darwin-arm64.node` (or `darwin-x64`) into `npm/darwin-arm64/` (or `npm/darwin-x64/`), then run `pnpm prepublishOnly` again.
538488
4. Publish the main package with `pnpm publish --access public`. The `prepublishOnly` hook runs automatically, but running step 3 manually lets you verify each platform succeeded before tagging the main release.
539489

540490
If any platform publish fails, fix it and re-run `pnpm prepublishOnly` before retrying `pnpm publish` so consumers never receive a release referring to missing optional dependencies.
541491

492+
### How to verify the Mac build (方式 B 第 2 步后)
493+
494+
- **Apple Silicon (M1/M2/M3):** in the repo root, a file named `rush-fs.darwin-arm64.node` must exist.
495+
- **Intel Mac:** in the repo root, a file named `rush-fs.darwin-x64.node` must exist.
496+
497+
Command to check: `ls -la rush-fs.darwin-*.node` in the package directory. If you see the file, the Mac native build succeeded.
498+
499+
### Local single-platform publish (Mac only)
500+
501+
If you are not using CI and only have a Mac build:
502+
503+
1. `pnpm build` (or `pnpm version patch` to also bump version).
504+
2. `napi create-npm-dirs` to create `npm/darwin-arm64/` (and other platform dirs).
505+
3. Copy the built `.node` into the matching npm dir, e.g.
506+
`cp rush-fs.darwin-arm64.node npm/darwin-arm64/`
507+
4. `pnpm prepublishOnly` — only the Mac platform package will be published; others will show "doesn't exist" (expected).
508+
5. `pnpm publish --access public`. Users on other platforms will need to build from source or you publish those platform packages later via CI.
509+
542510
## License
543511

544512
MIT

0 commit comments

Comments
 (0)