diff --git a/.github/workflows/update-draft-hips.yml b/.github/workflows/update-draft-hips.yml new file mode 100644 index 000000000..962c2d518 --- /dev/null +++ b/.github/workflows/update-draft-hips.yml @@ -0,0 +1,118 @@ +name: Update Draft HIPs Data + +on: + schedule: + - cron: "0 */6 * * *" # Runs every 6 hours + workflow_dispatch: # Allows manual triggering + +jobs: + update-draft-hips: + if: github.ref == 'refs/heads/main' # Only run on main branch + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: read + steps: + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3.5.2 + + - name: Setup Node.js + uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3.6.0 + with: + node-version: "20" + + - name: Create Script + run: | + mkdir -p _data + cat << 'EOF' > fetch-draft-hips.js + const https = require('https'); + + async function makeGraphQLRequest(query, token) { + return new Promise((resolve, reject) => { + const options = { + hostname: 'api.github.com', + path: '/graphql', + method: 'POST', + headers: { + 'Authorization': `Bearer ${token}`, + 'Content-Type': 'application/json', + 'User-Agent': 'Node.js' + } + }; + + const req = https.request(options, (res) => { + let data = ''; + res.on('data', chunk => { data += chunk; }); + res.on('end', () => resolve(JSON.parse(data))); + }); + + req.on('error', reject); + req.write(JSON.stringify({ query })); + req.end(); + }); + } + + async function getAllPRs() { + const query = ` + query { + repository(name: "hedera-improvement-proposal", owner: "hashgraph") { + pullRequests(first: 100, states: [OPEN], orderBy: {field: CREATED_AT, direction: DESC}) { + nodes { + title + number + url + headRefOid + files(first: 100) { + edges { + node { + path + additions + deletions + } + } + } + author { + login + } + } + } + } + } + `; + + try { + const result = await makeGraphQLRequest(query, process.env.GITHUB_TOKEN); + + if (result.errors) { + console.error('GraphQL errors:', result.errors); + process.exit(1); + } + + return result.data.repository.pullRequests.nodes; + } catch (error) { + console.error('Error fetching PRs:', error); + throw error; + } + } + + // Run the main function + getAllPRs().then(prs => { + const fs = require('fs'); + fs.writeFileSync('_data/draft_hips.json', JSON.stringify(prs, null, 2)); + }).catch(error => { + console.error('Failed to fetch PRs:', error); + process.exit(1); + }); + EOF + + - name: Run Script + run: node fetch-draft-hips.js + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Commit and Push Changes + run: | + git config --local user.email "github-actions[bot]@users.noreply.github.com" + git config --local user.name "github-actions[bot]" + git add _data/draft_hips.json + git commit -m "Update draft HIPs data [skip ci]" || echo "No changes to commit" + git push origin main || echo "No changes to push" diff --git a/_config.yml b/_config.yml index 770718471..a15d7d38d 100644 --- a/_config.yml +++ b/_config.yml @@ -32,6 +32,9 @@ defaults: values: layout: "hip" +include: + - _data + # Exclude from processing. # The following items will not be processed, by default. Create a custom list # to override the default setting. diff --git a/_includes/head.html b/_includes/head.html index 2efbe7cb2..4e6cffa83 100644 --- a/_includes/head.html +++ b/_includes/head.html @@ -1,5 +1,4 @@
- diff --git a/assets/js/pr-integration.js b/assets/js/pr-integration.js index 06e171141..121f97b6d 100644 --- a/assets/js/pr-integration.js +++ b/assets/js/pr-integration.js @@ -69,51 +69,14 @@ class HIPPRIntegration { async fetchPRData() { try { - const token = document.querySelector('meta[name="github-token"]').content; - - const query = { - query: `query { - repository(name: "hedera-improvement-proposal", owner: "hashgraph") { - pullRequests(first: 100, orderBy: {field: CREATED_AT, direction: DESC}, states: [OPEN]) { - nodes { - title - number - url - headRefOid - files(last: 100) { - edges { - node { - path - additions - deletions - } - } - } - author { - login - } - } - } - } - }` - }; - - const response = await fetch('https://api.github.com/graphql', { - method: 'POST', - headers: { - 'Authorization': `Bearer ${token}`, - 'Content-Type': 'application/json', - }, - body: JSON.stringify(query) - }); + // Try with site.baseurl if it's set in _config.yml + const baseUrl = document.querySelector('meta[name="site-baseurl"]')?.content || ''; + const response = await fetch(`${baseUrl}/_data/draft_hips.json`); - const data = await response.json(); - - if (!response.ok || data.errors) { - console.error('GraphQL errors:', data.errors); - return null; + if (!response.ok) { + throw new Error('Failed to fetch draft HIPs data'); } - return data.data.repository.pullRequests.nodes; + return await response.json(); } catch (error) { console.error('Error in fetchPRData:', error); throw error; @@ -123,14 +86,14 @@ class HIPPRIntegration { async filterHIPPRs(prs) { const validHips = []; const seenPRs = new Set(); - + for (const pr of prs) { if (seenPRs.has(pr.number)) continue; - + const mdFiles = pr.files.edges.filter(file => file.node.path.endsWith('.md')); let bestMetadata = null; let bestFile = null; - + // Try all MD files and pick the one with the most complete metadata for (const file of mdFiles) { try { @@ -138,16 +101,16 @@ class HIPPRIntegration { const response = await fetch(contentUrl); const content = await response.text(); const metadata = this.parseHIPMetadata(content); - + // Skip template files and empty metadata if (file.node.path.includes('template') || !metadata.title) { continue; } - + // If we don't have metadata yet, or this file has a better title - if (!bestMetadata || - (metadata.title && metadata.title.length > 3 && - (!bestMetadata.title || metadata.title.length > bestMetadata.title.length))) { + if (!bestMetadata || + (metadata.title && metadata.title.length > 3 && + (!bestMetadata.title || metadata.title.length > bestMetadata.title.length))) { bestMetadata = metadata; bestFile = file; } @@ -155,7 +118,7 @@ class HIPPRIntegration { console.error(`Error checking file ${file.node.path}:`, error); } } - + // If we found valid metadata, add it to the results if (bestMetadata && bestFile) { validHips.push({ @@ -166,7 +129,7 @@ class HIPPRIntegration { seenPRs.add(pr.number); } } - + return validHips; }