Skip to content

Update README ecosystem table #114

Update README ecosystem table

Update README ecosystem table #114

name: Update README ecosystem table
on:
schedule:
# daily @ midnight UTC
- cron: '0 0 * * *'
workflow_dispatch:
inputs:
reason:
description: 'Reason for manually triggering the update'
required: false
default: 'Manual refresh of ecosystem table'
type: string
repository_dispatch:
types: [update-ecosystem]
jobs:
update-readme:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout .github repository
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Update README ecosystem table
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
// grab all public repos
const repos = await github.paginate(github.rest.repos.listForOrg, {
org: 'Neobotics-Foundation-Inc',
type: 'public',
sort: 'updated',
direction: 'desc'
});
// remove the .github repo and any archived repos
const filteredRepos = repos.filter(repo =>
!repo.archived &&
repo.name !== '.github'
).sort((a, b) => a.name.localeCompare(b.name));
// accounting for no public repositories found
if (filteredRepos.length === 0) {
console.log('No public repositories found');
return;
}
// generate table rows
const tableRows = filteredRepos.map(repo => {
const name = repo.name;
// account for pipe characters in description by changing | to \|
let description = repo.description || 'No description';
description = description.replace(/\|/g, '\\|');
// truncate to first 3 words and add ...
const words = description.split(' ');
if (words.length > 3) {
description = words.slice(0, 3).join(' ') + '...';
}
return `| [**${name}**](${repo.html_url})<br><em>${description}</em> | ![Language](https://img.shields.io/github/languages/top/Neobotics-Foundation-Inc/${name}?style=flat-square&labelColor=1B2036) | ![License](https://img.shields.io/github/license/Neobotics-Foundation-Inc/${name}?style=flat-square&label=) | ![Issues](https://img.shields.io/github/issues/Neobotics-Foundation-Inc/${name}?style=flat-square&label=) | ![Last Commit](https://img.shields.io/github/last-commit/Neobotics-Foundation-Inc/${name}?style=flat-square&label=) | ![Contributors](https://img.shields.io/github/contributors/Neobotics-Foundation-Inc/${name}?style=flat-square&label=) |`;
}).join('\n');
// build the complete table
const tableHeader = '| Repository | Language | License | Issues | Last Commit | Contrib. |\n|------------|:--------:|:-------:|:------:|:-----------:|:--------:|';
const newTable = `${tableHeader}\n${tableRows}`;
// read the current README
const readmePath = 'profile/README.md';
let readme = fs.readFileSync(readmePath, 'utf8');
// replace the ecosystem table using regex
// Match from the table header to the next ---
const tableRegex = /\| Repository \| Language \| License \| Issues \| Last Commit \| Contrib\. \|[\s\S]*?\n\n---/;
if (tableRegex.test(readme)) {
readme = readme.replace(tableRegex, `${newTable}\n\n---`);
console.log('Successfully replaced ecosystem table');
} else {
console.log('Could not find ecosystem table to replace. Make sure the README has the correct table header.');
console.log('Expected header: | Repository | Language | License | Issues | Last Commit | Contrib. |');
return;
}
// write the updated README
fs.writeFileSync(readmePath, readme);
console.log(`Updated ecosystem table with ${filteredRepos.length} repositories`);
- name: Commit changes
run: |
git config --local user.email "github-actions[bot]@users.noreply.github.com"
git config --local user.name "github-actions[bot]"
git add profile/README.md
git diff --staged --quiet || git commit -m "docs: auto-update ecosystem table [skip ci]"
git push