diff --git a/.github/workflows/pkg.pr.new.yml b/.github/workflows/pkg.pr.new.yml new file mode 100644 index 000000000..125aeda5f --- /dev/null +++ b/.github/workflows/pkg.pr.new.yml @@ -0,0 +1,95 @@ +name: Publish to pkg.pr.new + +# Publishes a continuous preview release to https://pkg.pr.new whenever a +# maintainer adds the `pkg.pr.new` label to a pull request (or via manual +# dispatch). Requires the pkg.pr.new GitHub App to be installed on the repo: +# https://github.com/apps/pkg-pr-new + +# One-shot per label by design (matches rolldown's PR preview): a preview is +# built only when the `pkg.pr.new` label itself is added (the job guards check +# the triggering label, github.event.label.name, NOT the full label set, so +# adding any other label to an already-labeled PR does not rebuild). +# `synchronize` is intentionally NOT subscribed, so later commits do not +# rebuild — re-apply the label or use workflow_dispatch to refresh. This avoids +# an 8-platform native build on every push. +on: + workflow_dispatch: + pull_request: + types: [labeled] + +permissions: {} + +# Cancel an in-flight preview when the label is re-applied on the same PR. +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + DEBUG: 'napi:*' + +jobs: + build: + name: Build + if: > + github.repository == 'voidzero-dev/oxc-angular-compiler' && + (github.event_name == 'workflow_dispatch' || + (github.event_name == 'pull_request' && github.event.label.name == 'pkg.pr.new')) + permissions: + contents: read + uses: ./.github/workflows/reusable-build.yml + + publish: + name: Publish preview + if: > + github.repository == 'voidzero-dev/oxc-angular-compiler' && + (github.event_name == 'workflow_dispatch' || + (github.event_name == 'pull_request' && github.event.label.name == 'pkg.pr.new')) + needs: build + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 + + - name: Install pnpm + uses: pnpm/action-setup@08c4be7e2e672a47d11bd04269e27e5f3e8529cb # v6.0.0 + + - name: Install Node.js + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + with: + node-version: 24 + cache: pnpm + + - name: Install dependencies + run: pnpm install + + - name: Download artifacts + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 + with: + path: napi/angular-compiler/artifacts + + - name: Create npm dirs + run: pnpm --filter ./napi/angular-compiler exec napi create-npm-dirs + + - name: Move artifacts + run: pnpm --filter ./napi/angular-compiler artifacts + + - name: Build TypeScript + run: pnpm --filter ./napi/angular-compiler build:ts + + # Inject the platform binding packages into the root package's + # optionalDependencies (without publishing them to npm) so pkg.pr.new + # rewrites those deps to the preview URLs it generates. --no-gh-release + # keeps `napi pre-publish` from attempting a real GitHub release tag. + - name: Prepare optionalDependencies + run: pnpm --filter ./napi/angular-compiler exec napi pre-publish -t npm --skip-optional-publish --no-gh-release + + # Invoke the lockfile-pinned pkg-pr-new binary directly, NOT via + # `pnpm exec`: the previous step injects binding optionalDependencies into + # napi/angular-compiler/package.json, desyncing it from the lockfile, and + # the workspace's `verifyDepsBeforeRun: install` would make `pnpm exec` + # fail the frozen-lockfile check before pkg-pr-new runs. The direct call + # skips that gate while still using the pinned install (not `pnpm dlx`). + # Requires the pkg.pr.new GitHub App on the repo. + - name: Publish preview to pkg.pr.new + run: ./node_modules/.bin/pkg-pr-new publish './napi/angular-compiler/npm/*' './napi/angular-compiler' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4b4a99acb..2b0cf7021 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,105 +16,10 @@ concurrency: jobs: build: - name: Build - ${{ matrix.target }} + name: Build permissions: contents: read - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - include: - - target: x86_64-unknown-linux-gnu - os: ubuntu-24.04-arm - - target: x86_64-unknown-linux-musl - os: ubuntu-latest - - target: aarch64-unknown-linux-gnu - os: ubuntu-latest - - target: aarch64-unknown-linux-musl - os: ubuntu-latest - - target: x86_64-apple-darwin - os: macos-latest - - target: aarch64-apple-darwin - os: macos-latest - - target: x86_64-pc-windows-msvc - os: windows-latest - - target: aarch64-pc-windows-msvc - os: windows-latest - - steps: - - name: Support longpaths - if: ${{ matrix.os == 'windows-latest' }} - run: git config --system core.longpaths true - - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 - - - name: Update submodules - run: git submodule update --init --recursive - - - name: Print rustup toolchain version - shell: bash - id: rustup-version - run: | - export RUST_TOOLCHAIN_VERSION="$(grep 'channel' rust-toolchain.toml | head -1 | awk -F '"' '{print $2}')" - echo "Rust toolchain version: $RUST_TOOLCHAIN_VERSION" - echo "RUST_TOOLCHAIN_VERSION=$RUST_TOOLCHAIN_VERSION" >> "$GITHUB_OUTPUT" - - - name: Install Rust - uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable - with: - toolchain: '${{ steps.rustup-version.outputs.RUST_TOOLCHAIN_VERSION }}' - targets: ${{ matrix.target }} - - - name: Cache Rust - uses: Swatinem/rust-cache@fb003b4f771bbf9c2de31d5f65c40689cc097fb5 # v2.1.0 - - - uses: mlugg/setup-zig@fa65c4058643678a4e4a9a60513944a7d8d35440 # v2.1.0 - if: ${{ contains(matrix.target, 'musl') }} - with: - version: 0.15.2 - - - name: Install cargo-zigbuild - uses: taiki-e/install-action@cca35edeb1d01366c2843b68fc3ca441446d73d3 # v2.77.1 - if: ${{ contains(matrix.target, 'musl') }} - env: - GITHUB_TOKEN: ${{ github.token }} - with: - tool: cargo-zigbuild - - - name: Install pnpm - uses: pnpm/action-setup@08c4be7e2e672a47d11bd04269e27e5f3e8529cb # v6.0.0 - - - name: Install Node.js - uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 - with: - node-version: 24 - cache: pnpm - - - name: Install dependencies - run: pnpm install - - - name: Build ${{ matrix.target }} - working-directory: napi/angular-compiler - if: ${{ !contains(matrix.target , 'gnu') && !contains(matrix.target, 'musl') }} - run: pnpm build-dev --release --target ${{ matrix.target }} - - - name: Build ${{ matrix.target }} - working-directory: napi/angular-compiler - if: ${{ contains(matrix.target , 'gnu') }} - run: pnpm build-dev --release --target ${{ matrix.target }} --use-napi-cross - env: - TARGET_CC: clang - - - name: Build ${{ matrix.target }} - working-directory: napi/angular-compiler - if: ${{ contains(matrix.target, 'musl') }} - run: pnpm build-dev --release --target ${{ matrix.target }} -x - - - name: Upload artifact - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 - with: - name: bindings-${{ matrix.target }} - path: napi/angular-compiler/*.node - if-no-files-found: error + uses: ./.github/workflows/reusable-build.yml publish: name: Publish diff --git a/.github/workflows/reusable-build.yml b/.github/workflows/reusable-build.yml new file mode 100644 index 000000000..221260abc --- /dev/null +++ b/.github/workflows/reusable-build.yml @@ -0,0 +1,116 @@ +name: Reusable Build + +# Builds the native NAPI bindings for every target and uploads them as +# `bindings-` artifacts. Called by both `release.yml` (tag releases) +# and `pkg.pr.new.yml` (PR preview packages) so the build matrix lives in one +# place. + +on: + workflow_call: + +permissions: {} + +env: + DEBUG: 'napi:*' + +jobs: + build: + name: Build - ${{ matrix.target }} + permissions: + contents: read + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + include: + - target: x86_64-unknown-linux-gnu + os: ubuntu-24.04-arm + - target: x86_64-unknown-linux-musl + os: ubuntu-latest + - target: aarch64-unknown-linux-gnu + os: ubuntu-latest + - target: aarch64-unknown-linux-musl + os: ubuntu-latest + - target: x86_64-apple-darwin + os: macos-latest + - target: aarch64-apple-darwin + os: macos-latest + - target: x86_64-pc-windows-msvc + os: windows-latest + - target: aarch64-pc-windows-msvc + os: windows-latest + + steps: + - name: Support longpaths + if: ${{ matrix.os == 'windows-latest' }} + run: git config --system core.longpaths true + - uses: taiki-e/checkout-action@7d1e50e93dc4fb3bba58f85018fadf77898aee8b # v1.4.2 + + - name: Update submodules + run: git submodule update --init --recursive + + - name: Print rustup toolchain version + shell: bash + id: rustup-version + run: | + export RUST_TOOLCHAIN_VERSION="$(grep 'channel' rust-toolchain.toml | head -1 | awk -F '"' '{print $2}')" + echo "Rust toolchain version: $RUST_TOOLCHAIN_VERSION" + echo "RUST_TOOLCHAIN_VERSION=$RUST_TOOLCHAIN_VERSION" >> "$GITHUB_OUTPUT" + + - name: Install Rust + uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable + with: + toolchain: '${{ steps.rustup-version.outputs.RUST_TOOLCHAIN_VERSION }}' + targets: ${{ matrix.target }} + + - name: Cache Rust + uses: Swatinem/rust-cache@fb003b4f771bbf9c2de31d5f65c40689cc097fb5 # v2.1.0 + + - uses: mlugg/setup-zig@fa65c4058643678a4e4a9a60513944a7d8d35440 # v2.1.0 + if: ${{ contains(matrix.target, 'musl') }} + with: + version: 0.15.2 + + - name: Install cargo-zigbuild + uses: taiki-e/install-action@cca35edeb1d01366c2843b68fc3ca441446d73d3 # v2.77.1 + if: ${{ contains(matrix.target, 'musl') }} + env: + GITHUB_TOKEN: ${{ github.token }} + with: + tool: cargo-zigbuild + + - name: Install pnpm + uses: pnpm/action-setup@08c4be7e2e672a47d11bd04269e27e5f3e8529cb # v6.0.0 + + - name: Install Node.js + uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 + with: + node-version: 24 + cache: pnpm + + - name: Install dependencies + run: pnpm install + + - name: Build ${{ matrix.target }} + working-directory: napi/angular-compiler + if: ${{ !contains(matrix.target , 'gnu') && !contains(matrix.target, 'musl') }} + run: pnpm build-dev --release --target ${{ matrix.target }} + + - name: Build ${{ matrix.target }} + working-directory: napi/angular-compiler + if: ${{ contains(matrix.target , 'gnu') }} + run: pnpm build-dev --release --target ${{ matrix.target }} --use-napi-cross + env: + TARGET_CC: clang + + - name: Build ${{ matrix.target }} + working-directory: napi/angular-compiler + if: ${{ contains(matrix.target, 'musl') }} + run: pnpm build-dev --release --target ${{ matrix.target }} -x + + - name: Upload artifact + uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + with: + name: bindings-${{ matrix.target }} + path: napi/angular-compiler/*.node + if-no-files-found: error diff --git a/package.json b/package.json index 47aca4e3d..fdb2715d3 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "@napi-rs/cli": "catalog:", "oxfmt": "catalog:", "oxlint": "^1.56.0", - "oxlint-tsgolint": "^0.23.0" + "oxlint-tsgolint": "^0.23.0", + "pkg-pr-new": "0.0.75" }, "packageManager": "pnpm@11.4.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fd553eab0..61355f5fc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -59,6 +59,9 @@ importers: oxlint-tsgolint: specifier: ^0.23.0 version: 0.23.0 + pkg-pr-new: + specifier: 0.0.75 + version: 0.0.75 napi/angular-compiler: dependencies: @@ -600,6 +603,7 @@ packages: '@angular/platform-browser-dynamic@22.0.1': resolution: {integrity: sha512-Z0h2gVNxPoJqzon7OlOhfScuMgPyW4qbJZAZCBMRYC8se+7YP1w81dw5dmqyeqf66pD+NwhkJXL1hOrYKK1m2g==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} + deprecated: '@angular/platform-browser-dynamic is deprecated. Use `@angular/platform-browser` instead.' peerDependencies: '@angular/common': 22.0.1 '@angular/compiler': 22.0.1 @@ -4107,6 +4111,10 @@ packages: pixi.js@7.4.3: resolution: {integrity: sha512-uIWdH0EI2dVgNoqN9aFaHCmR0V65OEhMkXs2sek3c/QP2ItV6UoM+ouX9esSv3ibo20F+J5D1XwnQhUZI6wqeQ==} + pkg-pr-new@0.0.75: + resolution: {integrity: sha512-u9mdErTewKSMsr+ceCt8VcNuNP0ro5AXiPXhUVApuEyqr2Zlvt+DdCFBcm+yGWN8mhOdZJ27meIDbnoZgfzpOw==} + hasBin: true + playwright-core@1.60.0: resolution: {integrity: sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA==} engines: {node: '>=18'} @@ -7609,6 +7617,8 @@ snapshots: '@pixi/text-bitmap': 7.4.3(@pixi/assets@7.4.3(@pixi/core@7.4.3))(@pixi/core@7.4.3)(@pixi/display@7.4.3(@pixi/core@7.4.3))(@pixi/mesh@7.4.3(@pixi/core@7.4.3)(@pixi/display@7.4.3(@pixi/core@7.4.3)))(@pixi/text@7.4.3(@pixi/core@7.4.3)(@pixi/sprite@7.4.3(@pixi/core@7.4.3)(@pixi/display@7.4.3(@pixi/core@7.4.3)))) '@pixi/text-html': 7.4.3(@pixi/core@7.4.3)(@pixi/display@7.4.3(@pixi/core@7.4.3))(@pixi/sprite@7.4.3(@pixi/core@7.4.3)(@pixi/display@7.4.3(@pixi/core@7.4.3)))(@pixi/text@7.4.3(@pixi/core@7.4.3)(@pixi/sprite@7.4.3(@pixi/core@7.4.3)(@pixi/display@7.4.3(@pixi/core@7.4.3)))) + pkg-pr-new@0.0.75: {} + playwright-core@1.60.0: {} playwright@1.60.0: