Skip to content

Commit 0ed08c2

Browse files
authored
Merge pull request #40 from AdamG100/master
Add Discord release notification workflow
2 parents 6075dde + 80ca629 commit 0ed08c2

2 files changed

Lines changed: 105 additions & 1 deletion

File tree

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
name: Discord Release Notification
2+
3+
"on":
4+
push:
5+
branches:
6+
- master
7+
paths:
8+
- "versioned_docs/version-3/releases/**.mdx"
9+
10+
jobs:
11+
notify:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
with:
16+
fetch-depth: 2
17+
18+
- name: Detect new release files
19+
id: detect
20+
run: |
21+
NEW_FILES=$(git diff --name-status HEAD~1 HEAD -- 'versioned_docs/version-3/releases/*.mdx' | grep '^A' | awk '{print $2}' | grep -v 'index.mdx' || true)
22+
echo "files=$NEW_FILES" >> $GITHUB_OUTPUT
23+
24+
- name: Set up Node.js
25+
if: steps.detect.outputs.files != ''
26+
uses: actions/setup-node@v4
27+
with:
28+
node-version: '22'
29+
30+
- name: Install gray-matter
31+
if: steps.detect.outputs.files != ''
32+
run: npm install gray-matter
33+
34+
- name: Send Discord notification
35+
if: steps.detect.outputs.files != ''
36+
env:
37+
DISCORD_WEBHOOK: ${{ secrets.DISCORD_RELEASE_WEBHOOK }}
38+
DISCORD_ROLE_ID: ${{ secrets.DISCORD_RELEASE_ROLE_ID }}
39+
NEW_FILES: ${{ steps.detect.outputs.files }}
40+
SITE_URL: https://docs.tcadmin.com
41+
run: |
42+
node << 'EOF'
43+
const fs = require('fs');
44+
const matter = require('gray-matter');
45+
46+
const files = process.env.NEW_FILES.trim().split('\n').filter(Boolean);
47+
const webhookUrl = process.env.DISCORD_WEBHOOK;
48+
const roleId = process.env.DISCORD_ROLE_ID;
49+
const siteUrl = process.env.SITE_URL;
50+
51+
for (const file of files) {
52+
const raw = fs.readFileSync(file, 'utf8');
53+
const { data, content } = matter(raw);
54+
55+
const version = data.sidebar_label ?? file.replace(/.*\//, '').replace(/\.mdx?$/, '');
56+
const date = data.date ? new Date(data.date).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' }) : null;
57+
const slug = file.replace(/.*\//, '').replace(/\.mdx?$/, '');
58+
const url = `${siteUrl}/3/releases/${slug}`;
59+
60+
// Auto-generate description from New Features bold items
61+
let description = data.description || '';
62+
if (!description) {
63+
const featuresMatch = content.match(/###\s+New Features([\s\S]*?)(?:###|$)/);
64+
if (featuresMatch) {
65+
const names = [];
66+
const re = /\*\*([^*]+)\*\*/g;
67+
let m;
68+
while ((m = re.exec(featuresMatch[1])) !== null) {
69+
names.push(m[1]);
70+
if (names.length === 5) break;
71+
}
72+
if (names.length) description = names.join(', ') + (names.length === 5 ? ', and more.' : '.');
73+
}
74+
}
75+
76+
const embed = {
77+
title: `TCAdmin v3 — Version ${version}`,
78+
url,
79+
color: 0x57F287,
80+
description: description || 'A new version of TCAdmin v3 has been released.',
81+
fields: date ? [{ name: 'Release Date', value: date, inline: true }] : [],
82+
footer: { text: 'TCAdmin Documentation' },
83+
timestamp: data.date ? new Date(data.date).toISOString() : new Date().toISOString(),
84+
};
85+
86+
const body = {
87+
content: roleId ? `<@&${roleId}>` : undefined,
88+
embeds: [embed],
89+
};
90+
91+
const res = await fetch(webhookUrl, {
92+
method: 'POST',
93+
headers: { 'Content-Type': 'application/json' },
94+
body: JSON.stringify(body),
95+
});
96+
97+
if (!res.ok) {
98+
console.error(`Discord webhook failed: ${res.status} ${await res.text()}`);
99+
process.exit(1);
100+
}
101+
102+
console.log(`Notified Discord for ${version}`);
103+
}
104+
EOF

docusaurus.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ const config = {
4343
return items.map((/** @type {any} */ item) => {
4444
if (item.type === "category") {
4545
const sorted = /** @type {any[]} */ (sortItems(item.items));
46-
if (item.label === "Release Notes") {
46+
if (item.label === "Releases") {
4747
sorted.sort((/** @type {any} */ a, /** @type {any} */ b) => {
4848
const la = a.label ?? "";
4949
const lb = b.label ?? "";

0 commit comments

Comments
 (0)