Add GitHub Health Dashboard workflow (#5286)
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
name: Update GitHub Health Dashboard
|
||||
|
||||
# Trigger configuration
|
||||
on:
|
||||
# Run daily at midnight UTC
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
# Allow manual triggering from GitHub UI
|
||||
workflow_dispatch:
|
||||
|
||||
# Define permissions for the GITHUB_TOKEN
|
||||
permissions:
|
||||
# Required to read repository contents
|
||||
contents: read
|
||||
# Required to read issues and PRs
|
||||
issues: read
|
||||
pull-requests: read
|
||||
# Required to update discussions
|
||||
discussions: write
|
||||
|
||||
jobs:
|
||||
update-dashboard:
|
||||
name: 'Update Health Dashboard'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: 'Update Dashboard'
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const owner = context.repo.owner;
|
||||
const repo = context.repo.repo;
|
||||
const discussionNumber = 5285;
|
||||
|
||||
console.log(`Fetching health metrics for ${owner}/${repo}`);
|
||||
|
||||
// Fetch open issues
|
||||
const { data: openIssues } = await github.rest.issues.listForRepo({
|
||||
owner,
|
||||
repo,
|
||||
state: 'open',
|
||||
per_page: 100
|
||||
});
|
||||
|
||||
// Filter out PRs (issues API includes PRs)
|
||||
const issues = openIssues.filter(issue => !issue.pull_request);
|
||||
const totalOpenIssues = issues.length;
|
||||
|
||||
// Count issues without labels (recent ones)
|
||||
const issuesWithoutLabels = issues.filter(issue => issue.labels.length === 0);
|
||||
|
||||
// Count issues by specific labels
|
||||
const labelCounts = {};
|
||||
const targetLabels = ['P0', 'P1', 'Compaction', 'Windows', 'Provider', 'MCP/Extensions', 'Linux'];
|
||||
|
||||
targetLabels.forEach(label => {
|
||||
labelCounts[label] = issues.filter(issue =>
|
||||
issue.labels.some(l => l.name === label)
|
||||
).length;
|
||||
});
|
||||
|
||||
// Fetch open PRs
|
||||
const { data: openPRs } = await github.rest.pulls.list({
|
||||
owner,
|
||||
repo,
|
||||
state: 'open',
|
||||
per_page: 100
|
||||
});
|
||||
|
||||
const totalOpenPRs = openPRs.length;
|
||||
|
||||
// Format the dashboard markdown
|
||||
const timestamp = new Date().toUTCString();
|
||||
const formattedDate = new Date().toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
|
||||
|
||||
const dashboardBody = '# GitHub Health\n\n' +
|
||||
'**Updated:** ' + formattedDate + '\n\n' +
|
||||
'## Issues\n\n' +
|
||||
'**Open:** ' + totalOpenIssues + '\n\n' +
|
||||
'**No labels:** ' + issuesWithoutLabels.length + ' (these are recent)\n\n' +
|
||||
'### Label Breakdown\n\n' +
|
||||
'| Label | Count |\n' +
|
||||
'|-------|-------|\n' +
|
||||
'| [P0](https://github.com/' + owner + '/' + repo + '/labels/P0) | ' + (labelCounts['P0'] || 0) + ' |\n' +
|
||||
'| [P1](https://github.com/' + owner + '/' + repo + '/labels/P1) | ' + (labelCounts['P1'] || 0) + ' |\n' +
|
||||
'| [Compaction](https://github.com/' + owner + '/' + repo + '/labels/Compaction) | ' + (labelCounts['Compaction'] || 0) + ' |\n' +
|
||||
'| [Windows](https://github.com/' + owner + '/' + repo + '/labels/Windows) | ' + (labelCounts['Windows'] || 0) + ' |\n' +
|
||||
'| [Provider](https://github.com/' + owner + '/' + repo + '/labels/Provider) | ' + (labelCounts['Provider'] || 0) + ' |\n' +
|
||||
'| [MCP/Extensions](https://github.com/' + owner + '/' + repo + '/labels/MCP%2FExtensions) | ' + (labelCounts['MCP/Extensions'] || 0) + ' |\n' +
|
||||
'| [Linux](https://github.com/' + owner + '/' + repo + '/labels/Linux) | ' + (labelCounts['Linux'] || 0) + ' |\n\n' +
|
||||
'## Open PRs\n\n' +
|
||||
'**Total:** ' + totalOpenPRs + '\n\n' +
|
||||
'---\n\n' +
|
||||
'*Last updated: ' + timestamp + '*\n' +
|
||||
'*This dashboard is automatically updated daily by [GitHub Actions](https://github.com/' + owner + '/' + repo + '/actions/workflows/update-health-dashboard.yml)*';
|
||||
|
||||
console.log('Dashboard generated, updating discussion...');
|
||||
|
||||
// Get the discussion node ID using GraphQL
|
||||
const discussionQuery = `
|
||||
query GetDiscussion($owner: String!, $repo: String!, $number: Int!) {
|
||||
repository(owner: $owner, name: $repo) {
|
||||
discussion(number: $number) {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const discussionResult = await github.graphql(discussionQuery, {
|
||||
owner,
|
||||
repo,
|
||||
number: discussionNumber
|
||||
});
|
||||
|
||||
const discussionId = discussionResult.repository.discussion.id;
|
||||
console.log(`Found discussion ID: ${discussionId}`);
|
||||
|
||||
// Update the discussion using GraphQL mutation
|
||||
const updateMutation = `
|
||||
mutation UpdateDiscussion($discussionId: ID!, $body: String!) {
|
||||
updateDiscussion(input: {discussionId: $discussionId, body: $body}) {
|
||||
discussion {
|
||||
id
|
||||
number
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
await github.graphql(updateMutation, {
|
||||
discussionId,
|
||||
body: dashboardBody
|
||||
});
|
||||
|
||||
console.log(`Successfully updated discussion #${discussionNumber}`);
|
||||
Reference in New Issue
Block a user