Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
776540ff78 | ||
|
|
7483d7cbbe |
@@ -1,197 +0,0 @@
|
|||||||
name: CI
|
|
||||||
|
|
||||||
# Signage builds, tests, and runs only inside an Ekklesia workspace, so every job first assembles it
|
|
||||||
# into the platform commit pinned in ci/platform.env (ci/assemble.sh) and installs that workspace
|
|
||||||
# with --frozen-lockfile from ci/pnpm-lock.yaml.
|
|
||||||
#
|
|
||||||
# The same trust rules as the platform's own CI (docs/development/security.md there):
|
|
||||||
# * every action is pinned by a full commit SHA;
|
|
||||||
# * every checkout sets `persist-credentials: false`, and nothing in this workflow pushes;
|
|
||||||
# * no repository, organization, or instance secret is referenced;
|
|
||||||
# * there is no `pull_request_target`;
|
|
||||||
# * the self-hosted runner executes trusted, reviewed code only.
|
|
||||||
#
|
|
||||||
# The server is Gitea 1.24, which ignores `permissions`, `concurrency`, and `timeout-minutes`
|
|
||||||
# (https://docs.gitea.com/1.24/usage/actions/comparison). They are declared so the workflow is already
|
|
||||||
# correct on a release that honours them; on 1.24 they bound nothing, and `permissions` does not
|
|
||||||
# restrict the job token.
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ci-${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
lint:
|
|
||||||
name: lint
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
timeout-minutes: 15
|
|
||||||
steps:
|
|
||||||
- name: Check out repository
|
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
||||||
with:
|
|
||||||
# Nothing here pushes, so the job token is never needed after checkout and must not be left
|
|
||||||
# in .git/config for a later step to read.
|
|
||||||
persist-credentials: false
|
|
||||||
|
|
||||||
- name: Assemble Signage into the pinned platform
|
|
||||||
run: bash ci/assemble.sh
|
|
||||||
|
|
||||||
- name: Set up Node.js at the platform's version
|
|
||||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
||||||
with:
|
|
||||||
node-version-file: build/workspace/.node-version
|
|
||||||
|
|
||||||
- name: Install the assembled workspace (frozen lockfile)
|
|
||||||
working-directory: build/workspace
|
|
||||||
run: |
|
|
||||||
corepack enable
|
|
||||||
corepack install
|
|
||||||
pnpm install --frozen-lockfile
|
|
||||||
|
|
||||||
- name: Lint
|
|
||||||
working-directory: build/workspace
|
|
||||||
run: pnpm --filter @ekklesia/signage lint
|
|
||||||
|
|
||||||
typecheck:
|
|
||||||
name: typecheck
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
timeout-minutes: 15
|
|
||||||
steps:
|
|
||||||
- name: Check out repository
|
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
||||||
with:
|
|
||||||
# Nothing here pushes, so the job token is never needed after checkout and must not be left
|
|
||||||
# in .git/config for a later step to read.
|
|
||||||
persist-credentials: false
|
|
||||||
|
|
||||||
- name: Assemble Signage into the pinned platform
|
|
||||||
run: bash ci/assemble.sh
|
|
||||||
|
|
||||||
- name: Set up Node.js at the platform's version
|
|
||||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
||||||
with:
|
|
||||||
node-version-file: build/workspace/.node-version
|
|
||||||
|
|
||||||
- name: Install the assembled workspace (frozen lockfile)
|
|
||||||
working-directory: build/workspace
|
|
||||||
run: |
|
|
||||||
corepack enable
|
|
||||||
corepack install
|
|
||||||
pnpm install --frozen-lockfile
|
|
||||||
|
|
||||||
- name: Build the platform packages Signage depends on
|
|
||||||
working-directory: build/workspace
|
|
||||||
run: pnpm exec turbo run build --filter='@ekklesia/signage^...'
|
|
||||||
|
|
||||||
- name: Typecheck the server, browser, and browser-test projects
|
|
||||||
working-directory: build/workspace
|
|
||||||
run: pnpm --filter @ekklesia/signage typecheck
|
|
||||||
|
|
||||||
test:
|
|
||||||
name: test
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
timeout-minutes: 15
|
|
||||||
steps:
|
|
||||||
- name: Check out repository
|
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
||||||
with:
|
|
||||||
# Nothing here pushes, so the job token is never needed after checkout and must not be left
|
|
||||||
# in .git/config for a later step to read.
|
|
||||||
persist-credentials: false
|
|
||||||
|
|
||||||
- name: Assemble Signage into the pinned platform
|
|
||||||
run: bash ci/assemble.sh
|
|
||||||
|
|
||||||
- name: Set up Node.js at the platform's version
|
|
||||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
||||||
with:
|
|
||||||
node-version-file: build/workspace/.node-version
|
|
||||||
|
|
||||||
- name: Install the assembled workspace (frozen lockfile)
|
|
||||||
working-directory: build/workspace
|
|
||||||
run: |
|
|
||||||
corepack enable
|
|
||||||
corepack install
|
|
||||||
pnpm install --frozen-lockfile
|
|
||||||
|
|
||||||
- name: Build the platform packages Signage depends on
|
|
||||||
working-directory: build/workspace
|
|
||||||
run: pnpm exec turbo run build --filter='@ekklesia/signage^...'
|
|
||||||
|
|
||||||
- name: Unit, browser, and display contract tests
|
|
||||||
working-directory: build/workspace
|
|
||||||
run: pnpm --filter @ekklesia/signage test
|
|
||||||
|
|
||||||
build:
|
|
||||||
name: build
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
timeout-minutes: 20
|
|
||||||
steps:
|
|
||||||
- name: Check out repository
|
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
||||||
with:
|
|
||||||
# Nothing here pushes, so the job token is never needed after checkout and must not be left
|
|
||||||
# in .git/config for a later step to read.
|
|
||||||
persist-credentials: false
|
|
||||||
|
|
||||||
- name: Assemble Signage into the pinned platform
|
|
||||||
run: bash ci/assemble.sh
|
|
||||||
|
|
||||||
- name: Set up Node.js at the platform's version
|
|
||||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
|
||||||
with:
|
|
||||||
node-version-file: build/workspace/.node-version
|
|
||||||
|
|
||||||
- name: Install the assembled workspace (frozen lockfile)
|
|
||||||
working-directory: build/workspace
|
|
||||||
run: |
|
|
||||||
corepack enable
|
|
||||||
corepack install
|
|
||||||
pnpm install --frozen-lockfile
|
|
||||||
|
|
||||||
# The same gates the platform's image build runs against exactly this module set: its boundary
|
|
||||||
# rules (which apply to modules), the manifest, and the migrations.
|
|
||||||
- name: Platform gates (boundaries, module manifest, migrations)
|
|
||||||
working-directory: build/workspace
|
|
||||||
run: |
|
|
||||||
pnpm boundaries
|
|
||||||
pnpm modules:validate
|
|
||||||
pnpm migrations:validate
|
|
||||||
|
|
||||||
- name: Build Signage and the platform it depends on
|
|
||||||
working-directory: build/workspace
|
|
||||||
run: pnpm exec turbo run build --filter='@ekklesia/signage...'
|
|
||||||
|
|
||||||
# Signage inside Ekklesia, end to end, in a real browser: the platform's own Dockerfile builds the
|
|
||||||
# deployment image with Signage in it, and the platform's split-topology deployment smoke runs
|
|
||||||
# against it, pairing a kiosk display and running the scenarios in ci/display-scenarios. A
|
|
||||||
# disposable database and object store with generated secrets; nothing is pushed or logged in to.
|
|
||||||
integration:
|
|
||||||
name: integration
|
|
||||||
needs:
|
|
||||||
- test
|
|
||||||
- build
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
timeout-minutes: 45
|
|
||||||
env:
|
|
||||||
DOCKER_BUILDKIT: "1"
|
|
||||||
steps:
|
|
||||||
- name: Check out repository
|
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
||||||
with:
|
|
||||||
persist-credentials: false
|
|
||||||
|
|
||||||
- name: Assemble Signage into the pinned platform
|
|
||||||
run: bash ci/assemble.sh
|
|
||||||
|
|
||||||
- name: Build the image and run the display scenarios
|
|
||||||
run: bash ci/integration.sh
|
|
||||||
@@ -4,4 +4,3 @@ dist/
|
|||||||
coverage/
|
coverage/
|
||||||
*.log
|
*.log
|
||||||
.DS_Store
|
.DS_Store
|
||||||
build/
|
|
||||||
|
|||||||
@@ -1,72 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# Assembles Signage into the Ekklesia platform it is tested against: the platform at the commit pinned
|
|
||||||
# in ci/platform.env, this checkout at modules/signage, and ci/pnpm-lock.yaml as the workspace
|
|
||||||
# lockfile. Signage cannot build or run outside an Ekklesia workspace, so every CI job starts here.
|
|
||||||
#
|
|
||||||
# bash ci/assemble.sh [--allow-missing-lock] [output directory]
|
|
||||||
#
|
|
||||||
# The output directory (default build/workspace) is deleted and recreated. The platform is fetched
|
|
||||||
# by its `main` branch and the pinned commit must be on it, so CI only ever runs reviewed platform
|
|
||||||
# code; the checkout is then by commit, so nothing after it depends on a ref the network can move.
|
|
||||||
# Every .git directory is removed afterwards.
|
|
||||||
#
|
|
||||||
# --allow-missing-lock keeps the platform's own lockfile. Only ci/update-lock.sh uses it.
|
|
||||||
set -Eeuo pipefail
|
|
||||||
|
|
||||||
root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
||||||
allow_missing_lock=0
|
|
||||||
if [[ "${1:-}" == "--allow-missing-lock" ]]; then
|
|
||||||
allow_missing_lock=1
|
|
||||||
shift
|
|
||||||
fi
|
|
||||||
out="${1:-$root/build/workspace}"
|
|
||||||
|
|
||||||
fail() {
|
|
||||||
echo "assemble: $*" >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
for command in git tar; do
|
|
||||||
command -v "$command" >/dev/null || fail "$command is required."
|
|
||||||
done
|
|
||||||
|
|
||||||
# Read the two pins without sourcing the file: it is data, not a script.
|
|
||||||
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)"
|
|
||||||
commit="$(pin EKKLESIA_PLATFORM_COMMIT)"
|
|
||||||
[[ "$commit" =~ ^[0-9a-f]{40}$ ]] || fail "EKKLESIA_PLATFORM_COMMIT must be a full commit SHA."
|
|
||||||
|
|
||||||
rm -rf "$out"
|
|
||||||
mkdir -p "$(dirname -- "$out")"
|
|
||||||
git init --quiet "$out"
|
|
||||||
git -C "$out" remote add origin "$repository"
|
|
||||||
git -C "$out" fetch --quiet --no-tags origin "+refs/heads/main:refs/remotes/origin/main" ||
|
|
||||||
fail "cannot fetch the platform's main from ${repository}."
|
|
||||||
git -C "$out" cat-file -e "${commit}^{commit}" 2>/dev/null ||
|
|
||||||
fail "the pinned platform commit ${commit} is not on the platform's main."
|
|
||||||
git -C "$out" merge-base --is-ancestor "$commit" refs/remotes/origin/main ||
|
|
||||||
fail "the pinned platform commit ${commit} is not on the platform's main."
|
|
||||||
git -C "$out" -c advice.detachedHead=false checkout --quiet --detach "$commit"
|
|
||||||
[[ "$(git -C "$out" rev-parse HEAD)" == "$commit" ]] || fail "the platform did not check out at ${commit}."
|
|
||||||
rm -rf "$out/.git"
|
|
||||||
echo "assemble: platform ${commit}"
|
|
||||||
|
|
||||||
[[ ! -e "$out/modules/signage" ]] || fail "the platform checkout already has modules/signage."
|
|
||||||
mkdir -p "$out/modules/signage"
|
|
||||||
# Exactly the files this checkout tracks, as committed or as changed in the working tree. Nothing
|
|
||||||
# installed, built, or ignored, and not the CI scaffolding, which is not part of the module.
|
|
||||||
git -C "$root" ls-files -z --cached --others --exclude-standard -- . ':!ci' ':!.gitea' |
|
|
||||||
tar -C "$root" --null --files-from=- --create --file=- |
|
|
||||||
tar -C "$out/modules/signage" --extract --file=-
|
|
||||||
echo "assemble: signage $(git -C "$root" rev-parse HEAD 2>/dev/null || echo "(working tree)")"
|
|
||||||
|
|
||||||
if [[ -f "$root/ci/pnpm-lock.yaml" ]]; then
|
|
||||||
cp "$root/ci/pnpm-lock.yaml" "$out/pnpm-lock.yaml"
|
|
||||||
elif ((allow_missing_lock == 0)); then
|
|
||||||
fail "ci/pnpm-lock.yaml is missing; run bash ci/update-lock.sh."
|
|
||||||
fi
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
# The platform's display-device scenarios this repository's CI runs against Signage, one per line
|
|
||||||
# (scripts/lib/deploy-smoke-display.mjs in the pinned platform). Pairing a kiosk and restarting it on
|
|
||||||
# the same profile always run first. A change that makes another scenario pass adds it here.
|
|
||||||
two-pages
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
#!/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.
|
|
||||||
#
|
|
||||||
# bash ci/integration.sh (after bash ci/assemble.sh)
|
|
||||||
set -Eeuo pipefail
|
|
||||||
|
|
||||||
root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
||||||
workspace="$root/build/workspace"
|
|
||||||
[[ -f "$workspace/deploy/Dockerfile" ]] || {
|
|
||||||
echo "integration: run bash ci/assemble.sh first." >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
image="signage-ci:${GITHUB_SHA:-local}-${GITHUB_RUN_ID:-0}-${GITHUB_RUN_ATTEMPT:-1}"
|
|
||||||
trap 'docker image rm --force "$image" >/dev/null 2>&1 || true' EXIT
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
DOCKER_BUILDKIT=1 docker build --quiet --file "$workspace/deploy/Dockerfile" --tag "$image" \
|
|
||||||
"$workspace" >/dev/null
|
|
||||||
echo "integration: built the deployment image with Signage; scenarios: ${scenarios}"
|
|
||||||
|
|
||||||
cd "$workspace"
|
|
||||||
EKKLESIA_SMOKE_TOPOLOGY=split \
|
|
||||||
EKKLESIA_SMOKE_IMAGE="$image" \
|
|
||||||
EKKLESIA_SMOKE_DISPLAY_DEVICE=1 \
|
|
||||||
EKKLESIA_SMOKE_DISPLAY_SCENARIOS="$scenarios" \
|
|
||||||
EKKLESIA_SMOKE_WATCH_MS=120000 \
|
|
||||||
EKKLESIA_SMOKE_RECYCLE_WATCH_MS=120000 \
|
|
||||||
bash scripts/smoke-deploy.sh
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
# The Ekklesia platform Signage's CI builds and tests against: one reviewed commit on the platform's
|
|
||||||
# `main`, never a moving ref. ci/assemble.sh refuses a commit that is not on `main`.
|
|
||||||
#
|
|
||||||
# Move it deliberately: change the commit, run `bash ci/update-lock.sh`, and commit both.
|
|
||||||
EKKLESIA_PLATFORM_REPOSITORY=https://git.riverofglorymn.org/River_of_Glory_Church/Ekklesia.git
|
|
||||||
EKKLESIA_PLATFORM_COMMIT=f50e8f42018c15698709739e2ba54771e97df08a
|
|
||||||
Generated
-4403
File diff suppressed because it is too large
Load Diff
@@ -1,21 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
# Regenerates ci/pnpm-lock.yaml: the lockfile of Signage assembled into the pinned platform. Run it
|
|
||||||
# after changing Signage's dependencies or ci/platform.env, and commit the result. CI installs with
|
|
||||||
# --frozen-lockfile, so a stale lockfile fails there rather than resolving anything new.
|
|
||||||
#
|
|
||||||
# bash ci/update-lock.sh
|
|
||||||
#
|
|
||||||
# Uses the platform's own pinned pnpm (its packageManager field) through Corepack.
|
|
||||||
set -Eeuo pipefail
|
|
||||||
|
|
||||||
root="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
||||||
work="$(mktemp -d)"
|
|
||||||
trap 'rm -rf "$work"' EXIT
|
|
||||||
|
|
||||||
bash "$root/ci/assemble.sh" --allow-missing-lock "$work/workspace"
|
|
||||||
cd "$work/workspace"
|
|
||||||
corepack enable >/dev/null 2>&1 || true
|
|
||||||
corepack install >/dev/null
|
|
||||||
pnpm install --lockfile-only
|
|
||||||
cp pnpm-lock.yaml "$root/ci/pnpm-lock.yaml"
|
|
||||||
echo "update-lock: wrote ci/pnpm-lock.yaml"
|
|
||||||
Reference in New Issue
Block a user