Skip to content

Commit 131597c

Browse files
lsimonslsimons-bot
andcommitted
Auto-refresh the repository list weekly
Mirror the capability just added to schubergphilis.github.io: a scheduled workflow that reruns `mise run docs-repos` every Monday, commits repos.json if it changed, and dispatches the Pages deploy. A push made with GITHUB_TOKEN does not trigger other workflows, so deploy.yml has to be asked for explicitly. Also narrow the generated list to repos that carry an open source license, to keep the two refresh scripts aligned. All eight listed Lab271 repos are Apache-2.0, so this changes nothing today; it only guards future additions. Unlike the sibling script there is still no "recent activity" cutoff, since the org is small enough to list in full. Assisted-by: Claude:claude-opus-5 Co-Authored-By: lsimons-bot <bot@leosimons.com>
1 parent 65bb19f commit 131597c

3 files changed

Lines changed: 85 additions & 3 deletions

File tree

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
name: Refresh repository list
2+
3+
on:
4+
schedule:
5+
# Mondays at 05:17 UTC — off the hour to avoid the top-of-hour scheduling queue
6+
- cron: '17 5 * * 1'
7+
workflow_dispatch:
8+
9+
permissions:
10+
contents: read
11+
12+
# never let two refreshes race to push the same file
13+
concurrency:
14+
group: refresh-repos
15+
cancel-in-progress: false
16+
17+
jobs:
18+
refresh:
19+
runs-on: ubuntu-latest
20+
permissions:
21+
contents: write
22+
# needed to dispatch the Pages deploy below
23+
actions: write
24+
steps:
25+
- name: Checkout code
26+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
27+
with:
28+
persist-credentials: false
29+
30+
- name: Set up mise
31+
uses: jdx/mise-action@9e7f7633ff6f6d6048a9418a68d48f288f50eb14 # v4.2.3
32+
with:
33+
install: true
34+
cache: true
35+
36+
- name: Regenerate docs/src/data/repos.json
37+
env:
38+
# only used to read public repository metadata from the org
39+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
40+
run: mise run docs-repos
41+
42+
- name: Commit and push any changes
43+
id: commit
44+
env:
45+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
46+
run: |
47+
if git diff --quiet -- docs/src/data/repos.json; then
48+
echo "No changes to the repository list."
49+
echo "changed=false" >> "$GITHUB_OUTPUT"
50+
exit 0
51+
fi
52+
git config user.name 'github-actions[bot]'
53+
git config user.email '41898282+github-actions[bot]@users.noreply.github.com'
54+
git add docs/src/data/repos.json
55+
git commit -m 'Refresh the list of public repositories'
56+
git push "https://x-access-token:${GH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" \
57+
"HEAD:${GITHUB_REF_NAME}"
58+
echo "changed=true" >> "$GITHUB_OUTPUT"
59+
60+
# A push made with GITHUB_TOKEN does not trigger other workflows, so ask
61+
# for the Pages deploy explicitly. workflow_dispatch is one of the two
62+
# events that GITHUB_TOKEN is allowed to fire.
63+
- name: Trigger the Pages deploy
64+
if: steps.commit.outputs.changed == 'true'
65+
env:
66+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
67+
run: gh workflow run deploy.yml --ref "${GITHUB_REF_NAME}"

AGENTS.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,19 @@ When starting the dev server directly (not via mise), use background mode:
4545
(`mise run docs-icons`).
4646
- `src/assets/hero.jpg`: the hero photo.
4747
- `src/data/repos.json`: committed, auto-generated list of public `Lab271`
48-
repos. Regenerate with `mise run docs-repos` rather than editing by hand.
48+
repos that carry an open source license. Regenerate with `mise run
49+
docs-repos` rather than editing by hand.
50+
- `scripts/refresh-repos.mjs`: what `mise run docs-repos` runs. Plain node, no
51+
dependencies, so it works without `bun install`.
4952
- `.github/workflows/ci.yml`: build and type-check on push/PR, plus a `zizmor`
5053
job auditing the workflows themselves.
5154
- `.github/workflows/deploy.yml`: builds and publishes `docs/dist` to GitHub
5255
Pages on every push to `main`. The repository's Pages source must be set to
5356
"GitHub Actions" (Settings, then Pages) for this to work.
57+
- `.github/workflows/refresh-repos.yml`: weekly (Monday) rerun of `mise run
58+
docs-repos`, committing `repos.json` to `main` if it changed. A push made with
59+
`GITHUB_TOKEN` does not trigger other workflows, so it dispatches `deploy.yml`
60+
afterwards instead of relying on the push event.
5461
- `.github/dependabot.yml`: weekly updates for the `docs/` bun lockfile and the
5562
GitHub Actions used in workflows.
5663

docs/scripts/refresh-repos.mjs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
// The org is small enough to list in full, so - unlike the schubergphilis
77
// equivalent - there is no "recent activity" cutoff here. Forks and archived
88
// repos are excluded by `gh`; this repo and the org profile repo are excluded
9-
// below because neither is a project.
9+
// below because neither is a project, and so are repos without an open source
10+
// license.
1011
import { execFileSync } from 'node:child_process';
1112
import { writeFileSync } from 'node:fs';
1213
import { fileURLToPath } from 'node:url';
@@ -32,13 +33,20 @@ const raw = execFileSync(
3233
'--limit',
3334
'1000',
3435
'--json',
35-
'name,description,url,homepageUrl,primaryLanguage,pushedAt',
36+
'name,description,url,homepageUrl,primaryLanguage,pushedAt,licenseInfo',
3637
],
3738
{ encoding: 'utf8' },
3839
);
3940

41+
// GitHub reports a detected license as a `licenseInfo.key`; repos without a
42+
// LICENSE file have no `licenseInfo` at all, and repos whose license file it
43+
// cannot match to a known license get the `other` pseudo-license (SPDX
44+
// `NOASSERTION`). Neither counts as open source for our purposes.
45+
const hasOpenSourceLicense = (repo) => repo.licenseInfo !== null && repo.licenseInfo.key !== 'other';
46+
4047
const repos = JSON.parse(raw)
4148
.filter((repo) => !EXCLUDE.has(repo.name.toLowerCase()))
49+
.filter(hasOpenSourceLicense)
4250
.sort((a, b) => new Date(b.pushedAt) - new Date(a.pushedAt))
4351
.map(({ name, description, url, homepageUrl, primaryLanguage, pushedAt }) => ({
4452
name,

0 commit comments

Comments
 (0)