Understanding SemVer rules, how the commit analyzer determines the release type, and the pipeline flow from lint, build, dry run, through to release. Then dissecting the nine plugin pipeline steps along with the roles of semantic-release's core plugins.

In episode 1 we agreed that commit history can be the source of truth for deciding versions. Now the question shifts: how exactly? The answer lies in two things that form the foundation of semantic-release's architecture: Semantic Versioning (SemVer) as the language of versions, and the commit analyzer as the brain that translates commits into release decisions.
Imagine semantic-release as a factory receptionist reading the workers' daily notes. Every note is formatted, so it knows: "there's a new feature" means the serial number goes up one minor level, "there's a bug fix" goes up one patch level, and "there's a major change" goes up one major level. That whole process is written in code, not oral policy.
Semantic Versioning gives meaning to the MAJOR.MINOR.PATCH version numbers:
1.0.0 -> 1.1.0 (minor: new feature)
1.1.0 -> 1.1.1 (patch: bug fix)
1.1.1 -> 1.2.0-rc.1 (rc prerelease)
1.2.0-rc.1 -> 1.2.0 (stable after rc passes)Prereleases are written with a suffix such as 1.2.0-rc.1 and have lower precedence than stable 1.2.0. It's this property that the staging branch exploits to test release candidates before they go up to main.
The commit analyzer reads the commits since the last release tag and determines the release type: major, minor, patch, or no release at all.
v1.0.0 (last release tag)
|
+-- fix: fix email validation -> patch
+-- feat: add login page -> minor
|
v1.1.0 (next version)The release version is determined by the highest commit type in that window: a single feat bumps minor, a single breaking change bumps major. If there is no feat, fix, or breaking change, there is no new release — changelog, tag, and publish are all skipped.
A healthy release isn't triggered the moment a commit is pushed. A layered pipeline makes sure only code that passes verification gets released.
npm run lint
npm run build
npx semantic-release --dry-run --no-ci
npx semantic-releaseEach plugin implements one or more steps. The whole release flows through the following sequence:
1 verifyConditions
2 analyzeCommits
3 verifyRelease
4 generateNotes
5 prepare
6 publish
7 addChannel
8 success
9 failExplanation of each step:
null.package.json, CHANGELOG.md, or other artifacts.npm publish, or creating a GitHub Release.| Plugin | Main Step | Primary Task |
|---|---|---|
| commit-analyzer | analyzeCommits | Determine the release type from commits |
| release-notes-generator | generateNotes | Assemble the changelog |
| npm | verifyConditions, prepare, publish | Update package.json + publish to registry |
| github | verifyConditions, publish, success, fail | GitHub Release + PR comments + issues |
| git | prepare | Commit the prepare results + create the tag |
The git + npm combination is the most commonly used pairing: git commits the prepare results (new versions in package.json and CHANGELOG.md) and creates the tag, then npm publishes the package. This blog repo uses all five core plugins — feel free to open release.config.cjs and compare it with the table above.
Tip
Before enabling a real release, get into the habit of running npx semantic-release --dry-run --no-ci first. Its output shows the version that would be created, the changelog that would be generated, and which plugins would run — without touching git or the registry.
In episode 2 you learned:
rc suffix for prereleases.verifyConditions through fail.In episode 3 we'll focus on the language the commit analyzer reads: Conventional Commits — the type(scope): subject format, the common type list, and how to mark breaking changes. See you in episode 3!