Skip to content

Conversation

@daniel-samson
Copy link
Owner

@daniel-samson daniel-samson commented Dec 8, 2025

Summary

Replace the outdated Github-Actions-Community/merge-release action with semantic-release, the modern, industry-standard solution for automated versioning and npm package publishing.

Problem with merge-release

The current merge-release action has several limitations:

  • ❌ Unmaintained (last release August 2023)
  • ❌ Open issue: "The 'latest version' is wrong" (April 2024)
  • ❌ Limited OIDC/trusted publishing support
  • ❌ Poor error messages and debugging
  • ❌ No automatic changelog generation
  • ❌ Limited npm ecosystem integration

Solution: semantic-release

semantic-release is the industry standard with:

  • ✅ 3000+ GitHub stars, actively maintained
  • ✅ Full npm trusted publishing support with OIDC
  • ✅ Automatic package provenance attestation
  • ✅ Semantic versioning based on conventional commits
  • ✅ Automatic changelog generation (CHANGELOG.md)
  • ✅ GitHub release integration
  • ✅ Better error handling and debugging
  • ✅ Used by thousands of JavaScript projects

Changes

1. publish.yml Updates

  • Replace Github-Actions-Community/merge-release@main with cycjimmy/semantic-release-action@v4
  • Add required permissions: contents: write, issues: write, pull-requests: write
  • Add fetch-depth: 0 to get full commit history for analysis
  • Simplify to use npm ci instead of cache (cleaner)
  • Remove custom publish logic, let semantic-release handle it

2. New .releaserc.json Configuration

Created semantic-release configuration with plugins:

{
  "branches": ["main"],
  "plugins": [
    "@semantic-release/commit-analyzer",       // Analyze commits for version
    "@semantic-release/release-notes-generator", // Generate release notes
    "@semantic-release/changelog",             // Create CHANGELOG.md
    "@semantic-release/npm",                   // Publish to npm
    "@semantic-release/git",                   // Commit version changes
    "@semantic-release/github"                 // Create GitHub releases
  ]
}

3. Commit Message Format (Conventional Commits)

Releases are triggered automatically based on commit message prefixes:

Commit Type Example Version Impact
feat: feat: add new feature Minor bump (1.0.0 → 1.1.0)
fix: fix: resolve bug Patch bump (1.0.0 → 1.0.1)
BREAKING CHANGE: In message body Major bump (1.0.0 → 2.0.0)

Benefits

Security

  • ✅ Full OIDC trusted publishing support (no long-lived tokens)
  • ✅ Automatic package provenance generation
  • ✅ Each publish uses unique, short-lived OIDC tokens

Automation

  • ✅ Automatic version bumping from commit messages
  • ✅ Automatic changelog generation
  • ✅ Automatic GitHub release creation
  • ✅ Automatic git commit with version bump

Quality

  • ✅ Professional release notes
  • ✅ Semantic versioning (prevents version mistakes)
  • ✅ Better error messages
  • ✅ Industry standard solution

Maintenance

  • ✅ Well-maintained project
  • ✅ Large community
  • ✅ Good documentation
  • ✅ Regular updates

Permissions

The publish job now requires:

  • id-token: write - For OIDC token generation (npm trusted publishing)
  • contents: write - For pushing version commits and tags
  • issues: write - For GitHub integration
  • pull-requests: write - For GitHub integration

Testing

To test locally:

npx semantic-release --dry-run

This will simulate the release process without publishing or pushing.

Migration Notes

The project's existing commit history and future commits should follow Conventional Commits format for automatic version bumping to work correctly:

feat: add new feature
fix: resolve bug
BREAKING CHANGE: <description>

References

🤖 Generated with Claude Code


Note

