5. Some automation magic using the (Lerna) CLI

2 min read

exile.watch logo
exile.watch logo

This page is part of The toolkit I needed to make it all happen list - 5/7


To avoid the hassle of manually managing versioning and publishing, I set up a straightforward GitHub Actions workflow to automate these processes for me:

# .github/workflows/release.yml
name: Release

on:
  push:
    paths:
      - 'packages/**'
    branches:
      - main

jobs:
  publish:
    name: Publish to NPM
    if: "!contains(github.event.head_commit.message, '[skip ci]')"
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          token: ${{ secrets.GH_TOKEN }}
          fetch-depth: 0 # Fetch-depth 0 necessary to get full commit history for checking changes

      - uses: actions/setup-node@v4
        with:
          node-version-file: '.nvmrc'
          cache: 'npm'

      - name: Configure Git
        run: |
          git config --global user.name "${{ secrets.GIT_USER_NAME }}"
          git config --global user.email "${{ secrets.GIT_USER_EMAIL }}"

      - name: "GitHub Package Registry Identity"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          echo "//npm.pkg.github.com/:_authToken=$GITHUB_TOKEN" > .npmrc
          echo "@exile-watch:registry=https://npm.pkg.github.com/" >> .npmrc

      - name: Install dependencies
        run: npm ci

      - name: Build
        run: npm run build

      - name: Lerna publish
        if: success()
        env:
          CI: true
          GH_TOKEN: ${{ secrets.GH_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
        run: lerna publish --yes

This GitHub Actions workflow, defined in .github/workflows/release.yml, automates the process of versioning and publishing our packages to NPM whenever changes are pushed to the main branch affecting any files within the packages/** directory.

Here's what each step accomplishes:

  • Checkout Repository Uses the actions/checkout@v4 action to check out your repository code, making it accessible to the workflow. The fetch-depth: 0 option ensures the entire commit history is available, which is crucial for Lerna to accurately determine version changes.

  • Setup Node.js The actions/setup-node@v4 action prepares the environment by setting up the Node.js version specified in the .nvmrc file. It also caches NPM dependencies to speed up the build process in future runs.

  • Configure Git Configures Git with the user name and email stored in your GitHub secrets. This information is used for commit operations performed by Lerna during the versioning process.

  • GitHub Package Registry Identity Sets up authentication for the GitHub Package Registry by writing the GitHub token to .npmrc. This step ensures that the workflow can publish packages to the GitHub Package Registry under your account.

  • Install Dependencies Runs npm ci to install the project dependencies based on the package-lock.json file. This command is preferred for continuous integration workflows as it installs dependencies faster and more reliably than npm install.

  • Build Executes the npm run build command to build the project. This step compiles the source code into an executable format before publishing.

  • Lerna Publish: Finally, the lerna publish --yes command, run only if all previous steps have succeeded, publishes the updated packages to NPM. The --yes flag automates the confirmation process, allowing Lerna to proceed without manual intervention. The environment variables CI, GH_TOKEN, and NPM_TOKEN are set to ensure Lerna can operate in the CI environment and authenticate with NPM and GitHub Package Registry as needed.


Moving beyond automation with Lerna's CLI, next up we explore the process of validating changes in our packages—how we ensure that updated packages integrate smoothly within exile.watch, whether through local bumps or prereleases.

Last updated