102 lines
3.5 KiB
Bash
Executable File
102 lines
3.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
ROOT=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
|
|
OUT_INPUT=${1:-"$ROOT/dist/release"}
|
|
OUT=$(realpath -m -- "$OUT_INPUT")
|
|
VERSION=${RELEASE_VERSION:-local-development}
|
|
|
|
case "$OUT" in
|
|
"$ROOT"/dist/*) ;;
|
|
*)
|
|
echo "release output must stay below project dist/: $OUT" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
if [[ -e "$OUT" || -L "$OUT" ]]; then
|
|
echo "release output already exists; refusing to replace it: $OUT" >&2
|
|
exit 1
|
|
fi
|
|
|
|
go_version=$(go version)
|
|
case "$go_version" in
|
|
"go version go1.27.1 "*) ;;
|
|
*) echo "release requires Go 1.27.1, got: $go_version" >&2; exit 1 ;;
|
|
esac
|
|
source_ref=$(git -C "$ROOT" rev-parse HEAD 2>/dev/null || printf 'unavailable')
|
|
source_dirty=false
|
|
if [[ -n "$(git -C "$ROOT" status --porcelain --untracked-files=all -- . 2>/dev/null)" ]]; then
|
|
source_dirty=true
|
|
fi
|
|
cd -- "$ROOT"
|
|
"$ROOT/scripts/check-proto.sh" > /dev/null
|
|
"$ROOT/scripts/check-contracts.sh" > /dev/null
|
|
go mod verify
|
|
mkdir -p -- "$(dirname -- "$OUT")"
|
|
mkdir -- "$OUT"
|
|
go build -trimpath -buildvcs=false -o "$OUT/sip-go-agent" ./cmd/sip-go-agent
|
|
cp -- go.mod go.sum "$OUT/"
|
|
(
|
|
cd -- "$OUT"
|
|
sha256sum sip-go-agent go.mod go.sum > SHA256SUMS
|
|
)
|
|
|
|
python3 - "$OUT/manifest.json" "$VERSION" "$source_ref" "$source_dirty" "$go_version" "$OUT" "$ROOT" <<'PY'
|
|
import hashlib
|
|
import json
|
|
import pathlib
|
|
import sys
|
|
|
|
manifest_path, version, source_ref, source_dirty, go_version, out, project_root = sys.argv[1:]
|
|
root = pathlib.Path(out)
|
|
project = pathlib.Path(project_root)
|
|
def sha256(name):
|
|
return hashlib.sha256((root / name).read_bytes()).hexdigest()
|
|
def project_sha256(path):
|
|
return hashlib.sha256((project / path).read_bytes()).hexdigest()
|
|
|
|
v01 = json.loads((project / "docs/contracts/local-contract-manifest-v0.1.json").read_text())
|
|
v02 = json.loads((project / "docs/contracts/local-contract-manifest-v0.2.json").read_text())
|
|
topology = json.loads((project / "docs/contracts/mq-topology-v0.1-proposal.json").read_text())
|
|
if (v01["manifest_version"], v02["manifest_version"], topology["contract_version"]) != (
|
|
"local-contract-manifest.v0.1", "local-contract-manifest.v0.2", "project-saas-dispatcher.v0.1"
|
|
):
|
|
raise SystemExit("unexpected project-local contract or queue topology version")
|
|
|
|
manifest = {
|
|
"manifest_version": 1,
|
|
"scope": "local-development",
|
|
"version": version,
|
|
"source_ref": source_ref,
|
|
"source_dirty": source_dirty == "true",
|
|
"go_version": go_version,
|
|
"binary": {"path": "sip-go-agent", "sha256": sha256("sip-go-agent")},
|
|
"module_files": {
|
|
"go.mod": sha256("go.mod"),
|
|
"go.sum": sha256("go.sum"),
|
|
},
|
|
"contract_attestation": {
|
|
"local_business": {
|
|
"version": v01["manifest_version"],
|
|
"manifest_sha256": project_sha256("docs/contracts/local-contract-manifest-v0.1.json"),
|
|
},
|
|
"task_discovery": {
|
|
"version": v02["manifest_version"],
|
|
"manifest_sha256": project_sha256("docs/contracts/local-contract-manifest-v0.2.json"),
|
|
},
|
|
"mq_topology": {
|
|
"version": topology["contract_version"],
|
|
"manifest_sha256": project_sha256("docs/contracts/mq-topology-v0.1-proposal.json"),
|
|
},
|
|
"proto_manifest_sha256": project_sha256("proto/manifest.json"),
|
|
},
|
|
"security": {
|
|
"credentials_embedded": False,
|
|
"production_approval": False,
|
|
},
|
|
}
|
|
pathlib.Path(manifest_path).write_text(json.dumps(manifest, indent=2, sort_keys=True) + "\n")
|
|
PY
|
|
|
|
printf 'release manifest: %s\n' "$OUT/manifest.json"
|