Files

172 lines
3.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# ci-local.sh — Run augur CI quality gates locally.
# Mirrors .github/workflows/ci-quality-gates.yml without GitHub-hosted runners.
set -euo pipefail
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$REPO_ROOT"
run_contracts=false
run_backend=false
run_extensions=false
explicit_stage=false
skip_install=false
declare -a suites=()
declare -a default_suites=(
"tests"
"tests-copilot"
"tests-deepseek"
"tests-perplexity"
"tests-grok"
"tests-poe"
)
usage() {
cat <<'EOF'
Usage: ./scripts/ci-local.sh [options]
Runs local CI gates equivalent to .github/workflows/ci-quality-gates.yml:
1) contracts -> scripts/check-contract-drift.sh
2) backend -> go mod download, go vet ./..., go test ./... -count=1
3) extensions -> npm ci + npm test in each extension test suite
If no stage options are provided, all stages run.
Options:
--contracts Run contracts drift check stage
--backend Run backend Go stage
--extensions Run extension Jest stage
--suite NAME Extension suite name (repeatable), e.g. tests-deepseek
--skip-install Skip dependency install steps (go mod download, npm ci)
-h, --help Show this help
Examples:
./scripts/ci-local.sh
./scripts/ci-local.sh --backend
./scripts/ci-local.sh --extensions --suite tests --suite tests-copilot
./scripts/ci-local.sh --contracts --backend --skip-install
EOF
}
log() {
printf '[ci-local] %s\n' "$*"
}
die() {
printf '[ci-local] ERROR: %s\n' "$*" >&2
exit 1
}
require_cmd() {
local cmd="$1"
command -v "$cmd" >/dev/null 2>&1 || die "required command not found: $cmd"
}
parse_args() {
while [[ $# -gt 0 ]]; do
case "$1" in
--contracts)
explicit_stage=true
run_contracts=true
shift
;;
--backend)
explicit_stage=true
run_backend=true
shift
;;
--extensions)
explicit_stage=true
run_extensions=true
shift
;;
--suite)
shift
[[ $# -gt 0 ]] || die "--suite requires a value"
suites+=("$1")
shift
;;
--skip-install)
skip_install=true
shift
;;
-h|--help)
usage
exit 0
;;
*)
die "unknown argument: $1"
;;
esac
done
if [[ "$explicit_stage" == false ]]; then
run_contracts=true
run_backend=true
run_extensions=true
fi
if [[ "${#suites[@]}" -eq 0 ]]; then
suites=("${default_suites[@]}")
fi
}
run_contracts_stage() {
require_cmd git
log "Stage: contracts"
AUGUR_CONTRACT_DRIFT_USE_WORKTREE=1 scripts/check-contract-drift.sh
}
run_backend_stage() {
require_cmd go
log "Stage: backend"
if [[ "$skip_install" == false ]]; then
go mod download
fi
go vet ./...
go test ./... -count=1
}
run_extensions_stage() {
require_cmd npm
log "Stage: extensions"
for suite in "${suites[@]}"; do
local suite_dir="$REPO_ROOT/browser-extensions/history-extensions/$suite"
[[ -d "$suite_dir" ]] || die "extension suite directory not found: $suite_dir"
log "Suite: $suite"
if [[ "$skip_install" == false ]]; then
(cd "$suite_dir" && npm ci)
fi
(cd "$suite_dir" && npm test -- --runInBand)
done
}
main() {
parse_args "$@"
local started_at
started_at="$(date +%s)"
log "Starting local CI pipeline in $REPO_ROOT"
if [[ "$run_contracts" == true ]]; then
run_contracts_stage
fi
if [[ "$run_backend" == true ]]; then
run_backend_stage
fi
if [[ "$run_extensions" == true ]]; then
run_extensions_stage
fi
local ended_at duration
ended_at="$(date +%s)"
duration="$((ended_at - started_at))"
log "All selected stages passed (${duration}s)."
}
main "$@"