πŸš€ Stop Copy-Pasting NPM Publish Workflows – I Built a Reusable GitHub Action



This content originally appeared on DEV Community and was authored by Phuc (Felix) Bui

Ever find yourself copying the same GitHub Actions workflow across multiple npm packages? I got tired of maintaining duplicate publishing workflows, so I built a reusable action that handles it all.

The Problem 😤

I was copy-pasting this same workflow across 10+ repositories:

  • Setup Node.js and PNPM
  • Run tests (if they exist)
  • Update package.json version
  • Build the package
  • Publish to NPM
  • Commit changes back

Every time I wanted to improve the workflow, I had to update it in multiple repos. Not fun!

The Solution ✨

I created Publish NPM Action – a single reusable action that handles the entire npm publishing pipeline.

What it does:

  • 🧪 Smart testing – Automatically detects and runs tests
  • 📦 Version sync – Updates package.json with your release tag
  • 🏗 Flexible building – Works with any build system
  • 🔄 Git integration – Commits build files back to your repo
  • 🛡 Secure publishing – Handles NPM authentication safely

Usage – Dead Simple 💫

Just create .github/workflows/publish.yml:

name: Publish on Release

on:
  release:
    types: [published]

permissions:
  contents: write
  packages: write

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
        with:
          ref: main
          token: ${{ secrets.GITHUB_TOKEN }}
          fetch-depth: 0

      - name: Publish NPM Package
        uses: phucbm/publish-npm-action@v1
        with:
          npm-token: ${{ secrets.NPM_TOKEN }}

That’s it! Create a release, and your package automatically publishes to NPM.

Advanced Configuration 🛠

Need customization? The action is highly configurable:

- name: Publish NPM Package
  uses: phucbm/publish-npm-action@v1
  with:
    npm-token: ${{ secrets.NPM_TOKEN }}
    # node-version: '20'                               # Node.js version, default is '18'
    # build-command: 'npm run build:prod'              # Build command, default is 'pnpm build'
    # output-dir: 'build/'                             # Output directory, default is 'dist/'
    # target-branch: 'develop'                         # Target branch, default is 'main'
    # skip-tests: 'true'                               # Skip tests, default is 'false'
    # commit-files: 'CHANGELOG.md docs/ types/'        # Additional files to commit, default is ''

Perfect for different project setups:

  • React apps: output-dir: 'build/'
  • TypeScript libs: commit-files: 'types/'
  • Monorepos: Custom build commands and paths

Real-World Benefits 🎯

Since switching to this action:

  • ✅ 15-line workflows instead of 80+ lines
  • ✅ Centralized updates – improve once, benefits everywhere
  • ✅ Zero maintenance per repository
  • ✅ Consistent publishing across all projects
  • ✅ Less copy-paste errors

Quick Setup Guide 📋

  1. Add NPM token to GitHub Secrets as NPM_TOKEN
  2. Copy the workflow above to .github/workflows/publish.yml
  3. Create a release with semantic versioning (e.g., v1.2.3)
  4. Watch the magic happen! 🪄

The action handles everything: tests, builds, version updates, and publishing.

Try It Out! 🚀

The action is available on the GitHub Marketplace.

Have feedback or feature requests? Drop them in the GitHub repo!

What’s your npm publishing workflow like? Have you automated it? Drop a comment below! 👇


This content originally appeared on DEV Community and was authored by Phuc (Felix) Bui