Skip to content

Commit

Permalink
⚡️ update Github Action
Browse files Browse the repository at this point in the history
  • Loading branch information
ChunhThanhDe committed Nov 4, 2024
1 parent 0fb8052 commit f9a9d97
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 118 deletions.
210 changes: 101 additions & 109 deletions .github/updateLeaderboard.js
Original file line number Diff line number Diff line change
@@ -1,135 +1,127 @@
const fs = require('fs');

module.exports = async ({ github, context }) => {
const query = `query($owner:String!, $name:String!, $issue_number:Int!) {
repository(owner:$owner, name:$name){
issue(number:$issue_number) {
title
bodyText
author {
avatarUrl(size: 24)
login
url
try {
console.log('Starting leaderboard update...');

const query = `query($owner:String!, $name:String!, $issue_number:Int!) {
repository(owner:$owner, name:$name){
issue(number:$issue_number) {
title
bodyText
author {
avatarUrl(size: 24)
login
url
}
updatedAt
}
}
updatedAt
}`;

const variables = {
owner: context.repo.owner,
name: context.repo.repo,
issue_number: context.issue.number,
};

const result = await github.graphql(query, variables);
console.log(JSON.stringify(result, null, 2));

const issue = result.repository.issue;

const nameMatch = /👤 Name:\s*(.*?)\n-/.exec(issue.bodyText);
const githubLinkMatch = /🔗 GitHub Profile Link:\s*(.*?)\n-/.exec(issue.bodyText);
const messageMatch = /💬 Message:\s*(.*?)\n-/.exec(issue.bodyText);
const scoreMatch = /Score:\s*(\d+)/.exec(issue.title);
const dateMatch = /Game Result Submission:\s*(.*?) - Score:/.exec(issue.title);
const modeMatch = /Mode:\s*(\d+)/.exec(issue.title);
const winMatch = /Win:\s*(\d+)/.exec(issue.title);

// Extract values or fallback to author details if null
const name = nameMatch ? nameMatch[1].trim() : issue.author.login;
const githubLink = githubLinkMatch ? githubLinkMatch[1].trim() : issue.author.url;
const message = messageMatch ? messageMatch[1].trim() : '';
const score = scoreMatch ? parseInt(scoreMatch[1].trim()) : null;
const date = dateMatch ? dateMatch[1].trim() : null;
const mode = modeMatch ? parseInt(modeMatch[1].trim()) : null;
const win = winMatch ? parseInt(winMatch[1].trim()) : null;

// Check for null values
if (score === null || date === null || mode === null || win === null) {
console.log('One or more required fields are missing. Stopping further processing.');
return false;
}
}
}`;

const variables = {
owner: context.repo.owner,
name: context.repo.repo,
issue_number: context.issue.number,
};

const result = await github.graphql(query, variables);
console.log(JSON.stringify(result, null, 2));

const issue = result.repository.issue;

const nameMatch = /👤 Name:\s*(.*?)\n-/.exec(issue.bodyText);
const githubLinkMatch = /🔗 GitHub Profile Link:\s*(.*?)\n-/.exec(issue.bodyText);
const messageMatch = /💬 Message:\s*(.*?)\n-/.exec(issue.bodyText);
const scoreMatch = /Score:\s*(\d+)/.exec(issue.title);
const dateMatch = /Game Result Submission:\s*(.*?) - Score:/.exec(issue.title);
const modeMatch = /Mode:\s*(\d+)/.exec(issue.title);
const winMatch = /Win:\s*(\d+)/.exec(issue.title);


// Extract values or fallback to author details if null
const name = nameMatch ? nameMatch[1].trim() : issue.author.login; // Use author's GitHub login if name not found
const githubLink = githubLinkMatch ? githubLinkMatch[1].trim() : issue.author.url; // Use author's URL if not found
const message = messageMatch ? messageMatch[1].trim() : ''; // Default message if not found
const score = scoreMatch ? parseInt(scoreMatch[1].trim()) : null; // Extract score
const date = dateMatch ? dateMatch[1].trim() : null; // Extract date
const mode = modeMatch ? parseInt(modeMatch[1].trim()) : null; // Extract mode
const win = winMatch ? parseInt(winMatch[1].trim()) : null; // Extract win status

// Check if any of the extracted values are null, if so, stop processing
if (score === null || date === null || mode === null || win === null) {
console.log('One or more required fields are missing. Stopping further processing.');
return; // Exit or stop further execution as needed
}

// Map mode values to difficulty levels
const modeMapping = {
0: 'Easy',
1: 'Medium',
2: 'Hard'
};
// Map mode values to difficulty levels
const modeMapping = {
0: 'Easy',
1: 'Medium',
2: 'Hard'
};

// Get the corresponding difficulty level or 'N/A' if not found
const difficulty = modeMapping[mode] || '';
const difficulty = modeMapping[mode] || '';
const gameOutcome = win === 1 ? 'Win' : 'Game Over';

// Determine game outcome based on win value
const gameOutcome = win === 1 ? 'Win' : (win === 0 ? 'Game Over' : '');
const newLeaderboardItem = `| ${score} | ${difficulty} | [<img src="${issue.author.avatarUrl}" alt="${issue.author.login}" width="24" /> ${name}](${githubLink}) | ${message} | ${date} |\n`;
const newEntry = `| ${date} | [<img src="${issue.author.avatarUrl}" alt="${issue.author.login}" width="24" /> ${name}](${githubLink}) | ${message} | ${difficulty} | ${score} | ${gameOutcome} |`;

const newLeaderboardItem = `| ${score} | ${difficulty} | [<img src="${issue.author.avatarUrl}" alt="${issue.author.login}" width="24" /> ${name}](${githubLink}) | ${message} | ${date} |\n`;
const readmePath = 'README.md';
let readme = fs.readFileSync(readmePath, 'utf8');

const newEntry = `| ${date} | [<img src="${issue.author.avatarUrl}" alt="${issue.author.login}" width="24" /> ${name}](${githubLink}) | ${message} | ${difficulty} | ${score} | ${gameOutcome} |`;
// Update Recent Plays
const recentPlaysSection = /<!-- Recent Plays -->[\s\S]*?<!-- \/Recent Plays -->/.exec(readme);
if (recentPlaysSection) {
let recentPlaysContent = recentPlaysSection[0];

const readmePath = 'README.md';
let readme = fs.readFileSync(readmePath, 'utf8');
let recentPlaysRows = recentPlaysContent
.split('\n')
.filter(row => row.startsWith('|') && !row.includes('Date | Player | Message | Game Mode | Score | Status ') && !row.includes('|------|--------|---------|-----------|-------|--------|'));

// Update Recent Plays
const recentPlaysSection = /<!-- Recent Plays -->[\s\S]*?<!-- \/Recent Plays -->/.exec(readme);
if (recentPlaysSection) {
let recentPlaysContent = recentPlaysSection[0];
recentPlaysRows.unshift(newEntry);

if (recentPlaysRows.length > 20) {
recentPlaysRows = recentPlaysRows.slice(0, 20);
}

let recentPlaysRows = recentPlaysContent
.split('\n')
.filter(row => row.startsWith('|') && !row.includes('Date | Player | Message | Game Mode | Score | Status ') && !row.includes('|------|--------|---------|-----------|-------|--------|'));
const updatedRecentPlays = `<!-- Recent Plays -->\n| Date | Player | Message | Game Mode | Score | Status |\n|------|--------|---------|-----------|-------|--------|\n${recentPlaysRows.join('\n')}\n<!-- /Recent Plays -->`;
readme = readme.replace(recentPlaysSection[0], updatedRecentPlays);
}

// Update Leaderboard
const leaderboardSection = /<!-- Leaderboard -->[\s\S]*?<!-- \/Leaderboard -->/.exec(readme);
if (leaderboardSection && win === 1) {
let leaderboardContent = leaderboardSection[0];

recentPlaysRows.unshift(newEntry);
let leaderboardRows = leaderboardContent
.split('\n')
.filter(row => row.startsWith('|') && !row.includes('Score | Game Mode | Player | Message | Date') && !row.includes('|-------|-----------|--------|---------|------|'));

console.log("Current length of recentPlaysRows after sorting:", recentPlaysRows.length);
if (recentPlaysRows.length > 20) {
recentPlaysRows = recentPlaysRows.slice(0, 20);
}
leaderboardRows.unshift(newLeaderboardItem);

leaderboardRows.sort((a, b) => {
const scoreA = parseInt(a.split('|')[1].trim(), 10);
const scoreB = parseInt(b.split('|')[1].trim(), 10);
const dateA = new Date(a.split('|')[5].trim());
const dateB = new Date(b.split('|')[5].trim());

const updatedRecentPlays = `<!-- Recent Plays -->\n| Date | Player | Message | Game Mode | Score | Status |\n|------|--------|---------|-----------|-------|--------|\n${recentPlaysRows.join('\n')}\n<!-- /Recent Plays -->`;
readme = readme.replace(recentPlaysSection[0], updatedRecentPlays);
}
return scoreB - scoreA || dateB - dateA;
});

// Update Leaderboard
const leaderboardSection = /<!-- Leaderboard -->[\s\S]*?<!-- \/Leaderboard -->/.exec(readme);
if (leaderboardSection && win === 1 ) {
let leaderboardContent = leaderboardSection[0];
leaderboardContent = leaderboardContent.replace(/<!-- \/Leaderboard -->/, `${newLeaderboardItem}<!-- \/Leaderboard -->`);

let leaderboardRows = leaderboardContent
.split('\n')
.filter(row => row.startsWith('|') && !row.includes('Score | Game Mode | Player | Message | Date') && !row.includes('|-------|-----------|--------|---------|------|'));

leaderboardRows.sort((a, b) => {
const scoreA = a.match(/^\| (\d+) \|/);
const scoreB = b.match(/^\| (\d+) \|/);
const dateA = a.match(/\| (\d+) \| ([^|]+) \| ([^|]+) \| ([^|]+) \| ([^|]+) \|/)[5].trim();
const dateB = b.match(/\| (\d+) \| ([^|]+) \| ([^|]+) \| ([^|]+) \| ([^|]+) \|/)[5].trim();

if (scoreB && scoreA) {
const scoreDiff = parseInt(scoreB[1]) - parseInt(scoreA[1]);
if (scoreDiff !== 0) {
return scoreDiff;
}
if (leaderboardRows.length > 20) {
leaderboardRows = leaderboardRows.slice(0, 20);
}

return dateB.localeCompare(dateA);
});

console.log("Current length of leaderboardRows after sorting:", leaderboardRows.length);

if (leaderboardRows.length > 20) {
leaderboardRows = leaderboardRows.slice(0, 20);
const updatedLeaderboard = `<!-- Leaderboard -->\n| Score | Game Mode | Player | Message | Date |\n|-------|-----------|--------|---------|------|\n${leaderboardRows.join('\n')}\n<!-- /Leaderboard -->`;
readme = readme.replace(leaderboardSection[0], updatedLeaderboard);
}

const updatedLeaderboard = `<!-- Leaderboard -->\n| Score | Game Mode | Player | Message | Date |\n|-------|-----------|--------|---------|------|\n${leaderboardRows.join('\n')}\n<!-- /Leaderboard -->`;
readme = readme.replace(leaderboardSection[0], updatedLeaderboard);
}
fs.writeFileSync(readmePath, readme, 'utf8');
console.log('README.md updated successfully.');

fs.writeFileSync(readmePath, readme, 'utf8');
console.log('README.md updated successfully.');
return true;
} catch (error) {
console.error('Error:', error);
return false;
}
};
24 changes: 15 additions & 9 deletions .github/workflows/update_leaderboard.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,28 @@ jobs:
permissions:
contents: write
issues: write
pull-requests: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Update leaderboard from comments
- name: Run updateLeaderboard script
id: update_leaderboard
uses: actions/github-script@v7
with:
script: |
const updateLeaderboard = require('./.github/updateLeaderboard.js');
updateLeaderboard({github, context});
const result = await updateLeaderboard({ github, context });
return result;
- name: Commit changes
run: |
git config --global user.name 'Github Actions'
git config --global user.email '41898282+github-actions[bot]@users.noreply.github.com'
git add README.md
git commit -m ':sparkles: Update leaderboard' || echo "No changes to commit"
git push https://x-access-token:${{ secrets.GH_TOKEN }}@github.com/${{ github.repository }} HEAD:main
- name: Create Pull Request
if: steps.update_leaderboard.outputs.result == 'true'
uses: peter-evans/create-pull-request@v5
with:
branch: update-leaderboard
commit-message: ':sparkles: Update leaderboard'
title: 'Update Leaderboard'
body: |
This PR updates the leaderboard based on the latest game results.
base: main

0 comments on commit f9a9d97

Please sign in to comment.