Skip to content

Commit 3dd649a

Browse files
authored
Fix draft HIP site refresh (#1527)
Signed-off-by: Michael Garber <michael.garber@hashgraph.com>
1 parent 3d230b0 commit 3dd649a

5 files changed

Lines changed: 90 additions & 54 deletions

File tree

.github/workflows/deploy-site.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ name: Deploy Site
33
on:
44
push:
55
branches: [main]
6+
# Draft HIPs live only in open pull requests, so refresh the published
7+
# GitHub Pages artifact even when main has not changed.
8+
schedule:
9+
- cron: "0 */6 * * *"
610
workflow_dispatch:
711

812
permissions:
@@ -37,6 +41,10 @@ jobs:
3741
working-directory: site
3842
run: npm ci
3943

44+
- name: Test site
45+
working-directory: site
46+
run: npm test
47+
4048
- name: Setup Pages
4149
id: pages
4250
uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6.0.0
@@ -46,10 +54,11 @@ jobs:
4654
run: npm run build:data
4755
env:
4856
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
57+
REQUIRE_LIVE_DRAFT_HIPS: "true"
4958

5059
- name: Build site
5160
working-directory: site
52-
run: npm run build
61+
run: npm run build:app
5362
env:
5463
VITE_BASE: ${{ steps.pages.outputs.base_path }}/
5564

.github/workflows/update-draft-hips.yml

Lines changed: 0 additions & 36 deletions
This file was deleted.

site/package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
"scripts": {
66
"build:data": "node scripts/build-data.js",
77
"dev": "npm run build:data && vite",
8-
"build": "npm run build:data && vite build",
8+
"build:app": "vite build",
9+
"build": "npm run build:data && npm run build:app",
910
"preview": "vite preview",
10-
"test": "node --test scripts/hip-parse.test.js"
11+
"test": "node --test scripts/*.test.js"
1112
},
1213
"dependencies": {
1314
"gray-matter": "^4.0.3",

site/scripts/build-data.js

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const OUT_DIR = path.resolve('public/data');
1414
const PUBLIC_ASSETS = path.resolve('public/assets');
1515
const REPO_OWNER = 'hiero-ledger';
1616
const REPO_NAME = 'hiero-improvement-proposals';
17+
const REQUIRE_LIVE_DRAFT_HIPS = process.env.REQUIRE_LIVE_DRAFT_HIPS === 'true';
1718

1819
fs.mkdirSync(OUT_DIR, { recursive: true });
1920

@@ -88,26 +89,39 @@ async function getDraftPRs() {
8889
},
8990
body: JSON.stringify({ query }),
9091
});
92+
if (!res.ok) {
93+
throw new Error(`GitHub GraphQL request failed with HTTP ${res.status}`);
94+
}
9195
const json = await res.json();
92-
if (json.errors) {
93-
console.warn(` Draft-HIP PR fetch: ${json.errors[0]?.message || 'GraphQL error'} — falling back to committed data`);
94-
} else {
95-
const nodes = json.data?.repository?.pullRequests?.nodes || [];
96-
// Keep only PRs that ADD a new HIP/hip-*.md file — the same filter the
97-
// old update-draft-hips.yml workflow used to produce _data/draft_hips.json.
98-
const drafts = nodes.filter(pr =>
99-
(pr.files?.edges || []).some(e =>
100-
e.node.changeType === 'ADDED' &&
101-
/^HIP\/hip-[A-Za-z0-9-]+\.md$/.test(e.node.path)
102-
)
103-
);
104-
console.log(`Fetched ${drafts.length} open draft-HIP PRs from GitHub`);
105-
return drafts;
96+
if (json.errors?.length) {
97+
throw new Error(json.errors[0]?.message || 'GitHub GraphQL request failed');
98+
}
99+
100+
const nodes = json.data?.repository?.pullRequests?.nodes;
101+
if (!Array.isArray(nodes)) {
102+
throw new Error('GitHub GraphQL response did not include pull requests');
106103
}
104+
105+
// Keep only PRs that ADD a new HIP/hip-*.md file — the same filter the
106+
// old update-draft-hips.yml workflow used to produce _data/draft_hips.json.
107+
const drafts = nodes.filter(pr =>
108+
(pr.files?.edges || []).some(e =>
109+
e.node.changeType === 'ADDED' &&
110+
/^HIP\/hip-[A-Za-z0-9-]+\.md$/.test(e.node.path)
111+
)
112+
);
113+
console.log(`Fetched ${drafts.length} open draft-HIP PRs from GitHub`);
114+
return drafts;
107115
} catch (e) {
116+
if (REQUIRE_LIVE_DRAFT_HIPS) {
117+
throw new Error(`Required live draft-HIP fetch failed: ${e.message}`);
118+
}
108119
console.warn(` Draft-HIP PR fetch failed (${e.message}) — falling back to committed data`);
109120
}
110121
} else {
122+
if (REQUIRE_LIVE_DRAFT_HIPS) {
123+
throw new Error('GITHUB_TOKEN is required when REQUIRE_LIVE_DRAFT_HIPS=true');
124+
}
111125
console.log('No GITHUB_TOKEN set — using committed _data/draft_hips.json if present');
112126
}
113127

@@ -404,4 +418,7 @@ async function main() {
404418
if (Object.keys(prReviews).length) console.log(` ${Object.keys(prReviews).length} PR review threads cached`);
405419
}
406420

407-
main();
421+
main().catch((error) => {
422+
console.error(`Site data build failed: ${error.message}`);
423+
process.exitCode = 1;
424+
});
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import test from 'node:test';
2+
import assert from 'node:assert/strict';
3+
import fs from 'fs';
4+
import path from 'path';
5+
import { fileURLToPath } from 'url';
6+
7+
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..');
8+
const deployWorkflowPath = path.join(repoRoot, '.github', 'workflows', 'deploy-site.yml');
9+
const legacyRefreshWorkflowPath = path.join(
10+
repoRoot,
11+
'.github',
12+
'workflows',
13+
'update-draft-hips.yml',
14+
);
15+
const deployWorkflow = fs.readFileSync(deployWorkflowPath, 'utf8');
16+
17+
function workflowStep(name) {
18+
const marker = ` - name: ${name}\n`;
19+
const start = deployWorkflow.indexOf(marker);
20+
assert.notEqual(start, -1, `Missing workflow step: ${name}`);
21+
const next = deployWorkflow.indexOf('\n - name:', start + marker.length);
22+
return deployWorkflow.slice(start, next === -1 ? undefined : next);
23+
}
24+
25+
test('the GitHub Pages workflow owns the scheduled draft-HIP refresh', () => {
26+
assert.match(deployWorkflow, /schedule:\s*\n\s+- cron: "0 \*\/6 \* \* \*"/);
27+
assert.equal(
28+
fs.existsSync(legacyRefreshWorkflowPath),
29+
false,
30+
'The obsolete Netlify refresh workflow must not be restored',
31+
);
32+
assert.doesNotMatch(deployWorkflow, /NETLIFY_BUILD_HOOK/);
33+
});
34+
35+
test('the production workflow generates data once with live drafts required', () => {
36+
const dataStep = workflowStep('Build data');
37+
const siteStep = workflowStep('Build site');
38+
39+
assert.match(dataStep, /run: npm run build:data\s/);
40+
assert.match(dataStep, /GITHUB_TOKEN: \$\{\{ secrets\.GITHUB_TOKEN \}\}/);
41+
assert.match(dataStep, /REQUIRE_LIVE_DRAFT_HIPS: "true"/);
42+
assert.match(siteStep, /run: npm run build:app\s/);
43+
assert.doesNotMatch(siteStep, /GITHUB_TOKEN/);
44+
assert.equal((deployWorkflow.match(/run: npm run build:data\s/g) || []).length, 1);
45+
});

0 commit comments

Comments
 (0)