ci: add update-contributors workflow (#3014)

This commit is contained in:
Meier Lukas
2025-05-12 18:01:27 +02:00
committed by GitHub
parent 593d97e27a
commit 6c71724e2e
3 changed files with 144 additions and 1 deletions

View File

@@ -6,7 +6,7 @@ on:
jobs:
approve-automatic-prs:
runs-on: ubuntu-latest
if: github.actor_id == 158783068 || github.actor_id == 190541745 # Id of renovate bot and crowdin bot see https://api.github.com/users/homarr-renovate%5Bbot%5D and https://api.github.com/users/homarr-crowdin%5Bbot%5D
if: github.actor_id == 158783068 || github.actor_id == 190541745 || github.actor_id == 210161987 # Id of renovate bot and crowdin bot see https://api.github.com/users/homarr-renovate%5Bbot%5D and https://api.github.com/users/homarr-crowdin%5Bbot%5D and https://api.github.com/users/homarr-update-contributors%5Bbot%5D
steps:
- name: Checkout code
uses: actions/checkout@v4

View File

@@ -0,0 +1,70 @@
name: Update Contributors
on:
schedule:
- cron: "0 12 * * FRI" # At 12:00 on Friday.
workflow_dispatch:
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
CROWDIN_TOKEN: "${{ secrets.CROWDIN_UPDATE_CONTRIBUTORS_TOKEN }}"
permissions:
contents: write
jobs:
update-contributors:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [22]
steps:
- name: Obtain token
id: obtainToken
uses: tibdex/github-app-token@v2
with:
private_key: ${{ secrets.HOMARR_UPDATE_CONTRIBUTORS_PRIVATE_KEY }}
app_id: ${{ vars.HOMARR_UPDATE_CONTRIBUTORS_APP_ID }}
- name: Checkout repository
uses: actions/checkout@v4
env:
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Run update script
run: node ./scripts/update-contributors.mjs
- name: Commit changes
env:
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
run: |
git config --global user.email "210161987+homarr-update-contributors[bot]@users.noreply.github.com"
git config --global user.name "Homarr Update Contributors"
git add .
git commit -m "chore: update contributors"
- name: Create Pull Request
id: create-pull-request
uses: peter-evans/create-pull-request@v7
with:
token: ${{ steps.obtainToken.outputs.token }}
branch: update-contributors
base: dev
title: "chore: update contributors"
delete-branch: true
body: |
This PR updates the contributors list in the static-data directory.
- name: Install GitHub CLI
run: sudo apt-get install -y gh
- name: Enable auto-merge
env:
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
run: |
gh pr merge ${{steps.create-pull-request.outputs.pull-request-number}} --auto --squash

View File

@@ -0,0 +1,73 @@
import fs from "fs/promises";
const sources = {
crowdin: [
{ projectId: 534422 },
{ projectId: 742587 },
],
github: [
{ slug: "ajnart", repository: "homarr" },
{ slug: "homarr-labs", repository: "homarr" },
],
};
const env = {
GITHUB_TOKEN: process.env.GITHUB_TOKEN,
CROWDIN_TOKEN: process.env.CROWDIN_TOKEN,
};
const fetchGithubContributors = async (slug, repository) => {
const url = `https://api.github.com/repos/${slug}/${repository}/contributors?per_page=999`;
const options = {
method: "GET",
headers: {
Authorization: `Bearer ${env.GITHUB_TOKEN}`,
Accept: "application/vnd.github+json",
"X-GitHub-Api-Version": "2022-11-28",
},
};
const response = await fetch(url, options);
const data = await response.json();
return data;
};
const fetchCrowdinMembers = async (projectId) => {
const url = `https://crowdin.com/api/v2/projects/${projectId}/members`;
const options = {
method: "GET",
headers: {
Accept: "application/json",
Authorization: `Bearer ${env.CROWDIN_TOKEN}`,
},
};
const response = await fetch(url, options);
const data = await response.json();
return data.data.flatMap((data) => data.data);
};
const distinctBy = (callback) => (value, index, self) => {
return self.findIndex((item) => callback(item) === callback(value)) === index;
};
const githubContributors = [];
const crowdinContributors = [];
for (const { repository, slug } of sources.github) {
githubContributors.push(...(await fetchGithubContributors(slug, repository)));
}
const distinctGithubContributors = githubContributors
.filter(distinctBy((contributor) => contributor.login))
.sort((a, b) => b.contributions - a.contributions)
.map(({ contributions, ...props }) => props)
.filter((contributor) => !contributor.login.includes("[bot]"));
await fs.writeFile("./static-data/contributors.json", JSON.stringify(distinctGithubContributors));
for (const { projectId } of sources.crowdin) {
crowdinContributors.push(...(await fetchCrowdinMembers(projectId)));
}
const distinctCrowdinContributors = crowdinContributors.filter(distinctBy((contributor) => contributor.username));
await fs.writeFile("./static-data/translators.json", JSON.stringify(distinctCrowdinContributors));