Problem
The generate_changelog workflow fires on every push to main, including when a release PR is merged. When a release PR lands, the tag (e.g. v5.4.0) is created as part of that same commit. Commitizen then runs in --incremental mode, finds no commits after the newly-created tag, and exits with code 3 — failing the job.
Example failed run: https://github.com/dfinity/icp-js-core/actions/runs/25162483015/job/73761141579
Relevant log lines:
No commits found
##[error]Process completed with exit code 3.
Root cause
In actions/generate-changelog/action.yaml, the cz changelog command is run without any exit-code handling:
run: cz changelog --incremental --merge-prerelease --file-name="$FILE_NAME" --version-scheme semver2
Commitizen exit code 3 means "NoneReleased" / nothing to changelog — it is a no-op, not an error.
Possible solutions
Option A — Handle exit code 3 in actions/generate-changelog/action.yaml (recommended)
Treat exit code 3 as success at the action level, since it precisely means "nothing to do":
run: |
cz changelog --incremental --merge-prerelease --file-name="$FILE_NAME" --version-scheme semver2 || {
code=$?; [ "$code" -eq 3 ] && { echo "No new commits since last tag, skipping."; exit 0; }; exit $code
}
Fixes the root cause at the right level and handles any "no commits" scenario generically.
Option B — Skip the job when triggered by a release commit (in the reusable workflow)
Add a pre-check in .github/workflows/generate-changelog.yaml that detects a release commit and skips changelog generation:
- name: Check for release commit
id: check
run: |
msg=$(git log -1 --format=%s)
[[ "$msg" =~ ^chore:[[:space:]]release ]] && echo "skip=true" >> $GITHUB_OUTPUT || true
- name: Generate changelog
if: steps.check.outputs.skip != 'true'
uses: dfinity/ci-tools/actions/generate-changelog@...
More targeted but depends on the release commit message format staying stable.
Happy to open a PR for whichever approach is preferred.
Problem
The
generate_changelogworkflow fires on every push tomain, including when a release PR is merged. When a release PR lands, the tag (e.g.v5.4.0) is created as part of that same commit. Commitizen then runs in--incrementalmode, finds no commits after the newly-created tag, and exits with code 3 — failing the job.Example failed run: https://github.com/dfinity/icp-js-core/actions/runs/25162483015/job/73761141579
Relevant log lines:
Root cause
In
actions/generate-changelog/action.yaml, thecz changelogcommand is run without any exit-code handling:Commitizen exit code 3 means "NoneReleased" / nothing to changelog — it is a no-op, not an error.
Possible solutions
Option A — Handle exit code 3 in
actions/generate-changelog/action.yaml(recommended)Treat exit code 3 as success at the action level, since it precisely means "nothing to do":
Fixes the root cause at the right level and handles any "no commits" scenario generically.
Option B — Skip the job when triggered by a release commit (in the reusable workflow)
Add a pre-check in
.github/workflows/generate-changelog.yamlthat detects a release commit and skips changelog generation:More targeted but depends on the release commit message format staying stable.
Happy to open a PR for whichever approach is preferred.