Skip to content

Commit 3f8b6b8

Browse files
authored
docs: add rss feed to release notes and blog posts (#7534)
* add rss feeder project * delete rss-feed folder * update website build, add link to release docs website * create rss feed for blog posts * fix lint * fix spelling * fix url in docs * fix link to posts in xml file * verdaccio builds * fix url * Revert "verdaccio builds" This reverts commit 63c4a8b. * review feedback * Revert "Revert "verdaccio builds"" This reverts commit bab8e32. * update yarn lock * Revert "Revert "Revert "verdaccio builds""" This reverts commit a511141. * make title more specific * Revert "Revert "Revert "Revert "verdaccio builds"""" This reverts commit 58a4510. * Revert "Revert "Revert "Revert "Revert "verdaccio builds""""" This reverts commit 07abf14.
1 parent 3e352bf commit 3f8b6b8

File tree

5 files changed

+160
-3
lines changed

5 files changed

+160
-3
lines changed

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@
5656
"bumpVersions": "node scripts/bumpVersions.js",
5757
"test:parcel": "jest --testMatch '**/*.parceltest.{ts,tsx}'",
5858
"blc:local": "npx git+ssh://[email protected]:ktabors/rsp-blc.git -u http://localhost:1234/",
59-
"blc:prod": "npx git+ssh://[email protected]:ktabors/rsp-blc.git -u https://react-spectrum.adobe.com/"
59+
"blc:prod": "npx git+ssh://[email protected]:ktabors/rsp-blc.git -u https://react-spectrum.adobe.com/",
60+
"createRssFeed": "node scripts/createFeed.mjs"
6061
},
6162
"workspaces": [
6263
"packages/react-stately",
@@ -210,6 +211,7 @@
210211
"verdaccio": "^5.13.0",
211212
"walk-object": "^4.0.0",
212213
"wsrun": "^5.0.0",
214+
"xml": "^1.0.1",
213215
"yargs": "^17.2.1"
214216
},
215217
"resolutions": {

packages/dev/docs/src/PostListing.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@
1212

1313
import clsx from 'clsx';
1414
import docStyles from '@react-spectrum/docs/src/docs.css';
15+
import {Flex, Link} from '@adobe/react-spectrum';
1516
import {getAnchorProps} from './utils';
1617
import linkStyle from '@adobe/spectrum-css-temp/components/link/vars.css';
1718
import {PageContext, renderHTMLfromMarkdown, Time} from '@react-spectrum/docs';
1819
import React from 'react';
20+
import RSS from '@spectrum-icons/workflow/RSS';
1921
import typographyStyles from '@adobe/spectrum-css-temp/components/typography/vars.css';
2022

2123
export function PostListing({type}) {
@@ -27,6 +29,15 @@ export function PostListing({type}) {
2729
return (
2830
<>
2931
{blogPages.map(page => <BlogPost key={page.name} {...page} />)}
32+
<div style={{display: 'flex', justifyContent: 'end'}}>
33+
<Link
34+
href={`../${type}/${type}-feed.rss`}
35+
target="_blank">
36+
<Flex gap="size-100" alignItems="center">
37+
<span>RSS Link</span><RSS size="S" />
38+
</Flex>
39+
</Link>
40+
</div>
3041
</>
3142
);
3243
}

scripts/buildWebsite.js

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ async function build() {
6060
name === 'tailwind-variants' ||
6161
name === 'react' ||
6262
name === 'react-dom' ||
63-
name === 'typescript'
63+
name === 'typescript' ||
64+
name === 'xml'
6465
)
6566
),
6667
dependencies: {
@@ -78,7 +79,8 @@ async function build() {
7879
scripts: {
7980
// Add a public url if provided via arg (for verdaccio prod doc website build since we want a commit hash)
8081
build: `DOCS_ENV=production PARCEL_WORKER_BACKEND=process GIT_HASH=${gitHash} parcel build 'docs/*/*/docs/*.mdx' 'docs/react-aria-components/docs/**/*.mdx' 'packages/dev/docs/pages/**/*.mdx' ${publicUrlFlag}`,
81-
postinstall: 'patch-package'
82+
postinstall: 'patch-package',
83+
createRssFeed: "node scripts/createFeed.mjs"
8284
},
8385
'@parcel/transformer-css': packageJSON['@parcel/transformer-css']
8486
};
@@ -134,6 +136,7 @@ async function build() {
134136
fs.copySync(path.join(__dirname, '..', '.yarn', 'releases'), path.join(dir, '.yarn', 'releases'));
135137
fs.copySync(path.join(__dirname, '..', '.yarn', 'plugins'), path.join(dir, '.yarn', 'plugins'));
136138
fs.copySync(path.join(__dirname, '..', '.yarnrc.yml'), path.join(dir, '.yarnrc.yml'));
139+
fs.copySync(path.join(__dirname, '..', 'scripts', 'createFeed.mjs'), path.join(dir, 'scripts', 'createFeed.mjs'));
137140

138141
// Delete mdx files from dev/docs that shouldn't go out yet.
139142
let devPkg = JSON.parse(fs.readFileSync(path.join(dir, 'packages/dev/docs/package.json'), 'utf8'));
@@ -170,8 +173,14 @@ async function build() {
170173
// Build the website
171174
await run('yarn', ['build'], {cwd: dir, stdio: 'inherit'});
172175

176+
// Generate the rss file for the release notes and blog
177+
await run('yarn', ['createRssFeed', 'releases'], {cwd: dir, stdio: 'inherit'});
178+
await run('yarn', ['createRssFeed', 'blog'], {cwd: dir, stdio: 'inherit'});
179+
173180
// Copy the build back into dist, and delete the temp dir.
174181
fs.copySync(path.join(dir, 'dist'), path.join(__dirname, '..', 'dist', 'production', 'docs'));
182+
fs.copySync(path.join(dir, 'scripts', 'releases-feed.rss'), path.join(__dirname, '..', 'dist', 'production', 'docs', 'releases', 'releases-feed.rss'))
183+
fs.copySync(path.join(dir, 'scripts', 'blog-feed.rss'), path.join(__dirname, '..', 'dist', 'production', 'docs', 'blog', 'blog-feed.rss'))
175184
fs.removeSync(dir);
176185
}
177186

scripts/createFeed.mjs

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
* Copyright 2024 Adobe. All rights reserved.
3+
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License. You may obtain a copy
5+
* of the License at http://www.apache.org/licenses/LICENSE-2.0
6+
*
7+
* Unless required by applicable law or agreed to in writing, software distributed under
8+
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9+
* OF ANY KIND, either express or implied. See the License for the specific language
10+
* governing permissions and limitations under the License.
11+
*/
12+
13+
import glob from 'glob';
14+
import fs from 'fs';
15+
import xml from "xml";
16+
import process from 'process';
17+
import {parseArgs} from 'node:util';
18+
19+
let options = {
20+
releases: {
21+
type: 'string'
22+
},
23+
blog: {
24+
type: 'string'
25+
}
26+
};
27+
28+
(async function createRssFeed() {
29+
30+
let args = parseArgs({options, allowPositionals: true});
31+
32+
if (args.positionals.length < 1) {
33+
console.error('Expected at least one argument');
34+
process.exit(1);
35+
}
36+
37+
let type = args.positionals[0];
38+
if (type !== 'releases' && type !== 'blog') {
39+
console.error('Expected argument to be either releases or blog');
40+
process.exit(1);
41+
}
42+
43+
let titleType = type === 'releases' ? 'Releases' : 'Blog'
44+
let posts = getFeed(type);
45+
const feedObject = {
46+
rss: [
47+
{_attr: {
48+
version: "2.0",
49+
"xmlns:atom": "http://www.w3.org/2005/Atom",
50+
},
51+
},
52+
{channel: [
53+
{"atom:link": {
54+
_attr: {
55+
href: `https://react-spectrum.adobe.com/${type}/${type}-feed.rss`,
56+
rel: "self",
57+
type: "application/rss+xml",
58+
},
59+
},
60+
},
61+
{title: `Adobe React Spectrum ${titleType}`},
62+
{link: `https://react-spectrum.adobe.com/${type}`},
63+
{description: "A collection of libraries and tools that help you build adaptive, accessible, and robust user experiences."},
64+
{language: "en-US"},
65+
...buildFeed(type, posts)
66+
],
67+
},
68+
],
69+
};
70+
71+
const feed = xml(feedObject, {declaration: true});
72+
await fs.writeFile(`scripts/${type}-feed.rss`, feed, (err) => console.log(err === null ? 'Success' : err));
73+
})();
74+
75+
function getFeed(type) {
76+
let files = glob.sync(`packages/dev/docs/pages/${type}/*.mdx`, {ignore: [`packages/dev/docs/pages/${type}/index.mdx`]});
77+
let posts = [];
78+
79+
for (let file of files) {
80+
let contents = fs.readFileSync(file, 'utf8').split("\n");
81+
82+
let date = '';
83+
let description = '';
84+
let title = '';
85+
let index = 0;
86+
while (date === '' || description === '' || title === '' && index < contents.length) {
87+
if (contents[index].startsWith('description')) {
88+
description = contents[index].replace('description:', '').trim();
89+
} else if (contents[index].startsWith('date:')) {
90+
date = contents[index].replace('date:', '').trim();
91+
} else if (contents[index].startsWith('#')) {
92+
title = contents[index].replace('#', '').trim();
93+
}
94+
index++;
95+
}
96+
97+
let f = file.split('/');
98+
let fileName = f[f.length - 1].replace('.mdx', '');
99+
100+
let post = {date: date, description: description, title: title, fileName: fileName};
101+
posts.push(post);
102+
}
103+
104+
posts = posts.sort((a, b) => a.date < b.date ? 1 : -1).slice(0, 5);
105+
return posts;
106+
}
107+
108+
function buildFeed(type, posts) {
109+
const feedItems = [];
110+
111+
feedItems.push(
112+
...posts.map(function (post) {
113+
const feedItem = {
114+
item: [
115+
{title: post.title},
116+
{pubDate: new Date(post.date).toUTCString(),},
117+
{guid: [
118+
{ _attr: { isPermaLink: true } },
119+
`https://react-spectrum.adobe.com/${type}/${post.fileName}.html`,
120+
],
121+
},
122+
{description: {
123+
_cdata: post.description,
124+
},
125+
},
126+
],
127+
};
128+
return feedItem;
129+
})
130+
);
131+
132+
return feedItems;
133+
}
134+

yarn.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29324,6 +29324,7 @@ __metadata:
2932429324
verdaccio: "npm:^5.13.0"
2932529325
walk-object: "npm:^4.0.0"
2932629326
wsrun: "npm:^5.0.0"
29327+
xml: "npm:^1.0.1"
2932729328
yargs: "npm:^17.2.1"
2932829329
languageName: unknown
2932929330
linkType: soft

0 commit comments

Comments
 (0)