DEV Community

Andrea Stagi
Andrea Stagi

Posted on • Edited on

Publish to NPM using GitHub Actions

I recently needed to find a way to publish packages to NPM automatically and since all my projects are hosted on GitHub I thought why not using GitHub actions? In this article I explain how to do that in 3 simple steps!

👉🏻 Pssst... you can also check some real life examples:

Generate a new token on NPM

First of all you need to create a new NPM token that will be used to publish packages to NPM.

From NPM dashboard open main menu and select "Access token", then click on "Generate new token"

image

select "Automation" token to bypass two-factor authentication when publishing

image

then copy your token, it will be used as a GitHub secret as explained in the next section

image

Store your token as a GitHub secret

GitHub Actions can access your GitHub secrets, so that's the perfect place where to store your token!

Under "Settings" -> "Secrets" click on "New repository secret" and add your NPM Token your previously copied (in this example I use NPM_TOKEN label to identify it)

image

Now it's time to write some code and create a new action to publish your package!

Write your action

Create a new GitHub Action publish.yml inside your project under .github/workflows.



name: Publish to NPM
on:
  release:
    types: [created]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Setup Node
        uses: actions/setup-node@v2
        with:
          node-version: '14.x'
          registry-url: 'https://registry.npmjs.org'
      - name: Install dependencies and build 🔧
        run: npm ci && npm run build
      - name: Publish package on NPM 📦
        run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}


Enter fullscreen mode Exit fullscreen mode

This action should run only when you create a new release on GitHub



on:
  release:
    types: [created]


Enter fullscreen mode Exit fullscreen mode

The steps it executes are really clear:

  • Checkout code
  • Setup Node.js environment (using Node.js 14.x here)
  • Install dependencies and build your package (if needed)
  • Publish to NPM! As you can see this step uses our NPM_TOKEN secret to initialize NODE_AUTH_TOKEN env variable

  <span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">Publish package to NPM 📦</span>
    <span class="na">run</span><span class="pi">:</span> <span class="s">npm publish</span>
    <span class="na">env</span><span class="pi">:</span>
      <span class="na">NODE_AUTH_TOKEN</span><span class="pi">:</span> <span class="s">${{ secrets.NPM_TOKEN }}</span>
Enter fullscreen mode Exit fullscreen mode
Enter fullscreen mode Exit fullscreen mode




Create a new release

In order to see your action running, you need to create a new release on GitHub.

image

After that your package will be successfully published to NPM 🎉

Top comments (10)

Collapse
 
ivangsp profile image
Ivan gsp

Thank you for sharing, I was able to publish my package by following your guide

Collapse
 
msrajawat298 profile image
Mayank Singh Kushwah

I got this error can someone help me ?
github.com/vitabletec/general-js-t...
Successfully compiled 3 files with Babel (545ms).
npm notice
npm notice 📦 general-js-toolkit@1.0.1
npm notice === Tarball Contents ===
npm notice 1.9kB dist/test/util.spec.js
npm notice 401B dist/index.js

npm notice 10.8kB dist/util.js

npm notice 2.2kB package.json

npm notice 1.8kB readme.md

npm notice === Tarball Details ===
npm notice name: general-js-toolkit

npm notice version: 1.0.1

npm notice filename: general-js-toolkit-1.0.1.tgz

npm notice package size: 5.1 kB

npm notice unpacked size: 17.2 kB

npm notice shasum: 18c7147b68eb2c56a968bfb6bd41be4321425571
npm notice integrity: sha512-CVl0X9wdh/hlh[...]VPdCmFSytoGNA==
npm notice total files: 5

npm notice
npm ERR! code ENEEDAUTH
npm ERR! need auth This command requires you to be logged in to registry.npmjs.org/
npm ERR! need auth You need to authorize this machine using npm adduser

npm ERR! A complete log of this run can be found in:
npm ERR! /home/runner/.npm/_logs/2023-03-23T13_22_53_572Z-debug-0.log
Error: Process completed with exit code 1.

[debug]Finishing: Build and publish

Collapse
 
eliav2 profile image
Eliav2

finally got it!!! registry-url: "https://registry.npmjs.org" is important! see ! so make sure to include it.

sharing my final workflow, which works with pnpm workspaces with cache:

name: Publish to NPM
on:
  release:
    types: [created]
jobs:
  build-and-publish-express-typed:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          registry-url: "https://registry.npmjs.org"
      - uses: pnpm/action-setup@v3
        name: Install pnpm
        with:
          version: 9
          run_install: false
      - name: Get pnpm store directory
        shell: bash
        run: |
          echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
      - uses: actions/cache@v4
        name: Setup pnpm cache
        with:
          path: ${{ env.STORE_PATH }}
          key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
          restore-keys: |
            ${{ runner.os }}-pnpm-store-

      - name: Install dependencies
        run: pnpm install
        working-directory: packages/express-typed
      # no need to build the package, prepublish script will take care of it
      - name: Publish package on NPM 📦
        run: npm publish
        working-directory: packages/express-typed
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
airtonix profile image
Zenobius Jiricek • Edited

protip: instead of using all the disparate setup this setup that actions (and then most likely not replicating that in local dev)....

just use asdf locally and then asdf-vm/actions/install@v3 in your worfklow.

Now your entire toolchain is versioned by one file .tool-versions and your local dev will always match your ci toolchain and vice versa.

common .tool-versions I use is:

just 1.25.2
nodejs 20.12.1
yarn 1.22.19
shellcheck 0.9.0
jq 1.7.1
yq 4.44.2
shfmt 3.8.0
action-validator 0.6.0
act 0.2.63
Enter fullscreen mode Exit fullscreen mode

#friendsdontletfriendsusenvm

Collapse
 
varundeva profile image
Varun Deva

In github repo at right side it will show publish your package.
At that place does npm package url will gets updated??

Collapse
 
astagi profile image
Andrea Stagi

No that section is related to GitHub packages, in case you use GitHub's packaging system.. I usually hide that section from settings if I publish packages to NPM.

Collapse
 
varundeva profile image
Varun Deva

Got it.
Thank you

Collapse
 
greggman profile image
Greggman

Should you be using npm ci && npm run build?

Collapse
 
astagi profile image
Andrea Stagi

+1 for CI! Thanks!

Collapse
 
fuco profile image
Jakub Bednár

Tyvm, this has helped me a ton :)