~bigbes/sr-ht-compare

ref: 4f3961888c6889fc2ea19c9bcbb68359015d3475 sr-ht-compare/.build.yml -rw-r--r-- 9.5 KiB
4f396188 — bigbes rename the service to diff.sr.ht 9 days ago
                                                                                
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# builds.sr.ht manifest for diff.sr.ht. One linear pipeline: install the
# cache helper, assemble the shared SCSS, restore caches, package with abuild,
# publish the apk, save the caches.
#
# The reasoning behind every task lives in docs/ci.md, not here: builds.sr.ht
# stores the submitted manifest in a varchar(16384), so a manifest over 16 KiB
# cannot be submitted at all — and the failure is a branch with no CI, not a red
# build. Add paragraphs to docs/ci.md and a pointer here.
image: alpine/edge
packages:
  - abuild
  - curl
  - go
  - git
  - rclone
  # For `make css`, not for the package — see docs/ci.md#packages.
  - sassc
  - minify
secrets:
  # File secret `apk-ci-s3`, installed at ~/.apk-ci.env, containing
  # APK_CI_S3_ACCESS_KEY / APK_CI_S3_SECRET_KEY for the Garage `repo` bucket.
  - apk-ci-s3
  # S3 credentials for the cacher CI cache (Garage `docker-cache` bucket),
  # same pair the bencher and ci-cacher builds use.
  - 7dde4219-0783-4581-a67d-c94749de3600   # ~/.s3-cache-key-id
  - 0e5b3530-6f19-4f30-9b73-9339dd382e46   # ~/.s3-cache-key-secret
sources:
  - https://git.srht.bigb.es/~bigbes/sr-ht-compare
environment:
  REPO: sr-ht-compare
  APK_REPO: alpine/v3.22/bigbes/x86_64
  S3_BUCKET: repo
  S3_ENDPOINT: https://s3.bigb.es
  # CORE_VER must track the deployment's SRHT_CORE_VER; BOOTSTRAP_REV is the
  # submodule commit core.sr.ht pins at that tag. See docs/ci.md#environment.
  CORE_VER: "0.84.5"
  BOOTSTRAP_REV: 779ad9f174ea5ab7e755f6df0ec9e5912d67dd16
submitter:
  git.sr.ht:
    allow-refs:
      - refs/heads/master
      - "refs/tags/v*"
