artifacts: - cover.out - bench.txt environment: APK_REPO: alpine/v3.22/bigbes/x86_64 ARTIFACTS_CHANNEL: ~bigbes/main ARTIFACTS_DIST: v3.22 ARTIFACTS_ENDPOINT: https://artifacts.srht.bigb.es BENCH_ORIGIN: https://bench.srht.bigb.es BENCH_REPO: ~bigbes/sr-ht-artifacts BOOTSTRAP_REV: 779ad9f174ea5ab7e755f6df0ec9e5912d67dd16 BUILD_SUBMITTER: git.sr.ht CACHE_BACKEND: cacher CACHE_NS: sr-ht-artifacts CACHE_SUBPREFIX: deps CONFORMANCE_MODE: report CONFORMANCE_REV: v1.1.1 CORE_VER: 0.84.5 COVER_ORIGIN: https://cov.srht.bigb.es COVER_REPO: ~bigbes/sr-ht-artifacts GIT_REF: refs/heads/master REPO: sr-ht-artifacts S3_BUCKET: repo S3_ENDPOINT: https://s3.bigb.es image: alpine/edge packages: - abuild - curl - docker - git - go - postgresql - postgresql-client - postgresql-contrib - rclone - sassc - minify secrets: - e322d5a2-b6b5-4425-aa37-12b038282461 - 7dde4219-0783-4581-a67d-c94749de3600 - 0e5b3530-6f19-4f30-9b73-9339dd382e46 - c7968415-1a6d-4ca0-a188-150fb7f57b65 sources: - "https://git.srht.bigb.es/~bigbes/sr-ht-artifacts#d7f73d6fd5378ca8113418fe9657c8c1af4754ab" submitter: git.sr.ht: allow-refs: - refs/heads/master - refs/tags/v* tasks: - cache_setup: | # Leaves $CACHE and $CACHE_KEY_PREFIX behind. docs/ci.md#cache_setup case "$CACHE_BACKEND" in cacher) curl -sSL https://bigbes.pages.srht.bigb.es/ci-cacher/install.sh | sh # install.sh's PATH line reaches only LATER tasks, hence the repeat. export PATH="$HOME/.local/bin:$PATH" cacher init \ --endpoint https://s3.bigb.es \ --region garage \ --bucket docker-cache \ --prefix "$CACHE_NS/$CACHE_SUBPREFIX" \ --key-file ~/.s3-cache-key-id \ --secret-file ~/.s3-cache-key-secret echo 'export CACHE="cacher" CACHE_KEY_PREFIX=""' >> ~/.buildenv ;; art) if [ ! -r ~/.srht-token ]; then echo "CACHE_BACKEND=art needs the working token at ~/.srht-token" >&2 exit 1 fi mkdir -p ~/.local/bin (cd "$REPO" && CGO_ENABLED=0 go build -o ~/.local/bin/art ./cmd/art) echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.buildenv export PATH="$HOME/.local/bin:$PATH" art init \ --endpoint "$ARTIFACTS_ENDPOINT" \ --cache-ns "$CACHE_NS" \ --token-file ~/.srht-token echo "export CACHE=\"art cache\" CACHE_KEY_PREFIX=\"$CACHE_SUBPREFIX/\"" >> ~/.buildenv ;; *) echo "CACHE_BACKEND must be cacher or art, got '$CACHE_BACKEND'" >&2 exit 1 ;; esac - scss: | $CACHE dir download "${CACHE_KEY_PREFIX}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 -f /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 -rf /tmp/bootstrap/scss ~/scss/bootstrap/scss ' sudo mkdir -p /usr/share/sourcehut sudo cp -rf ~/scss /usr/share/sourcehut/scss - keygen: | SUDO=sudo abuild-keygen -a -n -i -q - version: | # Both are EXPORTED, never sed-ed into the APKBUILD. 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 SRHT_VERSION=$desc" >> ~/.buildenv git status --porcelain - cache_restore: | # Not `go mod download all`: it rewrites go.sum. docs/ci.md#cache_restore cd "$REPO" KEY_MOD=$($CACHE key "${CACHE_KEY_PREFIX}gomod/{hash}.tar.zst" --hash-from go.sum) KEY_GOC=$($CACHE key "${CACHE_KEY_PREFIX}gocache/{hash}.tar.zst" --hash-from go.sum) echo "export KEY_MOD=$KEY_MOD KEY_GOC=$KEY_GOC" >> ~/.buildenv $CACHE dir download "$KEY_MOD" ~/go/pkg/mod --optional $CACHE dir download "$KEY_GOC" ~/.cache/go-build --optional 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; moving it aside" mv -f "$HOME/go/pkg/mod" /tmp/artifacts-invalid-mod-cache fi go mod download go mod verify - postgres: | sudo install -d -o postgres -g postgres /run/postgresql /var/lib/postgresql/data sudo -u postgres initdb -D /var/lib/postgresql/data sudo -u postgres pg_ctl -D /var/lib/postgresql/data -l /tmp/pg.log -w start \ -o "-k /run/postgresql -h 127.0.0.1 -c fsync=off -c full_page_writes=off -c synchronous_commit=off" sudo -u postgres createuser -s "$(id -un)" sudo -u postgres createdb -O "$(id -un)" artifactsrht_test echo "export ARTIFACTSRHT_TEST_PG='postgresql://$(id -un)@127.0.0.1/artifactsrht_test?sslmode=disable'" \ >> ~/.buildenv - test_env: | # Without this, 23 tests skip and the build is green. docs/ci.md#test_env if ! docker version >/dev/null 2>&1; then sudo service docker start until sudo docker version >/dev/null 2>&1; do sleep 1; done sudo chmod 0666 /var/run/docker.sock fi # Both images out of the cache, not Docker Hub. docs/ci.md#test_env $CACHE docker download "${CACHE_KEY_PREFIX}img/garage-2.3.0.tar.zst" dxflrs/garage:v2.3.0 --pull $CACHE docker download "${CACHE_KEY_PREFIX}img/dind-29.tar.zst" docker:29-dind --pull cat >> ~/.buildenv <<'EOF' export ARTIFACTSRHT_TEST_S3=1 export ARTIFACTSRHT_TEST_INTEGRATION=1 export ARTIFACTSRHT_TEST_DOCKER=1 EOF GARAGE_RPC_SECRET=$(head -c 32 /dev/urandom | od -An -tx1 | tr -d ' \n') GARAGE_ADMIN_TOKEN=$(head -c 32 /dev/urandom | od -An -tx1 | tr -d ' \n') GARAGE_ACCESS_KEY=GK$(head -c 16 /dev/urandom | od -An -tx1 | tr -d ' \n') GARAGE_SECRET_KEY=$(head -c 32 /dev/urandom | od -An -tx1 | tr -d ' \n') cat > /tmp/garage.toml </dev/null | grep -q artifacts; do if [ "$(date +%s)" -ge "$deadline" ]; then docker logs artifacts-test-garage echo "garage did not create its default bucket" >&2 exit 1 fi sleep 1 done cat >> ~/.buildenv </dev/null 2>&1; then sudo service docker start until sudo docker version >/dev/null 2>&1; do sleep 1; done sudo chmod 0666 /var/run/docker.sock fi ARTIFACTS_E2E_PULL=1 go test -tags e2e -count=1 -timeout 40m ./e2e - conformance: | # Known gaps and what flipping to enforce needs: docs/ci.md#conformance cd "$REPO" case "$CONFORMANCE_MODE" in report|enforce) ;; *) echo "CONFORMANCE_MODE must be report or enforce, got '$CONFORMANCE_MODE'" >&2; exit 1 ;; esac if ! docker version >/dev/null 2>&1; then sudo service docker start until sudo docker version >/dev/null 2>&1; do sleep 1; done sudo chmod 0666 /var/run/docker.sock fi git clone -q --depth 1 --branch "$CONFORMANCE_REV" \ https://github.com/opencontainers/distribution-spec /tmp/distribution-spec (cd /tmp/distribution-spec/conformance && \ GOMODCACHE=/tmp/conformance-gomodcache go test -c -o /tmp/conformance.test .) if ARTIFACTS_E2E_PULL=1 ARTIFACTS_E2E_CONFORMANCE=/tmp/conformance.test \ go test -tags e2e -v -count=1 -timeout 20m -run TestOCIConformance ./e2e \ > /tmp/conformance.log 2>&1 then status=0; else status=1; fi cat /tmp/conformance.log # A run that never reached the suite must not read as a known gap. if ! grep -q "Specs in" /tmp/conformance.log; then echo "the conformance suite did not run to a summary" >&2 exit 1 fi if [ "$status" -ne 0 ] && [ "$CONFORMANCE_MODE" = enforce ]; then echo "conformance failed and CONFORMANCE_MODE is enforce" >&2 exit 1 fi if [ "$status" -ne 0 ]; then echo "conformance failed; CONFORMANCE_MODE is report, see the summary above" fi - build: | cd "$REPO" REPODEST=$HOME/packages abuild -d find "$HOME/packages" -name '*.apk' - publish: | if [ ! -r ~/.apk-ci.env ]; then echo "no apk repository credentials; package built but 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 find "$HOME/packages" -name '*.apk' -print | while read -r file; do rclone copyto "$file" "garage:$S3_BUCKET/$APK_REPO/$(basename "$file")" done - publish_artifacts: | # The same apk into this service's own channel, beside the S3 copy above. # Codes, the 409 case and the loop shape: docs/ci.md#publish_artifacts if [ ! -r ~/.srht-token ]; then echo "no ~/.srht-token: nothing was published to artifacts.sr.ht" exit 0 fi count=$(find "$HOME/packages" -name '*.apk' | wc -l) test "$count" -gt 0 || { echo "no .apk under $HOME/packages" >&2; exit 1; } url="$ARTIFACTS_ENDPOINT/api/v1/pkg/$ARTIFACTS_CHANNEL/apk/$ARTIFACTS_DIST" failed= for file in $(find "$HOME/packages" -name '*.apk'); do set +x # the token must not reach the log code=$(curl -sS -o /tmp/artifacts.out -w '%{http_code}' -X PUT \ -H "Authorization: Bearer $(cat ~/.srht-token)" \ --data-binary "@$file" "$url") set -x case "$code" in 200|201) echo "published $(basename "$file") -> $code" ;; 409) echo "WARNING: $(basename "$file") already published with other bytes; kept the published copy" ;; *) echo "FAILED $(basename "$file") -> $code" >&2 cat /tmp/artifacts.out >&2 echo >&2 failed=1 ;; esac done test -z "$failed" || exit 1 echo "index: $ARTIFACTS_ENDPOINT/$ARTIFACTS_CHANNEL/apk/$ARTIFACTS_DIST/x86_64/APKINDEX.tar.gz" - publish_client: | # linux/amd64 art for the sibling builds. docs/ci.md#publish_client if [ ! -r ~/.srht-token ]; then echo "no ~/.srht-token: the client was not published" exit 0 fi cd "$REPO" CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o /tmp/art ./cmd/art /tmp/art --endpoint "$ARTIFACTS_ENDPOINT" --token-file ~/.srht-token \ blob push "$ARTIFACTS_CHANNEL" /tmp/art --to art/art-linux-amd64 - cache_save: | $CACHE dir upload "$KEY_MOD" ~/go/pkg/mod $CACHE dir upload "$KEY_GOC" ~/.cache/go-build - coverage: | # The test task's profile, to this instance's own cov.sr.ht. Last, after # everything that could strand an apk. docs/ci.md#coverage cd "$REPO" if [ ! -r ~/.srht-token ]; then echo "no ~/.srht-token; the profile is still this build's cover.out" exit 0 fi test -s "$HOME/cover.out" || { echo "test wrote no cover.out" >&2; exit 1; } ref="${GIT_REF#refs/heads/}"; ref="${ref#refs/tags/}" url="$COVER_ORIGIN/api/v1/repos/$COVER_REPO/reports" url="$url?commit=$(git rev-parse HEAD)&ref=$ref&key=$JOB_ID&job_url=$JOB_URL" echo "uploading cover.out to $url" set +x # the Authorization header must not reach the log curl -sS --fail-with-body -X POST \ -H "Authorization: Bearer $(cat ~/.srht-token)" \ --data-binary "@$HOME/cover.out" "$url" echo - bench: | # This build's own benchmarks, to this instance's own bench.sr.ht. The # DSN guard and the name list are load-bearing: docs/ci.md#bench cd "$REPO" if [ -z "$ARTIFACTSRHT_TEST_PG" ]; then echo "ARTIFACTSRHT_TEST_PG is unset: the PostgreSQL benchmark would" >&2 echo "skip and this build would upload a short file silently." >&2 exit 1 fi make -s bench > "$HOME/bench.txt" cat "$HOME/bench.txt" for name in $(make -s bench-names); do grep -q "^$name" "$HOME/bench.txt" || \ { echo "$name produced no result line" >&2; exit 1; } done if [ ! -r ~/.srht-token ]; then echo "no ~/.srht-token; the results are above and are bench.txt" exit 0 fi ref="${GIT_REF#refs/heads/}"; ref="${ref#refs/tags/}" url="$BENCH_ORIGIN/api/v1/repos/$BENCH_REPO/runs" url="$url?commit=$(git rev-parse HEAD)&ref=$ref&key=$JOB_ID&job_url=$JOB_URL" url="$url&visibility=public" echo "uploading bench.txt to $url" set +x # the Authorization header must not reach the log curl -sS --fail-with-body -X POST \ -H "Authorization: Bearer $(cat ~/.srht-token)" \ --data-binary "@$HOME/bench.txt" "$url" echo