muse-bridge-deploy.sh
bash
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1
docs: MuseHub-first before ISR #74 — staging solidify NEXT
Human
1 day ago
| 1 | #!/usr/bin/env bash |
| 2 | # Muse+git-mirror safe bridge deploy (SD-14). Token-substituted by overseer-kit. |
| 3 | set -euo pipefail |
| 4 | |
| 5 | REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" |
| 6 | MIRROR_REL="${MUSE_BRIDGE_MIRROR_DIR:-.muse/mirror}" |
| 7 | GIT_REMOTE="origin" |
| 8 | MIRROR_BRANCH="muse-mirror" |
| 9 | MAIN_BRANCH="main" |
| 10 | MUSE_ROOT="${REPO_ROOT}" |
| 11 | COMMIT_MSG="${1:-mirror: overseer bridge deploy}" |
| 12 | |
| 13 | _resolve_abs() { |
| 14 | local base="$1" |
| 15 | local rel="$2" |
| 16 | if [[ "${rel}" = /* ]]; then |
| 17 | local dir base_name |
| 18 | dir="$(cd "$(dirname "${rel}")" && pwd)" |
| 19 | base_name="$(basename "${rel}")" |
| 20 | echo "${dir}/${base_name}" |
| 21 | else |
| 22 | echo "${base%/}/${rel#./}" |
| 23 | fi |
| 24 | } |
| 25 | |
| 26 | REPO_ABS="$(cd "${REPO_ROOT}" && pwd -P)" |
| 27 | MIRROR_ABS="$(_resolve_abs "${REPO_ROOT}" "${MIRROR_REL}")" |
| 28 | GIT_REMOTE_URL="$(git -C "${REPO_ROOT}" config --get "remote.${GIT_REMOTE}.url" 2>/dev/null || true)" |
| 29 | if [[ -z "${GIT_REMOTE_URL}" ]]; then |
| 30 | echo "refused: git remote '${GIT_REMOTE}' URL not configured" >&2 |
| 31 | exit 1 |
| 32 | fi |
| 33 | |
| 34 | # S3: refuse repo-root export (blocks --git-dir .) |
| 35 | if [[ "${MIRROR_ABS}" == "${REPO_ABS}" ]]; then |
| 36 | echo "refused: mirror directory equals repo root (destructive export blocked)" >&2 |
| 37 | exit 1 |
| 38 | fi |
| 39 | |
| 40 | # S4: provision / update isolated mirror checkout on mirror_branch from remote |
| 41 | mkdir -p "$(dirname "${MIRROR_ABS}")" |
| 42 | if [[ ! -d "${MIRROR_ABS}/.git" ]]; then |
| 43 | if git clone --branch "${MIRROR_BRANCH}" "${GIT_REMOTE_URL}" "${MIRROR_ABS}" 2>/dev/null; then |
| 44 | : |
| 45 | else |
| 46 | git clone "${GIT_REMOTE_URL}" "${MIRROR_ABS}" |
| 47 | git -C "${MIRROR_ABS}" checkout -B "${MIRROR_BRANCH}" 2>/dev/null \ |
| 48 | || git -C "${MIRROR_ABS}" checkout "${MIRROR_BRANCH}" |
| 49 | fi |
| 50 | else |
| 51 | git -C "${MIRROR_ABS}" fetch "${GIT_REMOTE}" |
| 52 | git -C "${MIRROR_ABS}" checkout "${MIRROR_BRANCH}" |
| 53 | fi |
| 54 | |
| 55 | # S5: non-secret sentinel under REPO_ROOT (prove dev tree untouched) |
| 56 | SENTINEL="${REPO_ROOT}/.overseer/.muse-bridge-sentinel" |
| 57 | mkdir -p "$(dirname "${SENTINEL}")" |
| 58 | echo "muse-bridge-sentinel" > "${SENTINEL}" |
| 59 | |
| 60 | # S6: track .env files before export |
| 61 | ENV_WAS=0 |
| 62 | ENV_LOCAL_WAS=0 |
| 63 | [[ -f "${REPO_ROOT}/.env" ]] && ENV_WAS=1 |
| 64 | [[ -f "${REPO_ROOT}/.env.local" ]] && ENV_LOCAL_WAS=1 |
| 65 | |
| 66 | # S7: cwd-safe muse bridge git-export to isolated mirror only |
| 67 | muse -C "${MUSE_ROOT}" bridge git-export \ |
| 68 | --git-dir "${MIRROR_ABS}" \ |
| 69 | --git-branch "${MIRROR_BRANCH}" \ |
| 70 | --git-remote "${GIT_REMOTE}" \ |
| 71 | --exclude ".muse/*" \ |
| 72 | --exclude ".env" \ |
| 73 | --exclude ".env.local" \ |
| 74 | --commit-message "${COMMIT_MSG}" |
| 75 | |
| 76 | # S5 post-export sentinel check |
| 77 | if [[ ! -f "${SENTINEL}" ]]; then |
| 78 | echo "refused: dev-tree sentinel missing after export" >&2 |
| 79 | exit 1 |
| 80 | fi |
| 81 | |
| 82 | # S6 post-export env check |
| 83 | if [[ "${ENV_WAS}" -eq 1 && ! -f "${REPO_ROOT}/.env" ]]; then |
| 84 | echo "refused: .env disappeared after export" >&2 |
| 85 | exit 1 |
| 86 | fi |
| 87 | if [[ "${ENV_LOCAL_WAS}" -eq 1 && ! -f "${REPO_ROOT}/.env.local" ]]; then |
| 88 | echo "refused: .env.local disappeared after export" >&2 |
| 89 | exit 1 |
| 90 | fi |
| 91 | |
| 92 | # S10: optional stack audit (skip when no package.json) |
| 93 | if [[ -f "${REPO_ROOT}/package.json" ]] && command -v pnpm >/dev/null 2>&1; then |
| 94 | (cd "${REPO_ROOT}" && pnpm audit) || true |
| 95 | fi |
| 96 | |
| 97 | # S13: publish mirror_branch on remote (never main_branch / S8) |
| 98 | if ! git -C "${MIRROR_ABS}" ls-remote --exit-code "${GIT_REMOTE}" "refs/heads/${MIRROR_BRANCH}" >/dev/null 2>&1; then |
| 99 | git -C "${MIRROR_ABS}" push "${GIT_REMOTE}" "${MIRROR_BRANCH}" |
| 100 | fi |
| 101 | |
| 102 | # S9: open or update PR mirror_branch → main_branch when gh is available |
| 103 | if command -v gh >/dev/null 2>&1; then |
| 104 | if ! gh pr list --head "${MIRROR_BRANCH}" --base "${MAIN_BRANCH}" --state open --json number -q '.[0].number' 2>/dev/null | grep -q .; then |
| 105 | gh pr create \ |
| 106 | --base "${MAIN_BRANCH}" \ |
| 107 | --head "${MIRROR_BRANCH}" \ |
| 108 | --title "Mirror: ${COMMIT_MSG}" \ |
| 109 | --body "Automated muse-mirror bridge PR (SD-14)." \ |
| 110 | 2>/dev/null || true |
| 111 | fi |
| 112 | else |
| 113 | echo "warning: gh not found; mirror branch published but no PR opened" >&2 |
| 114 | fi |
| 115 | |
| 116 | exit 0 |
File History
2 commits
sha256:a78e7e5a8740e03315f325d19edeb3aa1b306b3337d04abbaa9a9e0f3bbeb7a1
docs: MuseHub-first before ISR #74 — staging solidify NEXT
Human
1 day ago
sha256:4671b7f787ddbe63ced31c895b688c77ab495653b65a730b423329f26b3c1439
feat: K1-P1 complete — agent provenance, build-verification…
Sonnet 4.6
patch
53 days ago