feat(nx): expand implicitDependencies globs against project names #375
Workflow file for this run
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
| name: CI | |
| env: | |
| DEBUG: napi:* | |
| APP_NAME: domino | |
| MACOSX_DEPLOYMENT_TARGET: '10.13' | |
| CARGO_INCREMENTAL: '1' | |
| 'on': | |
| push: | |
| branches: | |
| - main | |
| tags-ignore: | |
| - '**' | |
| paths-ignore: | |
| - '**/*.md' | |
| - LICENSE | |
| - '**/*.gitignore' | |
| - .editorconfig | |
| - docs/** | |
| pull_request: | |
| types: | |
| - opened | |
| - synchronize | |
| - reopened | |
| - edited | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| lint: | |
| name: Lint | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup node | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| cache: yarn | |
| - name: Install Rust toolchain | |
| run: rustup show | |
| - name: Install dependencies | |
| run: yarn install --frozen-lockfile | |
| - name: Oxlint | |
| run: yarn lint | |
| - name: Cargo fmt | |
| run: cargo fmt -- --check | |
| - name: Clippy | |
| run: cargo clippy | |
| - name: Test publish-preview script | |
| run: node --test tests/publish-preview.test.js | |
| verify-pr-title: | |
| name: Verify PR title | |
| if: github.event_name == 'pull_request' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Validate conventional commit format | |
| env: | |
| PR_TITLE: ${{ github.event.pull_request.title }} | |
| run: | | |
| TITLE="$PR_TITLE" | |
| PATTERN="^(feat|fix|chore|ci|docs|refactor|test|perf|build|style|revert)(\(.+\))?(!)?: .+" | |
| if [[ ! "$TITLE" =~ $PATTERN ]]; then | |
| echo "::error::PR title must follow conventional commits format." | |
| echo "" | |
| echo "Expected: <type>(<optional scope>): <description>" | |
| echo "Got: $TITLE" | |
| echo "" | |
| echo "Allowed types: feat, fix, chore, ci, docs, refactor, test, perf, build, style, revert" | |
| echo "Examples:" | |
| echo " feat: add new parser" | |
| echo " fix(resolver): handle circular imports" | |
| echo " feat!: redesign API" | |
| exit 1 | |
| fi | |
| echo "PR title is valid: $TITLE" | |
| build: | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| settings: | |
| - host: macos-latest | |
| target: x86_64-apple-darwin | |
| build: yarn build --target x86_64-apple-darwin | |
| - host: windows-latest | |
| build: yarn build --target x86_64-pc-windows-msvc | |
| target: x86_64-pc-windows-msvc | |
| - host: ubuntu-latest | |
| target: x86_64-unknown-linux-gnu | |
| build: yarn build --target x86_64-unknown-linux-gnu --use-napi-cross | |
| - host: ubuntu-latest | |
| target: x86_64-unknown-linux-musl | |
| build: yarn build --target x86_64-unknown-linux-musl -x | |
| - host: macos-latest | |
| target: aarch64-apple-darwin | |
| build: yarn build --target aarch64-apple-darwin | |
| - host: ubuntu-latest | |
| target: aarch64-unknown-linux-musl | |
| build: yarn build --target aarch64-unknown-linux-musl -x | |
| - host: ubuntu-latest | |
| target: aarch64-unknown-linux-gnu | |
| build: yarn build --target aarch64-unknown-linux-gnu --use-napi-cross | |
| name: stable - ${{ matrix.settings.target }} - node@22 | |
| runs-on: ${{ matrix.settings.host }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup node | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| cache: yarn | |
| - name: Install Rust toolchain | |
| run: | | |
| rustup show | |
| rustup target add ${{ matrix.settings.target }} | |
| - name: Cache cargo | |
| uses: actions/cache@v4 | |
| if: ${{ !contains(matrix.settings.target, 'linux-gnu') }} | |
| with: | |
| path: | | |
| ~/.cargo/registry/index/ | |
| ~/.cargo/registry/cache/ | |
| ~/.cargo/git/db/ | |
| ~/.napi-rs | |
| .cargo-cache | |
| target/ | |
| key: ${{ matrix.settings.target }}-cargo-${{ matrix.settings.host }} | |
| # NO cargo cache for Linux GNU - cross builds in Docker with different GLIBC | |
| # Caching host-compiled dependencies would contaminate cross build with wrong GLIBC version | |
| # - name: Cache cargo (no target for Linux GNU) | |
| # uses: actions/cache@v4 | |
| # if: ${{ contains(matrix.settings.target, 'linux-gnu') }} | |
| # with: | |
| # path: | | |
| # ~/.cargo/registry/index/ | |
| # ~/.cargo/registry/cache/ | |
| # ~/.cargo/git/db/ | |
| # ~/.napi-rs | |
| # .cargo-cache | |
| # key: ${{ matrix.settings.target }}-cargo-${{ matrix.settings.host }} | |
| - name: Install cross | |
| uses: taiki-e/install-action@v2 | |
| if: ${{ contains(matrix.settings.target, 'linux-gnu') }} | |
| env: | |
| GITHUB_TOKEN: ${{ github.token }} | |
| with: | |
| tool: cross | |
| - 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 cross-compilation dependencies | |
| if: ${{ contains(matrix.settings.target, 'linux') && matrix.settings.host == 'ubuntu-latest' }} | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y build-essential pkg-config perl | |
| - name: Install dependencies | |
| run: yarn install --frozen-lockfile | |
| - name: Build native addon | |
| env: | |
| PKG_CONFIG_ALLOW_CROSS: 1 | |
| run: ${{ matrix.settings.build }} | |
| shell: bash | |
| - name: Build binary executable | |
| env: | |
| PKG_CONFIG_ALLOW_CROSS: 1 | |
| run: | | |
| if [[ "${{ matrix.settings.target }}" == *"windows"* ]]; then | |
| cargo build --release --target ${{ matrix.settings.target }} --bin domino | |
| BINARY_SOURCE="target/${{ matrix.settings.target }}/release/domino.exe" | |
| BINARY_DEST="domino-${{ matrix.settings.target }}.exe" | |
| elif [[ "${{ matrix.settings.target }}" == *"linux-gnu"* ]]; then | |
| # Use cross to build with older GLIBC version (same approach as oxc) | |
| # Clean everything to avoid contamination from host-compiled dependencies | |
| rm -rf target/${{ matrix.settings.target }} | |
| rm -rf ~/.cargo/registry/cache | |
| rm -rf ~/.cargo/git/checkouts | |
| cross build --release --target=${{ matrix.settings.target }} --bin domino | |
| BINARY_SOURCE="target/${{ matrix.settings.target }}/release/domino" | |
| BINARY_DEST="domino-${{ matrix.settings.target }}" | |
| # Verify GLIBC requirement | |
| echo "Checking GLIBC requirement for binary:" | |
| objdump -T "$BINARY_SOURCE" | grep GLIBC | sed 's/.*GLIBC_\([.0-9]*\).*/\1/g' | sort -V | tail -1 || echo "No GLIBC symbols found" | |
| elif [[ "${{ matrix.settings.target }}" == *"musl"* ]]; then | |
| # Use cargo-zigbuild for musl targets (same approach as oxc) | |
| cargo zigbuild --release --target=${{ matrix.settings.target }} --bin domino | |
| BINARY_SOURCE="target/${{ matrix.settings.target }}/release/domino" | |
| BINARY_DEST="domino-${{ matrix.settings.target }}" | |
| else | |
| cargo build --release --target ${{ matrix.settings.target }} --bin domino | |
| BINARY_SOURCE="target/${{ matrix.settings.target }}/release/domino" | |
| BINARY_DEST="domino-${{ matrix.settings.target }}" | |
| fi | |
| # Copy binary to repo root with target suffix (like oxc: domino-{target} or domino-{target}.exe) | |
| cp "$BINARY_SOURCE" "$BINARY_DEST" | |
| echo "BINARY_PATH=$BINARY_DEST" >> $GITHUB_ENV | |
| 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 | |
| ${{ env.BINARY_PATH }} | |
| if-no-files-found: error | |
| test-macOS-windows-binding: | |
| name: Test bindings on ${{ matrix.settings.target }} - node@${{ matrix.node }} | |
| needs: | |
| - build | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| settings: | |
| - host: windows-latest | |
| target: x86_64-pc-windows-msvc | |
| architecture: x64 | |
| - host: macos-latest | |
| target: aarch64-apple-darwin | |
| architecture: arm64 | |
| - host: macos-latest | |
| target: x86_64-apple-darwin | |
| architecture: x64 | |
| node: | |
| - '20' | |
| - '22' | |
| runs-on: ${{ matrix.settings.host }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup node | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: ${{ matrix.node }} | |
| architecture: ${{ matrix.settings.architecture }} | |
| cache: yarn | |
| - name: Install dependencies | |
| run: yarn install --frozen-lockfile | |
| - name: Download artifacts | |
| uses: actions/download-artifact@v6 | |
| with: | |
| name: bindings-${{ matrix.settings.target }} | |
| path: . | |
| - name: List packages | |
| run: ls -R . | |
| shell: bash | |
| - name: Test bindings | |
| run: yarn test | |
| test-linux-binding: | |
| name: Test ${{ matrix.target }} - node@${{ matrix.node }} | |
| needs: | |
| - build | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| target: | |
| - x86_64-unknown-linux-gnu | |
| - x86_64-unknown-linux-musl | |
| - aarch64-unknown-linux-gnu | |
| node: | |
| - '20' | |
| - '22' | |
| runs-on: ${{ contains(matrix.target, 'aarch64') && 'ubuntu-24.04-arm' || 'ubuntu-latest' }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - name: Setup node | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: ${{ matrix.node }} | |
| cache: yarn | |
| - name: Output docker params | |
| id: docker | |
| run: | | |
| node -e " | |
| if ('${{ matrix.target }}'.startsWith('aarch64')) { | |
| console.log('PLATFORM=linux/arm64') | |
| } else if ('${{ matrix.target }}'.startsWith('armv7')) { | |
| console.log('PLATFORM=linux/arm/v7') | |
| } else { | |
| console.log('PLATFORM=linux/amd64') | |
| } | |
| " >> $GITHUB_OUTPUT | |
| node -e " | |
| if ('${{ matrix.target }}'.endsWith('-musl')) { | |
| console.log('IMAGE=node:${{ matrix.node }}-alpine') | |
| } else { | |
| console.log('IMAGE=node:${{ matrix.node }}-slim') | |
| } | |
| " >> $GITHUB_OUTPUT | |
| - name: Install dependencies | |
| run: yarn install --frozen-lockfile | |
| - name: Download artifacts | |
| uses: actions/download-artifact@v6 | |
| with: | |
| name: bindings-${{ matrix.target }} | |
| path: . | |
| - name: List packages | |
| run: ls -R . | |
| shell: bash | |
| - name: Set up QEMU | |
| uses: docker/setup-qemu-action@v3 | |
| if: ${{ contains(matrix.target, 'armv7') }} | |
| with: | |
| platforms: all | |
| - run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes | |
| if: ${{ contains(matrix.target, 'armv7') }} | |
| - name: Test bindings | |
| uses: addnab/docker-run-action@v3 | |
| with: | |
| image: ${{ steps.docker.outputs.IMAGE }} | |
| options: '-v ${{ github.workspace }}:${{ github.workspace }} -w ${{ github.workspace }} --platform ${{ steps.docker.outputs.PLATFORM }}' | |
| run: | | |
| # Reinstall dependencies inside container to get correct platform binaries | |
| # Host installed GNU binaries, but Alpine/musl needs musl binaries | |
| # This allows Yarn to re-evaluate optionalDependencies for the current platform | |
| yarn install | |
| yarn test | |
| save-pr-metadata: | |
| name: Save PR metadata | |
| if: github.event_name == 'pull_request' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Save PR number and head SHA | |
| run: | | |
| echo '{"pr_number": "${{ github.event.pull_request.number }}", "head_sha": "${{ github.event.pull_request.head.sha }}"}' > pr-metadata.json | |
| - uses: actions/upload-artifact@v5 | |
| with: | |
| name: pr-metadata | |
| path: pr-metadata.json | |
| publish: | |
| name: Publish | |
| if: github.event_name == 'push' | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| id-token: write | |
| needs: | |
| - lint | |
| - test-macOS-windows-binding | |
| - test-linux-binding | |
| steps: | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| token: ${{ secrets.GH_PAT || secrets.GITHUB_TOKEN }} | |
| - name: Setup node | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: 24 | |
| cache: yarn | |
| registry-url: https://registry.npmjs.org/ | |
| - name: Install dependencies | |
| run: yarn install --frozen-lockfile | |
| - name: Download all artifacts | |
| uses: actions/download-artifact@v6 | |
| with: | |
| path: artifacts | |
| - name: Determine version bump | |
| id: version | |
| run: | | |
| COMMIT_MSG=$(git log -1 --pretty=%s) | |
| if echo "$COMMIT_MSG" | grep -qE "^[0-9]+\.[0-9]+\.[0-9]+$"; then | |
| echo "Current commit is a version commit, skipping bump" | |
| echo "is_release=true" >> $GITHUB_OUTPUT | |
| exit 0 | |
| fi | |
| echo "is_release=false" >> $GITHUB_OUTPUT | |
| LAST_TAG=$(git describe --tags --abbrev=0 --match "v[0-9]*" 2>/dev/null || echo "") | |
| if [ -z "$LAST_TAG" ]; then | |
| LAST_TAG=$(git describe --tags --abbrev=0 --match "[0-9]*" 2>/dev/null || echo "") | |
| fi | |
| if [ -z "$LAST_TAG" ]; then | |
| echo "No previous tags found, using all commits" | |
| SUBJECTS=$(git log --format="%s" --no-merges) | |
| BODIES=$(git log --format="%b" --no-merges) | |
| else | |
| echo "Last tag: $LAST_TAG" | |
| SUBJECTS=$(git log "${LAST_TAG}..HEAD" --format="%s" --no-merges) | |
| BODIES=$(git log "${LAST_TAG}..HEAD" --format="%b" --no-merges) | |
| fi | |
| echo "=== Commits since last tag ===" | |
| echo "$SUBJECTS" | |
| echo "=== End commits ===" | |
| BUMP="patch" | |
| BUMP_REASON="default (no feat: or breaking changes detected)" | |
| if echo "$SUBJECTS" | grep -qE "^[a-z]+(\(.+\))?!:"; then | |
| BUMP="major" | |
| BREAKING_SUBJECT=$(echo "$SUBJECTS" | grep -E "^[a-z]+(\(.+\))?!:" | head -1) | |
| BUMP_REASON="breaking change in commit subject: ${BREAKING_SUBJECT}" | |
| elif echo "$BODIES" | grep -qE "^BREAKING[ -]CHANGE:"; then | |
| BUMP="major" | |
| BUMP_REASON="BREAKING CHANGE footer found in commit body" | |
| elif echo "$SUBJECTS" | grep -qE "^feat(\(.+\))?:"; then | |
| BUMP="minor" | |
| BUMP_REASON="feat: commit detected" | |
| fi | |
| echo "" | |
| echo "##################################################" | |
| echo "# Version bump: $BUMP" | |
| echo "# Reason: $BUMP_REASON" | |
| echo "##################################################" | |
| if [ "$BUMP" = "major" ]; then | |
| CURRENT_VERSION=$(node -p "require('./package.json').version") | |
| NEXT_MAJOR=$((${CURRENT_VERSION%%.*} + 1)).0.0 | |
| echo "" | |
| echo "::warning::MAJOR version bump detected: ${CURRENT_VERSION} → ${NEXT_MAJOR}" | |
| echo "::warning::Triggered by: ${BUMP_REASON}" | |
| echo "::warning::If this is unintentional, check commit messages for accidental '!:' suffix or 'BREAKING CHANGE:' footer" | |
| fi | |
| echo "bump=$BUMP" >> $GITHUB_OUTPUT | |
| - name: Bump version | |
| id: bump | |
| if: steps.version.outputs.is_release != 'true' | |
| run: | | |
| npm version ${{ steps.version.outputs.bump }} --no-git-tag-version --ignore-scripts | |
| node scripts/sync-cargo-version.js | |
| NEW_VERSION=$(node -p "require('./package.json').version") | |
| echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT | |
| echo "Bumped to $NEW_VERSION" | |
| - name: Generate packages | |
| if: steps.version.outputs.is_release != 'true' | |
| run: node scripts/generate-packages.js | |
| - name: List packages | |
| if: steps.version.outputs.is_release != 'true' | |
| run: ls -R ./npm | |
| shell: bash | |
| - name: Publish to npm | |
| if: steps.version.outputs.is_release != 'true' | |
| run: | | |
| PKG_NAME=$(node -p "require('./package.json').name") | |
| PKG_VERSION=$(node -p "require('./package.json').version") | |
| if npm view "${PKG_NAME}@${PKG_VERSION}" version >/dev/null 2>&1; then | |
| echo "Version ${PKG_VERSION} already published, skipping" | |
| exit 0 | |
| fi | |
| npm config set provenance true | |
| npm publish --access public | |
| env: | |
| NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} | |
| - name: Push version commit and tag | |
| if: steps.version.outputs.is_release != 'true' | |
| env: | |
| HUSKY: '0' | |
| run: | | |
| git config user.name "github-actions[bot]" | |
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | |
| # generate-packages.js bumps optionalDependencies to the new version — refresh lockfile | |
| # so CI (yarn install --frozen-lockfile) does not fail on the version commit. | |
| # Yarn defaults to immutable installs on CI, so allow lockfile updates here. | |
| # Retry yarn install to handle npm registry propagation delay after publish. | |
| for i in 1 2 3 4 5; do | |
| if YARN_ENABLE_IMMUTABLE_INSTALLS=false yarn install; then | |
| break | |
| fi | |
| echo "yarn install attempt $i failed, retrying in 15s..." | |
| sleep 15 | |
| done | |
| git add package.json Cargo.toml yarn.lock | |
| git commit -m "${{ steps.bump.outputs.new_version }}" | |
| git tag "v${{ steps.bump.outputs.new_version }}" | |
| git push --atomic origin main "v${{ steps.bump.outputs.new_version }}" |