Files
actual/packages/docs/scripts/generate-upcoming-release-notes.mjs
Stephen Brown II 123cf1e25a [AI] docs: fix broken blog links and add enforce-doc-links remark plugin (#8180)
* [AI] docs: fix broken blog links and add enforce-doc-links remark plugin

- Fix three docs/ pages that linked to blog posts using URL slugs instead of
  file paths, with an extra ../ level in the relative path
- Add src/remark/enforce-doc-links.js: remark plugin that enforces link hygiene
  in docs/ and blog/ at build time (no absolute internal links, .md extension
  required, slug-style links caught via frontmatter cache)
- Upgrade onBrokenMarkdownLinks from 'warn' to 'throw' so broken .md file-path
  links fail the build rather than being silently ignored

* [autofix.ci] apply automated fixes

* [AI] docs: add vfile to spell-check allowlist

* [AI] docs: fix build failures from cross-plugin and absolute links

- Revert docs→blog links to URL-slug style (Docusaurus cannot resolve .md
  file paths across content plugins — blog is a separate plugin from docs)
- Fix absolute /docs/... links in two blog posts to relative URL form
- Fix generate-upcoming-release-notes.mjs hardcoded /docs/releases absolute
  URLs to relative ./releases.md paths
- Update enforce-doc-links plugin: exempt docs→blog URL-slug links from Rule 3
  (cross-plugin constraint means slug URLs are the required format there);
  improve Rule 1 error hint to distinguish docs vs blog context

* [AI] docs: fix blog→docs links to use absolute URLs

Blog posts are embedded in multiple Docusaurus URL contexts (individual post,
paginated list pages, tag pages), so relative URLs resolve differently per
context. Blog→docs links must use absolute URLs (/docs/...) — relative URLs
like ../docs/... incorrectly resolve to /blog/docs/... on list pages.

Update enforce-doc-links plugin to exempt blog files from Rule 1 (absolute
link check) since absolute URLs are the required format for blog→docs links.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2026-06-10 19:58:39 +00:00

63 lines
2.0 KiB
JavaScript

// Generates `docs/upcoming-release-notes.md` from the repo-root
// `upcoming-release-notes/` directory. These per-PR notes are the changes that
// have been merged but not yet published in a stable release — i.e. what ships
// in the nightly builds. The page is regenerated on every docs build, so
// it always reflects the current set of unreleased changes.
//
// This runs before `docusaurus start` / `docusaurus build` (see package.json).
import * as fs from 'node:fs/promises';
import { join } from 'node:path';
import { fileURLToPath } from 'node:url';
import {
formatNotes,
parseReleaseNotes,
} from '@actual-app/ci-actions/src/release-notes/util.mjs';
const repoRoot = fileURLToPath(new URL('../../..', import.meta.url));
const notesDir = join(repoRoot, 'upcoming-release-notes');
const outputPath = join(
repoRoot,
'packages/docs/docs/upcoming-release-notes.md',
);
const intro = `:::info
These changes have been merged but are **not yet part of a stable release**. They
ship in the nightly builds — try them via the \`nightly\` Docker image tag, or the
hosted demo at [nightly.actualbudget.org](https://nightly.actualbudget.org).
For changes in stable releases, see the [Release Notes](./releases.md).
:::`;
const header = `---
title: Upcoming Release
description: Release notes for changes that are merged but not yet released, available in the nightly builds.
sidebar_label: Upcoming Release
---
<!-- This page is auto-generated from the upcoming-release-notes/ directory. Do not edit it by hand. -->
# Upcoming Release
${intro}`;
const { notesByCategory, files } = await parseReleaseNotes(
notesDir,
'actualbudget',
'actual',
);
const body =
files.length === 0
? `There are no unreleased changes right now — everything has shipped in a stable [release](./releases.md).`
: formatNotes(notesByCategory);
await fs.writeFile(outputPath, `${header}\n\n${body}\n`);
console.log(
`Generated ${outputPath} from ${files.length} upcoming release note(s).`,
);