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/mirror-sync.yml
blob: a95bad43edbdf0e66ae4af120d3e8004e0823a7d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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"