Skip to content

Nx Release - Affected Logic #33276

@marc-wilson

Description

@marc-wilson

Current Behavior

In a multi-app monorepo, nx release (version/publish) appears to assume all releaseable projects were built, which conflicts with Nx’s “affected” workflow. This effectively forces a choice between using affected or using release.

Example CI (simplified)

- run: npx nx affected -t lint,test,build,docker:build
- run: npx nx release version --dockerVersion=${{ github.sha }}
- run: npx nx release publish

On every PR, we only build affected apps/targets (great!).
But nx release publish then tries to publish everything in the release group, implicitly assuming every project has its artifact ready (e.g., container images), which breaks the affected pattern.


Expected behavior

  • A way for nx release to respect the affected graph, or
  • First-class flags/inputs so version/publish can target only affected projects (or a provided subset) without custom scripting.

Examples:

nx release version --projects $(npx nx show projects --affected)
nx release publish --projects $(npx nx show projects --affected)

Or even a native --affected flag for nx release version/publish.


Actual behavior

  • nx release publish considers all projects in the release group (or repo), which assumes non-affected projects were also built and are ready to publish.
  • This conflicts with the incremental/affected workflow that Nx promotes as a core feature.

Why this matters

Nx positions “affected” as a core productivity/value driver. When release requires publishing everything, pipelines either:

  1. Abandon “affected” and build everything every time (slow, costly), or
  2. Add custom glue code around nx release to filter projects (more complexity).

This breaks one of Nx’s biggest selling points—incremental builds and deploys.


Minimal reproduction (conceptual)

  1. Monorepo with multiple publishable apps/packages (each with docker:build and a release group).
  2. Change one app.
  3. Run:
    npx nx affected -t docker:build
    npx nx release version
    npx nx release publish
  4. Observe publish attempts to release all projects, not just the affected/built ones.

The docker example uses run-many which isn't a good idea because my repo is quite large.

name: Docker Publish

on:
  push:
    branches: [main]

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: 20

      - name: Install dependencies
        run: npm ci

      - name: Build applications
        run: npx nx run-many -t build

      - name: Login to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_TOKEN }}

      - name: Build and tag Docker images
        run: npx nx release version --dockerVersionScheme=production

      - name: Publish Docker images
        run: npx nx release publish

There's this one which doesn't build anything at all. so not really a realistic example

name: Publish

on:
  push:
    tags:
      - v*.*.*

jobs:
  test:
    name: Publish
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write # needed for provenance data generation
    timeout-minutes: 10
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
        with:
          fetch-depth: 0
          filter: tree:0

      - name: Install Node
        uses: actions/setup-node@v4
        with:
          node-version: 20
          registry-url: https://registry.npmjs.org/

      - name: Install dependencies
        run: npm install
        shell: bash

      - name: Print Environment Info
        run: npx nx report
        shell: bash

      - name: Publish packages
        run: npx nx release publish
        shell: bash
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_ACCESS_TOKEN }}
          NPM_CONFIG_PROVENANCE: true

Expected Behavior

nx release should not try and publish things that aren't affected or provide some --affected flag.

GitHub Repo

No response

Steps to Reproduce

  1. Create a monorepo
  2. Make one of your libs or apps with a docker container "releasable"
  3. Put together a GitHub pipeline that only releases your "releasable" app when it has been affected

Nx Report

Node           : 22.12.0
OS             : darwin-arm64
Native Target  : aarch64-macos
pnpm           : 10.19.0

nx                     : 22.0.1
@nx/js                 : 22.0.1
@nx/jest               : 22.0.1
@nx/eslint             : 22.0.1
@nx/workspace          : 22.0.1
@nx/devkit             : 22.0.1
@nx/esbuild            : 22.0.1
@nx/eslint-plugin      : 22.0.1
@nx/module-federation  : 22.0.1
@nx/nest               : 22.0.1
@nx/next               : 22.0.1
@nx/node               : 22.0.1
@nx/plugin             : 22.0.1
@nx/react              : 22.0.1
@nx/rollup             : 22.0.1
@nx/vite               : 22.0.1
@nx/web                : 22.0.1
@nx/webpack            : 22.0.1
@nx/docker             : 22.0.1
typescript             : 5.9.3
---------------------------------------
Registered Plugins:
@nx/js/typescript
@nx/next/plugin
@nx/jest/plugin
@nx/eslint/plugin
@nx/docker
@nx/vite/plugin
@nx/webpack/plugin
@nx/js/typescript

Failure Logs

Package Manager Version

No response

Operating System

  • macOS
  • Linux
  • Windows
  • Other (Please specify)

Additional Information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions