Skip to content

fix(sources): use shared yamlEscape in release frontmatter#37

Merged
harlan-zw merged 1 commit intomainfrom
fix/release-frontmatter-yaml-escaping
Mar 19, 2026
Merged

fix(sources): use shared yamlEscape in release frontmatter#37
harlan-zw merged 1 commit intomainfrom
fix/release-frontmatter-yaml-escaping

Conversation

@oritwoen
Copy link
Copy Markdown
Collaborator

@oritwoen oritwoen commented Mar 19, 2026

Description

formatRelease was hand-rolling YAML escaping for the name field - only replacing double quotes, missing backslashes, newlines, colons, and other special characters. tag and version fields were emitted completely unescaped. Release names like v2.0: Breaking Changes or anything with a backslash would produce corrupt YAML frontmatter in cached release files.

Same class of bug that was fixed in buildFrontmatter (#34). Applied the same fix: use the shared yamlEscape() from core/yaml.ts.

Also escaped tag and version in formatRelease and latest in generateReleaseIndex for consistency.

Linked Issues

Related to #34

Additional context

Regression tests added for generateReleaseIndex - formatRelease is not exported so tested indirectly. All 26 release tests pass, typecheck clean.

Summary by CodeRabbit

  • Bug Fixes

    • Improved YAML escaping for release information. Release tags and names containing special YAML characters are now properly formatted and quoted to prevent parsing errors.
  • Tests

    • Added test coverage for YAML formatting of release indices, ensuring special characters in tags are correctly escaped.

formatRelease was hand-rolling YAML escaping for the name field
(only escaping double quotes) and emitting tag/version fields
unescaped. Release names with backslashes, newlines, or colons
would produce corrupt frontmatter.

Same class of bug fixed in buildFrontmatter (#34).
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 19, 2026

📝 Walkthrough

Walkthrough

The PR improves YAML generation in release handling by consistently applying yamlEscape to frontmatter fields (tag, version, name, and latest) instead of ad-hoc escaping. This ensures special characters in release identifiers are properly escaped for YAML compliance.

Changes

Cohort / File(s) Summary
YAML Escaping Enhancement
src/sources/releases.ts
Added yamlEscape import and applied it consistently to tag, version, name fields in formatRelease and latest field in generateReleaseIndex frontmatter, replacing previous manual quote-escaping for name.
Release Index Tests
test/unit/releases.test.ts
Updated imports to include generateReleaseIndex and added test suite verifying proper YAML quoting behavior for latest tag values containing special characters vs. normal values.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Suggested reviewers

  • harlan-zw

Poem

🐰 A rabbit hops through YAML fields with glee,
No more manual quotes, just yamlEscape, you see!
Special chars now handled with consistent care,
The frontmatter's safer—a burrow beyond compare! 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main change: replacing hand-rolled YAML escaping with a shared yamlEscape utility in release frontmatter generation.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/release-frontmatter-yaml-escaping
📝 Coding Plan
  • Generate coding plan for human review comments

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

@oritwoen oritwoen self-assigned this Mar 19, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
test/unit/releases.test.ts (1)

201-217: Nice regression coverage; consider adding backslash/newline cases too.

You already cover colon/normal tags well. Adding \ and newline cases would better lock in the escaping contract that this PR targets.

✅ Small test expansion
 describe('generateReleaseIndex', () => {
   it('escapes special YAML characters in tag names', () => {
     const releases = [
       makeRelease('v3.0.0: breaking', 'notes'),
     ]
     const index = generateReleaseIndex(releases)
     expect(index).toContain('latest: "v3.0.0: breaking"')
   })

+  it('escapes backslashes and newlines in tags', () => {
+    const releases = [
+      makeRelease('v3.0.0\\beta\nnext', 'notes'),
+    ]
+    const index = generateReleaseIndex(releases)
+    expect(index).toContain('latest: "v3.0.0\\\\beta\\nnext"')
+  })
+
   it('handles normal tags without quoting', () => {
     const releases = [
       makeRelease('v1.0.0', 'notes'),
     ]
     const index = generateReleaseIndex(releases)
     expect(index).toContain('latest: v1.0.0')
   })
 })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unit/releases.test.ts` around lines 201 - 217, Add tests to cover tag
names containing a backslash and a newline to ensure generateReleaseIndex
correctly escapes those characters; in test/unit/releases.test.ts extend the
describe('generateReleaseIndex') block to create releases via makeRelease with
tag strings like one containing a backslash (e.g. "v1.2.3\\extra") and one
containing a newline (e.g. "v1.2.3\nnewline"), call generateReleaseIndex on each
and assert the produced index contains the properly quoted/escaped YAML
representation for those tags (use the same pattern as the existing colon and
normal tag assertions to verify the exact escaped string appears).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@test/unit/releases.test.ts`:
- Around line 201-217: Add tests to cover tag names containing a backslash and a
newline to ensure generateReleaseIndex correctly escapes those characters; in
test/unit/releases.test.ts extend the describe('generateReleaseIndex') block to
create releases via makeRelease with tag strings like one containing a backslash
(e.g. "v1.2.3\\extra") and one containing a newline (e.g. "v1.2.3\nnewline"),
call generateReleaseIndex on each and assert the produced index contains the
properly quoted/escaped YAML representation for those tags (use the same pattern
as the existing colon and normal tag assertions to verify the exact escaped
string appears).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 97757ef9-b588-49f1-b803-5f9f006550ca

📥 Commits

Reviewing files that changed from the base of the PR and between fb094d6 and abba06b.

📒 Files selected for processing (2)
  • src/sources/releases.ts
  • test/unit/releases.test.ts

@oritwoen oritwoen requested a review from harlan-zw March 19, 2026 13:49
oritwoen added a commit that referenced this pull request Mar 19, 2026
formatBlogRelease hand-rolled YAML escaping for the title field
and left version/url completely unescaped. Blog post titles with
backslashes, newlines, or colons would produce corrupt frontmatter.

Third instance of the same bug class (after buildFrontmatter #34
and formatRelease #37).
@harlan-zw harlan-zw merged commit 97b82de into main Mar 19, 2026
3 checks passed
@oritwoen oritwoen deleted the fix/release-frontmatter-yaml-escaping branch March 19, 2026 14:49
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