mirror of
https://github.com/kuhyx/diet-guard.git
synced 2026-11-10 17:47:20 +01:00
ci: split ci-mirror into <60s gate steps
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
file-length / file length <= 250 lines (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Waiting to run
Tests / test (push) Waiting to run
release-apk / release (APK) (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
file-length / file length <= 250 lines (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Waiting to run
Tests / test (push) Waiting to run
release-apk / release (APK) (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WzxdWXTUM9dpnCS2wtFkx4
This commit is contained in:
parent
1b5e201136
commit
3960fb8ca0
@ -132,9 +132,82 @@ repos:
|
||||
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: ci-mirror
|
||||
name: CI mirror (clean-venv pytest + pre-commit --all-files)
|
||||
entry: bash scripts/ci_mirror.sh
|
||||
# Split into <60 s steps (run in this order); no-arg ci_mirror.sh is the CI form.
|
||||
- id: ci-mirror-venv
|
||||
name: CI mirror 1 (clean venv)
|
||||
entry: bash scripts/ci_mirror.sh venv
|
||||
language: system
|
||||
pass_filenames: false
|
||||
always_run: true
|
||||
require_serial: true
|
||||
stages: [manual]
|
||||
- id: ci-mirror-precommit
|
||||
name: CI mirror 2 (pre-commit --all-files)
|
||||
entry: bash scripts/ci_mirror.sh precommit
|
||||
language: system
|
||||
pass_filenames: false
|
||||
always_run: true
|
||||
require_serial: true
|
||||
stages: [manual]
|
||||
- id: ci-mirror-pytest
|
||||
name: CI mirror 3 (pytest, xvfb, 100% cov)
|
||||
entry: bash scripts/ci_mirror.sh pytest
|
||||
language: system
|
||||
pass_filenames: false
|
||||
always_run: true
|
||||
require_serial: true
|
||||
stages: [manual]
|
||||
- id: ci-mirror-flutter-analyze
|
||||
name: CI mirror 4 (flutter analyze)
|
||||
entry: bash scripts/ci_mirror.sh flutter-analyze
|
||||
language: system
|
||||
pass_filenames: false
|
||||
always_run: true
|
||||
require_serial: true
|
||||
stages: [manual]
|
||||
- id: ci-mirror-flutter-test-1
|
||||
name: CI mirror 5 (flutter test 1/6)
|
||||
entry: bash scripts/ci_mirror.sh flutter-test --shard 0/6
|
||||
language: system
|
||||
pass_filenames: false
|
||||
always_run: true
|
||||
require_serial: true
|
||||
stages: [manual]
|
||||
- id: ci-mirror-flutter-test-2
|
||||
name: CI mirror 6 (flutter test 2/6)
|
||||
entry: bash scripts/ci_mirror.sh flutter-test --shard 1/6
|
||||
language: system
|
||||
pass_filenames: false
|
||||
always_run: true
|
||||
require_serial: true
|
||||
stages: [manual]
|
||||
- id: ci-mirror-flutter-test-3
|
||||
name: CI mirror 7 (flutter test 3/6)
|
||||
entry: bash scripts/ci_mirror.sh flutter-test --shard 2/6
|
||||
language: system
|
||||
pass_filenames: false
|
||||
always_run: true
|
||||
require_serial: true
|
||||
stages: [manual]
|
||||
- id: ci-mirror-flutter-test-4
|
||||
name: CI mirror 8 (flutter test 4/6)
|
||||
entry: bash scripts/ci_mirror.sh flutter-test --shard 3/6
|
||||
language: system
|
||||
pass_filenames: false
|
||||
always_run: true
|
||||
require_serial: true
|
||||
stages: [manual]
|
||||
- id: ci-mirror-flutter-test-5
|
||||
name: CI mirror 9 (flutter test 5/6)
|
||||
entry: bash scripts/ci_mirror.sh flutter-test --shard 4/6
|
||||
language: system
|
||||
pass_filenames: false
|
||||
always_run: true
|
||||
require_serial: true
|
||||
stages: [manual]
|
||||
- id: ci-mirror-flutter-test-6
|
||||
name: CI mirror 10 (flutter test 6/6)
|
||||
entry: bash scripts/ci_mirror.sh flutter-test --shard 5/6
|
||||
language: system
|
||||
pass_filenames: false
|
||||
always_run: true
|
||||
|
||||
@ -2,7 +2,7 @@ name: diet_guard_app
|
||||
description: "Companion phone app for diet_guard: log meals on the go."
|
||||
publish_to: 'none'
|
||||
|
||||
version: 1.0.125+1
|
||||
version: 1.0.126+1
|
||||
|
||||
environment:
|
||||
sdk: ^3.12.2
|
||||
|
||||
@ -119,27 +119,79 @@ flutter_clean_env() {
|
||||
# hooks) then the full test suite. Deliberately fails rather than skips when
|
||||
# flutter is missing -- a gate that quietly passes on a machine without the
|
||||
# toolchain is the same as no gate.
|
||||
run_flutter_gates() {
|
||||
require_app() {
|
||||
if [[ ! -f "$APP_DIR/pubspec.yaml" ]]; then
|
||||
log "no app/pubspec.yaml — skipping the Flutter gates"
|
||||
return
|
||||
return 1
|
||||
fi
|
||||
if ! command -v flutter >/dev/null 2>&1; then
|
||||
fail "flutter is not on PATH but app/ exists (cannot verify the app)"
|
||||
fi
|
||||
}
|
||||
|
||||
run_flutter_analyze() {
|
||||
require_app || return 0
|
||||
log "flutter analyze (app/)"
|
||||
(cd "$APP_DIR" && flutter_clean_env analyze) || fail "flutter analyze"
|
||||
}
|
||||
|
||||
run_flutter_test() {
|
||||
require_app || return 0
|
||||
log "flutter test (app/)"
|
||||
(cd "$APP_DIR" && flutter_clean_env test) || fail "flutter test"
|
||||
}
|
||||
|
||||
run_flutter_gates() {
|
||||
run_flutter_analyze
|
||||
run_flutter_test
|
||||
}
|
||||
|
||||
# Bucket I of N of the app's test files (every N-th, sorted), so the N buckets
|
||||
# partition the suite exactly. Each bucket stays under the 60 s action cap.
|
||||
run_flutter_test_shard() {
|
||||
[[ ${1:-} =~ ^([0-9]+)/([1-9][0-9]*)$ ]] || fail "flutter-test --shard wants I/N, got '${1:-}'"
|
||||
local index=${BASH_REMATCH[1]} total=${BASH_REMATCH[2]} hooks i=0 file
|
||||
local -a files=()
|
||||
hooks="$(grep -c '^ - id: ci-mirror-flutter-test-[0-9]' "$ROOT/.pre-commit-config.yaml" || true)"
|
||||
((total == hooks && index < total)) \
|
||||
|| fail "shard $index/$total does not match the $hooks ci-mirror-flutter-test-N hooks"
|
||||
require_app || return 0
|
||||
while IFS= read -r file; do
|
||||
if ((i % total == index)); then
|
||||
files+=("${file#"$APP_DIR"/}")
|
||||
fi
|
||||
i=$((i + 1))
|
||||
done < <(find "$APP_DIR/test" -name '*_test.dart' | LC_ALL=C sort)
|
||||
((${#files[@]} > 0)) || fail "flutter test shard $index/$total has no test files"
|
||||
log "flutter test shard $index/$total (${#files[@]} files)"
|
||||
(cd "$APP_DIR" && flutter_clean_env test "${files[@]}") || fail "flutter test shard $index/$total"
|
||||
}
|
||||
|
||||
# No phase argument (or pytest options) runs everything, exactly as CI does.
|
||||
main() {
|
||||
require_file
|
||||
ensure_venv
|
||||
run_precommit_all_files
|
||||
run_pytest_clean_venv "$@"
|
||||
run_flutter_gates
|
||||
log "all CI gates passed locally — safe to push"
|
||||
case "${1:-all}" in
|
||||
venv) ensure_venv ;;
|
||||
precommit) run_precommit_all_files ;;
|
||||
pytest)
|
||||
shift
|
||||
ensure_venv
|
||||
run_pytest_clean_venv "$@"
|
||||
;;
|
||||
flutter-analyze) run_flutter_analyze ;;
|
||||
flutter-test)
|
||||
[[ "${2:-}" == "--shard" ]] || fail "usage: ci_mirror.sh flutter-test --shard I/N"
|
||||
run_flutter_test_shard "${3:-}"
|
||||
;;
|
||||
*)
|
||||
[[ "${1:-}" == "all" ]] && shift
|
||||
ensure_venv
|
||||
run_precommit_all_files
|
||||
run_pytest_clean_venv "$@"
|
||||
run_flutter_gates
|
||||
;;
|
||||
esac
|
||||
log "gates passed locally — safe to push"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user