Skip to content

Repository files navigation

Checks

ExodusMovement/lerna-release-action

Action that allows selectively releasing packages in a lerna monorepo. It works around lerna's opinionated releasing of every dependant if a package changed. This comes with its own dangers and should be used with caution. The action creates a release PR that is assigned to the user that dispatched the workflow.

Version workflow

name: Version
on:
  workflow_dispatch:
    inputs:
      packages:
        description: 'Selected packages as comma separated string, e.g. @exodus/storage-spec,@exodus/formatting or just storage-spec,formatting'
        type: string
        required: true

jobs:
  version:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - uses: actions/setup-node@v3
        with:
          node-version-file: '.nvmrc'
      - name: Enable package manager
        run: corepack enable
      - name: Install dependencies
        run: corepack pnpm install --frozen-lockfile
      - uses: ExodusMovement/lerna-release-action/version@master
        name: Version
        with:
          github-token: ${{ secrets.GH_AUTOMATION_PAT }} # should not be the default GITHUB_TOKEN, otherwise subsequent automation will not run (such as checks on the release PR)
          packages: ${{ inputs.packages }}

Enabling auto-merge

The Version action can enable auto-merge on the created pull request. This is possible when the repository allows auto-merge, squash merging is enabled and has branch protection rules set up.

To use it, set the auto-merge input of the action to true.

- uses: ExodusMovement/lerna-release-action/version@master
  name: Version
  with:
    # other inputs here
    auto-merge: true

Publish workflow

name: Publish
on:
  pull_request:
    types:
      - closed
  workflow_dispatch:

jobs:
  publish:
    runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v3
      with:
        ref: ${{ github.event.pull_request.head.sha }}
    - uses: actions/setup-node@v3
      with:
        node-version-file: '.nvmrc'
    - name: Enable package manager
      run: corepack enable
    - name: Install dependencies
      run: corepack pnpm install --frozen-lockfile
    - name: Build
      run: corepack pnpm run build
    - name: Publish
      uses: ExodusMovement/lerna-release-action/publish@master

When refreshing the lockfile after selective versioning, the action prefers the repository's declared package manager from the root package.json#packageManager or lerna.json#npmClient. If neither is present, it falls back to lockfile detection.

Version dispatch workflow

Automatically start versioning of packages when a PR is merged. Requires using ExodusMovement/lerna-package-name-action to label PRs, as these package labels will be used to determine the packages to be versioned.

name: Version dispatch
on:
  pull_request:
    types:
      - opened
      - synchronize
      - reopened
      - edited # required: the PR title gates the release, so title edits must re-run this
      - labeled
      - unlabeled
      - closed

jobs:
  invoke-versioning:
    if: contains(github.event.pull_request.labels.*.name , 'publish-on-merge') == false && contains(github.event.pull_request.labels.*.name , 'skip-release') == false
    name: Invoke version workflow
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: ExodusMovement/lerna-release-action/version-dispatch@master
        with:
          version-workflow-id: version.yaml
          github-token: ${{ secrets.GH_AUTOMATION_PAT }}
          exclude-commit-types: chore,docs,test,ci

PR title gates the release

A PR whose title carries no release-worthy conventional-commit type (chore:, docs:, refactor:, or a non-conventional subject) releases nothing, whatever its individual commits say — no version dispatch on merge, and no version preview comment while the PR is open.

The reason is squash merging: the PR title becomes the commit on the default branch, and changelogs are generated from that history. A chore: title cannot produce a changelog entry, so releasing on the PR's commits would publish a version whose changelog reads **Note:** Version bump only for package ….

To release from a PR, give it a feat:, fix:, perf: or breaking (!) title. The title decides whether anything releases at all, and commit-level types decide which packages bump. The commits also decide by how much, unless the title is breaking.

Because the title is part of the gate, include edited in the workflow's types: — otherwise retitling a PR leaves a stale preview comment (or a missing one) until the next push.

A breaking PR title releases a major

A ! in the title promotes every package the PR releases to major, whatever level its individual commits carry. Squash merging is again the reason: the title is the commit that lands on the default branch, so its ! is what the generated changelog and every consumer see. A feat(x)!: title over a plain feat(x): commit would otherwise cut a minor whose changelog carries a BREAKING CHANGES section, and consumers would resolve the incompatible version through a range that still matches it.

The title never widens the release set. A package that no releasing commit touched stays unreleased, because only the commits carry the per-package file attribution.

Running from a subdirectory

All three actions (version, publish, version-dispatch) accept an optional path input — the working directory to run in, relative to the checkout root. Set it when the lerna workspace lives in a subdirectory of the repository rather than at its root:

- uses: ExodusMovement/lerna-release-action/version@master
  with:
    github-token: ${{ secrets.GH_AUTOMATION_PAT }}
    packages: ${{ inputs.packages }}
    path: apps/mobile

The actions still create commits, tags and PRs against the whole repository — path only scopes where lerna, the package manager and workspace discovery run. When omitted, the actions run at the checkout root exactly as before.

About

Selectively release packages from a lerna monorepo

Resources

Stars

1 star

Watchers

6 watching

Forks

Releases

Packages

Used by

Contributors

Languages