mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-28 16:01:18 +01:00
Merge pull request #21741 from LasseRosenow/guides-add-riot-changelog
doc/starlight: add RIOT changelog
This commit is contained in:
commit
0b436d8898
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@ -18,4 +18,8 @@
|
||||
"editor.tabSize": 2,
|
||||
"editor.insertSpaces": true,
|
||||
},
|
||||
"[javascript][typescript]": {
|
||||
"editor.tabSize": 2,
|
||||
"editor.insertSpaces": true
|
||||
}
|
||||
}
|
||||
|
||||
@ -892,7 +892,7 @@ INPUT = ../../doc.txt \
|
||||
src/emulators.md \
|
||||
src/release-cycle.md \
|
||||
src/io-mapping-and-shields.md \
|
||||
src/changelog.md \
|
||||
src/changelog-deprecated.md \
|
||||
src/LOSTANDFOUND.md \
|
||||
../../makefiles/pseudomodules.inc.mk \
|
||||
../../makefiles/blob.inc.mk \
|
||||
|
||||
6
doc/doxygen/src/changelog-deprecated.md
Normal file
6
doc/doxygen/src/changelog-deprecated.md
Normal file
@ -0,0 +1,6 @@
|
||||
# Changelog (Deprecated) {#changelog}
|
||||
|
||||
@deprecated This page is deprecated.
|
||||
See [Changelog](https://guide.riot-os.org/changelog)
|
||||
on the RIOT Guide Site for the latest information.
|
||||
This page will be removed after release 2026.04.
|
||||
@ -1,13 +1,28 @@
|
||||
// @ts-check
|
||||
import { defineConfig } from "astro/config";
|
||||
import starlight from "@astrojs/starlight";
|
||||
import rehypeGithubEmoji from "rehype-github-emoji";
|
||||
|
||||
// https://astro.build/config
|
||||
export default defineConfig({
|
||||
site: "https://guide.riot-os.org",
|
||||
markdown: {
|
||||
rehypePlugins: [rehypeGithubEmoji],
|
||||
},
|
||||
integrations: [
|
||||
starlight({
|
||||
title: "RIOT Documentation",
|
||||
head: [
|
||||
{
|
||||
tag: "link",
|
||||
attrs: {
|
||||
rel: "alternate",
|
||||
type: "application/rss+xml",
|
||||
title: "RIOT Changelog",
|
||||
href: "/changelog/rss.xml",
|
||||
},
|
||||
},
|
||||
],
|
||||
social: [
|
||||
{
|
||||
icon: "github",
|
||||
@ -150,6 +165,10 @@ export default defineConfig({
|
||||
"misc/how_to_doc",
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Changelog",
|
||||
link: "changelog",
|
||||
},
|
||||
],
|
||||
customCss: ["./src/styles/custom.css", "./src/fonts/font-face.css"],
|
||||
logo: {
|
||||
@ -165,7 +184,7 @@ export default defineConfig({
|
||||
vite: {
|
||||
server: {
|
||||
fs: {
|
||||
allow: ["./", "../doxygen"],
|
||||
allow: ["./", "../doxygen", "../../release-notes.txt"],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
2759
doc/starlight/package-lock.json
generated
2759
doc/starlight/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -10,8 +10,10 @@
|
||||
"astro": "astro"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/starlight": "^0.33.1",
|
||||
"astro": "^5.5.3",
|
||||
"sharp": "^0.32.5"
|
||||
"@astrojs/rss": "^4.0.12",
|
||||
"@astrojs/starlight": "^0.36.0",
|
||||
"astro": "^5.14.0",
|
||||
"rehype-github-emoji": "^1.0.0",
|
||||
"sharp": "^0.34.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,125 @@
|
||||
import { defineCollection } from "astro:content";
|
||||
import { glob } from "astro/loaders";
|
||||
import { defineCollection, z } from "astro:content";
|
||||
import { glob, type Loader } from "astro/loaders";
|
||||
import { docsSchema } from "@astrojs/starlight/schema";
|
||||
import { promises as fs } from "node:fs";
|
||||
|
||||
export const collections = {
|
||||
docs: defineCollection({
|
||||
loader: glob({ pattern: "**/*.(md|mdx)", base: "../guides" }),
|
||||
schema: docsSchema(),
|
||||
}),
|
||||
changelog: defineCollection({
|
||||
loader: changelogLoader(),
|
||||
schema: z.object({
|
||||
title: z.string(),
|
||||
release: z.string(),
|
||||
codeName: z.string(),
|
||||
slug: z.string(),
|
||||
date: z.date(),
|
||||
markdown: z.string(),
|
||||
}),
|
||||
}),
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate a content collection containing the release notes of each release as an entry.
|
||||
* This function parses the release-notes.txt file from the root of the RIOT repository.
|
||||
* The release-notes syntax is converted to correct markdown and then parsed.
|
||||
*/
|
||||
export function changelogLoader(): Loader {
|
||||
return {
|
||||
name: "changelog-loader",
|
||||
load: async (context): Promise<void> => {
|
||||
// Read release-notes.txt file
|
||||
const buffer = await fs.readFile("../../release-notes.txt");
|
||||
// Convert the buffer to text
|
||||
const content = buffer.toString("utf8");
|
||||
// convert the text to an array of lines
|
||||
const lines = content.split("\n");
|
||||
|
||||
let currentReleaseHeading: string | null = null;
|
||||
let currentReleaseHeadingIndex: number | null = null;
|
||||
|
||||
for (const [index, line] of lines.entries()) {
|
||||
const nextLine = lines[index + 1];
|
||||
|
||||
// Convert "Setext Style" headings to "ATX Style" headings
|
||||
// This is necessary to support heading nesting higher than h1 and h2
|
||||
// Check if next line contains only "=" characters
|
||||
if (/^=+$/.test(nextLine)) {
|
||||
// If yes add a "##" to the current lines beginning
|
||||
lines[index] = `# ${line}`;
|
||||
// Remove the next lines content
|
||||
lines[index + 1] = "";
|
||||
}
|
||||
// Check if next line contains only "-" characters
|
||||
if (/^-+$/.test(nextLine)) {
|
||||
// If yes add a "###" to the current lines beginning
|
||||
lines[index] = `## ${line}`;
|
||||
// Remove the next lines content
|
||||
lines[index + 1] = "";
|
||||
}
|
||||
|
||||
// Convert all headings to be one level lower
|
||||
// h1 => h2, h2 => h3, h3 => h4 etc.
|
||||
// This is necessary, because the heading levels of this file are wrong (for markdown)
|
||||
// We cannot have more than one h1 per document etc.
|
||||
if (lines[index].startsWith("#")) {
|
||||
lines[index] = `#${lines[index]}`;
|
||||
}
|
||||
|
||||
// Check if the current line is a RIOT release heading
|
||||
// or if we have reached the last line of the file.
|
||||
if (
|
||||
/(RIOT-.*? - Release Notes)|(Release 2013\.08)/.test(line) ||
|
||||
index == lines.length - 1
|
||||
) {
|
||||
// If we already found a release heading before, we now
|
||||
// reached the end of its changelog
|
||||
if (
|
||||
currentReleaseHeading != null &&
|
||||
currentReleaseHeadingIndex != null
|
||||
) {
|
||||
// Extract the release (YYYY.MM.*) from the release heading
|
||||
const release =
|
||||
currentReleaseHeading.match(/(\d{4}\.\d{2}(\.\d+)?)/)?.[1] || "";
|
||||
|
||||
// Create a slug based on the date
|
||||
const slug = release.replaceAll(".", "-");
|
||||
|
||||
// Generate a date object from the slug (since it is a date)
|
||||
const date = new Date(release);
|
||||
|
||||
// Extract the release code name from the heading if it exists
|
||||
const codeName =
|
||||
currentReleaseHeading.match(/"([^"]+)"/)?.[1] || null;
|
||||
|
||||
// Extract current release content
|
||||
const currentReleaseContent = lines
|
||||
.slice(currentReleaseHeadingIndex + 1, index)
|
||||
.join("\n");
|
||||
|
||||
// Add entry to content collection
|
||||
context.store.set({
|
||||
id: slug,
|
||||
data: {
|
||||
title: `RIOT-${release}${
|
||||
codeName ? ` "${codeName}"` : ""
|
||||
} - Release Notes`,
|
||||
release: release,
|
||||
codeName: codeName,
|
||||
slug: slug,
|
||||
date: date,
|
||||
markdown: currentReleaseContent,
|
||||
},
|
||||
rendered: await context.renderMarkdown(currentReleaseContent),
|
||||
});
|
||||
}
|
||||
|
||||
currentReleaseHeading = line;
|
||||
currentReleaseHeadingIndex = index;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
33
doc/starlight/src/pages/changelog.astro
Normal file
33
doc/starlight/src/pages/changelog.astro
Normal file
@ -0,0 +1,33 @@
|
||||
---
|
||||
import StarlightPage from "@astrojs/starlight/components/StarlightPage.astro";
|
||||
import { LinkButton, LinkCard } from "@astrojs/starlight/components";
|
||||
import { getCollection } from "astro:content";
|
||||
|
||||
const changelog = await getCollection("changelog");
|
||||
---
|
||||
|
||||
<StarlightPage
|
||||
frontmatter={{
|
||||
title: "Changelog",
|
||||
description: "Complete version history and release notes for RIOT",
|
||||
}}
|
||||
>
|
||||
<LinkButton
|
||||
href="/changelog/rss.xml"
|
||||
variant="secondary"
|
||||
icon="rss"
|
||||
iconPlacement="start"
|
||||
>
|
||||
Subscribe to RSS Feed
|
||||
</LinkButton>
|
||||
<!-- Add a gap between the rss-feed button and the link-cards -->
|
||||
<div style={{ height: "0.5rem" }}></div>
|
||||
{
|
||||
changelog.map((entry) => (
|
||||
<LinkCard
|
||||
title={`${entry.data.release}${entry.data.codeName ? ` "${entry.data.codeName}"` : ""}`}
|
||||
href={`/changelog/${entry.data.slug}`}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</StarlightPage>
|
||||
30
doc/starlight/src/pages/changelog/[version].astro
Normal file
30
doc/starlight/src/pages/changelog/[version].astro
Normal file
@ -0,0 +1,30 @@
|
||||
---
|
||||
import StarlightPage from "@astrojs/starlight/components/StarlightPage.astro";
|
||||
import { getCollection, render } from "astro:content";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const changelog = await getCollection("changelog");
|
||||
|
||||
return changelog.map((entry) => ({
|
||||
params: {
|
||||
version: entry.data.slug,
|
||||
},
|
||||
props: {
|
||||
entry: entry,
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
||||
const { entry } = Astro.props;
|
||||
const { Content, headings } = await render(entry);
|
||||
---
|
||||
|
||||
<StarlightPage
|
||||
frontmatter={{
|
||||
title: entry.data.title,
|
||||
description: "List of all changes in this release",
|
||||
pagefind: false, // We don't want to pollute our search with release-notes entries
|
||||
}}
|
||||
headings={headings}
|
||||
><Content />
|
||||
</StarlightPage>
|
||||
23
doc/starlight/src/pages/changelog/rss.xml.js
Normal file
23
doc/starlight/src/pages/changelog/rss.xml.js
Normal file
@ -0,0 +1,23 @@
|
||||
import rss from "@astrojs/rss";
|
||||
import { getCollection } from "astro:content";
|
||||
|
||||
export async function GET(context) {
|
||||
const changelog = await getCollection("changelog");
|
||||
|
||||
return rss({
|
||||
// `<title>` field in output xml
|
||||
title: "RIOT Changelog",
|
||||
// `<description>` field in output xml
|
||||
description: "Changelog of RIOT releases",
|
||||
// Pull in your project "site" from the endpoint context
|
||||
// https://docs.astro.build/en/reference/api-reference/#site
|
||||
site: context.site,
|
||||
// Array of `<item>`s in output xml
|
||||
// See "Generating items" section for examples using content collections and glob imports
|
||||
items: changelog.map((entry) => ({
|
||||
title: entry.data.title,
|
||||
link: `/changelog/${entry.data.slug}`,
|
||||
pubDate: entry.data.date,
|
||||
})),
|
||||
});
|
||||
}
|
||||
@ -5,7 +5,7 @@
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@components/*": ["src/components/*"],
|
||||
"@components/*": ["src/components/*"]
|
||||
},
|
||||
"types": ["astro/client", "astro/astro-jsx"]
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user