feat(ci): add Flutter CI/CD pipeline for Forgejo Actions (Stage 4C)
Add Forgejo Actions workflows for automated Flutter validation on PRs: - flutter-analyze.yml: runs dart analyze --fatal-infos on all 8 packages/apps - flutter-test.yml: runs flutter test per package with pass/fail reporting - Aggregate test result summary table in workflow output - Workflows trigger on PRs to main and all non-main branch pushes - Uses ghcr.io/cirruslabs/flutter:stable container image Populate tools/ directory with CI helper scripts: - run_all_tests.sh: local test runner with optional --analyze flag - README.md: documents scripts and CI workflow inventory Validated locally: - dart analyze: all 8 packages/apps clean (no issues) - core: 20/20 tests passed - design_system: 41/41 tests passed - feature_wordpress: 294/294 tests passed - kell_web: 24/24 tests passed - Total: 379/379 tests passed
This commit is contained in:
parent
0a0abc2c3d
commit
b00072474b
|
|
@ -0,0 +1,77 @@
|
||||||
|
name: Flutter Analyze
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "**"
|
||||||
|
- "!main"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
analyze:
|
||||||
|
name: Dart Analyze
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: ghcr.io/cirruslabs/flutter:stable
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: kell_creations_apps
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install dependencies — core
|
||||||
|
run: cd packages/core && flutter pub get
|
||||||
|
|
||||||
|
- name: Install dependencies — design_system
|
||||||
|
run: cd packages/design_system && flutter pub get
|
||||||
|
|
||||||
|
- name: Install dependencies — feature_wordpress
|
||||||
|
run: cd packages/feature_wordpress && flutter pub get
|
||||||
|
|
||||||
|
- name: Install dependencies — feature_inventory
|
||||||
|
run: cd packages/feature_inventory && flutter pub get
|
||||||
|
|
||||||
|
- name: Install dependencies — feature_orders
|
||||||
|
run: cd packages/feature_orders && flutter pub get
|
||||||
|
|
||||||
|
- name: Install dependencies — feature_policy
|
||||||
|
run: cd packages/feature_policy && flutter pub get
|
||||||
|
|
||||||
|
- name: Install dependencies — kell_web
|
||||||
|
run: cd apps/kell_web && flutter pub get
|
||||||
|
|
||||||
|
- name: Install dependencies — kell_mobile
|
||||||
|
run: cd apps/kell_mobile && flutter pub get
|
||||||
|
|
||||||
|
- name: Analyze — core
|
||||||
|
run: cd packages/core && dart analyze --fatal-infos
|
||||||
|
|
||||||
|
- name: Analyze — design_system
|
||||||
|
run: cd packages/design_system && dart analyze --fatal-infos
|
||||||
|
|
||||||
|
- name: Analyze — feature_wordpress
|
||||||
|
run: cd packages/feature_wordpress && dart analyze --fatal-infos
|
||||||
|
|
||||||
|
- name: Analyze — feature_inventory
|
||||||
|
run: cd packages/feature_inventory && dart analyze --fatal-infos
|
||||||
|
|
||||||
|
- name: Analyze — feature_orders
|
||||||
|
run: cd packages/feature_orders && dart analyze --fatal-infos
|
||||||
|
|
||||||
|
- name: Analyze — feature_policy
|
||||||
|
run: cd packages/feature_policy && dart analyze --fatal-infos
|
||||||
|
|
||||||
|
- name: Analyze — kell_web
|
||||||
|
run: cd apps/kell_web && dart analyze --fatal-infos
|
||||||
|
|
||||||
|
- name: Analyze — kell_mobile
|
||||||
|
run: cd apps/kell_mobile && dart analyze --fatal-infos
|
||||||
|
|
||||||
|
- name: Summary
|
||||||
|
if: always()
|
||||||
|
run: echo "✅ Dart analyze completed for all packages and apps"
|
||||||
|
|
@ -0,0 +1,127 @@
|
||||||
|
name: Flutter Test
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- "**"
|
||||||
|
- "!main"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
name: Flutter Tests
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: ghcr.io/cirruslabs/flutter:stable
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: kell_creations_apps
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Install dependencies — core
|
||||||
|
run: cd packages/core && flutter pub get
|
||||||
|
|
||||||
|
- name: Install dependencies — design_system
|
||||||
|
run: cd packages/design_system && flutter pub get
|
||||||
|
|
||||||
|
- name: Install dependencies — feature_wordpress
|
||||||
|
run: cd packages/feature_wordpress && flutter pub get
|
||||||
|
|
||||||
|
- name: Install dependencies — kell_web
|
||||||
|
run: cd apps/kell_web && flutter pub get
|
||||||
|
|
||||||
|
- name: Test — core
|
||||||
|
run: |
|
||||||
|
cd packages/core
|
||||||
|
flutter test --reporter expanded 2>&1 | tee test_output.txt
|
||||||
|
echo ""
|
||||||
|
echo "=== core test summary ==="
|
||||||
|
TOTAL=$(grep -cE '^\s*✓' test_output.txt || echo "0")
|
||||||
|
FAILED=$(grep -cE '^\s*✗' test_output.txt || echo "0")
|
||||||
|
echo " Passed: $TOTAL"
|
||||||
|
echo " Failed: $FAILED"
|
||||||
|
# Fail the step if any tests failed
|
||||||
|
if [ "$FAILED" -gt 0 ]; then exit 1; fi
|
||||||
|
|
||||||
|
- name: Test — design_system
|
||||||
|
run: |
|
||||||
|
cd packages/design_system
|
||||||
|
flutter test --reporter expanded 2>&1 | tee test_output.txt
|
||||||
|
echo ""
|
||||||
|
echo "=== design_system test summary ==="
|
||||||
|
TOTAL=$(grep -cE '^\s*✓' test_output.txt || echo "0")
|
||||||
|
FAILED=$(grep -cE '^\s*✗' test_output.txt || echo "0")
|
||||||
|
echo " Passed: $TOTAL"
|
||||||
|
echo " Failed: $FAILED"
|
||||||
|
if [ "$FAILED" -gt 0 ]; then exit 1; fi
|
||||||
|
|
||||||
|
- name: Test — feature_wordpress
|
||||||
|
run: |
|
||||||
|
cd packages/feature_wordpress
|
||||||
|
flutter test --reporter expanded 2>&1 | tee test_output.txt
|
||||||
|
echo ""
|
||||||
|
echo "=== feature_wordpress test summary ==="
|
||||||
|
TOTAL=$(grep -cE '^\s*✓' test_output.txt || echo "0")
|
||||||
|
FAILED=$(grep -cE '^\s*✗' test_output.txt || echo "0")
|
||||||
|
echo " Passed: $TOTAL"
|
||||||
|
echo " Failed: $FAILED"
|
||||||
|
if [ "$FAILED" -gt 0 ]; then exit 1; fi
|
||||||
|
|
||||||
|
- name: Test — kell_web
|
||||||
|
run: |
|
||||||
|
cd apps/kell_web
|
||||||
|
flutter test --reporter expanded 2>&1 | tee test_output.txt
|
||||||
|
echo ""
|
||||||
|
echo "=== kell_web test summary ==="
|
||||||
|
TOTAL=$(grep -cE '^\s*✓' test_output.txt || echo "0")
|
||||||
|
FAILED=$(grep -cE '^\s*✗' test_output.txt || echo "0")
|
||||||
|
echo " Passed: $TOTAL"
|
||||||
|
echo " Failed: $FAILED"
|
||||||
|
if [ "$FAILED" -gt 0 ]; then exit 1; fi
|
||||||
|
|
||||||
|
- name: Aggregate test report
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
echo ""
|
||||||
|
echo "╔══════════════════════════════════════╗"
|
||||||
|
echo "║ Flutter Test Results Summary ║"
|
||||||
|
echo "╠══════════════════════════════════════╣"
|
||||||
|
echo "║ Package Pass Fail ║"
|
||||||
|
echo "╠══════════════════════════════════════╣"
|
||||||
|
|
||||||
|
TOTAL_PASS=0
|
||||||
|
TOTAL_FAIL=0
|
||||||
|
|
||||||
|
for pkg in packages/core packages/design_system packages/feature_wordpress apps/kell_web; do
|
||||||
|
NAME=$(basename "$pkg")
|
||||||
|
OUTPUT="$pkg/test_output.txt"
|
||||||
|
if [ -f "$OUTPUT" ]; then
|
||||||
|
PASS=$(grep -cE '^\s*✓' "$OUTPUT" || echo "0")
|
||||||
|
FAIL=$(grep -cE '^\s*✗' "$OUTPUT" || echo "0")
|
||||||
|
else
|
||||||
|
PASS="—"
|
||||||
|
FAIL="—"
|
||||||
|
fi
|
||||||
|
printf "║ %-20s %-7s %-7s ║\n" "$NAME" "$PASS" "$FAIL"
|
||||||
|
if [ "$PASS" != "—" ]; then TOTAL_PASS=$((TOTAL_PASS + PASS)); fi
|
||||||
|
if [ "$FAIL" != "—" ]; then TOTAL_FAIL=$((TOTAL_FAIL + FAIL)); fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "╠══════════════════════════════════════╣"
|
||||||
|
printf "║ %-20s %-7s %-7s ║\n" "TOTAL" "$TOTAL_PASS" "$TOTAL_FAIL"
|
||||||
|
echo "╚══════════════════════════════════════╝"
|
||||||
|
|
||||||
|
if [ "$TOTAL_FAIL" -gt 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo "❌ Some tests failed. See individual package results above."
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo ""
|
||||||
|
echo "✅ All $TOTAL_PASS tests passed across all packages."
|
||||||
|
fi
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
# Tools
|
||||||
|
|
||||||
|
CI/CD helper scripts for the Kell Creations Flutter monorepo.
|
||||||
|
|
||||||
|
## Scripts
|
||||||
|
|
||||||
|
### `run_all_tests.sh`
|
||||||
|
|
||||||
|
Runs `flutter test` across all testable packages and apps, producing a per-package pass/fail summary.
|
||||||
|
|
||||||
|
**Usage:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# From kell_creations_apps/ directory
|
||||||
|
./tools/run_all_tests.sh # Run tests only
|
||||||
|
./tools/run_all_tests.sh --analyze # Run dart analyze + tests
|
||||||
|
```
|
||||||
|
|
||||||
|
**What it does:**
|
||||||
|
|
||||||
|
1. Installs dependencies (`flutter pub get`) for all packages and apps.
|
||||||
|
2. Optionally runs `dart analyze --fatal-infos` on each package/app.
|
||||||
|
3. Runs `flutter test --reporter expanded` for packages with tests.
|
||||||
|
4. Prints an aggregate pass/fail summary table.
|
||||||
|
|
||||||
|
**Adding new packages:**
|
||||||
|
|
||||||
|
When a new package gains tests, add its path to the `TESTABLE` array in the script. For packages that should be analyzed but have no tests yet, add to the `ANALYZABLE` array only.
|
||||||
|
|
||||||
|
**Exit codes:**
|
||||||
|
|
||||||
|
- `0` — all tests passed (and analyze clean, if `--analyze` was used)
|
||||||
|
- `1` — one or more failures detected
|
||||||
|
|
||||||
|
## CI Workflows
|
||||||
|
|
||||||
|
The corresponding Forgejo Actions workflows live in `.forgejo/workflows/`:
|
||||||
|
|
||||||
|
| Workflow | Trigger | Purpose |
|
||||||
|
| --------------------- | ----------------- | -------------------------------------------- |
|
||||||
|
| `flutter-analyze.yml` | PRs and branches | Runs `dart analyze` on all packages and apps |
|
||||||
|
| `flutter-test.yml` | PRs and branches | Runs `flutter test` with result reporting |
|
||||||
|
| `validate-docs.yml` | Non-main branches | Validates MkDocs documentation build |
|
||||||
|
| `publish-docs.yml` | Push to main | Publishes documentation to docs host |
|
||||||
|
|
@ -0,0 +1,147 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# ──────────────────────────────────────────────────────────────────────
|
||||||
|
# run_all_tests.sh — Run flutter test for all testable packages and apps
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./tools/run_all_tests.sh # Run from kell_creations_apps/
|
||||||
|
# ./tools/run_all_tests.sh --analyze # Also run dart analyze first
|
||||||
|
#
|
||||||
|
# Exit codes:
|
||||||
|
# 0 — all tests passed (and analyze clean, if requested)
|
||||||
|
# 1 — one or more failures
|
||||||
|
# ──────────────────────────────────────────────────────────────────────
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||||
|
|
||||||
|
# Packages/apps with tests (add new ones here as they gain tests)
|
||||||
|
TESTABLE=(
|
||||||
|
packages/core
|
||||||
|
packages/design_system
|
||||||
|
packages/feature_wordpress
|
||||||
|
apps/kell_web
|
||||||
|
)
|
||||||
|
|
||||||
|
# All packages/apps to analyze (includes those without tests)
|
||||||
|
ANALYZABLE=(
|
||||||
|
packages/core
|
||||||
|
packages/design_system
|
||||||
|
packages/feature_wordpress
|
||||||
|
packages/feature_inventory
|
||||||
|
packages/feature_orders
|
||||||
|
packages/feature_policy
|
||||||
|
apps/kell_web
|
||||||
|
apps/kell_mobile
|
||||||
|
)
|
||||||
|
|
||||||
|
RUN_ANALYZE=false
|
||||||
|
if [[ "${1:-}" == "--analyze" ]]; then
|
||||||
|
RUN_ANALYZE=true
|
||||||
|
fi
|
||||||
|
|
||||||
|
OVERALL_EXIT=0
|
||||||
|
|
||||||
|
# ── Dependency install ───────────────────────────────────────────────
|
||||||
|
echo ""
|
||||||
|
echo "══════════════════════════════════════"
|
||||||
|
echo " Installing dependencies"
|
||||||
|
echo "══════════════════════════════════════"
|
||||||
|
|
||||||
|
for pkg in "${ANALYZABLE[@]}"; do
|
||||||
|
echo " → $pkg"
|
||||||
|
(cd "$ROOT_DIR/$pkg" && flutter pub get --no-example) > /dev/null 2>&1
|
||||||
|
done
|
||||||
|
|
||||||
|
# ── Analyze (optional) ──────────────────────────────────────────────
|
||||||
|
if $RUN_ANALYZE; then
|
||||||
|
echo ""
|
||||||
|
echo "══════════════════════════════════════"
|
||||||
|
echo " Running dart analyze"
|
||||||
|
echo "══════════════════════════════════════"
|
||||||
|
|
||||||
|
ANALYZE_FAILURES=()
|
||||||
|
for pkg in "${ANALYZABLE[@]}"; do
|
||||||
|
NAME=$(basename "$pkg")
|
||||||
|
printf " %-25s" "$NAME"
|
||||||
|
if (cd "$ROOT_DIR/$pkg" && dart analyze --fatal-infos) > /dev/null 2>&1; then
|
||||||
|
echo "✅ clean"
|
||||||
|
else
|
||||||
|
echo "❌ issues found"
|
||||||
|
ANALYZE_FAILURES+=("$NAME")
|
||||||
|
OVERALL_EXIT=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ${#ANALYZE_FAILURES[@]} -gt 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo " ❌ Analyze failures: ${ANALYZE_FAILURES[*]}"
|
||||||
|
else
|
||||||
|
echo ""
|
||||||
|
echo " ✅ All packages analyze clean"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ── Tests ────────────────────────────────────────────────────────────
|
||||||
|
echo ""
|
||||||
|
echo "══════════════════════════════════════"
|
||||||
|
echo " Running flutter test"
|
||||||
|
echo "══════════════════════════════════════"
|
||||||
|
|
||||||
|
declare -A RESULTS_PASS
|
||||||
|
declare -A RESULTS_FAIL
|
||||||
|
TEST_FAILURES=()
|
||||||
|
|
||||||
|
for pkg in "${TESTABLE[@]}"; do
|
||||||
|
NAME=$(basename "$pkg")
|
||||||
|
echo ""
|
||||||
|
echo " ── $NAME ──"
|
||||||
|
|
||||||
|
TMPFILE=$(mktemp)
|
||||||
|
if (cd "$ROOT_DIR/$pkg" && flutter test --reporter expanded 2>&1) | tee "$TMPFILE"; then
|
||||||
|
: # tests passed
|
||||||
|
else
|
||||||
|
TEST_FAILURES+=("$NAME")
|
||||||
|
OVERALL_EXIT=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
PASS=$(grep -cE '^\s*✓' "$TMPFILE" 2>/dev/null || echo "0")
|
||||||
|
FAIL=$(grep -cE '^\s*✗' "$TMPFILE" 2>/dev/null || echo "0")
|
||||||
|
RESULTS_PASS[$NAME]=$PASS
|
||||||
|
RESULTS_FAIL[$NAME]=$FAIL
|
||||||
|
rm -f "$TMPFILE"
|
||||||
|
done
|
||||||
|
|
||||||
|
# ── Summary ──────────────────────────────────────────────────────────
|
||||||
|
echo ""
|
||||||
|
echo "╔══════════════════════════════════════╗"
|
||||||
|
echo "║ Flutter Test Results Summary ║"
|
||||||
|
echo "╠══════════════════════════════════════╣"
|
||||||
|
echo "║ Package Pass Fail ║"
|
||||||
|
echo "╠══════════════════════════════════════╣"
|
||||||
|
|
||||||
|
TOTAL_PASS=0
|
||||||
|
TOTAL_FAIL=0
|
||||||
|
|
||||||
|
for pkg in "${TESTABLE[@]}"; do
|
||||||
|
NAME=$(basename "$pkg")
|
||||||
|
P=${RESULTS_PASS[$NAME]:-0}
|
||||||
|
F=${RESULTS_FAIL[$NAME]:-0}
|
||||||
|
printf "║ %-20s %-7s %-7s ║\n" "$NAME" "$P" "$F"
|
||||||
|
TOTAL_PASS=$((TOTAL_PASS + P))
|
||||||
|
TOTAL_FAIL=$((TOTAL_FAIL + F))
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "╠══════════════════════════════════════╣"
|
||||||
|
printf "║ %-20s %-7s %-7s ║\n" "TOTAL" "$TOTAL_PASS" "$TOTAL_FAIL"
|
||||||
|
echo "╚══════════════════════════════════════╝"
|
||||||
|
|
||||||
|
if [ $OVERALL_EXIT -ne 0 ]; then
|
||||||
|
echo ""
|
||||||
|
echo "❌ Failures detected. See details above."
|
||||||
|
else
|
||||||
|
echo ""
|
||||||
|
echo "✅ All $TOTAL_PASS tests passed across all packages."
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit $OVERALL_EXIT
|
||||||
Loading…
Reference in New Issue