|
1 | | -name: Update Draft HIPs Data |
| 1 | +name: Refresh Draft HIPs on Site |
| 2 | + |
| 3 | +# Draft HIPs (open PRs that add a new HIP) are fetched live during the site |
| 4 | +# build (see site/scripts/build-data.js). This job just triggers a Netlify |
| 5 | +# rebuild on a schedule so the published site stays current, WITHOUT committing |
| 6 | +# any generated data to main. Requires a NETLIFY_BUILD_HOOK repo secret; if it |
| 7 | +# is not set, the job is a no-op. |
2 | 8 |
|
3 | 9 | on: |
4 | 10 | schedule: |
5 | | - - cron: "0 */6 * * *" # Runs every 6 hours |
6 | | - workflow_dispatch: # Allows manual triggering |
| 11 | + - cron: "0 */6 * * *" # every 6 hours |
| 12 | + workflow_dispatch: # allow manual triggering |
7 | 13 |
|
8 | 14 | permissions: |
9 | 15 | contents: read |
10 | 16 |
|
11 | 17 | jobs: |
12 | | - update-draft-hips: |
13 | | - if: ${{ github.ref == 'refs/heads/main' }} # Only run on main branch |
| 18 | + trigger-site-rebuild: |
| 19 | + if: ${{ github.ref == 'refs/heads/main' }} |
14 | 20 | runs-on: hiero-improvement-proposals-linux-medium |
15 | | - permissions: |
16 | | - contents: read |
17 | 21 | steps: |
18 | 22 | - name: Harden the runner (Audit all outbound calls) |
19 | 23 | uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4 |
20 | 24 | with: |
21 | 25 | egress-policy: audit |
22 | 26 |
|
23 | | - - name: Checkout Code |
24 | | - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 |
25 | | - with: |
26 | | - token: ${{ secrets.GH_ACCESS_TOKEN }} |
27 | | - ref: 'main' |
28 | | - |
29 | | - - name: Import GPG Key |
30 | | - id: gpg_importer |
31 | | - uses: step-security/ghaction-import-gpg@69c854a83c7f79463f8bdf46772ab09826c560cd # v6.3.1 |
32 | | - with: |
33 | | - git_commit_gpgsign: true |
34 | | - git_tag_gpgsign: true |
35 | | - git_user_signingkey: true |
36 | | - gpg_private_key: ${{ secrets.GPG_KEY_CONTENTS }} |
37 | | - passphrase: ${{ secrets.GPG_KEY_PASSPHRASE }} |
38 | | - |
39 | | - - name: Setup Node.js |
40 | | - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 |
41 | | - with: |
42 | | - node-version: "20" |
43 | | - |
44 | | - - name: Create Script |
45 | | - run: | |
46 | | - mkdir -p _data |
47 | | - cat << 'EOF' > fetch-draft-hips.js |
48 | | - const https = require('https'); |
49 | | - const fs = require('fs'); |
50 | | -
|
51 | | - async function makeGraphQLRequest(query, token) { |
52 | | - return new Promise((resolve, reject) => { |
53 | | - const options = { |
54 | | - hostname: 'api.github.com', |
55 | | - path: '/graphql', |
56 | | - method: 'POST', |
57 | | - headers: { |
58 | | - 'Authorization': `Bearer ${token}`, |
59 | | - 'Content-Type': 'application/json', |
60 | | - 'User-Agent': 'Node.js' |
61 | | - } |
62 | | - }; |
63 | | -
|
64 | | - const req = https.request(options, (res) => { |
65 | | - let data = ''; |
66 | | - res.on('data', chunk => { data += chunk; }); |
67 | | - res.on('end', () => resolve(JSON.parse(data))); |
68 | | - }); |
69 | | -
|
70 | | - req.on('error', reject); |
71 | | - req.write(JSON.stringify({ query })); |
72 | | - req.end(); |
73 | | - }); |
74 | | - } |
75 | | -
|
76 | | - async function getAllPRs() { |
77 | | - const query = ` |
78 | | - query { |
79 | | - repository(name: "hiero-improvement-proposals", owner: "hiero-ledger") { |
80 | | - pullRequests(first: 100, states: [OPEN], orderBy: {field: CREATED_AT, direction: DESC}) { |
81 | | - nodes { |
82 | | - title |
83 | | - number |
84 | | - url |
85 | | - headRefOid |
86 | | - files(first: 100) { |
87 | | - edges { |
88 | | - node { |
89 | | - path |
90 | | - changeType |
91 | | - additions |
92 | | - deletions |
93 | | - } |
94 | | - } |
95 | | - } |
96 | | - author { |
97 | | - login |
98 | | - } |
99 | | - } |
100 | | - } |
101 | | - } |
102 | | - } |
103 | | - `; |
104 | | -
|
105 | | - try { |
106 | | - const result = await makeGraphQLRequest(query, process.env.GITHUB_TOKEN); |
107 | | - |
108 | | - if (result.errors) { |
109 | | - console.error('GraphQL errors:', result.errors); |
110 | | - process.exit(1); |
111 | | - } |
112 | | -
|
113 | | - // Check if data and the expected path to nodes exist |
114 | | - if (!result.data || !result.data.repository || !result.data.repository.pullRequests || !result.data.repository.pullRequests.nodes) { |
115 | | - console.error('Unexpected GraphQL response structure:', result); |
116 | | - process.exit(1); |
117 | | - } |
118 | | -
|
119 | | - return result.data.repository.pullRequests.nodes; |
120 | | - } catch (error) { |
121 | | - console.error('Error fetching PRs:', error); |
122 | | - throw error; |
123 | | - } |
124 | | - } |
125 | | -
|
126 | | - // Run the main function |
127 | | - getAllPRs().then(allPRs => { |
128 | | - const draftHIPPRs = allPRs.filter(pr => { |
129 | | - if (!pr.files || !pr.files.edges) { |
130 | | - return false; |
131 | | - } |
132 | | - const hipFiles = pr.files.edges.filter(edge => { |
133 | | - const fileNode = edge.node; |
134 | | - const isNewHIPFile = /^HIP\/hip-[a-zA-Z0-9-]+\.md$/.test(fileNode.path); |
135 | | - return fileNode.changeType === 'ADDED' && isNewHIPFile; |
136 | | - }).map(edge => edge.node); |
137 | | -
|
138 | | - return hipFiles.length > 0; |
139 | | - }); |
140 | | -
|
141 | | - const outputPath = '_data/draft_hips.json'; |
142 | | - |
143 | | - if (fs.existsSync(outputPath)) { |
144 | | - console.log(`Removing existing file: ${outputPath}`); |
145 | | - fs.unlinkSync(outputPath); |
146 | | - } |
147 | | - |
148 | | - console.log(`Writing ${draftHIPPRs.length} filtered PRs to: ${outputPath}`); |
149 | | - fs.writeFileSync(outputPath, JSON.stringify(draftHIPPRs, null, 2)); |
150 | | - }).catch(error => { |
151 | | - console.error('Failed to fetch and filter PRs:', error); |
152 | | - process.exit(1); |
153 | | - }); |
154 | | - EOF |
155 | | -
|
156 | | - - name: Run Script |
157 | | - run: node fetch-draft-hips.js |
158 | | - env: |
159 | | - GITHUB_TOKEN: ${{ secrets.GH_ACCESS_TOKEN }} |
160 | | - |
161 | | - - name: Commit and Push Changes |
| 27 | + - name: Trigger Netlify build (re-fetches open draft-HIP PRs at build time) |
162 | 28 | env: |
163 | | - GITHUB_USER_EMAIL: ${{ vars.GIT_USER_EMAIL }} |
164 | | - GITHUB_USER_NAME: ${{ vars.GIT_USER_NAME }} |
| 29 | + NETLIFY_BUILD_HOOK: ${{ secrets.NETLIFY_BUILD_HOOK }} |
165 | 30 | run: | |
166 | | - set -e |
167 | | - git config --local user.email "$GITHUB_USER_EMAIL" |
168 | | - git config --local user.name "$GITHUB_USER_NAME" |
169 | | - git add _data/draft_hips.json |
170 | | - git diff --cached --quiet && echo "No changes to commit" && exit 0 |
171 | | - |
172 | | - git commit -s -S -m "Update draft HIPs data [skip ci]" |
173 | | - git push origin main |
174 | | - set +e |
| 31 | + if [ -z "$NETLIFY_BUILD_HOOK" ]; then |
| 32 | + echo "NETLIFY_BUILD_HOOK secret not set — skipping." |
| 33 | + echo "Add the secret (Netlify build hook URL) to enable scheduled draft-HIP refreshes." |
| 34 | + exit 0 |
| 35 | + fi |
| 36 | + curl -fsS -X POST -d '{}' "$NETLIFY_BUILD_HOOK" && echo "Netlify build triggered." |
0 commit comments