tasks:
  # S3-backed CI cache helper (go.bigb.es/cacher), installed from its own
  # published release. Two tasks and not one: install.sh appends its PATH export
  # to ~/.buildenv, which only the NEXT task sources. The installer verifies
  # what it downloads against checksums.txt. See docs/ci.md#cacher.
  - cacher_install: |
      curl -fsSL https://bigbes.pages.srht.bigb.es/ci-cacher/install.sh | sh
  - cacher_init: |
      cacher init \
        --endpoint    https://s3.bigb.es \
        --region      garage \
        --bucket      docker-cache \
        --prefix      sr-ht-compare/deps \
        --key-file    ~/.s3-cache-key-id \
        --secret-file ~/.s3-cache-key-secret
  - scss: |
      # Assemble the shared sourcehut partials no apk ships, the way
      # core.sr.ht's `make install-scss` would, cached by the two pins so an
      # outage at git.sr.ht or github.com can't fail us. --exec runs on a miss
      # and seeds the cache after; it sees exported vars only, hence the inline
      # key and the single quotes. See docs/ci.md#scss.
      cacher dir download "scss/${CORE_VER}-${BOOTSTRAP_REV}.tar.zst" ~/scss --exec '
        git clone --depth 1 --branch "$CORE_VER" \
          https://git.sr.ht/~sircmpwn/core.sr.ht /tmp/core
        mkdir -p ~/scss/bootstrap
        cp /tmp/core/scss/*.scss /tmp/core/scss/*.css ~/scss/
        git init -q /tmp/bootstrap
        git -C /tmp/bootstrap remote add origin https://github.com/twbs/bootstrap
        git -C /tmp/bootstrap fetch -q --depth 1 origin "$BOOTSTRAP_REV"
        git -C /tmp/bootstrap checkout -q FETCH_HEAD
        cp -r /tmp/bootstrap/scss ~/scss/bootstrap/scss
      '
      sudo mkdir -p /usr/share/sourcehut
      sudo cp -r ~/scss /usr/share/sourcehut/scss
  - keygen: |
      # Throwaway signing key, and -i is not optional: docs/ci.md#keygen.
      SUDO=sudo abuild-keygen -a -n -i -q
  - version: |
      # ONE `git describe` decides the pkgver: a tag, else <tag>_git<n>, else the
      # family's 0.0.<commit count>. EXPORTED rather than sed-ed into the tracked
      # APKBUILD (which reads $PKGVER), because rewriting a tracked file flips
      # the VCS stamp Go records into every binary built afterwards to dirty —
      # do not "tidy" it back into a sed. The tree is printed because this is the
      # last moment it is provably clean. See docs/ci.md#version.
      cd "$REPO"
      desc=$(git describe --tags --always --dirty)
      base=${desc%-dirty}
      case "$base" in
        v*-g*) n=${base%-g*}; ver="${n%-*}"; ver="${ver#v}_git${n##*-}" ;;
        v*)    ver="${base#v}" ;;
        *)     ver="0.0.$(git rev-list --count HEAD)" ;;
      esac
      echo "export PKGVER=$ver" >> ~/.buildenv
      echo "building $ver from $desc"
      git status --porcelain
  - cache_restore: |
      # Go module and build caches keyed by go.sum; --optional makes a genuine
      # miss a cold build rather than an error, which `|| true` could not tell
      # apart from bad credentials. abuild re-pins both, so the exports here are
      # only for the repair block below. See docs/ci.md#cache_restore.
      KEY_MOD=$(cacher key "gomod/{hash}.tar.zst" --hash-from "$REPO/go.sum")
      KEY_GOC=$(cacher key "gocache/{hash}.tar.zst" --hash-from "$REPO/go.sum")
      echo "export KEY_MOD=$KEY_MOD KEY_GOC=$KEY_GOC" >> ~/.buildenv
      cacher dir download "$KEY_MOD" ~/go/pkg/mod        --optional
      cacher dir download "$KEY_GOC" ~/.cache/go-build   --optional
      # Repair block for the HALF-restored module cache — the normal failure
      # here, not a freak one, and it reads like a code bug. Do not remove and
      # do not soften to `|| true`:
      # docs/ci.md#the-half-restored-module-cache.
      cd "$REPO"
      chmod -R u+w ~/go/pkg/mod 2>/dev/null || true
      if ! go mod verify >/dev/null 2>&1; then
        echo "restored module cache did not verify — discarding it"
        rm -rf ~/go/pkg/mod
      fi
      # `go mod download`, and NOT `go mod download all` — do not add the `all`
      # back as an optimization. It resolves the whole module graph, including
      # test dependencies of dependencies, and APPENDS their hashes to go.sum:
      # 145 lines in this repository, 228 in the bench sibling, whose build #359
      # packaged a "-dirty" binary because of it. A modified tracked file in the
      # checkout at `go build` time is the exact stamp this pipeline exists to
      # prevent. Without `all` go.sum is untouched and `go mod verify` still
      # passes. See docs/ci.md#not-go-mod-download-all.
      go mod download
      go mod verify
      # This print is NOT belt-and-braces. It is the ONLY thing here that
      # catches a go.sum rewrite, and no flag stands behind it. Do not replace
      # it with an appeal to -mod=readonly: readonly governs updates to the
      # module REQUIREMENTS, it does not stop writes to go.sum. Measured with
      # GOFLAGS=-mod=readonly explicitly on the command line — `go mod download
      # all` still appended the same 145 lines and still exited 0. A modified or
      # untracked file here is a "+dirty" stamp in the packaged binary.
      # docs/ci.md#not-go-mod-download-all.
      git status --porcelain
  - test: |
      cd "$REPO"
      # gofmt -l exits 0 whether or not it printed anything, so the only way to
      # fail on its output is to look at the output; tee keeps the filenames in
      # the log, where they are the whole diagnosis. See docs/ci.md#test.
      gofmt -l . | tee /tmp/fmt
      test ! -s /tmp/fmt || { echo "gofmt would change the files above" >&2; exit 1; }
      go vet ./...
      # `make test` and not a bare `go test ./...`: the test command lives in
      # one place. There is no DSN guard and no service to reach — every suite
      # here is hermetic (gitx builds a bare repo with the local git, web is
      # httptest + ecoretest) — so nothing can skip, and a failure is a non-zero
      # exit that fails this task. That is what the APKBUILD's `!check` now
      # rests on. docs/ci.md#test.
      make test
  - build: |
      cd "$REPO"
      # -d: makedepends come from `packages:` above, so skip abuild's own
      # dependency resolution. The APKBUILD runs `make css` before the compile
      # and `make check-css` after it, because web/ go:embed-s static/.
      # See docs/ci.md#build.
      REPODEST=$HOME/packages abuild -d
      find "$HOME/packages" -name '*.apk'
  - publish: |
      # The gate is the honest answer to a build handed no secrets, not a
      # fallback: without ~/.apk-ci.env every earlier task has still run and a
      # signed apk is sitting in $HOME/packages. See docs/ci.md#publish.
      if [ ! -r ~/.apk-ci.env ]; then
        echo "no ~/.apk-ci.env: this build has no apk repo credentials"
        echo "the package was built and signed, and is not published"
        exit 0
      fi
      set +x   # never echo the S3 credentials into the build log
      . ~/.apk-ci.env
      export RCLONE_CONFIG_GARAGE_TYPE=s3
      export RCLONE_CONFIG_GARAGE_PROVIDER=Other
      export RCLONE_CONFIG_GARAGE_ENDPOINT="$S3_ENDPOINT"
      export RCLONE_CONFIG_GARAGE_REGION=garage
      export RCLONE_CONFIG_GARAGE_FORCE_PATH_STYLE=true
      export RCLONE_CONFIG_GARAGE_ACCESS_KEY_ID="$APK_CI_S3_ACCESS_KEY"
      export RCLONE_CONFIG_GARAGE_SECRET_ACCESS_KEY="$APK_CI_S3_SECRET_KEY"
      set -x
      # Upload only, never delete; abuild nests output under
      # $REPODEST/<repo>/<arch>/, so flatten to a fixed prefix rather than
      # mirroring the tree. See docs/ci.md#publish.
      find "$HOME/packages" -name '*.apk' -print | while read -r f; do
        rclone copyto "$f" "garage:$S3_BUCKET/$APK_REPO/$(basename "$f")"
        echo "uploaded $(basename "$f")"
      done
      echo "published; apk-mirror on phoebe re-indexes within 15 minutes"
  - cache_save: |
      # AFTER publish so an S3 hiccup cannot strand a good apk, and fatal on
      # purpose. Without --force an upload skips a key already there, so no
      # `cacher exists ||` guard is needed. See docs/ci.md#cache_save.
      cacher dir upload "$KEY_MOD" ~/go/pkg/mod
      cacher dir upload "$KEY_GOC" ~/.cache/go-build