@@ -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.
712on :
813 schedule :
914 - cron : " 0 9 1 * *"
@@ -15,6 +20,7 @@ permissions:
1520jobs :
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
0 commit comments