fix: use rendered release note html

This commit is contained in:
lucaronin
2026-04-19 20:53:39 +02:00
parent db21ae4708
commit ea14f1a389
4 changed files with 36 additions and 12 deletions

View File

@@ -265,7 +265,7 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
mkdir -p _site/alpha _site/stable
gh api repos/${{ github.repository }}/releases --paginate > _site/releases.json
gh api -H "Accept: application/vnd.github.html+json" repos/${{ github.repository }}/releases --paginate > _site/releases.json
PAGES_URL="https://refactoringhq.github.io/${GITHUB_REPOSITORY#*/}"
curl -fsSL "${PAGES_URL}/alpha/latest.json" -o _site/alpha/latest.json || echo '{}' > _site/alpha/latest.json

View File

@@ -301,7 +301,7 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
mkdir -p _site/alpha _site/stable
gh api repos/${{ github.repository }}/releases --paginate > _site/releases.json
gh api -H "Accept: application/vnd.github.html+json" repos/${{ github.repository }}/releases --paginate > _site/releases.json
PAGES_URL="https://refactoringhq.github.io/${GITHUB_REPOSITORY#*/}"
gh release download --repo ${{ github.repository }} "${{ needs.version.outputs.tag }}" --pattern "alpha-latest.json" --output _site/alpha/latest.json || echo '{}' > _site/alpha/latest.json

View File

@@ -11,6 +11,7 @@ describe('buildReleaseHistoryPage', () => {
},
],
body: '## Highlights\n\n- Faster startup\n- Better release notes',
body_html: '<h2>Highlights</h2><ul><li>Faster startup</li><li>Better release notes</li></ul>',
html_url: 'https://github.com/refactoringhq/tolaria/releases/tag/stable-v2026.4.19',
name: 'Tolaria Stable 2026.4.19',
prerelease: false,
@@ -25,6 +26,7 @@ describe('buildReleaseHistoryPage', () => {
},
],
body: '**Alpha** notes with [details](https://example.com/details).',
body_html: '<p><strong>Alpha</strong> notes with <a href="https://example.com/details">details</a>.</p>',
html_url: 'https://github.com/refactoringhq/tolaria/releases/tag/2026.4.19-alpha.1',
name: 'Alpha 2026.4.19.1',
prerelease: true,
@@ -44,6 +46,20 @@ describe('buildReleaseHistoryPage', () => {
expect(html).toContain('View on GitHub')
})
it('falls back to escaped paragraph markup when rendered html is unavailable', () => {
const html = buildReleaseHistoryPage([
{
body: 'First paragraph\nwith a line break.\n\nSecond paragraph',
name: 'Fallback release',
prerelease: false,
published_at: '2026-04-19T11:00:00Z',
tag_name: 'stable-v2026.4.19',
},
])
expect(html).toContain('<p>First paragraph<br>with a line break.</p><p>Second paragraph</p>')
})
it('filters draft releases and shows an empty state for channels without published builds', () => {
const html = buildReleaseHistoryPage([
{

View File

@@ -1,8 +1,3 @@
import { createElement } from 'react'
import Markdown from 'react-markdown'
import { renderToStaticMarkup } from 'react-dom/server'
import remarkGfm from 'remark-gfm'
type ReleaseAssetPayload = {
browser_download_url?: unknown
name?: unknown
@@ -11,6 +6,7 @@ type ReleaseAssetPayload = {
type GitHubReleasePayload = {
assets?: ReleaseAssetPayload[]
body?: unknown
body_html?: unknown
draft?: unknown
html_url?: unknown
name?: unknown
@@ -376,7 +372,6 @@ const RELEASE_HISTORY_PAGE_SCRIPT = `
})();
`
const MARKDOWN_REMARK_PLUGINS = [remarkGfm]
const RELEASE_CHANNEL_LABELS: Record<ReleaseChannel, string> = {
alpha: 'Alpha',
stable: 'Stable',
@@ -446,8 +441,22 @@ function normalizeDownloads(assets: ReleaseAssetPayload[] | undefined): ReleaseD
return downloads
}
function renderReleaseNotes(markdown: string): string {
return renderToStaticMarkup(createElement(Markdown, { remarkPlugins: MARKDOWN_REMARK_PLUGINS }, markdown))
function buildFallbackReleaseNotesHtml(markdownFallback: string): string {
const paragraphs = markdownFallback
.split(/\n{2,}/)
.map(part => part.trim())
.filter(part => part.length > 0)
.map(part => `<p>${escapeHtml(part).replaceAll('\n', '<br>')}</p>`)
return paragraphs.join('')
}
function resolveReleaseNotesHtml(renderedHtml: unknown, markdownFallback: unknown): string {
const bodyHtml = normalizeText(renderedHtml)
if (bodyHtml !== null) return bodyHtml
const fallback = normalizeText(markdownFallback) ?? 'No release notes provided.'
return buildFallbackReleaseNotesHtml(fallback)
}
function normalizeReleaseEntry(release: GitHubReleasePayload): [ReleaseChannel, ReleaseEntry] | null {
@@ -455,13 +464,12 @@ function normalizeReleaseEntry(release: GitHubReleasePayload): [ReleaseChannel,
const title = normalizeText(release.name) ?? normalizeText(release.tag_name) ?? 'Untitled release'
const tagName = normalizeText(release.tag_name) ?? 'Unknown tag'
const notes = normalizeText(release.body) ?? 'No release notes provided.'
const channel: ReleaseChannel = release.prerelease === true ? 'alpha' : 'stable'
return [channel, {
downloads: normalizeDownloads(release.assets),
githubUrl: normalizeUrl(release.html_url),
notesHtml: renderReleaseNotes(notes),
notesHtml: resolveReleaseNotesHtml(release.body_html, release.body),
publishedLabel: formatPublishedLabel(release.published_at),
tagName,
title,