Skip to content

feat: Add GitHub Actions workflow for automated npm publishing#13

Merged
mokhld merged 16 commits intomainfrom
feature/release-pipeline
Mar 19, 2025
Merged

feat: Add GitHub Actions workflow for automated npm publishing#13
mokhld merged 16 commits intomainfrom
feature/release-pipeline

Conversation

@mokhld
Copy link
Copy Markdown
Contributor

@mokhld mokhld commented Mar 14, 2025

Description

This PR introduces enhancements to our GitHub Actions publishing workflow (publish.yml) to support:

  • Semantic versioning control via commit messages.
  • Multiple major-version release branches (release/v1, release/v2, etc.) with dedicated npm dist-tags.
  • Manual workflow triggers with flexible publishing options.

Why are we doing this?

We want to:

  • Clearly manage multiple major versions of our package simultaneously.
  • Allow easy backporting/ cherry-picking of fixes and features to older major versions without affecting the latest release.
  • Provide explicit control over semantic version bumps (patch, minor, major) directly from commit messages.
  • Enable on-demand publishing with configurable options for special cases via the workflow.

What's changing?

1. Automatic Patch Versioning for Regular Code Changes

When PRs with file changes are merged to main or a release branch:

  • The workflow automatically detects relevant file changes
  • It performs a build and then publishes a patch version bump
  • This happens without requiring any special commit messages

2. Semantic Versioning via Empty Commits

We can explicitly control the type of version bump by creating an empty commit with the keywords #minor or #major:

  • Default (no keyword): Patch (1.0.01.0.1)
  • Include #minor: Minor (1.0.01.1.0)
  • Include #major: Major (1.0.02.0.0)

E.g:

git commit --allow-empty -m "chore(release): #minor" # Minor bump
git commit --allow-empty -m "chore(release): #major" # Major bump

3. Major-Version Release Branches

We can now support long-lived release branches for each major version:

  • Branch naming: release/v1, release/v2, etc.
  • Each branch maintains its own semantic versioning independently.
  • Each branch publishes to npm with a dedicated dist-tag, ensuring older versions don't overwrite the default latest tag.

Example:

  • main branch publishes as latest (e.g., 3.0.0, 3.1.0, etc.)
  • release/v2 branch publishes as 2x (e.g., 2.0.0, 2.0.1, 2.1.0, etc.)
  • Users can install specific major versions easily:
    npm install @defra/forms-engine-plugin # latest from main
    npm install @defra/forms-engine-plugin@2x # latest from release/v2

4. Manual Workflow Trigger

We've added a manual workflow trigger with configurable options:

  • Version bump type: Explicitly choose patch, minor, or major
  • Custom npm tag: Always specify a custom tag when publishing from non-standard branches- defaults is beta. You don't have to specific a tag if it's a release branch as it will pick it up from there.
  • Dry run mode: Test the publishing process without actually publishing- this is true by default.

This allows for special publishing scenarios like beta releases, or when we need to publish outside the normal merge process.

How does this workflow trigger?

The workflow runs in three ways:

1. Standard Development Flow (File Changes)

When PR is merged to main:

PR with code changes → main → build → patch bump → publish with "latest" tag

Example:

  • You develop a bug fix on a feature branch
  • Create a PR targeting main
  • After approval, you merge the PR
  • The workflow builds and publishes version 1.0.1 with the beta tag
  • Users get this version when they run npm install @defra/forms-engine-plugin

2. Backporting to Release Branches

Cherry-pick commits to release branches:

Cherry-pick bug fix → release/v2 → build → patch bump → publish with "2x" tag

Example:

  • We have a critical bug fix in main (version 3.0.0)
  • You cherry-pick the fix to release/v2 to support users of the plugin that are using one of the stable release branches:
    git checkout release/v2
    git cherry-pick abc123def  # Commit hash from main
    git push origin release/v2
  • The workflow builds and publishes version 2.0.1 with the 2x tag
  • Users on version 2 get the fix with npm install @defra/forms-engine-plugin@2x

3. Version Bumps via Empty Commits

Minor version bump on release branch:

Empty commit with #minor → release/v2 → build → minor bump → publish with "2x" tag

Example:

  • We need to release a new minor version on release/v2 after several patches
  • Push an empty commit with the MINOR keyword:
    git checkout release/v2
    git commit --allow-empty -m "release: #minor version bump"
    git push origin release/v2
  • The workflow builds and publishes version 2.1.0 with the 2x tag

Major version bump on main:

Empty commit with #major → main → build → #major bump → publish with "latest" tag

Example:

  • We want to release version 4.0.0 from main (currently at 3.x.x)
  • Push an empty commit with the #major keyword:
    git checkout main
    git commit --allow-empty -m "release: #major version for breaking changes"
    git push origin main
  • The workflow builds and publishes version 4.0.0 with the beta tag

4. Special Releases via Manual Workflow

Beta release from feature branch:

Manual trigger → feature/foo-bar→ select "minor" + tag "beta" → build → publish with "beta" tag

Example:

  • We have new feature in development or just want to test out a beta before V1 for example:
    1. Go to Actions → Publish Engine Plugin → Run workflow
    2. Select our feature branch
    3. Set version bump to "minor"
    4. Set npm tag to "beta"
    5. Run the workflow
  • The workflow builds and publishes with the beta tag
  • Testers can install with npm install @defra/forms-engine-plugin@beta

@mokhld mokhld force-pushed the feature/release-pipeline branch from acd76b5 to 8f7ab82 Compare March 17, 2025 15:44
@mokhld mokhld changed the title Feature/release pipeline feat: Add GitHub Actions workflow for automated npm publishing Mar 17, 2025
@mokhld mokhld marked this pull request as ready for review March 17, 2025 16:46
@mokhld mokhld requested a review from a team March 17, 2025 16:47
@whitewaterdesign
Copy link
Copy Markdown
Contributor

whitewaterdesign commented Mar 17, 2025

Looking good. Just one question, on the release branches, is there any protection in case we are in the wrong branch and push a commit?

@mokhld
Copy link
Copy Markdown
Contributor Author

mokhld commented Mar 17, 2025

Looking good. Just one question, on the release branches, is there any protection in case we are in the wrong branch and push a commit?

It will have to go through a PR ultimately for main. For the release branches we can setup a rule to prevent direct merges: https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/managing-a-branch-protection-rule

Comment thread .github/workflows/publish.yml Outdated
Comment thread .github/workflows/publish.yml Outdated
Comment thread .github/workflows/publish.yml Outdated
@alexluckett
Copy link
Copy Markdown
Contributor

alexluckett commented Mar 18, 2025

Looking good. Just one question, on the release branches, is there any protection in case we are in the wrong branch and push a commit?

We'll add branch protection on those branches. That won't sit in this workflow though, just in the repo settings.

@sonarqubecloud
Copy link
Copy Markdown

@mokhld mokhld requested a review from alexluckett March 18, 2025 17:18
@mokhld mokhld merged commit b4be3f9 into main Mar 19, 2025
10 checks passed
@mokhld mokhld deleted the feature/release-pipeline branch March 19, 2025 10:36
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.

3 participants