Skip to content

Commit 0511ac4

Browse files
TMHSDigitalclaude
andcommitted
Release workflow: one tag for build, data.json and CITATION.cff
The tag is picked first and exported as CATALOG_VERSION, the build output is asserted to carry it, CITATION.cff gets version and date-released committed to main before the release is cut, and an empty ledger section fails the run instead of producing two-line notes. Adds npm run reverify and a job timeout. Part of #137 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1 parent 66be788 commit 0511ac4

3 files changed

Lines changed: 68 additions & 8 deletions

File tree

‎.github/workflows/release.yml‎

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ name: Dataset release
44
# attach data.json, catalog.csv, the two feeds and llms.txt. Monthly, and on
55
# demand from the Actions tab. The release notes are the newest section of
66
# docs/review-ledger.md. A tag that already exists is left alone.
7+
#
8+
# The tag is chosen once, exported as CATALOG_VERSION so the build writes the
9+
# same string into data.json (site/build.mjs), asserted after the build, and
10+
# written into CITATION.cff on main before the release is cut, so the tagged
11+
# commit already cites itself.
712
on:
813
schedule:
914
- cron: "0 9 1 * *"
@@ -15,6 +20,7 @@ permissions:
1520
jobs:
1621
release:
1722
runs-on: ubuntu-latest
23+
timeout-minutes: 15
1824
steps:
1925
- name: Checkout
2026
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
@@ -27,26 +33,76 @@ jobs:
2733
with:
2834
node-version-file: .nvmrc
2935

30-
- name: Check and build
31-
run: npm test && node site/validate.mjs && node site/build.mjs
32-
33-
- name: Create the release
36+
- name: Pick the tag
37+
id: tag
3438
env:
3539
GH_TOKEN: ${{ github.token }}
3640
run: |
3741
tag="v$(date -u +%Y.%m.%d)"
3842
if gh release view "$tag" >/dev/null 2>&1; then
3943
echo "release $tag already exists; nothing to do"
40-
exit 0
44+
echo "skip=true" >> "$GITHUB_OUTPUT"
45+
fi
46+
echo "CATALOG_VERSION=$tag" >> "$GITHUB_ENV"
47+
echo "RELEASE_DATE=$(date -u +%F)" >> "$GITHUB_ENV"
48+
49+
- name: Check and build
50+
if: steps.tag.outputs.skip != 'true'
51+
run: npm test && node site/validate.mjs && node site/build.mjs
52+
53+
- name: Assert the dataset carries the tag
54+
if: steps.tag.outputs.skip != 'true'
55+
run: |
56+
got="$(jq -r .version site/dist/data.json)"
57+
if [ "$got" != "$CATALOG_VERSION" ]; then
58+
echo "data.json version is '$got' but the release tag is '$CATALOG_VERSION'"
59+
exit 1
4160
fi
61+
62+
- name: Write the version into CITATION.cff
63+
if: steps.tag.outputs.skip != 'true'
64+
run: |
65+
node - <<'JS'
66+
const fs = require("node:fs");
67+
const file = "CITATION.cff";
68+
let text = fs.readFileSync(file, "utf8");
69+
const version = `version: "${process.env.CATALOG_VERSION}"`;
70+
const released = `date-released: "${process.env.RELEASE_DATE}"`;
71+
text = /^version: .*$/m.test(text)
72+
? text.replace(/^version: .*$/m, version)
73+
: text.replace(/^date-released: .*$/m, (line) => `${version}\n${line}`);
74+
text = text.replace(/^date-released: .*$/m, released);
75+
fs.writeFileSync(file, text);
76+
JS
77+
if git diff --quiet -- CITATION.cff; then
78+
echo "CITATION.cff already current"
79+
else
80+
git config user.name "github-actions[bot]"
81+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
82+
git add CITATION.cff
83+
git commit -m "Release $CATALOG_VERSION: record the version in CITATION.cff"
84+
git push origin HEAD:main
85+
fi
86+
87+
- name: Create the release
88+
if: steps.tag.outputs.skip != 'true'
89+
env:
90+
GH_TOKEN: ${{ github.token }}
91+
run: |
4292
# Newest ledger section: from the first "## " heading to the next.
4393
awk '/^## /{n++} n==1' docs/review-ledger.md > release-notes.md
94+
if [ ! -s release-notes.md ]; then
95+
echo "docs/review-ledger.md has no '## ' section to use as release notes"
96+
exit 1
97+
fi
4498
{
4599
echo
46100
echo "Attached: \`data.json\` (full catalog), \`catalog.csv\`, \`feed.xml\` (new sources), \`reverified.xml\` (recent licence re-reads), \`llms.txt\`."
101+
echo "\`data.json\` carries \`\"version\": \"$CATALOG_VERSION\"\`; CITATION.cff on this tag cites the same version."
47102
echo "Field reference: https://github.com/${GITHUB_REPOSITORY}/blob/main/site/README.md"
48103
} >> release-notes.md
49-
gh release create "$tag" \
50-
--title "Catalog $tag" \
104+
gh release create "$CATALOG_VERSION" \
105+
--target "$(git rev-parse HEAD)" \
106+
--title "Catalog $CATALOG_VERSION" \
51107
--notes-file release-notes.md \
52108
site/dist/data.json site/dist/catalog.csv site/dist/feed.xml site/dist/reverified.xml site/dist/llms.txt

‎package.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"new-entry": "node site/new-entry.mjs",
1616
"links": "node site/check-links.mjs",
1717
"thumbs": "node site/thumbs.mjs",
18+
"reverify": "node site/reverify-batch.mjs",
1819
"serve": "npx --yes serve site/dist"
1920
}
2021
}

‎site/README.md‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ first of each month and on demand: it builds, tags `vYYYY.MM.DD` and creates a G
154154
release with `data.json`, `catalog.csv`, `feed.xml`, `reverified.xml` and `llms.txt`
155155
attached, with the newest section of `docs/review-ledger.md` as the notes. Fetch a fixed
156156
version by tag from the Releases page; `data.json` carries the same tag as `version`.
157+
The workflow passes the tag into the build as `CATALOG_VERSION`, fails if the built
158+
`data.json` disagrees, and commits the tag into `CITATION.cff` (`version`, `date-released`)
159+
on `main` before cutting the release, so the tagged commit cites itself.
157160

158161
## Re-verify batch
159162

@@ -164,7 +167,7 @@ months, and opens or updates one issue labelled `help wanted` and `good first is
164167
titled "Re-verify batch YYYY-MM: N entries due a licence re-read", with a checklist that
165168
names each entry's file, source URL and recorded licence. The selection rule is in
166169
`site/lib/reverify.mjs` and tested. When nothing is due the month is skipped. Preview it
167-
with `node site/reverify-batch.mjs`.
170+
with `node site/reverify-batch.mjs` (`npm run reverify`).
168171

169172
## Social preview
170173

0 commit comments

Comments
 (0)