#!/usr/bin/env bash # Builds deployable OPA bundles for every rule and gate. # # Composition model: SEPARATE EVALUATION. # - Each rule is built as its own bundle where the module lives at data.rules.. # - Each gate bundles the policy.rego of all its dependency rules; consumers evaluate # data.rules. per rule and combine results at runtime. set -euo pipefail source "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/common.sh" rm -rf "$ARTIFACTS_DIR" STAGE_DIR="$(mktemp -d)" trap 'rm -rf "$STAGE_DIR"' EXIT MANIFEST='{"revision":"","roots":["rules"],"rego_version":1}' write_manifest() { printf '%s' "$MANIFEST" > "$1/.manifest" } # --- rules --- for d in "$POLICIES_DIR"/rules/*/; do name="$(repo_name "$d")" version="$(repo_version "$d")" out="$ARTIFACTS_DIR/rules/$name/$version" mkdir -p "$out" echo "==> build rule $name@$version" mkdir -p "$STAGE_DIR/rule/$name" cp "$d/policy.rego" "$STAGE_DIR/rule/$name/policy.rego" write_manifest "$STAGE_DIR/rule/$name" (cd "$STAGE_DIR/rule/$name" && "$OPA" build -b . -o "$out/bundle.tar.gz") done # --- gates --- for g in "$POLICIES_DIR"/gates/*/; do name="$(repo_name "$g")" version="$(repo_version "$g")" out="$ARTIFACTS_DIR/gates/$name/$version" mkdir -p "$out" echo "==> build gate $name@$version" stage="$STAGE_DIR/gate/$name" for dep in $(node -p "Object.keys(require('$g/package.json').dependencies ?? {}).join(' ')"); do for r in "$POLICIES_DIR"/rules/*/; do rname="$(repo_name "$r")" if [ "$rname" = "$dep" ]; then mkdir -p "$stage/$rname" cp "$r/policy.rego" "$stage/$rname/policy.rego" break fi done done [ -d "$stage" ] || { echo "ERROR: gate $name has no buildable dependencies" >&2; exit 1; } write_manifest "$stage" (cd "$stage" && "$OPA" build -b . -o "$out/bundle.tar.gz") done echo "Artifacts written under $ARTIFACTS_DIR"