Skip to content

Commit 1b042a7

Browse files
authored
Merge pull request #128 from deadlydog/copilot/fix-77
Add GitHub Action to automatically update README with contributors
2 parents bcf0711 + d33e247 commit 1b042a7

File tree

1 file changed

+145
-0
lines changed

1 file changed

+145
-0
lines changed
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
name: Update README Contributors
2+
3+
on:
4+
# Run weekly on Sunday at 00:00 UTC
5+
schedule:
6+
- cron: '0 0 * * 0'
7+
8+
# Run when changes are merged to main
9+
push:
10+
branches:
11+
- main
12+
paths-ignore:
13+
- 'ReadMe.md' # Skip when only the ReadMe.md changes to avoid infinite loops
14+
- '.github/workflows/update-readme-contributors.yml' # Skip when this workflow file changes
15+
16+
# Allows manual triggering from the Actions tab
17+
workflow_dispatch:
18+
19+
jobs:
20+
update-contributors:
21+
runs-on: ubuntu-latest
22+
23+
steps:
24+
- name: Checkout the repo
25+
uses: actions/checkout@v4
26+
with:
27+
# Fetch with token that has write access to the repo
28+
token: ${{ secrets.GITHUB_TOKEN }}
29+
30+
- name: Update README with Contributors
31+
id: update-readme
32+
uses: actions/github-script@v7
33+
with:
34+
github-token: ${{ secrets.GITHUB_TOKEN }}
35+
script: |
36+
const fs = require('fs');
37+
const path = require('path');
38+
39+
try {
40+
// Fetch contributors from the repository
41+
console.log('Fetching contributors from GitHub API...');
42+
const contributorsResponse = await github.rest.repos.listContributors({
43+
owner: context.repo.owner,
44+
repo: context.repo.repo,
45+
per_page: 100
46+
});
47+
48+
const contributors = contributorsResponse.data;
49+
console.log(`Found ${contributors.length} contributors.`);
50+
51+
if (contributors.length === 0) {
52+
console.log('No contributors found. Skipping update.');
53+
return false;
54+
}
55+
56+
// Read the README file
57+
const readmePath = path.join(process.env.GITHUB_WORKSPACE, 'ReadMe.md');
58+
let readmeContent = fs.readFileSync(readmePath, 'utf8');
59+
60+
// Create the Contributors section
61+
let contributorsSection = `
62+
## 👥 Contributors
63+
64+
Thanks to these wonderful people who have contributed to tiPS:
65+
66+
<p align="center">
67+
`;
68+
69+
// Add each contributor to the section
70+
for (const contributor of contributors) {
71+
// Skip GitHub Actions bot or other bots
72+
if (contributor.login === 'github-actions[bot]' ||
73+
contributor.login === 'dependabot[bot]') {
74+
continue;
75+
}
76+
77+
contributorsSection += ` <a href="${contributor.html_url}" title="${contributor.login}"><img src="${contributor.avatar_url}" width="50" height="50" style="border-radius:50%;margin:5px;" alt="${contributor.login}"></a>\n`;
78+
}
79+
80+
contributorsSection += `</p>
81+
82+
`;
83+
84+
// Check if the README already has a Contributors section
85+
if (readmeContent.includes('## 👥 Contributors')) {
86+
// Replace the existing section using regex to capture everything between the Contributors heading and the next heading
87+
const pattern = /(## 👥 Contributors[\s\S]*?)(\r?\n\r?\n## )/;
88+
readmeContent = readmeContent.replace(pattern, contributorsSection + '$2');
89+
} else {
90+
// Insert before the Roadmap section
91+
readmeContent = readmeContent.replace(/(## 🛣️ Roadmap)/, contributorsSection + '$1');
92+
}
93+
94+
// Write the updated content back to the README file
95+
fs.writeFileSync(readmePath, readmeContent);
96+
97+
console.log('README updated with contributors.');
98+
99+
// Set output for next step - return true if we made changes
100+
return true;
101+
} catch (error) {
102+
console.error(`Error updating README: ${error}`);
103+
core.setFailed(`Failed to update README: ${error.message}`);
104+
return false;
105+
}
106+
result-encoding: string
107+
108+
- name: Commit and push changes if README was updated
109+
if: steps.update-readme.outputs.result == 'true'
110+
shell: pwsh
111+
run: |
112+
# Check if there are changes to commit
113+
$gitStatus = git status --porcelain
114+
if ([string]::IsNullOrWhiteSpace($gitStatus)) {
115+
Write-Output "No changes to commit. README is already up to date."
116+
exit 0
117+
}
118+
119+
# Configure git
120+
git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"
121+
git config --local user.name "github-actions[bot]"
122+
123+
# Add, commit and push changes
124+
git add ReadMe.md
125+
git commit -m "docs: update contributors in README [skip ci]"
126+
127+
# Push changes - retry up to 3 times in case of network issues
128+
$maxRetries = 3
129+
$retryCount = 0
130+
131+
while ($retryCount -lt $maxRetries) {
132+
try {
133+
git push
134+
Write-Output "Successfully pushed changes to the repository."
135+
exit 0
136+
}
137+
catch {
138+
$retryCount++
139+
Write-Output "Push failed. Retrying in 5 seconds... (Attempt $retryCount of $maxRetries)"
140+
Start-Sleep -Seconds 5
141+
}
142+
}
143+
144+
Write-Output "Failed to push changes after $maxRetries attempts."
145+
exit 1

0 commit comments

Comments
 (0)