Skip to content

ci: automate releases with semantic-release#814

Merged
PascalRepond merged 1 commit into
rero:stagingfrom
PascalRepond:rep-auto-release
Jun 11, 2026
Merged

ci: automate releases with semantic-release#814
PascalRepond merged 1 commit into
rero:stagingfrom
PascalRepond:rep-auto-release

Conversation

@PascalRepond

Copy link
Copy Markdown
Contributor

Add a manually-triggered release workflow.

On dispatch from the staging branch, semantic-release analyzes conventional commits, bumps the version in both package.json files, updates CHANGELOG.md, tags vX.Y.Z and creates a GitHub Release, then fast-forwards master. The published Release triggers the existing publish.yml workflow to push the package to npm.

Breaking changes are mapped to a minor bump so the major version is never raised automatically: it stays pinned to the Angular major and is only moved during a deliberate Angular migration release.

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

This PR adds automated semantic versioning and release management to the repository. It introduces npm scripts and dependencies for semantic-release with its plugins for changelog generation, git operations, and command execution. A new .releaserc.json configuration file defines the release behavior, including staging branch targeting, commit type mappings to version bumps, dual-package version updates (root and ng-core), and GitHub publishing. A GitHub Actions workflow in .github/workflows/release.yml provides the manual trigger on the staging branch and orchestrates the full release and master fast-forward process.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: automating releases with semantic-release through new workflow and configuration files.
Description check ✅ Passed The description is directly related to the changeset, explaining the release workflow's behavior, version bumping strategy, and integration with the publish workflow.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
.github/workflows/release.yml (1)

18-18: ⚡ Quick win

Consider pinning GitHub Actions to commit SHAs for security.

Using tag references like @v6 means the action can be updated by the action maintainer, which could introduce supply chain risks. Pinning to a specific commit SHA ensures immutability.

Example of SHA pinning
       - name: Checkout
-        uses: actions/checkout@v6
+        uses: actions/checkout@b80ff79f1755d06ba70441c368a6fe801f5f3a62  # v6
         with:
           fetch-depth: 0

       - name: Use Node.js 24
-        uses: actions/setup-node@v6
+        uses: actions/setup-node@39370e3970a6d050c480ffad4ff0ed4d3fdee5af  # v6
         with:
           node-version: 24

You can find commit SHAs for specific versions on the actions' GitHub releases pages.

Also applies to: 27-27

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/release.yml at line 18, The workflow currently uses
floating tags like "actions/checkout@v6" (and another similar use at the other
"uses" line) which are mutable; update those "uses:" entries to pin to the
specific commit SHAs for the actions (e.g., replace actions/checkout@v6 with
actions/checkout@<commit-sha>) so the action is immutable and auditable,
obtaining the correct SHA from the action's GitHub releases/commits and applying
the same SHA-pinning pattern to the other "uses:" occurrence referenced in the
comment.

Source: Linters/SAST tools

.releaserc.json (2)

36-41: 💤 Low value

Consider adding validation for the nested package.json path.

The prepareCmd assumes projects/rero/ng-core/package.json exists. If the directory structure changes, the command will fail silently after versioning the root package.json, leaving an inconsistent state.

This is likely fine for a stable monorepo structure, but you could add a validation step:

-        "prepareCmd": "npm version ${nextRelease.version} --no-git-tag-version --allow-same-version && (cd projects/rero/ng-core && npm version ${nextRelease.version} --no-git-tag-version --allow-same-version)"
+        "prepareCmd": "npm version ${nextRelease.version} --no-git-tag-version --allow-same-version && test -f projects/rero/ng-core/package.json && (cd projects/rero/ng-core && npm version ${nextRelease.version} --no-git-tag-version --allow-same-version)"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.releaserc.json around lines 36 - 41, The prepareCmd currently runs npm
version for the root and then blindly for the nested package path in the
prepareCmd string; add a validation step to check that the nested package.json
at projects/rero/ng-core/package.json exists before running the second npm
version, and if it does not exist either abort the prepareCmd (so the root
change is not left inconsistent) or perform a rollback (e.g., reset root
package.json version) and surface a clear error; update the prepareCmd shell
snippet to test for the file (or directory) presence and only run (cd
projects/rero/ng-core && npm version ${nextRelease.version} --no-git-tag-version
--allow-same-version) when the path is valid, otherwise exit with a non-zero
status and descriptive message.

9-21: ⚡ Quick win

Consider whether all commit types should trigger releases.

The current configuration triggers a patch release for every commit type including ci, chore, docs, test, and build. This means internal-only changes (like CI config tweaks or documentation updates) will create new versions.