Replaces merge-release with semantic-release, updates publish workflow permissions/steps, restricts to main, and adds .releaserc.json for automated versioning/releases.

  • CI/CD (.github/workflows/publish.yml)
    • Replace custom publish steps with cycjimmy/semantic-release-action@v4 (+ @semantic-release/git, @semantic-release/changelog).
    • Update permissions to include contents: write, issues: write, pull-requests: write; keep id-token: write.
    • Checkout with fetch-depth: 0 for full history; use npm ci and npm run build.
    • Restrict publish to pushes on main only.
  • Release Configuration (.releaserc.json)
    • Add semantic-release setup: commit analysis, release notes, changelog generation, npm publish, git commit of release artifacts, and GitHub releases.
    • Configure assets (package.json, package-lock.json, CHANGELOG.md) and release commit message format.

Written by Cursor Bugbot for commit 049bf17. This will update automatically on new commits. Configure here.

@daniel-samson
Copy link
Owner Author

@claude please review this pr

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the final PR Bugbot will review for you during this billing cycle

Your free Bugbot reviews will reset on January 27

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

Replace the outdated Github-Actions-Community/merge-release action with
semantic-release, which is the modern, well-maintained standard for
automated versioning and npm package publishing.

**Why semantic-release?**
- Actively maintained with 3000+ GitHub stars
- Industry standard for automated releases
- Better support for npm trusted publishing with OIDC
- Automatic changelog generation
- Semantic versioning based on conventional commits
- Better error handling and debugging

**Changes:**
1. Replace merge-release with cycjimmy/semantic-release-action@v4
2. Add semantic-release configuration (.releaserc.json)
3. Update permissions to allow GitHub integration (contents: write, issues: write, pull-requests: write)
4. Add fetch-depth: 0 for full commit history analysis
5. Configure semantic-release plugins:
   - @semantic-release/commit-analyzer (analyze commits for version bumping)
   - @semantic-release/release-notes-generator (generate release notes)
   - @semantic-release/changelog (maintain CHANGELOG.md)
   - @semantic-release/npm (publish to npm)
   - @semantic-release/git (commit version changes back)
   - @semantic-release/github (create GitHub releases)

**Commit Message Format:**
Commit messages must follow Conventional Commits format:
- feat: new feature → minor version bump
- fix: bug fix → patch version bump
- BREAKING CHANGE: → major version bump

**Benefits:**
- ✅ Better npm trusted publishing support with OIDC
- ✅ Automatic package provenance
- ✅ Professional release notes and changelog
- ✅ Semantic versioning automation
- ✅ GitHub release integration
- ✅ Better error messages and debugging
- ✅ Widely used in the JavaScript ecosystem

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@daniel-samson daniel-samson force-pushed the ci/modernize-publish-workflow branch from 97de1a4 to 049bf17 Compare December 8, 2025 19:05
@daniel-samson
Copy link
Owner Author

Bug Fixes Applied

Thanks to cursor bot for catching these issues! I've fixed both bugs:

1. ✅ Invalid JSON Syntax in branches parameter

Problem: The workflow had invalid YAML/JSON syntax:

branches: |
  [
    'main'
  ]

Single quotes in JSON arrays are invalid.

Solution: Removed the redundant branches parameter from the action config since .releaserc.json already defines the branch configuration. The semantic-release action will read from .releaserc.json which has the correct JSON: "branches": ["main"]

2. ✅ Branch Condition Mismatch

Problem: The workflow condition allowed both branches:

if: github.event_name == 'push' && ( github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' )

But .releaserc.json only configures main:

"branches": ["main"]

If the workflow triggered on master, semantic-release would skip the release.

Solution: Simplified the condition to only check for main:

if: github.event_name == 'push' && github.ref == 'refs/heads/main'

Changes Made

  • Removed invalid branches parameter from publish action config
  • Updated workflow condition to only check for main branch
  • Kept .releaserc.json with correct JSON syntax and proper configuration

The workflow should now function correctly with semantic-release!

@daniel-samson daniel-samson merged commit 798c2bc into main Dec 8, 2025
4 checks passed
@daniel-samson daniel-samson deleted the ci/modernize-publish-workflow branch December 8, 2025 19:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants