ci: restore external package integration
CI / lint (pull_request) Successful in 12s
CI / typecheck (pull_request) Successful in 13s
CI / test (pull_request) Successful in 16s
CI / build (pull_request) Successful in 10s
CI / integration (pull_request) Failing after 1m57s

This commit is contained in:
ekklesia
2026-10-09 22:30:52 -05:00
parent 6233de0e5c
commit c28e4b2de7
7 changed files with 106 additions and 58 deletions
+8 -3
View File
@@ -6,7 +6,7 @@
#
# The `integration` job is the one that starts Docker stacks. It must have its own
# EKKLESIA_CI_JOB_KEY, sweep stale CI stacks before it starts anything, and remove its own in a final
# `if: always()` step; and the image ci/integration.sh builds must carry the CI labels the sweep finds.
# `if: always()` step. The pinned platform smoke owns and labels every image and container.
set -Eeuo pipefail
root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
@@ -31,13 +31,18 @@ own="$(line_of 'ci-sweep.sh --job')"
last_step="$(grep -n -- " - name:" <<<"$job" | tail -1 | cut -d: -f1 || true)"
check '[[ -n "$job" ]]' "the workflow has an integration job"
check '! grep -q "if: false" <<<"$job"' "the integration job is enabled"
check 'grep -q "EKKLESIA_CI_JOB_KEY:" <<<"$job"' "the integration job names its stacks with its own key"
check '[[ -n "$stale" && -n "$run" ]] && ((stale < run))' "it sweeps stale CI stacks before it starts anything"
check '[[ -n "$own" && -n "$run" ]] && ((own > run)) && ((own > last_step))' \
"its last step removes its own stacks"
check 'sed -n "${last_step},\$p" <<<"$job" | grep -q "if: always()"' "that last step always runs"
check 'grep -q "EKKLESIA_CI_LABEL" "$root/ci/integration.sh" && grep -q "EKKLESIA_CI_CREATED_LABEL" "$root/ci/integration.sh"' \
"the image ci/integration.sh builds carries the CI labels"
check 'grep -q "EKKLESIA_SMOKE_MODULE_RELEASE_DIR" "$root/ci/integration.sh" && grep -q "bash scripts/smoke-deploy.sh" "$root/ci/integration.sh"' \
"the integration delegates its external package to the platform smoke"
check 'grep -Eq "^EKKLESIA_PLATFORM_REF=refs/(pull/[0-9]+/head|heads/main)$" "$root/ci/platform.env" && grep -Eq "^EKKLESIA_PLATFORM_COMMIT=[0-9a-f]{40}$" "$root/ci/platform.env"' \
"the platform harness is pinned by full ref and commit"
check 'grep -q "rev-parse refs/remotes/pinned" "$root/ci/fetch-platform.sh" && grep -q "does not resolve to EKKLESIA_PLATFORM_COMMIT" "$root/ci/fetch-platform.sh"' \
"the fetch verifies that the pinned ref resolves to the pinned commit"
((failures == 0)) || {
echo "check-cleanup: ${failures} check(s) failed." >&2
+39
View File
@@ -0,0 +1,39 @@
#!/usr/bin/env bash
# Fetches the exact Ekklesia source revision Signage's external-package integration runs against.
# The ref is fetched only to make the pinned object reachable; the checkout is always by full SHA.
set -Eeuo pipefail
root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
out="$root/build/platform"
fail() {
echo "fetch-platform: $*" >&2
exit 1
}
(($# == 0)) || fail "this command takes no arguments."
pin() {
local value
value="$(sed -n "s/^$1=//p" "$root/ci/platform.env")"
[[ -n "$value" ]] || fail "ci/platform.env has no $1."
printf '%s' "$value"
}
repository="$(pin EKKLESIA_PLATFORM_REPOSITORY)"
ref="$(pin EKKLESIA_PLATFORM_REF)"
commit="$(pin EKKLESIA_PLATFORM_COMMIT)"
[[ "$commit" =~ ^[0-9a-f]{40}$ ]] || fail "EKKLESIA_PLATFORM_COMMIT must be a full commit SHA."
[[ "$ref" == refs/* ]] || fail "EKKLESIA_PLATFORM_REF must be a full Git ref."
rm -rf "$out"
mkdir -p "$out"
git -C "$out" init --quiet
git -C "$out" remote add origin "$repository"
git -C "$out" fetch --quiet --no-tags --depth=1 origin "+${ref}:refs/remotes/pinned" ||
fail "cannot fetch the pinned platform ref."
[[ "$(git -C "$out" rev-parse refs/remotes/pinned)" == "$commit" ]] ||
fail "the pinned ref does not resolve to EKKLESIA_PLATFORM_COMMIT."
git -C "$out" -c advice.detachedHead=false checkout --quiet --detach "$commit"
rm -rf "$out/.git"
echo "fetch-platform: Ekklesia ${commit}"
+26 -26
View File
@@ -1,46 +1,46 @@
#!/usr/bin/env bash
# Signage inside Ekklesia, end to end: builds the deployment image from the assembled workspace with
# the platform's own Dockerfile, then runs the platform's split-topology deployment smoke against it
# with the display-device scenarios listed in ci/display-scenarios. A disposable PostgreSQL and object
# store, generated secrets, and an explicit migration apply against that fresh database only; nothing
# is pushed, published, or logged in to. The image is removed afterwards.
# Builds Signage as the canonical linux-x64-glibc Module Package, then gives that exact release pair
# to the pinned platform's generic deployment smoke. The platform image contains no Signage source:
# its verifier extracts the package into installation-owned module storage before migrations,
# discovery, browser UI/display checks, restart, container recreation, disable/re-enable, removal,
# and reinstall are exercised against disposable PostgreSQL and object-storage services.
#
# bash ci/fetch-platform.sh
# bash ci/integration.sh
#
# NOT RUN: the integration job is disabled (.gitea/workflows/ci.yml says why). This script still
# expects Ekklesia's deployment tree at build/workspace, which the removed ci/assemble.sh used to
# build; it is rewritten when Signage is installed into the generic image as a Module Package.
set -Eeuo pipefail
root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
workspace="$root/build/workspace"
[[ -f "$workspace/deploy/Dockerfile" ]] || {
echo "integration: Ekklesia's deployment tree is not at build/workspace." >&2
platform="$root/build/platform"
release="$root/build/module-package"
[[ -f "$platform/scripts/smoke-deploy.sh" ]] || {
echo "integration: run bash ci/fetch-platform.sh first." >&2
exit 1
}
# Named and labeled as a CI stack of this run and job (the platform's scripts/lib/ci-project.sh), so
# the workflow's final `ci-sweep.sh --job` removes it even if this script is killed before its trap.
# shellcheck source=/dev/null
source "$workspace/scripts/lib/ci-project.sh"
project="$(ci_project_name signage-image)"
image="${project}:latest"
trap 'docker image rm --force "$image" >/dev/null 2>&1 || true' EXIT
source_revision="${GITHUB_SHA:-$(git -C "$root" rev-parse HEAD 2>/dev/null || true)}"
[[ "$source_revision" =~ ^[0-9a-f]{40}$ ]] || {
echo "integration: no full source revision is available for the package." >&2
exit 1
}
rm -rf "$release"
mkdir -p "$release"
pnpm --dir "$root" build
pnpm --dir "$root" exec ekklesia-pack-module --module "$root" --target linux-x64-glibc \
--out "$release" --license-file "$root/LICENSE" --source-revision "$source_revision"
scenarios="$(sed -e 's/#.*//' -e '/^[[:space:]]*$/d' "$root/ci/display-scenarios" | tr '\n' ' ')"
[[ -n "${scenarios// /}" ]] || {
echo "integration: ci/display-scenarios lists no scenario." >&2
exit 1
}
echo "integration: external Signage package built; scenarios: ${scenarios}"
DOCKER_BUILDKIT=1 docker build --quiet --file "$workspace/deploy/Dockerfile" --tag "$image" \
--label "${EKKLESIA_CI_LABEL}=${project}" --label "${EKKLESIA_CI_CREATED_LABEL}=$(date +%s)" \
"$workspace" >/dev/null
echo "integration: built the deployment image with Signage; scenarios: ${scenarios}"
cd "$workspace"
cd "$platform"
EKKLESIA_SMOKE_TOPOLOGY=split \
EKKLESIA_SMOKE_IMAGE="$image" \
EKKLESIA_SMOKE_MODULE_RELEASE_DIR="$release" \
EKKLESIA_SMOKE_MODULE_ID=signage \
EKKLESIA_SMOKE_MODULE_PROBE_PATH=/api/v1/modules/signage/channel-groups \
EKKLESIA_SMOKE_DISPLAY_DEVICE=1 \
EKKLESIA_SMOKE_DISPLAY_SCENARIOS="$scenarios" \
EKKLESIA_SMOKE_WATCH_MS=120000 \
+5
View File
@@ -0,0 +1,5 @@
# The companion Core harness Signage uses to install and run its real external package. The pull ref
# remains reachable after its branch is deleted; the full commit pin makes the checkout immutable.
EKKLESIA_PLATFORM_REPOSITORY=https://git.riverofglorymn.org/River_of_Glory_Church/Ekklesia.git
EKKLESIA_PLATFORM_REF=refs/pull/90/head
EKKLESIA_PLATFORM_COMMIT=fa276031336b34270228fa9cb7f0330ade5d96a9