If this is intentional to ensure version bumps for every merged change, this is fine. However, if you want to release only for user-facing changes, consider removing non-functional types from releaseRules or setting them to { "release": false }.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.releaserc.json around lines 9 - 21, Currently every commit type in the
releaseRules array triggers a release; update the release policy inside
"releaseRules" to avoid publishing for non-user-facing changes by either
removing the entries for types like "ci", "chore", "docs", "test", "build",
"style", and "refactor" or explicitly set those entries to { "release": false }
so only user-facing types (e.g. "feat", "fix", "breaking") produce releases;
edit the "releaseRules" block to reflect your chosen approach.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/release.yml:
- Around line 44-49: The fast-forward step ("Fast-forward master to the release
commit") should only run when semantic-release actually made a release and when
master can safely be fast-forwarded; first verify a new release tag was created
(e.g., detect semantic-release output or check that a new tag exists) and only
proceed if present, then ensure master is an ancestor of staging before running
git merge --ff-only staging (use a git merge-base or ancestry check) and
otherwise fail with a clear error message and instructions to resolve
divergence; add comments or documentation explaining the divergence case and
what manual steps are required if the check fails.

---

Nitpick comments:
In @.github/workflows/release.yml:
- Line 18: The workflow currently uses floating tags like "actions/checkout@v6"
(and another similar use at the other "uses" line) which are mutable; update
those "uses:" entries to pin to the specific commit SHAs for the actions (e.g.,
replace actions/checkout@v6 with actions/checkout@<commit-sha>) so the action is
immutable and auditable, obtaining the correct SHA from the action's GitHub
releases/commits and applying the same SHA-pinning pattern to the other "uses:"
occurrence referenced in the comment.

In @.releaserc.json:
- Around line 36-41: The prepareCmd currently runs npm version for the root and
then blindly for the nested package path in the prepareCmd string; add a
validation step to check that the nested package.json at
projects/rero/ng-core/package.json exists before running the second npm version,
and if it does not exist either abort the prepareCmd (so the root change is not
left inconsistent) or perform a rollback (e.g., reset root package.json version)
and surface a clear error; update the prepareCmd shell snippet to test for the
file (or directory) presence and only run (cd projects/rero/ng-core && npm
version ${nextRelease.version} --no-git-tag-version --allow-same-version) when
the path is valid, otherwise exit with a non-zero status and descriptive
message.
- Around line 9-21: Currently every commit type in the releaseRules array
triggers a release; update the release policy inside "releaseRules" to avoid
publishing for non-user-facing changes by either removing the entries for types
like "ci", "chore", "docs", "test", "build", "style", and "refactor" or
explicitly set those entries to { "release": false } so only user-facing types
(e.g. "feat", "fix", "breaking") produce releases; edit the "releaseRules" block
to reflect your chosen approach.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 730f8af7-77b8-4362-93bc-91d40d85b365

📥 Commits

Reviewing files that changed from the base of the PR and between 7eeff59 and 32007bc.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (3)
  • .github/workflows/release.yml
  • .releaserc.json
  • package.json

Comment thread .github/workflows/release.yml
@PascalRepond PascalRepond requested a review from jma June 10, 2026 05:53

@Garfield-fr Garfield-fr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can you explain to me what triggers this action?

run: |
git fetch origin master
git checkout master
git merge --ff-only staging

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why not git reset --hard staging

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Because we don't want to mess with master linear commit history. I think it could also be git rebase staging, there should never be conflicts between staging and master, we only add the commit from staging to master.

For your other question, this action is triggered manually from Github when we decide to do a release. If we want to test the result locally before, we can run npm run release.

Add a manually-triggered release workflow.

On dispatch from the staging branch, semantic-release analyzes
conventional commits, bumps the version in both package.json files,
updates CHANGELOG.md, tags vX.Y.Z and creates a GitHub Release, then
fast-forwards master. The published Release triggers the existing
publish.yml workflow to push the package to npm.

Breaking changes are mapped to a minor bump so the major version is
never raised automatically: it stays pinned to the Angular major and
is only moved during a deliberate Angular migration release.

Also secure the github actions pinned versions and adds a dependabot
config to open PRs for new versions of used Actions.

Co-Authored-by: Pascal Repond <pascal.repond@rero.ch>
@PascalRepond PascalRepond merged commit 5a2a464 into rero:staging Jun 11, 2026
2 checks passed
@PascalRepond PascalRepond deleted the rep-auto-release branch June 11, 2026 10:23
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