Release #15
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Release: Maintainer-only; builds four platforms and publishes to npm. | |
| # Main package: @rush-fs/core (see package.json). Platform packages: @rush-fs/rush-fs-darwin-arm64, etc. | |
| # Trigger: | |
| # 1. Manual: Actions → Release → Run workflow (uses current main's package.json version) | |
| # 2. Tag: git tag v0.x.x && git push origin v0.x.x (bump version in package.json / Cargo.toml and push first) | |
| # Required: Secrets → NPM_TOKEN (npm Automation token with Publish permission) | |
| name: Release | |
| env: | |
| DEBUG: napi:* | |
| APP_NAME: rush-fs | |
| MACOSX_DEPLOYMENT_TARGET: '10.13' | |
| CARGO_INCREMENTAL: '1' | |
| NODE_VERSION: '20' | |
| on: | |
| workflow_dispatch: {} | |
| push: | |
| tags: | |
| - 'v*' | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| build: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| settings: | |
| - host: macos-latest | |
| target: x86_64-apple-darwin | |
| build: pnpm build --target x86_64-apple-darwin | |
| - host: windows-latest | |
| build: pnpm build --target x86_64-pc-windows-msvc | |
| target: x86_64-pc-windows-msvc | |
| - host: ubuntu-latest | |
| target: x86_64-unknown-linux-gnu | |
| build: pnpm build --target x86_64-unknown-linux-gnu --use-napi-cross | |
| - host: macos-latest | |
| target: aarch64-apple-darwin | |
| build: pnpm build --target aarch64-apple-darwin | |
| name: build - ${{ matrix.settings.target }} | |
| runs-on: ${{ matrix.settings.host }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Cache Rust toolchain | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.rustup | |
| key: rustup-${{ matrix.settings.host }}-${{ matrix.settings.target }}-stable | |
| - name: Install pnpm | |
| uses: pnpm/action-setup@v4 | |
| - name: Setup node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: pnpm | |
| - name: Install | |
| uses: dtolnay/rust-toolchain@stable | |
| with: | |
| toolchain: stable | |
| targets: ${{ matrix.settings.target }} | |
| - name: Cache cargo | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cargo/registry/index/ | |
| ~/.cargo/registry/cache/ | |
| ~/.cargo/git/db/ | |
| ~/.napi-rs | |
| .cargo-cache | |
| target/ | |
| key: ${{ matrix.settings.target }}-cargo-${{ matrix.settings.host }} | |
| - uses: mlugg/setup-zig@v2 | |
| if: ${{ contains(matrix.settings.target, 'musl') }} | |
| with: | |
| version: 0.14.1 | |
| - name: Install cargo-zigbuild | |
| uses: taiki-e/install-action@v2 | |
| if: ${{ contains(matrix.settings.target, 'musl') }} | |
| env: | |
| GITHUB_TOKEN: ${{ github.token }} | |
| with: | |
| tool: cargo-zigbuild | |
| - name: Setup toolchain | |
| run: ${{ matrix.settings.setup }} | |
| if: ${{ matrix.settings.setup }} | |
| shell: bash | |
| - name: Install dependencies | |
| run: pnpm install | |
| - name: Build | |
| run: ${{ matrix.settings.build }} | |
| shell: bash | |
| - name: Upload artifact | |
| uses: actions/upload-artifact@v5 | |
| with: | |
| name: bindings-${{ matrix.settings.target }} | |
| path: | | |
| ${{ env.APP_NAME }}.*.node | |
| ${{ env.APP_NAME }}.*.wasm | |
| if-no-files-found: error | |
| publish: | |
| name: Publish to npm | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| id-token: write | |
| needs: | |
| - build | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install pnpm | |
| uses: pnpm/action-setup@v4 | |
| - name: Setup node | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: ${{ env.NODE_VERSION }} | |
| cache: pnpm | |
| - name: Install dependencies | |
| run: pnpm install | |
| - name: Create npm dirs | |
| run: pnpm napi create-npm-dirs | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v4 | |
| with: | |
| path: artifacts | |
| - name: Move artifacts | |
| run: pnpm artifacts | |
| - name: List packages | |
| run: ls -R ./npm | |
| shell: bash | |
| - name: Update platform package names to use scope (@rush-fs/xxx) | |
| run: | | |
| for dir in npm/*/; do | |
| if [ -f "$dir/package.json" ]; then | |
| PKG_PATH="$dir/package.json" | |
| export PKG_PATH | |
| node -e " | |
| const fs = require('fs'); | |
| const pkgPath = process.env.PKG_PATH; | |
| const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')); | |
| console.log('Updating package name from', pkg.name, 'to @rush-fs/' + pkg.name); | |
| if (!pkg.name.startsWith('@rush-fs/')) { | |
| pkg.name = '@rush-fs/' + pkg.name; | |
| fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2)); | |
| } | |
| " | |
| fi | |
| done | |
| - name: Publish to npm | |
| run: | | |
| npm config set provenance true | |
| echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc | |
| # 先 fetch tags,然后检查对应的 tag 是否已存在 | |
| git fetch --tags --force | |
| VERSION=$(node -p "require('./package.json').version") | |
| TAG="v$VERSION" | |
| if git rev-parse "$TAG" >/dev/null 2>&1; then | |
| echo "Tag $TAG already exists, skipping GitHub Release creation" | |
| pnpm napi prepublish -t npm --no-gh-release | |
| else | |
| echo "Tag $TAG does not exist, will create GitHub Release" | |
| pnpm prepublishOnly | |
| fi | |
| # prepublish 之后再次更新包名(因为 prepublish 可能会更新 package.json) | |
| for dir in npm/*/; do | |
| if [ -f "$dir/package.json" ]; then | |
| PKG_PATH="$dir/package.json" | |
| export PKG_PATH | |
| node -e " | |
| const fs = require('fs'); | |
| const pkgPath = process.env.PKG_PATH; | |
| const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')); | |
| if (!pkg.name.startsWith('@rush-fs/')) { | |
| console.log('Fixing package name:', pkg.name, '-> @rush-fs/' + pkg.name); | |
| pkg.name = '@rush-fs/' + pkg.name; | |
| fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2)); | |
| } | |
| " | |
| fi | |
| done | |
| # 主包 index.js 里 require 的是 rush-fs-xxx,改为 @rush-fs/rush-fs-xxx 才能找到已发布的平台包 | |
| sed -i "s/require('rush-fs-/require('@rush-fs\/rush-fs-/g" index.js | |
| sed -i 's/require(\"rush-fs-/require(\"@rush-fs\/rush-fs-/g' index.js | |
| # optionalDependencies 必须在 prepublish 之后注入,否则会被 prepublish 覆盖,导致用户 pnpm i rush-fs 时不会自动安装平台包 | |
| node -e " | |
| const fs = require('fs'); | |
| const p = JSON.parse(fs.readFileSync('package.json', 'utf8')); | |
| const v = p.version; | |
| p.optionalDependencies = { | |
| '@rush-fs/rush-fs-win32-x64-msvc': v, | |
| '@rush-fs/rush-fs-darwin-x64': v, | |
| '@rush-fs/rush-fs-linux-x64-gnu': v, | |
| '@rush-fs/rush-fs-darwin-arm64': v | |
| }; | |
| fs.writeFileSync('package.json', JSON.stringify(p, null, 2)); | |
| " | |
| npm publish --access public | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| NPM_TOKEN: ${{ secrets.NPM_TOKEN }} |