#!/usr/bin/env bash set -euo pipefail ROOT=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd) mkdir -p -- "$ROOT/dist" WORK=$(mktemp -d "$ROOT/dist/.f06-local.XXXXXXXX") trap 'rm -rf -- "$WORK"' EXIT PACKAGE_VERSION="f06-$(basename -- "$WORK" | tr -cd '[:alnum:]')" PACKAGE_RELEASE="$ROOT/dist/release-$PACKAGE_VERSION" PACKAGE_STAGE="$ROOT/dist/package-$PACKAGE_VERSION" PACKAGE_ARCHIVE="$ROOT/dist/packages/sip-go-agent-$PACKAGE_VERSION-linux-amd64.tar.gz" for path in "$PACKAGE_RELEASE" "$PACKAGE_STAGE" "$PACKAGE_ARCHIVE" "$PACKAGE_ARCHIVE.sha256"; do if [[ -e "$path" || -L "$path" ]]; then echo "local package test path already exists: $path" >&2 exit 1 fi done mkdir -- "$PACKAGE_RELEASE" trap 'rm -rf -- "$WORK" "$PACKAGE_RELEASE" "$PACKAGE_STAGE"; rm -f -- "$PACKAGE_ARCHIVE" "$PACKAGE_ARCHIVE.sha256"' EXIT printf 'keep existing package output\n' > "$PACKAGE_RELEASE/sentinel" protected="$WORK/preexisting" mkdir -- "$protected" printf 'keep existing release output\n' > "$protected/sentinel" if RELEASE_VERSION=local-development "$ROOT/scripts/build-release.sh" "$protected" > "$WORK/rejected.log" 2>&1; then echo 'release build accepted a preexisting output directory' >&2 exit 1 fi if [[ ! -f "$protected/sentinel" ]] || [[ $(<"$protected/sentinel") != 'keep existing release output' ]]; then echo 'release build removed or changed a preexisting file' >&2 exit 1 fi if "$ROOT/deploys/build-package.sh" "$PACKAGE_VERSION" > "$WORK/package-rejected.log" 2>&1; then echo 'package build accepted a preexisting release directory' >&2 exit 1 fi if [[ ! -f "$PACKAGE_RELEASE/sentinel" ]] || [[ $(<"$PACKAGE_RELEASE/sentinel") != 'keep existing package output' ]]; then echo 'package build removed or changed a preexisting file' >&2 exit 1 fi "$ROOT/scripts/check-proto.sh" > "$WORK/proto.log" "$ROOT/scripts/check-contracts.sh" > "$WORK/contracts.log" RELEASE_VERSION=local-development "$ROOT/scripts/build-release.sh" "$WORK/release" > "$WORK/build.log" 2>&1 || { tail -n 25 "$WORK/build.log" >&2 exit 1 } (cd -- "$WORK/release" && sha256sum --check SHA256SUMS > /dev/null) python3 - "$ROOT" "$WORK/release" <<'PY' import hashlib import json import pathlib import sys root, release = map(pathlib.Path, sys.argv[1:]) manifest = json.loads((release / "manifest.json").read_text()) assert manifest["manifest_version"] == 1 assert manifest["scope"] == manifest["version"] == "local-development" assert manifest["security"] == {"credentials_embedded": False, "production_approval": False} assert manifest["binary"]["sha256"] == hashlib.sha256((release / "sip-go-agent").read_bytes()).hexdigest() assert manifest["go_version"].startswith("go version go1.27.1 ") v01 = json.loads((root / "docs/contracts/local-contract-manifest-v0.1.json").read_text()) v03 = json.loads((root / "docs/contracts/local-contract-manifest-v0.3.json").read_text()) topology = json.loads((root / "docs/contracts/mq-topology-v0.1-proposal.json").read_text()) assert v01["manifest_version"] == "local-contract-manifest.v0.1" assert v03["manifest_version"] == "local-contract-manifest.v0.3" assert v03["source"]["path"] == "docs/thirds/v0.3.md" assert "docs/contracts/task-discovery-v0.3-proposal.schema.json" in {item["path"] for item in v03["artifacts"]} assert all("task-discovery-v0.2" not in item["path"] for item in v03["artifacts"]) assert topology["contract_version"] == "project-saas-dispatcher.v0.1" assert all(topology["queues"][kind]["owner"] == "saas" for kind in ("task", "control", "result")) assert all(topology["queues"][kind]["queue_name"].endswith(".v3") for kind in ("task", "control", "result")) expected_attestation = { "local_business": { "version": v01["manifest_version"], "manifest_sha256": hashlib.sha256((root / "docs/contracts/local-contract-manifest-v0.1.json").read_bytes()).hexdigest(), }, "task_discovery": { "version": v03["manifest_version"], "manifest_sha256": hashlib.sha256((root / "docs/contracts/local-contract-manifest-v0.3.json").read_bytes()).hexdigest(), }, "mq_topology": { "version": topology["contract_version"], "manifest_sha256": hashlib.sha256((root / "docs/contracts/mq-topology-v0.1-proposal.json").read_bytes()).hexdigest(), }, "proto_manifest_sha256": hashlib.sha256((root / "proto/manifest.json").read_bytes()).hexdigest(), } assert manifest["contract_attestation"] == expected_attestation print("local artifact SHA-256:", manifest["binary"]["sha256"]) print("task discovery source SHA-256:", v03["source"]["sha256"]) print("source dirty:", manifest["source_dirty"]) print("production approved:", manifest["security"]["production_approval"]) PY if "$WORK/release/sip-go-agent" dispatcher --help | grep -Eq -- '--tenant-key|--consume'; then echo 'release exposes deprecated Dispatcher queue/tenant switches' >&2 exit 1 fi for mode in mixed real; do blocked_db="$WORK/blocked-$mode.sqlite" if SIP_GO_AGENT_MODE="$mode" DISPATCHER_DB="$blocked_db" RABBITMQ_URL='amqp://127.0.0.1:1/' \ DISPATCHER_GRPC_LISTEN='' DISPATCHER_AGENT_ENDPOINTS_FILE='' \ GO_SIP_OSS_ACCESS_KEY_ID='local-test-placeholder' GO_SIP_OSS_ACCESS_KEY_SECRET='local-test-placeholder' \ "$WORK/release/sip-go-agent" dispatcher --config "$ROOT/deploys/config/dispatcher.json.example" > "$WORK/blocked-$mode.log" 2>&1; then echo "release accepted unapproved $mode execution" >&2 exit 1 fi if ! grep -q 'isolated Mock only' "$WORK/blocked-$mode.log" || test -e "$blocked_db"; then echo "release reached resources before rejecting $mode execution" >&2 exit 1 fi done rm -- "$PACKAGE_RELEASE/sentinel" rmdir -- "$PACKAGE_RELEASE" "$ROOT/deploys/build-package.sh" "$PACKAGE_VERSION" > "$WORK/package.log" 2>&1 || { tail -n 25 "$WORK/package.log" >&2 exit 1 } (cd -- "$(dirname -- "$PACKAGE_ARCHIVE")" && sha256sum --check "$(basename -- "$PACKAGE_ARCHIVE").sha256" > /dev/null) mkdir -- "$WORK/extracted" tar -C "$WORK/extracted" -xzf "$PACKAGE_ARCHIVE" (cd -- "$WORK/extracted" && sha256sum --check package.SHA256SUMS > /dev/null) python3 - "$WORK/extracted" "$PACKAGE_VERSION" <<'PY' import json import pathlib import sys package, version = pathlib.Path(sys.argv[1]), sys.argv[2] manifest = json.loads((package / "manifest.json").read_text()) assert manifest["version"] == version assert manifest["scope"] == "local-development" assert manifest["security"]["production_approval"] is False assert manifest["contract_attestation"]["task_discovery"]["version"] == "local-contract-manifest.v0.3" PY echo 'F06 local release/package artifact and contract/queue gates passed; no deployment or dial attempted'