Skip to content

fix(release): detect changelog_file anywhere in the commitizen section#30

Merged
MAfarrag merged 5 commits into
mainfrom
harden-changelog-detection
Jul 21, 2026
Merged

fix(release): detect changelog_file anywhere in the commitizen section#30
MAfarrag merged 5 commits into
mainfrom
harden-changelog-detection

Conversation

@MAfarrag

@MAfarrag MAfarrag commented Jul 21, 2026

Copy link
Copy Markdown
Member

Description

The release/github action read changelog_file from a consumer's [tool.commitizen] config with a fixed
grep -A 20 window anchored at the header. When changelog_file sits further down — after a long version_files
array or a comment block — it falls outside that window, so detection returns empty, defaults to CHANGELOG.md,
and the release fails at the "Validate changelog file" step with Changelog file not found: CHANGELOG.md.

This surfaced in the earthlens uv workspace (7 distributions), where changelog_file was ~30 lines below the
[tool.commitizen] header. The failing run:
serapeum-org/earthlensactions/runs/29772553136 (job 88456747182). earthlens worked around it by reordering
its TOML; this PR removes the need for any such workaround.

What changed

  • Replace the grep -A 20 detection at both sites in actions/release/github/action.yml (the "Validate
    changelog file" step and the "Generate changelog and bump version" step) with a section-aware awk that:
    • scans from the [tool.commitizen] header to the next [...] table, so changelog_file is found regardless of
      how far below the header it sits;
    • tolerates a trailing comment on the header ([tool.commitizen] # ...);
    • accepts a double- or single-quoted value, anchoring extraction to the value's own opening quote so an inline
      # comment (even one containing quotes) is ignored while a # inside the value is preserved.
  • Update the three inline changelog lookups in .github/workflows/test-release-github.yml
    (recovery-no-duplicates, notes-from-changelog, notes-custom-changelog-path) to the same awk, so the suite
    and the action share one detection behaviour.
  • Add a regression job test-release-changelog-far-from-header that places changelog_file ~33 lines below the
    header and asserts the release uses the custom changelog instead of falling back to CHANGELOG.md. Its fixture is
    built with a section-scoped removal that does not assume [tool.commitizen] is the last table.

No inputs, outputs, or defaults change; existing consumers are unaffected. Fully backward compatible.

Issues

Motivation is the earthlens release failure linked in the Description. Related but separate: #9 (squash-merge
orphans the tag) and #14 (lockfile folded into the tag), neither of which this PR touches.

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How Has This Been Tested?

The test-release-github.yml suite was dispatched on this branch and all 35 jobs pass
(latest: actions/runs/29848301761). Relevant coverage:

  • Test release - changelog_file far below the commitizen header — new regression job; fails on the old
    grep -A 20 (fallback to a non-existent CHANGELOG.md), passes on the new awk.
  • recovery path no duplicates, release notes scoped to current version, release notes with custom changelog path — the three jobs whose inline detection was updated to the shared awk.
  • lockfile folded into tag (uv/pixi), pip unaffected — unchanged behaviour confirmed still green.

Locally, the hardened awk was verified against a 13-case battery (double/single quotes, header comment, inline
value comment, #-in-value, changelog_file_backup non-match, subsection non-match, after a multi-line array,
commented-out key, far-below-header, earthlens's actual failing pyproject.toml), and every run: script in both
files passes bash -n
— which caught a bash-quoting bug (an apostrophe inside the awk comment) before CI.

Two rounds of /review-rounds (independent adversarial reviews) were run; all should-fix findings are resolved.

Checklist:

  • updated version number in pyproject.toml. (n/a — actions are released via namespaced tags, e.g. github-release/vX)
  • added changes to History.rst. (n/a — repo has no History.rst)
  • updated the latest version in README file. (done at release-tag time)
  • I have added tests that prove my fix is effective or that my feature works.
  • New and existing unit tests pass locally with my changes. (full Actions suite green in CI, links above)
  • documentation are updated. (n/a — no user-facing docs changed; behaviour is transparent to consumers)

MAfarrag added 5 commits July 20, 2026 23:28
The action read changelog_file with a fixed `grep -A 20` window from the
[tool.commitizen] header. A config that places changelog_file further down —
e.g. after a long version_files array or comment block, as in the earthlens
uv workspace — fell outside the window, so detection returned empty, defaulted
to CHANGELOG.md, and the release failed with "Changelog file not found".

Replace the grep in both the validate step and the bump step with a
section-aware awk: scan from the [tool.commitizen] header to the next [...]
table and take the first double-quoted value of changelog_file (which also
drops any inline # comment). The key is now found regardless of how far below
the header it sits.

Add a regression job (test-release-changelog-far-from-header) that builds a
fixture placing changelog_file ~33 lines below the header and asserts the
release uses docs/change-log.md instead of falling back to CHANGELOG.md.
Round-1 review follow-ups to the section-aware changelog detection:

- Header with a trailing comment (`[tool.commitizen]  # ...`) is valid TOML
  but the end-anchored header regex missed it, silently falling back to
  CHANGELOG.md — a regression versus the old unanchored grep. Allow an
  optional trailing comment on the header line.
- Accept a single-quoted value (`changelog_file = 'x'`), not only
  double-quoted. A literal single quote is passed in via `awk -v q` so the
  awk program stays free of embedded single quotes.
- Drop `2>/dev/null` so a real awk/regex failure surfaces in the logs
  instead of being masked into a misleading "Changelog file not found".

Applied identically at both detection sites (validate step and bump step).
…kups

Three existing jobs (recovery-no-duplicates, notes-from-changelog,
notes-custom-changelog-path) reimplemented changelog_file detection inline
with the old `grep -A 20` window. Replace those copies with the same
section-aware awk the action now uses, so the test suite and the action
share one detection behaviour and the copies can catch future regressions.
…ar-header fixture

The far-from-header job deleted from [tool.commitizen] to EOF, which assumed
that section is last in the shared test-basic-uv fixture. Replace it with a
section-scoped awk that removes only the [tool.commitizen] table (header plus
body up to the next table), so the job no longer depends on section ordering
in a fixture shared by other jobs.
Round-2 review: the previous extractor tried a double-quote match across the
whole line first, so a single-quoted value with a double-quoted token in a
trailing comment (e.g. changelog_file = 'x.md'  # see "y") extracted the
comment token instead of the value. Anchor extraction to the first char after
`= ` — the value's own opening quote — and read to its matching close, which
also keeps a `#` inside a double-quoted value intact.

Apply identically to both action sites and the three inline test copies.
Also add a caveat comment noting the line-based scanner assumes the ordinary
commitizen layout (scalar keys; no multi-line-string or nested-array key that
opens a line with "[" ahead of changelog_file).
@MAfarrag MAfarrag changed the title Harden changelog detection fix(release): detect changelog_file anywhere in the commitizen section Jul 21, 2026
@MAfarrag
MAfarrag merged commit 5e1ef39 into main Jul 21, 2026
140 checks passed
@MAfarrag
MAfarrag deleted the harden-changelog-detection branch July 21, 2026 18:51
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.

release/github: changelog_file detection fails when the key is >20 lines below the [tool.commitizen] header

1 participant