feat(ci): ISOs are named by the day like CachyOS (steamify-cachyos-<ver>-<YYMMDD>), one per day and kind, at most 10 dev and 10 real releases kept
Sync git.upriser.nl mirror / sync (push) Skipped

This commit is contained in:
theupriser committed 2026-09-30 11:35:22 +02:00
1 parent 38ac8f1cba
commit 588627a14d
4 files changed
+53 -25

No files matched your search

+31 -4
View File
@@ -4,7 +4,9 @@
# GitHub releases take at most 2 GB per file, the ISO is bigger, and a release on the mirror only survives its # GitHub releases take at most 2 GB per file, the ISO is bigger, and a release on the mirror only survives its
# syncs when its tag comes from here. # syncs when its tag comes from here.
# Name: the Steamify version the ISO gets (its newest release) plus the time (UTC, GitHub's clock when the release starts): # Name: the Steamify version the ISO gets (its newest release) plus the time (UTC, GitHub's clock when the release starts):
# kind release: v<steamify>-<YYYY.MM.DD>-<HHMM>, a real release; kind dev: a pre-release v<steamify>-dev.<...>. # kind release: v<steamify>-<YYMMDD>, a real release; kind dev: a pre-release v<steamify>-dev-<YYMMDD> (like CachyOS: the
# day, no time). One ISO per day and kind: the newest build of a day replaces the earlier one. At most 10 dev and 10 real
# releases are kept (the oldest go, here and, with the mirror's next sync, there).
name: ISO 1/2 · Tag and release (GitHub) name: ISO 1/2 · Tag and release (GitHub)
# Always run from master. Started by steamify-cachyos (its bundle.yml, secret ISO_DISPATCH_TOKEN), which says what to # Always run from master. Started by steamify-cachyos (its bundle.yml, secret ISO_DISPATCH_TOKEN), which says what to
@@ -36,18 +38,19 @@ jobs:
- name: Tag and release - name: Tag and release
env: env:
GH_TOKEN: ${{ github.token }} GH_TOKEN: ${{ github.token }}
GIT_UPRISER_TOKEN: ${{ secrets.GIT_UPRISER_TOKEN }}
run: | run: |
steamify="$(gh release view -R theupriser/steamify-cachyos --json tagName -q .tagName)" steamify="$(gh release view -R theupriser/steamify-cachyos --json tagName -q .tagName)"
steamify="${steamify#v}" steamify="${steamify#v}"
stamp="$(date -u +%Y.%m.%d-%H%M)" stamp="$(date -u +%y%m%d)" day="$(date -u +%Y.%m.%d)"
kind="${{ inputs.kind }}" kind="${{ inputs.kind }}"
if [ -z "$kind" ] || [ "$kind" = auto ]; then if [ -z "$kind" ] || [ "$kind" = auto ]; then
if [ "${{ github.ref }}" = refs/heads/master ]; then kind=release; else kind=dev; fi if [ "${{ github.ref }}" = refs/heads/master ]; then kind=release; else kind=dev; fi
fi fi
if [ "$kind" = release ]; then if [ "$kind" = release ]; then
tag="v$steamify-$stamp" pre="" name="CachyOS with Steamify Live ISO $steamify ($stamp UTC)" tag="v$steamify-$stamp" pre="" name="CachyOS with Steamify Live ISO $steamify ($day UTC)"
else else
tag="v$steamify-dev.$stamp" pre="--prerelease" name="CachyOS with Steamify Live ISO $steamify (test build $stamp UTC)" tag="v$steamify-dev-$stamp" pre="--prerelease" name="CachyOS with Steamify Live ISO $steamify (test build $day UTC)"
fi fi
# The ISO's file on the mirror is named after the tag (iso-2-gitea-build.yml, profiledef.sh), so its # The ISO's file on the mirror is named after the tag (iso-2-gitea-build.yml, profiledef.sh), so its
# download link is known now. # download link is known now.
@@ -61,6 +64,21 @@ jobs:
Sources: [Steamify](https://github.com/theupriser/steamify-cachyos/tree/v$steamify), this repository at this tag, and the packages' sources at [CachyOS](https://github.com/CachyOS) and [Arch Linux](https://archlinux.org/packages/). Sources: [Steamify](https://github.com/theupriser/steamify-cachyos/tree/v$steamify), this repository at this tag, and the packages' sources at [CachyOS](https://github.com/CachyOS) and [Arch Linux](https://archlinux.org/packages/).
$section" $section"
# One ISO per day and kind: the newest build of a day replaces the earlier one (space), here and on the mirror.
mirror_sync() { [ -n "$GIT_UPRISER_TOKEN" ] && curl -fsS --retry 5 --retry-delay 10 --retry-all-errors -X POST -H "Authorization: token $GIT_UPRISER_TOKEN" "$GITEA_URL/api/v1/repos/$GITEA_REPO/mirror-sync" > /dev/null; }
if git ls-remote --exit-code --tags origin "refs/tags/$tag" > /dev/null 2>&1 || gh release view "$tag" > /dev/null 2>&1; then
echo "$tag exists: replacing it"
gh release delete "$tag" --cleanup-tag -y 2> /dev/null || true
git push origin ":refs/tags/$tag" 2> /dev/null || true
# The mirror has to see the tag go (it drops the tag and its release with the ISO); otherwise the new tag is only an
# update there and starts no build.
if mirror_sync; then
for _ in $(seq 36); do
[ "$(curl -s -o /dev/null -w '%{http_code}' "$GITEA_URL/api/v1/repos/$GITEA_REPO/tags/$tag")" = 404 ] && break
sleep 5
done
fi
fi
# An annotated tag: its own date, so the mirror sorts releases on the same commit in order (a # An annotated tag: its own date, so the mirror sorts releases on the same commit in order (a
# lightweight tag only has its commit's date). # lightweight tag only has its commit's date).
git config user.name "github-actions[bot]" git config user.name "github-actions[bot]"
@@ -69,6 +87,15 @@ jobs:
gh release create "$tag" --verify-tag $pre --title "$name" --notes "$notes" gh release create "$tag" --verify-tag $pre --title "$name" --notes "$notes"
echo "Released $tag" echo "Released $tag"
# Retention (space): at most 10 dev and 10 real releases; the oldest go, release and tag. The mirror drops the
# tag with its release and ISO at its next sync (the step below).
keep=10
for pre_flag in true false; do
gh release list -L 200 --json tagName,isPrerelease,createdAt \
-q "[.[] | select(.isPrerelease == $pre_flag)] | sort_by(.createdAt) | reverse | .[$keep:][] | .tagName" |
while read -r old; do echo "Retention: removing $old"; gh release delete "$old" --cleanup-tag -y; done
done
# Optional: sync the mirror at once instead of at its interval (a Gitea token with repository write # Optional: sync the mirror at once instead of at its interval (a Gitea token with repository write
# access as the secret GIT_UPRISER_TOKEN). # access as the secret GIT_UPRISER_TOKEN).
- name: Sync the Gitea mirror - name: Sync the Gitea mirror
+13 -14
View File
@@ -60,13 +60,13 @@ jobs:
id: tag id: tag
run: | run: |
tag="${{ github.ref_name }}" tag="${{ github.ref_name }}"
[[ "$tag" =~ ^v([0-9]+\.[0-9]+\.[0-9]+)-(dev\.)?([0-9]{4})\.([0-9]{2})\.([0-9]{2})-([0-9]{4})$ ]] || [[ "$tag" =~ ^v([0-9]+\.[0-9]+\.[0-9]+)-(dev-)?([0-9]{6})$ ]] ||
{ echo "::error::$tag is not a Steamify ISO release tag (v<steamify>-[dev.]<YYYY.MM.DD>-<HHMM>)"; exit 1; } { echo "::error::$tag is not a Steamify ISO release tag (v<steamify>-[dev-]<YYMMDD>)"; exit 1; }
m=("${BASH_REMATCH[@]}") m=("${BASH_REMATCH[@]}")
{ {
echo "STEAMIFY_VERSION=${m[1]}" echo "STEAMIFY_VERSION=${m[1]}"
# One moment for the ISO's label (profiledef.sh) and the release's name: the tag's (UTC). # The day (YYMMDD, UTC) for the ISO's label (profiledef.sh) and the release's name: the tag's.
echo "STEAMIFY_BUILD_STAMP=${m[3]}${m[4]}${m[5]}_${m[6]}" echo "STEAMIFY_BUILD_STAMP=${m[3]}"
echo "ISO_PRERELEASE=$([ -n "${m[2]}" ] && echo true || echo false)" echo "ISO_PRERELEASE=$([ -n "${m[2]}" ] && echo true || echo false)"
# The ISO's file name: the tag without its v (profiledef.sh). # The ISO's file name: the tag without its v (profiledef.sh).
echo "STEAMIFY_ISO_VERSION=${tag#v}" echo "STEAMIFY_ISO_VERSION=${tag#v}"
@@ -119,13 +119,13 @@ jobs:
- name: Version and time from the tag - name: Version and time from the tag
run: | run: |
tag="${{ github.ref_name }}" tag="${{ github.ref_name }}"
[[ "$tag" =~ ^v([0-9]+\.[0-9]+\.[0-9]+)-(dev\.)?([0-9]{4})\.([0-9]{2})\.([0-9]{2})-([0-9]{4})$ ]] || [[ "$tag" =~ ^v([0-9]+\.[0-9]+\.[0-9]+)-(dev-)?([0-9]{6})$ ]] ||
{ echo "::error::$tag is not a Steamify ISO release tag (v<steamify>-[dev.]<YYYY.MM.DD>-<HHMM>)"; exit 1; } { echo "::error::$tag is not a Steamify ISO release tag (v<steamify>-[dev-]<YYMMDD>)"; exit 1; }
m=("${BASH_REMATCH[@]}") m=("${BASH_REMATCH[@]}")
{ {
echo "STEAMIFY_VERSION=${m[1]}" echo "STEAMIFY_VERSION=${m[1]}"
# One moment for the ISO's label (profiledef.sh) and the release's name: the tag's (UTC). # The day (YYMMDD, UTC) for the ISO's label (profiledef.sh) and the release's name: the tag's.
echo "STEAMIFY_BUILD_STAMP=${m[3]}${m[4]}${m[5]}_${m[6]}" echo "STEAMIFY_BUILD_STAMP=${m[3]}"
echo "ISO_PRERELEASE=$([ -n "${m[2]}" ] && echo true || echo false)" echo "ISO_PRERELEASE=$([ -n "${m[2]}" ] && echo true || echo false)"
# The ISO's file name: the tag without its v (profiledef.sh). # The ISO's file name: the tag without its v (profiledef.sh).
echo "STEAMIFY_ISO_VERSION=${tag#v}" echo "STEAMIFY_ISO_VERSION=${tag#v}"
@@ -145,18 +145,17 @@ jobs:
iso="$(ls out/desktop/*.iso | head -n 1)" iso="$(ls out/desktop/*.iso | head -n 1)"
[ -f "$iso" ] || { echo "::error::no ISO in out/desktop"; exit 1; } [ -f "$iso" ] || { echo "::error::no ISO in out/desktop"; exit 1; }
tag="${{ github.ref_name }}" b="$STEAMIFY_BUILD_STAMP" tag="${{ github.ref_name }}" b="$STEAMIFY_BUILD_STAMP"
stamp="${b:0:4}.${b:4:2}.${b:6:2}-${b:9:4}" stamp="20${b:0:2}.${b:2:2}.${b:4:2}"
if [ "$ISO_PRERELEASE" = true ]; then if [ "$ISO_PRERELEASE" = true ]; then
name="CachyOS with Steamify Live ISO $STEAMIFY_VERSION (test build $stamp UTC)" name="CachyOS with Steamify Live ISO $STEAMIFY_VERSION (test build $stamp UTC)"
else else
name="CachyOS with Steamify Live ISO $STEAMIFY_VERSION ($stamp UTC)" name="CachyOS with Steamify Live ISO $STEAMIFY_VERSION ($stamp UTC)"
fi fi
# Never overwritten: a release for this tag that already has the ISO is left alone. # One ISO per day and kind: a release of this tag from an earlier build of the day is replaced.
api="${{ github.server_url }}/api/v1/repos/${{ github.repository }}" api="${{ github.server_url }}/api/v1/repos/${{ github.repository }}"
if curl -fsS -H "Authorization: token $TOKEN" "$api/releases/tags/$tag" -o /tmp/rel.json && if curl -fsS -H "Authorization: token $TOKEN" "$api/releases/tags/$tag" -o /tmp/rel.json; then
[ "$(jq '[.assets[] | select(.name | endswith(".iso"))] | length' /tmp/rel.json)" -gt 0 ]; then echo "Replacing the earlier release of $tag"
echo "::warning::$tag already has its ISO and won't be overwritten." curl -fsS -X DELETE -H "Authorization: token $TOKEN" "$api/releases/$(jq -r .id /tmp/rel.json)" || true
echo "publish=false" >> "$GITHUB_OUTPUT"; exit 0
fi fi
{ echo "publish=true"; echo "name=$name"; } >> "$GITHUB_OUTPUT" { echo "publish=true"; echo "name=$name"; } >> "$GITHUB_OUTPUT"
section="$(awk '/^## CachyOS with Steamify Live ISO/ {found = 1; next} found && /^#/ {exit} found' CHANGELOG.md)" section="$(awk '/^## CachyOS with Steamify Live ISO/ {found = 1; next} found && /^#/ {exit} found' CHANGELOG.md)"
+6 -4
View File
@@ -115,14 +115,16 @@ failure, and retry the copy (it's idempotent) rather than the whole build.
Full write-up, with every trap: `steamify-iso-release` in steamify-cachyos-dev. What matters here: Full write-up, with every trap: `steamify-iso-release` in steamify-cachyos-dev. What matters here:
- `.github/workflows/iso-1-github-tag.yml` (GitHub, `workflow_dispatch` only: by hand, or started by a new Steamify - `.github/workflows/iso-1-github-tag.yml` (GitHub, `workflow_dispatch` only: by hand, or started by a new Steamify
release, whose `bundle.yml` needs the secret `ISO_DISPATCH_TOKEN`) names the release: the Steamify version plus release, whose `bundle.yml` needs the secret `ISO_DISPATCH_TOKEN`) names the release like CachyOS does, by the day (GitHub's UTC
GitHub's UTC time, `vX.Y.Z-[dev.]YYYY.MM.DD-HHMM`, an **annotated** tag and a release with notes and the direct date, no time): `vX.Y.Z-YYMMDD` (real) or `vX.Y.Z-dev-YYMMDD` (dev), file `steamify-cachyos-X.Y.Z-[dev-]YYMMDD-x86_64.iso`, an **annotated** tag and a
download link. The workflow always runs from `master`; its input `kind` (`release`, `dev`, or `auto`: release on master, dev on other branches) decides: `release` is a real release, `dev` a `dev.` pre-release. steamify-cachyos' bundle.yml passes it: a version published from main -> `release`, a version on a release branch -> `dev`. release with notes and the direct download link. One ISO per day and kind: a second build the same day deletes
the earlier release and tag (GitHub), waits until the mirror has dropped them, then tags again. Retention: at most 10 dev and 10 real
releases are kept (space); the oldest are deleted with `gh release delete --cleanup-tag`, and the mirror drops their tags, releases and ISOs at its next sync. The workflow always runs from `master`; its input `kind` (`release`, `dev`, or `auto`: release on master, dev on other branches) decides: `release` is a real release, `dev` a `dev-` pre-release. steamify-cachyos' bundle.yml passes it: a version published from main -> `release`, a version on a release branch -> `dev`.
- `.github/workflows/iso-2-gitea-build.yml` (Gitea, `on: push: tags: v*`, skipped on GitHub) runs two jobs for that - `.github/workflows/iso-2-gitea-build.yml` (Gitea, `on: push: tags: v*`, skipped on GitHub) runs two jobs for that
tag: build the ISO, then attach it to the mirror's release. It is not tested there (the runner is small): the VM tests tag: build the ISO, then attach it to the mirror's release. It is not tested there (the runner is small): the VM tests
run on GitHub, in steamify-cachyos `vmtest.yml`, on the newest ISO release of the mirror. The tag decides everything: Steamify version (`steamify-prepare.sh` run on GitHub, in steamify-cachyos `vmtest.yml`, on the newest ISO release of the mirror. The tag decides everything: Steamify version (`steamify-prepare.sh`
takes `STEAMIFY_VERSION`), file name (`STEAMIFY_ISO_VERSION` -> `iso_version` in `profiledef.sh`), label takes `STEAMIFY_VERSION`), file name (`STEAMIFY_ISO_VERSION` -> `iso_version` in `profiledef.sh`), label
(`STEAMIFY_BUILD_STAMP`), boot menu and `/etc/steammachine-iso-build`. The build reads no clock; without a (`STEAMIFY_BUILD_STAMP`, YYMMDD), boot menu and `/etc/steammachine-iso-build`. The build reads no clock; without a
tag everything says `local`. tag everything says `local`.
- `util-iso.sh` runs `sudo mkarchiso`: sudo drops the environment, so `--preserve-env=STEAMIFY_ISO_VERSION, - `util-iso.sh` runs `sudo mkarchiso`: sudo drops the environment, so `--preserve-env=STEAMIFY_ISO_VERSION,
STEAMIFY_BUILD_STAMP` is required (without it the ISO comes out `-local-`). STEAMIFY_BUILD_STAMP` is required (without it the ISO comes out `-local-`).
+3 -3
View File
@@ -3,8 +3,8 @@
iso_name="steamify-cachyos" iso_name="steamify-cachyos"
# The label follows the release tag, which GitHub names (iso-1-github-tag.yml): the Steamify version on the ISO # The label follows the release tag, which GitHub names (iso-1-github-tag.yml): the Steamify version on the ISO
# (steamify-prepare.sh put it there) plus the tag's date and time, e.g. STEAMIFY_2_9_3_20260929_2030 (ISO 9660: # (steamify-prepare.sh put it there) plus the tag's day, e.g. STEAMIFY_2_9_3_260929 (ISO 9660:
# at most 32 characters, A-Z 0-9 _). STEAMIFY_BUILD_STAMP (YYYYMMDD_HHMM, UTC) comes from the tag; the build # at most 32 characters, A-Z 0-9 _). STEAMIFY_BUILD_STAMP (YYMMDD, UTC) comes from the tag; the build
# reads no clock of its own. Built by hand, without a tag: LOCAL. # reads no clock of its own. Built by hand, without a tag: LOCAL.
_steamify="$(sed -n 's/^VERSION=//p' "${BASH_SOURCE[0]%/*}/airootfs/usr/local/share/steamify/steamify.sh" 2>/dev/null | head -n 1)" _steamify="$(sed -n 's/^VERSION=//p' "${BASH_SOURCE[0]%/*}/airootfs/usr/local/share/steamify/steamify.sh" 2>/dev/null | head -n 1)"
_stamp="${STEAMIFY_BUILD_STAMP:-LOCAL}" _stamp="${STEAMIFY_BUILD_STAMP:-LOCAL}"
@@ -13,7 +13,7 @@ iso_label="${iso_label:0:32}"
iso_publisher="CachyOS <https://cachyos.org>" iso_publisher="CachyOS <https://cachyos.org>"
iso_application="Steamify CachyOS Live (based on CachyOS)" iso_application="Steamify CachyOS Live (based on CachyOS)"
# The file name (<iso_name>-<iso_version>-x86_64.iso) is the release tag without its v (STEAMIFY_ISO_VERSION # The file name (<iso_name>-<iso_version>-x86_64.iso) is the release tag without its v (STEAMIFY_ISO_VERSION
# from the tag: steamify-cachyos-2.9.3-dev.2026.09.29-2030-x86_64.iso). Built by hand, without a tag: local. # from the tag: steamify-cachyos-2.9.6-dev-260930-x86_64.iso). Built by hand, without a tag: local.
iso_version="${STEAMIFY_ISO_VERSION:-local}" iso_version="${STEAMIFY_ISO_VERSION:-local}"
install_dir="arch" install_dir="arch"
buildmodes=('iso') buildmodes=('iso')