Files
ekklesiaandClaude Opus 5.5 22f25854aa feat: Gitea CI, and releases built once, previewed and promoted as one file
ci.yml runs tools/check.sh and the container gate on every push and pull
request, with no secrets. Release 1 builds a version from its release
commit on master or release/*, gates it, and keeps it in a Gitea
pre-release. Release 2 gates that file again on the CI runner and
publishes it to canary (Preview) from the release runner. Release 3
promotes the file Preview ran, on a person's approval. Import records a
release from before Gitea kept the record. All of it is
tools/release-ci.sh calling the existing scripts.

docs/releasing.md: tracks, branches, each step, immutability, rollback,
secrets, runners, Nightly and the hardware lab as designs, the Gitea
administration still to do, and what was measured to make it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 18:47:42 -05:00

88 lines
3.4 KiB
YAML

# EVERY PUSH AND EVERY PULL REQUEST: THE REPOSITORY'S OWN CHECKS.
#
# This runs code nobody has reviewed yet. It is given no secret, it only
# ever runs on the ekklesia-ci runner, which holds no credential that
# reaches the update server or a classroom, and nothing it builds is kept
# as something that could be installed. See docs/releasing.md.
#
# The steps are the repository's own scripts. A test added to tests/ is
# run here with nothing in this file to change.
name: CI
on:
push:
branches: ['**']
pull_request:
jobs:
checks:
name: checks
runs-on: ekklesia-ci
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Sources, the manual, every test, and the change's hygiene
env:
PR_BASE: ${{ github.event.pull_request.base.sha }}
PUSH_BEFORE: ${{ github.event.before }}
run: |
# What the change is compared with: the pull request's base, or
# what the branch was before this push, or where it left master.
base="${PR_BASE:-$PUSH_BEFORE}"
if [ -z "$base" ] || ! git cat-file -e "$base^{commit}" 2>/dev/null; then
base="$(git merge-base HEAD origin/master 2>/dev/null || git rev-list --max-parents=0 HEAD | tail -n 1)"
fi
CHECK_LOG_DIR="$RUNNER_TEMP/checks" tools/check.sh --base "$base"
- name: Summary
if: always()
run: cat "$RUNNER_TEMP/checks/summary.md" 2>/dev/null || echo "no summary was written"
- name: Keep every check's full output
if: always()
uses: actions/upload-artifact@v3
with:
name: check-logs
path: ${{ runner.temp }}/checks
package:
name: package and container gate
needs: checks
runs-on: ekklesia-ci
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Build the package this commit describes
run: |
version="$(cat VERSION)"
SOURCE_DATE_EPOCH="$(git log -1 --format=%ct)" tools/build-release.sh "$version"
deb="dist/ekklesia-classroom_${version}_amd64.deb"
# It is the package it says it is, and building it changed nothing
# in the tree but, perhaps, the manual's revision date.
test "$(dpkg-deb --field "$deb" Package)" = ekklesia-classroom
test "$(dpkg-deb --field "$deb" Version)" = "$version"
test -z "$(git status --porcelain --untracked-files=no -- . ':(exclude)docs/manual/build')"
mkdir -p "$RUNNER_TEMP/package"
{ dpkg-deb --info "$deb"; echo; dpkg-deb --contents "$deb"; } > "$RUNNER_TEMP/package/contents.txt"
sha256sum "$deb" > "$RUNNER_TEMP/package/sha256.txt"
- name: Install it on Debian Trixie, fresh and over what the rooms run
run: |
version="$(cat VERSION)"
# --ci: an upgrade from a release that is not older than this
# commit's VERSION (master between releases) is recorded as
# skipped, not failed. A release build is never --ci.
RELEASE_GATE_REPORT="$RUNNER_TEMP/package/gate-report.txt" \
tools/release-gate.sh --ci "dist/ekklesia-classroom_${version}_amd64.deb"
- name: Keep the package's contents and the gate report (not the package)
if: always()
uses: actions/upload-artifact@v3
with:
name: package-report
path: ${{ runner.temp }}/package