Read-only mirror — the public repositories of the Forgejo instance, refreshed every 10 minutes. The live instance (fg.dieschoenewolke.de) is reachable only over the VPN; clone here with https://git.dieschoenewolke.de/git/<owner>/<repo>.git.
summaryrefslogtreecommitdiff
path: root/.forgejo/workflows
diff options
context:
space:
mode:
Diffstat (limited to '.forgejo/workflows')
-rw-r--r--.forgejo/workflows/mirror-sync.yml69
1 files changed, 69 insertions, 0 deletions
diff --git a/.forgejo/workflows/mirror-sync.yml b/.forgejo/workflows/mirror-sync.yml
new file mode 100644
index 0000000..a95bad4
--- /dev/null
+++ b/.forgejo/workflows/mirror-sync.yml
@@ -0,0 +1,69 @@
+name: Mirror distroless images
+
+# Keeps https://img.dieschoenewolke.de in step with gcr.io/distroless.
+#
+# The copying is done by zot's sync extension on the VPS, not by this job: the
+# registry diffs digests itself, pulls only what changed, and can do so while
+# the home Forgejo instance (and this runner) is down. This workflow is the
+# auditor — it compares upstream and mirror digests, pull-verifies anything new,
+# and only then writes a `synced-<repo>-<tag>-<digest12>` marker tag.
+#
+# That is the same "marker last" discipline as the Pureblog release pipeline:
+# a marker exists only for a ref that was proven pullable by digest. A run that
+# dies before the push leaves no marker, so the next run retries.
+#
+# gcr.io load: one anonymous token request per repo plus one manifest request
+# per ref = 8 requests per run, every 6 hours. No per-request storm, no docker
+# login, nothing that could hit an anonymous rate limit.
+
+on:
+ schedule:
+ - cron: "17 */6 * * *"
+ workflow_dispatch:
+ inputs:
+ verify_all:
+ description: "Pull-verify every ref, not just new digests (1/0)"
+ required: false
+ default: "0"
+ type: string
+
+concurrency:
+ group: distroless-mirror-sync
+ # Never cancel a run half way: a cancelled run could leave a tag pushed
+ # without the verification it claims. Runs are minutes apart anyway.
+ cancel-in-progress: false
+
+jobs:
+ verify:
+ runs-on: docker-cli
+ timeout-minutes: 30
+ container:
+ image: docker:29-cli
+ steps:
+ - name: Install workflow tools
+ run: apk add --no-cache bash curl git jq
+
+ - name: Check out the marker tags
+ uses: https://github.com/actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Compare upstream and mirror, verify, mark
+ env:
+ # docker:cli keeps the CLI in /usr/local/bin; the runner's DOCKER_HOST
+ # points at the daemon, so the pull goes over the public hostname and
+ # the real TLS/edge path.
+ VERIFY_PULL: ${{ inputs.verify_all == '1' && 'always' || 'new' }}
+ MARKERS_FILE: ${{ runner.temp }}/mirror-markers
+ run: ./scripts/verify-mirror.sh
+
+ - name: Publish marker tags
+ run: |
+ set -eu
+ file="${MARKERS_FILE:-$RUNNER_TEMP/mirror-markers}"
+ [ -s "$file" ] || { echo "no new markers"; exit 0; }
+ while read -r marker; do
+ [ -n "$marker" ] || continue
+ git push origin "refs/tags/$marker"
+ echo "marked $marker"
+ done <"$file"