chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
# Builds the image of @pdsjs/git-ci, the check runner, on a version tag,
# and publishes it as the `pds.js-git-ci` release of this repository:
# `docker pull knotless.dev/chadtmiller.com/pds.js/pds.js-git-ci:<version>`.
# It copies it to the pdsjs.dev PDS's own registry too. release-image.yml
# says how the image is built and published with no docker daemon.
on:
push: {refs: [refs/tags/v*]}
asked: {refs: [refs/heads/*]}
superseded: finish
image: buildpack-deps:trixie-curl
runners: [ci.knotless.dev]
secrets: [RELEASE_PASSWORD, PDSJS_SITE_TOKEN]
env:
REPO: knotless://chadtmiller.com/pds.js
PACKAGE: pds.js-git-ci
DOCKERFILE: packages/git-ci/Dockerfile
KNOTLESS_APPVIEW: https://knotless.dev
PDS_HOST: pds.pdsjs.dev
CRANE_VERSION: v0.20.2
KANIKO_IMAGE: gcr.io/kaniko-project/executor:v1.23.2
# Where kaniko's own image keeps them. A build replaces the rest of /.
SSL_CERT_DIR: /kaniko/ssl/certs
DOCKER_CONFIG: /kaniko/.docker
steps:
- name: check credentials
run: |
case "$KNOTLESS_RUN_REF" in
refs/tags/v*)
if [ -z "${RELEASE_PASSWORD:-}" ]; then
echo "RELEASE_PASSWORD is not granted, so this tag would publish nothing."
echo "Seal it to ci.knotless.dev with knotless secret. It is an app password for the repository's owner."
exit 1
fi ;;
*) echo "at $KNOTLESS_RUN_REF: building and testing, publishing nothing" ;;
esac
# kaniko's own image starts kaniko, not the command the runner keeps a
# container up with, so the steps take kaniko from its image. They run in
# Debian, whose /sbin is a link as in the images built: the runner mounts
# docker-init under /sbin, and a build cannot replace a directory that
# holds a mount with a link. The tools go under /kaniko, which a build
# leaves alone.
- name: tools
run: |
mkdir -p /kaniko/tools
cd /kaniko/tools
curl -fsSL "https://github.com/google/go-containerregistry/releases/download/$CRANE_VERSION/go-containerregistry_Linux_x86_64.tar.gz" | tar -xzf - crane
./crane export "$KANIKO_IMAGE" - | tar -xf - -C / kaniko
/kaniko/executor version
v=$(curl -fsSL https://knotless.dev/releases/latest)
name="knotless-$v-x86_64-unknown-linux-musl"
curl -fsSLO "https://knotless.dev/releases/$v/$name.tar.gz"
curl -fsSL -o sum "https://knotless.dev/releases/$v/$name.tar.gz.sha256"
[ "$(sha256sum "$name.tar.gz" | cut -d' ' -f1)" = "$(cut -d' ' -f1 sum)" ]
tar -xzf "$name.tar.gz"
mv "$name/knotless" knotless
- name: build
timeout: 45
run: |
# kaniko builds over the files of the image the steps run in, and
# removes them only between stages. A first stage of nothing makes it
# remove them before the Dockerfile's own stages.
{ echo 'FROM scratch AS empty'; cat "$DOCKERFILE"; } > /kaniko/Dockerfile
/kaniko/executor --force --context "dir://$PWD" --dockerfile /kaniko/Dockerfile \
--no-push --oci-layout-path /kaniko/image --snapshot-mode redo
cat /kaniko/image/index.json
# The daemon listens on no port and exits without credentials, so the
# test is what it prints, and as which user.
- name: smoke test
run: |
run="node scripts/run-image.mjs /kaniko/image"
# Named no repositories, the CLI prints its usage and exits 129.
code=0
usage=$($run 2>&1) || code=$?
if [ "$code" != 129 ]; then
echo "expected exit 129 with no repositories, got $code"
echo "$usage"
exit 1
fi
case "$usage" in
*PDSJS_CI_IDENTIFIER*) ;;
*) echo "the usage text is missing: $usage"; exit 1 ;;
esac
# Given a repository and no credentials, it reaches the credential check.
fatal=$($run PDSJS_CI_REPOS=alice.example.com/repo 2>&1) || true
case "$fatal" in
*"must both be set"*) ;;
*) echo "expected the credential error, got: $fatal"; exit 1 ;;
esac
# The entrypoint takes the state directory as root, then drops.
who=$($run -- id -un)
if [ "$who" != node ]; then
echo "steps would run as $who, not node"
exit 1
fi
# A workflow clones the repository under test, installs it, and may
# build an image. Without any one of these a run fails at its first step.
$run -- sh -c '
set -e
git --version
corepack --version
command -v git-remote-atproto
command -v g++
docker --version
docker buildx version
'
- name: publish
run: |
case "$KNOTLESS_RUN_REF" in refs/tags/v*) ;; *) exit 0 ;; esac
version="${KNOTLESS_RUN_REF#refs/tags/v}"
KNOTLESS_PASSWORD="$RELEASE_PASSWORD" /kaniko/tools/knotless publish "$REPO" "$PACKAGE" "$version" --oci /kaniko/image
- name: copy to the PDS
run: |
case "$KNOTLESS_RUN_REF" in refs/tags/v*) ;; *) exit 0 ;; esac
if [ -z "${PDSJS_SITE_TOKEN:-}" ]; then
echo "PDSJS_SITE_TOKEN is not granted, so the PDS copy is skipped"
exit 0
fi
status=$(node -e "fetch('https://$PDS_HOST/v2/').then((r) => console.log(r.status)).catch(() => console.log(0))")
if [ "$status" != "401" ]; then
echo "https://$PDS_HOST/v2/ answered $status, not the challenge, so the PDS registry is off"
exit 0
fi
tag="${KNOTLESS_RUN_REF#refs/tags/}"
crane=/kaniko/tools/crane
echo "$PDSJS_SITE_TOKEN" | $crane auth login "$PDS_HOST" -u pdsjs.dev --password-stdin
if ! $crane push /kaniko/image "$PDS_HOST/$PACKAGE:$tag" || ! $crane tag "$PDS_HOST/$PACKAGE:$tag" latest; then
echo "the PDS refused the push. A layer can be over the platform's request limit"
echo "(100 MB on the lowest Cloudflare plan). The release stands on knotless."
fi