add per-layer CI scripts and Gitea workflow (not activated)
ci/*.sh — shell-only, client-side-only so `git clone && make test` works on any Linux or macOS dev box without network or shared state. One script per testing layer so both Makefile targets and the CI workflow can call them without duplicating logic. Rewrite of the existing ci/test.sh to shell out to dart + flutter layers in one pass (analyze, format, dart test, flutter test) plus five new scripts for the other layers. smoke_bundle.sh is the "tests passed but app doesn't start" gate the user flagged: builds the Linux release bundle, runs it under xvfb for 5s, fails on any non-SIGTERM exit — catches dynamic-linker errors, missing-asset regressions, plugin-init crashes that widget tests can't see. .gitea/workflows/test.yml is a four-job pipeline (unit, integration, startup-bundle, e2e) that shells out to the ci/*.sh scripts. NOT activated — Gitea Actions has to be enabled in the instance settings first. GitHub-Actions-compatible, so copying to .github/workflows/ is the whole migration if the repo moves. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Executable
+53
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env bash
|
||||
# Startup regression gate: build the Linux release bundle and run it
|
||||
# under xvfb for 5 seconds. Non-zero exit = the app crashed on boot.
|
||||
#
|
||||
# Catches: dynamic-linker errors, plugin-init failures, asset-not-bundled
|
||||
# regressions, main-isolate unhandled errors surfacing pre-first-frame.
|
||||
# These are exactly the class of regressions `make test` / widget tests
|
||||
# cannot see because they never pump the real bundle.
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
BUNDLE="app/build/linux/x64/release/bundle/clide_app"
|
||||
|
||||
echo "==> build linux release bundle"
|
||||
(cd app && flutter build linux --release)
|
||||
|
||||
if [[ ! -x "$BUNDLE" ]]; then
|
||||
echo "smoke: bundle not found at $BUNDLE" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
echo "==> launching under xvfb for 5s"
|
||||
if ! command -v xvfb-run >/dev/null 2>&1; then
|
||||
echo "smoke: xvfb-run is required (install via: apt-get install xvfb)" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# Wrap with `timeout` so a healthy daemon-less app gets SIGTERM cleanly.
|
||||
# Expected: SIGTERM (exit 143) — the app stayed up the whole time.
|
||||
# Anything else: crash.
|
||||
set +e
|
||||
xvfb-run -a -s "-screen 0 1280x720x24" timeout --signal=TERM 5 "$BUNDLE"
|
||||
exit_code=$?
|
||||
set -e
|
||||
|
||||
# `timeout` exits 124 when it sends SIGTERM + the process terminates
|
||||
# gracefully, 143 when terminated without graceful cleanup, or the
|
||||
# app's own exit code if it self-exited first.
|
||||
case $exit_code in
|
||||
124|143)
|
||||
echo "==> smoke: app stayed up for 5s, killed by timeout (healthy)"
|
||||
exit 0
|
||||
;;
|
||||
0)
|
||||
echo "==> smoke: app exited cleanly before timeout (unusual; check main.dart)" >&2
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "==> smoke: app exited with $exit_code before timeout (CRASH)" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
+16
-4
@@ -1,8 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
# CI entry: run the full test matrix. Shells out to Makefile targets.
|
||||
# Fast test layer — unit + widget + golden. Runs in <60s on a warm
|
||||
# cache. Called from `make test` and the pre-push hook.
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
make test
|
||||
make test-integration
|
||||
echo "==> dart analyze (root package)"
|
||||
dart analyze
|
||||
|
||||
echo "==> dart format (whole tree)"
|
||||
dart format --set-exit-if-changed .
|
||||
|
||||
echo "==> dart test (root package)"
|
||||
dart test
|
||||
|
||||
echo "==> flutter analyze (app)"
|
||||
(cd app && flutter analyze)
|
||||
|
||||
echo "==> flutter test (app unit + widget + golden)"
|
||||
(cd app && flutter test)
|
||||
|
||||
Executable
+8
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
# A11y contract gate — semantic coverage + keyboard traversal + WCAG
|
||||
# contrast + i18n key coverage. Runs in <5s and is part of push-check.
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
echo "==> a11y suite"
|
||||
(cd app && flutter test test/a11y/)
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
# End-to-end layer: daemon subprocess + web WASM Playwright smoke.
|
||||
# Neither fits in `make test`; together they're the "everything still
|
||||
# works across process/runtime boundaries" gate.
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
echo "==> build bin/clide (required by daemon subprocess test)"
|
||||
make build
|
||||
|
||||
echo "==> daemon subprocess test"
|
||||
dart test test/daemon/
|
||||
|
||||
echo "==> browser WASM smoke (Playwright)"
|
||||
./tools/ui/build.sh
|
||||
./tools/ui/serve.sh
|
||||
trap './tools/ui/stop.sh >/dev/null 2>&1' EXIT
|
||||
(cd tools/ui && npx playwright test smoke.spec.ts)
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
# integration_test suite — the load-bearing "tests pass but app doesn't
|
||||
# start" regression gate. Flutter integration tests prefer one file at
|
||||
# a time on desktop; we iterate to avoid the "Unable to start the app"
|
||||
# error that hits when they run as a batch.
|
||||
set -euo pipefail
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
cd app
|
||||
for f in integration_test/*_test.dart; do
|
||||
echo "==> integration_test: $f"
|
||||
flutter test "$f"
|
||||
done
|
||||
Reference in New Issue
Block a user