Skip to content

feat(changelogs): port Bluefin Firehose to /changelogs page#702

Merged
castrojo merged 1 commit into
projectbluefin:mainfrom
castrojo:feature/firehose-changelogs
Apr 1, 2026
Merged

feat(changelogs): port Bluefin Firehose to /changelogs page#702
castrojo merged 1 commit into
projectbluefin:mainfrom
castrojo:feature/firehose-changelogs

Conversation

@castrojo
Copy link
Copy Markdown
Contributor

@castrojo castrojo commented Apr 1, 2026

Replace the PackageSummary + CombinedFeedItems layout with a full port of the Bluefin Firehose site (castrojo.github.io/bluefin-releases).

Layout: sticky sidebar (RSS links, featured app, filters, statistics)

  • main column of grouped release cards, sorted newest-first.

Data pipeline:

  • scripts/fetch-firehose.js fetches apps.json from the public Firehose GitHub Pages URL every 6 hours (matches pipeline schedule).
  • static/data/firehose-apps.json committed as empty seed so builds succeed before the first fetch.
  • fetch-firehose appended to fetch-data chain.
  • .gitignore negation added alongside sbom-attestations.json.

New components:

  • FirehoseCard: app icon, version, date, package badge, source/Flathub icon links, brew install copy button, release HTML, older releases toggle.
  • FirehoseFilters: verification, package type, category, app set, date range filters with result count and clear-all.
  • FirehoseFeed: orchestrates sidebar + feed, featured app banner, statistics panel, empty/no-match states.

Types:

  • src/types/firehose.ts: full type definitions from Go models.
  • src/types/firehose-apps.d.ts: ambient module declaration for static import.

Dependencies:

  • react-icons ^5.6.0 (SiFlathub, FaGithub, FaGitlab, FaCopy, FaCheck).

Assisted-by: Claude Sonnet 4.6 via GitHub Copilot

Replace the PackageSummary + CombinedFeedItems layout with a full port
of the Bluefin Firehose site (castrojo.github.io/bluefin-releases).

Layout: sticky sidebar (RSS links, featured app, filters, statistics)
+ main column of grouped release cards, sorted newest-first.

Data pipeline:
- scripts/fetch-firehose.js fetches apps.json from the public Firehose
  GitHub Pages URL every 6 hours (matches pipeline schedule).
- static/data/firehose-apps.json committed as empty seed so builds
  succeed before the first fetch.
- fetch-firehose appended to fetch-data chain.
- .gitignore negation added alongside sbom-attestations.json.

New components:
- FirehoseCard: app icon, version, date, package badge, source/Flathub
  icon links, brew install copy button, release HTML, older releases toggle.
- FirehoseFilters: verification, package type, category, app set, date
  range filters with result count and clear-all.
- FirehoseFeed: orchestrates sidebar + feed, featured app banner,
  statistics panel, empty/no-match states.

Types:
- src/types/firehose.ts: full type definitions from Go models.
- src/types/firehose-apps.d.ts: ambient module declaration for static import.

Dependencies:
- react-icons ^5.6.0 (SiFlathub, FaGithub, FaGitlab, FaCopy, FaCheck).

Assisted-by: Claude Sonnet 4.6 via GitHub Copilot
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@castrojo castrojo merged commit 5b6f9c4 into projectbluefin:main Apr 1, 2026
1 check passed
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces the "Bluefin Firehose" feature, which includes a new script to fetch application release data and a set of React components (FirehoseFeed, FirehoseCard, FirehoseFilters) to display and filter this data on the community feeds page. The implementation adds react-icons as a dependency and includes logic for caching and graceful degradation when fetching external data. Feedback highlights a potential XSS vulnerability when rendering HTML descriptions, as well as hydration issues in the SSG environment caused by non-deterministic date formatting and featured app selection.

Comment on lines +154 to +157
<div
className={styles.releaseBody}
dangerouslySetInnerHTML={{ __html: latestRelease.description }}
/>
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.

security-high high

Using dangerouslySetInnerHTML with data from an external source poses a significant XSS risk. The description field (and similarly on line 182) should be sanitized before being rendered. Even if the current source is trusted, this pattern is vulnerable if the upstream data (e.g., scraped GitHub release notes) contains malicious scripts. Consider using a library like dompurify to sanitize the HTML.

Comment on lines +11 to +21
function formatDate(iso: string): string {
try {
return new Date(iso).toLocaleDateString(undefined, {
year: "numeric",
month: "short",
day: "numeric",
});
} catch {
return iso;
}
}
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.

high

Using toLocaleDateString(undefined) causes hydration mismatches in SSG/SSR environments like Docusaurus because the server's locale during build may differ from the user's browser locale. This leads to React warnings and potential UI flickering. Use a fixed locale (e.g., 'en-US') to ensure consistency.

Suggested change
function formatDate(iso: string): string {
try {
return new Date(iso).toLocaleDateString(undefined, {
year: "numeric",
month: "short",
day: "numeric",
});
} catch {
return iso;
}
}
function formatDate(iso: string): string {
try {
return new Date(iso).toLocaleDateString("en-US", {
year: "numeric",
month: "short",
day: "numeric",
});
} catch {
return iso;
}
}

if (eligible.length === 0) return null;

// Deterministic hash from today's date string
const dateKey = new Date().toISOString().slice(0, 10); // "YYYY-MM-DD"
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.

high

Using new Date() for the dateKey will cause hydration mismatches if the date changes between the build time and the user's visit, or if timezones differ. This triggers React warnings. To fix this, use a stable value like firehoseData.metadata.generatedAt as the seed for the deterministic selection, ensuring the featured app remains consistent between server and client for a given build.

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.

1 participant