Generate Custom Last Commit Badges #3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: "Generate Custom Last Commit Badges" | |
on: | |
# Runs every Monday at 03:00 UTC | |
schedule: | |
- cron: "0 3 * * *" | |
workflow_dispatch: | |
jobs: | |
build-and-deploy-badges: | |
runs-on: ubuntu-latest | |
permissions: | |
contents: write # Needed to push to gh-pages | |
steps: | |
# 1) Check out this "badge-updater" repository | |
- name: Check out code | |
uses: actions/checkout@v4 | |
with: | |
# If you need the full history, set fetch-depth: 0 | |
fetch-depth: 0 | |
# 2) Gather repos and last-commit info via GitHub Script | |
- name: Gather commit data | |
id: gather | |
uses: actions/github-script@v6 | |
with: | |
script: | | |
const org = 'latex4ei'; | |
let repos = []; | |
let page = 1; | |
while (true) { | |
const { data } = await github.rest.repos.listForOrg({ | |
org, | |
per_page: 100, | |
page, | |
}); | |
if (data.length === 0) break; | |
repos = repos.concat(data); | |
page++; | |
} | |
const results = []; | |
for (const repo of repos) { | |
// Optionally skip archived repos: | |
if (repo.archived) { | |
core.info(`Skipping archived repo: ${repo.name}`); | |
continue; | |
} | |
const defaultBranch = repo.default_branch || 'master'; | |
try { | |
const { data: commits } = await github.rest.repos.listCommits({ | |
owner: org, | |
repo: repo.name, | |
sha: defaultBranch, | |
per_page: 1, | |
}); | |
if (commits.length) { | |
const lastCommitDate = new Date(commits[0].commit.author.date); | |
const diffDays = Math.round((Date.now() - lastCommitDate) / (1000 * 60 * 60 * 24)); | |
// Decide color based on how old the last commit is | |
let color = 'red'; | |
if (diffDays < 90) { | |
color = 'brightgreen'; | |
} else if (diffDays < 365) { | |
color = 'green'; | |
} else if (diffDays < 1095) { | |
color = 'yellowgreen'; | |
} else if (diffDays < 1825) { | |
color = 'yellow'; | |
} | |
results.push({ | |
name: repo.name, | |
diffDays, | |
color, | |
}); | |
} | |
} catch (err) { | |
core.warning(`Error fetching commits for ${repo.name}: ${err}`); | |
} | |
} | |
// Return data as JSON | |
return results; | |
# 3) Generate the badges using shields.io | |
- name: Generate badges | |
run: | | |
echo '${{ steps.gather.outputs.result }}' > repos.json | |
mkdir -p last-commit | |
node <<'EOF' | |
const fs = require('fs'); | |
const { execSync } = require('child_process'); | |
const repos = JSON.parse(fs.readFileSync('repos.json', 'utf8')); | |
for (const r of repos) { | |
// Construct a Shields URL with custom color | |
const format = 'svg'; // or 'png' | |
const url = `https://img.shields.io/github/last-commit/latex4ei/${r.name}.${format}?&color=${r.color}`; | |
const outFile = `last-commit/${r.name}.${format}`; | |
console.log(`Generating badge for ${r.name} (days ago: ${r.diffDays}, color: ${r.color})`); | |
execSync(`curl -sL "${url}" -o "${outFile}"`); | |
} | |
EOF | |
# 4) Deploy all the files (including badges/) to gh-pages | |
- name: Deploy | |
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main' | |
uses: JamesIves/[email protected] | |
with: | |
branch: gh-pages | |
folder: . | |
single-commit: true | |
silent: true |