@@ -7,13 +7,21 @@ has_script() {
77 [ -f package.json ] && node -e ' const p=require("./package.json"); process.exit(p.scripts?.[process.argv[1]] ? 0 : 1)' " $1 "
88}
99
10+ has_bun_native_coverage () {
11+ [ -f package.json ] && node -e ' const p=require("./package.json"); process.exit(p.scripts?.["test:coverage"]?.includes("bun test") ? 0 : 1)'
12+ }
13+
1014has_javascript () {
1115 git ls-files -- ' *.js' ' *.jsx' ' *.ts' ' *.tsx' | grep -q .
1216}
1317
1418has_python () {
1519 [ -f pyproject.toml ] || [ -f requirements.txt ] || [ -f requirements-dev.txt ] || \
16- git ls-files -- ' *.py' | grep -q .
20+ git ls-files -- ' *.py' ' :!.github/**' | grep -q .
21+ }
22+
23+ has_graph_project () {
24+ [ -f package.json ] && node -e ' const p=require("./package.json"); process.exit(p.devDependencies?.["@graphprotocol/graph-cli"] ? 0 : 1)'
1725}
1826
1927package_manager () {
@@ -44,6 +52,45 @@ run_package_tool() {
4452 esac
4553}
4654
55+ run_bun_coverage () {
56+ local log_file coverage_line functions lines minimum
57+ log_file=" $( mktemp) "
58+ if ! run_script test:coverage 2>&1 | tee " $log_file " ; then
59+ rm -f " $log_file "
60+ return 1
61+ fi
62+ coverage_line=" $( grep -E ' ^All files[[:space:]]*\|' " $log_file " | tail -n 1 || true) "
63+ if [ -z " $coverage_line " ]; then
64+ echo " Coverage summary not found in test:coverage output" >&2
65+ rm -f " $log_file "
66+ return 1
67+ fi
68+ functions=" $( printf ' %s\n' " $coverage_line " | awk -F' |' ' {gsub(/[[:space:]]/, "", $4); print $4}' ) "
69+ lines=" $( printf ' %s\n' " $coverage_line " | awk -F' |' ' {gsub(/[[:space:]]/, "", $5); print $5}' ) "
70+ minimum=" ${BUN_COVERAGE_MIN:- 80} "
71+ if ! awk -v functions=" $functions " -v lines=" $lines " -v minimum=" $minimum " \
72+ ' BEGIN { exit !(functions + 0 >= minimum && lines + 0 >= minimum) }' ; then
73+ echo " Coverage below ${minimum} %: functions=${functions} % lines=${lines} %" >&2
74+ rm -f " $log_file "
75+ return 1
76+ fi
77+ echo " Coverage threshold passed: functions=${functions} % lines=${lines} % (minimum ${minimum} %)"
78+ rm -f " $log_file "
79+ }
80+
81+ python_coverage_args () {
82+ if [ -f pyproject.toml ]; then
83+ python - << 'PY '
84+ import tomllib
85+ from pathlib import Path
86+
87+ config = tomllib.loads(Path("pyproject.toml").read_text())
88+ for source in config.get("tool", {}).get("coverage", {}).get("run", {}).get("source", []):
89+ print(f"--cov={source}")
90+ PY
91+ fi
92+ }
93+
4794install () {
4895 if [ -f package.json ]; then
4996 case " $( package_manager) " in
@@ -67,6 +114,12 @@ rust_component() {
67114 fi
68115}
69116
117+ has_rust_target () {
118+ local kind=" $1 "
119+ cargo metadata --no-deps --format-version 1 |
120+ jq -e --arg kind " $kind " ' any(.packages[].targets[]; (.kind | index($kind)) != null)' > /dev/null
121+ }
122+
70123format () {
71124 if has_script format:check; then run_script format:check
72125 elif has_javascript; then run_package_tool prettier --check .
@@ -84,7 +137,9 @@ lint() {
84137}
85138
86139type_check () {
87- if has_script type-check; then run_script type-check
140+ if has_graph_project; then
141+ echo " Skipping TypeScript type-check (Graph AssemblyScript project uses graph build/codegen)"
142+ elif has_script type-check; then run_script type-check
88143 elif has_script typecheck; then run_script typecheck
89144 else echo " Skipping type-check (script not defined)" ; fi
90145 if [ -f Cargo.toml ]; then cargo check; fi
@@ -95,25 +150,47 @@ type_check() {
95150 fi
96151}
97152
98- build () { run_script build; }
153+ build () {
154+ # Some frameworks validate session secrets while statically collecting pages.
155+ # Keep CI builds deterministic without weakening runtime/deployment validation.
156+ if [ " ${CI:- } " = true ] && [ -z " ${NEXTAUTH_SECRET:- } " ]; then
157+ export NEXTAUTH_SECRET=" ci-only-build-secret-not-for-runtime-0123456789"
158+ fi
159+ run_script build
160+ if [ -f Cargo.toml ]; then cargo build --all-targets --all-features; fi
161+ }
99162
100163unit () {
101164 # Bun repositories should expose test scripts backed by Bun's native runner.
102165 # Specialized repositories may keep their native runner (for example Matchstick or Hardhat).
103166 if has_script test:unit; then
104167 run_script test:unit
105168 elif has_script test:coverage; then
106- run_script test:coverage
169+ if [ " $( package_manager) " = bun ] && has_bun_native_coverage; then
170+ run_bun_coverage
171+ else
172+ run_script test:coverage
173+ fi
107174 elif has_script test && ! has_script test:integration; then
108175 run_script test
109176 else
110177 echo " Skipping JavaScript/TypeScript unit tests (script not defined)"
111178 fi
112- if [ -f Cargo.toml ]; then cargo test --lib --all-features; fi
179+ if [ -f Cargo.toml ]; then
180+ if has_rust_target lib; then cargo test --lib --all-features
181+ elif has_rust_target bin; then cargo test --bins --all-features
182+ else echo " Skipping Rust unit tests (no library or binary target)" ; fi
183+ fi
113184 if [ -d tests/unit ] && python -c ' import importlib.util; raise SystemExit(importlib.util.find_spec("pytest") is None)' 2> /dev/null; then
114- python -m pytest -q tests/unit --cov --cov-report=term-missing
185+ coverage_args=()
186+ while IFS= read -r arg; do [ -n " $arg " ] && coverage_args+=(" $arg " ); done < <( python_coverage_args)
187+ [ " ${# coverage_args[@]} " -gt 0 ] || coverage_args=(--cov)
188+ env -u MISE_GITHUB_TOKEN -u MISE_TRUSTED_CONFIG_PATHS -u MISE_YES -u MISE_LOG_LEVEL -u PYTHONHOME PYTHONPATH=" $PWD /.github/scripts" python -m pytest -q tests/unit " ${coverage_args[@]} " --cov-report=term-missing --cov-fail-under=" ${PYTHON_COVERAGE_MIN:- 80} "
115189 elif [ -d tests ] && [ ! -d tests/integration ] && python -c ' import importlib.util; raise SystemExit(importlib.util.find_spec("pytest") is None)' 2> /dev/null; then
116- python -m pytest -q tests --cov --cov-report=term-missing
190+ coverage_args=()
191+ while IFS= read -r arg; do [ -n " $arg " ] && coverage_args+=(" $arg " ); done < <( python_coverage_args)
192+ [ " ${# coverage_args[@]} " -gt 0 ] || coverage_args=(--cov)
193+ env -u MISE_GITHUB_TOKEN -u MISE_TRUSTED_CONFIG_PATHS -u MISE_YES -u MISE_LOG_LEVEL -u PYTHONHOME PYTHONPATH=" $PWD /.github/scripts" python -m pytest -q tests " ${coverage_args[@]} " --cov-report=term-missing --cov-fail-under=" ${PYTHON_COVERAGE_MIN:- 80} "
117194 else
118195 echo " Skipping Python unit tests (no unit suite detected)"
119196 fi
0 commit comments