Skip to content

Update Hacktoberfest Leaderboard #5

Update Hacktoberfest Leaderboard

Update Hacktoberfest Leaderboard #5

Workflow file for this run

name: Update Hacktoberfest Leaderboard
on:
schedule:
- cron: '0 * * * *' # Runs every hour at the start of the hour
workflow_dispatch: # Allows manual triggering
jobs:
update-leaderboard:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Update Leaderboard
uses: actions/github-script@v6
with:
github-token: ${{ secrets.HACKTOBERFEST_LEADERBOARD_TOKEN }}
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const issueNumber = 1; // Replace with your actual issue number
const REPOS = [
'galaxy-bytes/main-test-repo',
'GCodeHouse/Cohort4',
'TBD54566975/developer.tbd.website'
//'blackgirlbytes/LunaFocus'
];
const POINT_VALUES = {
small: 5,
medium: 10,
large: 15
};
const calculatePoints = (labels) => {
const size = labels.find(label => POINT_VALUES[label.name.toLowerCase()]);
return size ? POINT_VALUES[size.name.toLowerCase()] : POINT_VALUES.small;
};
const fetchRecentPRs = async (repo) => {
try {
console.log(`Fetching recent PRs for ${repo}`);
const [repoOwner, repoName] = repo.split('/');
const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString();
const { data: prs } = await github.rest.pulls.list({
owner: repoOwner,
repo: repoName,
state: 'closed',
sort: 'updated',
direction: 'desc',
per_page: 100
});
console.log(`Fetched ${prs.length} PRs for ${repo}`);
const hacktoberfestPRs = prs.filter(pr => {
const isMerged = !!pr.merged_at;
const isRecent = new Date(pr.merged_at) > new Date(thirtyDaysAgo);
const isHacktoberfest = pr.labels.some(label => label.name.toLowerCase() === 'hacktoberfest');
console.log(`PR #${pr.number}: merged=${isMerged}, recent=${isRecent}, hacktoberfest=${isHacktoberfest}`);
return isMerged && isRecent && isHacktoberfest;
}).map(pr => ({
user: pr.user.login,
points: calculatePoints(pr.labels),
repo: repo,
prNumber: pr.number,
prTitle: pr.title,
}));
console.log(`Found ${hacktoberfestPRs.length} qualifying PRs for ${repo}`);
return hacktoberfestPRs;
} catch (error) {
console.error(`Error fetching PRs for ${repo}: ${error.message}`);
return [];
}
};
const generateLeaderboard = async () => {
try {
const allPRs = await Promise.all(REPOS.map(fetchRecentPRs));
const flatPRs = allPRs.flat();
console.log(`Total qualifying PRs found: ${flatPRs.length}`);
console.log('Qualifying PRs:', JSON.stringify(flatPRs, null, 2));
const leaderboard = flatPRs.reduce((acc, pr) => {
if (!acc[pr.user]) acc[pr.user] = { points: 0, prs: 0 };
acc[pr.user].points += pr.points;
acc[pr.user].prs += 1;
return acc;
}, {});
console.log('Leaderboard object:', JSON.stringify(leaderboard, null, 2));
const sortedLeaderboard = Object.entries(leaderboard)
.sort(([, a], [, b]) => b.points - a.points)
.map(([username, data], index) => ({
rank: index + 1,
username,
points: data.points,
prs: data.prs
}));
console.log(`Generated leaderboard with ${sortedLeaderboard.length} entries`);
console.log('Sorted leaderboard:', JSON.stringify(sortedLeaderboard, null, 2));
return sortedLeaderboard;
} catch (error) {
console.error(`Error generating leaderboard: ${error.message}`);
return [];
}
};
const updateIssue = async (leaderboardData) => {
const issueBody = `
# Hacktoberfest Leaderboard
| Rank | Contributor | Points | PRs |
|------|-------------|--------|-----|
${leaderboardData.map(entry => `| ${entry.rank} | @${entry.username} | ${entry.points} | ${entry.prs} |`).join('\n')}
Last updated: ${new Date().toUTCString()}
`;
try {
await github.rest.issues.update({
owner,
repo,
issue_number: issueNumber,
body: issueBody
});
console.log("Issue updated successfully!");
console.log("Updated issue body:", issueBody);
} catch (error) {
throw new Error(`Failed to update issue: ${error.message}`);
}
};
// Main execution
const leaderboardData = await generateLeaderboard();
if (leaderboardData.length > 0) {
await updateIssue(leaderboardData);
} else {
console.log("No leaderboard data to update.");
const emptyIssueBody = `
# Hacktoberfest Leaderboard
No qualifying PRs found at this time.
Last updated: ${new Date().toUTCString()}
`;
await github.rest.issues.update({
owner,
repo,
issue_number: issueNumber,
body: emptyIssueBody
});
console.log("Updated issue with empty leaderboard message.");
}