2443909362
---ci--- project: nova-platform milestone: v1.0 status: complete requirements: covered: [REQ-01,REQ-02,REQ-03,REQ-04,REQ-05,REQ-06,REQ-07,REQ-08,REQ-09,REQ-10,REQ-11,REQ-12,REQ-13,REQ-14,REQ-15,REQ-16,REQ-17,REQ-18,REQ-19,REQ-20,REQ-21,REQ-22,REQ-23,REQ-24,REQ-25,REQ-26,REQ-27,REQ-28,REQ-29,REQ-30,REQ-31,REQ-32,REQ-33,REQ-34,REQ-35,REQ-36,REQ-37,REQ-38] partial: [] ---/ci--- v1.0 milestone complete: simplified infrastructure-delivery platform derived from Nova (acdl). 6 phases (P0-P5 + P6 final). 38 REQ-IDs. 38 decisions (D-001..D-038). 76 tests pass. Engine boundary holds. Happy paths green (check-only + CI). 13 L1 + 2 L2 modules. 5 terraform roots. Shell reproducibility. Zero OOS files. Tags: v0.1.0 (P0) → v0.1.1..v0.1.5 (P1..P5) → v0.1.6 (P6 = milestone release on v0.1 patch line).
116 lines
3.5 KiB
Bash
Executable File
116 lines
3.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Nova Platform — run_platform.sh
|
|
#
|
|
# Orchestrates: contract -> resolve -> adapter -> apply.
|
|
#
|
|
# Flags (per D-031): --check-only, --plan-only, --quiet, --help (-h).
|
|
# Default mode (no flag) = apply.
|
|
set -euo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
cd "$ROOT"
|
|
|
|
CHECK_ONLY=0
|
|
PLAN_ONLY=0
|
|
QUIET=0
|
|
CONTRACT=""
|
|
|
|
_print_help() {
|
|
cat <<EOF
|
|
usage: run_platform.sh [--check-only|--plan-only|--quiet|--help] [contract.yml]
|
|
|
|
--check-only Offline validation: contract -> resolve -> adapter -> validate. No AWS.
|
|
--plan-only AWS: above + terraform init/validate/plan. No apply.
|
|
--quiet Suppress streaming output.
|
|
-h, --help Show this help.
|
|
|
|
Default (no flag): full apply path (AWS required).
|
|
Default contract: contracts/static-assets.yml
|
|
EOF
|
|
}
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--check-only) CHECK_ONLY=1; shift;;
|
|
--plan-only) PLAN_ONLY=1; shift;;
|
|
--quiet) QUIET=1; shift;;
|
|
-h|--help) _print_help; exit 0;;
|
|
--*) echo "FAIL: unknown flag $1" >&2; exit 1;;
|
|
*) CONTRACT="$1"; shift;;
|
|
esac
|
|
done
|
|
|
|
[ -z "$CONTRACT" ] && CONTRACT="contracts/static-assets.yml"
|
|
|
|
fail() { echo "FAIL: $*" >&2; exit 1; }
|
|
|
|
WORK="${NOVA_WORK_DIR:-/tmp/nova_platform_run}"
|
|
TF_DIR="$WORK/tf"
|
|
rm -rf "$WORK"; mkdir -p "$TF_DIR"
|
|
|
|
banner() { [ "$QUIET" -eq 0 ] && echo "=== $* ==="; }
|
|
|
|
banner "Step 0: environment check"
|
|
python3 -c "
|
|
import sys, json, yaml
|
|
from pathlib import Path
|
|
sys.path.insert(0, '.')
|
|
from core import environment_check
|
|
contract = yaml.safe_load(open('$CONTRACT'))
|
|
env = environment_check.check(contract['environment'], Path('core/environments'))
|
|
print(f'env: {env[\"name\"]} ({env[\"region\"]})')
|
|
"
|
|
|
|
banner "Step 1: validate contract"
|
|
python3 -c "
|
|
import json, yaml, jsonschema
|
|
schema = json.load(open('schemas/contract.schema.json'))
|
|
contract = yaml.safe_load(open('$CONTRACT'))
|
|
jsonschema.validate(contract, schema)
|
|
print('contract valid')
|
|
"
|
|
|
|
banner "Step 2: resolve contract -> stack"
|
|
python3 core/contract_resolver.py "$CONTRACT" "$WORK/stack.json"
|
|
python3 -c "import json; s=json.load(open('$WORK/stack.json')); print(f'resources: {len(s[\"resources\"])}')"
|
|
|
|
banner "Step 3: adapter compiles stack -> HCL"
|
|
python3 adapters/terraform/adapter.py "$WORK/stack.json" "$TF_DIR/main.tf"
|
|
[ "$QUIET" -eq 0 ] && head -20 "$TF_DIR/main.tf"
|
|
|
|
if [ "$CHECK_ONLY" -eq 1 ]; then
|
|
python3 -c "
|
|
from pathlib import Path
|
|
main = Path('$TF_DIR/main.tf')
|
|
assert main.exists() and main.stat().st_size > 0, 'main.tf missing or empty'
|
|
content = main.read_text()
|
|
assert 'module \"' in content, 'no module blocks'
|
|
print('output structure valid')
|
|
"
|
|
echo "=== PLATFORM CHECK OK ==="
|
|
exit 0
|
|
fi
|
|
|
|
banner "Loading AWS credentials"
|
|
if [ -f .ciagent/.env.secrets ]; then
|
|
set -a
|
|
. .ciagent/.env.secrets
|
|
set +a
|
|
fi
|
|
export AWS_ACCESS_KEY_ID="${NOVA_AWS_ACCESS_KEY_ID:-${AWS_ACCESS_KEY_ID:-}}"
|
|
export AWS_SECRET_ACCESS_KEY="${NOVA_AWS_SECRET_ACCESS_KEY:-${AWS_SECRET_ACCESS_KEY:-}}"
|
|
export AWS_DEFAULT_REGION="${AWS_DEFAULT_REGION:-us-east-1}"
|
|
unset NOVA_AWS_ACCESS_KEY_ID NOVA_AWS_SECRET_ACCESS_KEY NOVA_FORGE_TOKEN 2>/dev/null || true
|
|
[ -z "$AWS_ACCESS_KEY_ID" ] && fail "no AWS credentials (set NOVA_AWS_* in .ciagent/.env.secrets)"
|
|
|
|
banner "Step 4: terraform init + validate + plan"
|
|
( cd "$TF_DIR" && terraform init -backend=false && terraform validate && terraform plan -out=tfplan )
|
|
|
|
if [ "$PLAN_ONLY" -eq 1 ]; then
|
|
echo "=== PLATFORM PLAN OK ==="
|
|
exit 0
|
|
fi
|
|
|
|
banner "Step 5: terraform apply"
|
|
( cd "$TF_DIR" && terraform apply -auto-approve tfplan )
|
|
echo "=== PLATFORM APPLY OK ===" |