was ssh://git@gitea.pastilhas.dev:2222/officerdev/platform.git now https://gitea.officer.dev/officerdev/platform.git Bigger than a URL swap. The SSH default could not clone on a genuinely fresh machine: the key machine-setup generates there is brand new and Gitea has never seen it, so `--repo` was effectively mandatory on a first install — which is the problem that flag was added for two hours ago. HTTPS needs no key and no agent, so the default now works on a blank box. The old comment explained SSH-because-private and set the condition for changing it: "back to HTTPS when the repository is public". It now is — verified with an anonymous `git ls-remote`, which lists refs with no credentials. Rewrote the comment to record why it moved and what to do if it ever goes private again, since that reasoning is the part worth keeping. clone_repo already runs GIT_TERMINAL_PROMPT=0, so a private repo would fail fast rather than hang on a username prompt. No change needed there. repo.sh is still the only place that sets this, and --repo / OFFICER_REPO still override it. Verified both. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
99 lines
4.6 KiB
Bash
99 lines
4.6 KiB
Bash
#!/bin/bash
|
|
# =============================================================================
|
|
# officer-setup — the repository
|
|
# =============================================================================
|
|
#
|
|
# Definitions only.
|
|
#
|
|
# ── Cloned as the owner, never as root ──
|
|
#
|
|
# A repository cloned by root is one the owner cannot pull, cannot commit in, and
|
|
# whose node_modules they cannot write. Every git operation here runs as the
|
|
# account, from a directory that account can stat.
|
|
|
|
[[ -n "${OFFICER_SETUP_REPO_LOADED:-}" ]] && return 0
|
|
OFFICER_SETUP_REPO_LOADED=1
|
|
|
|
# Public HTTPS, which is what this needed all along.
|
|
#
|
|
# It was ssh://git@gitea.pastilhas.dev:2222/... until 2026-08-14, and the reason was
|
|
# that the repository was private: an HTTPS clone of a private repo prompts for a
|
|
# username, and under sudo with no interactive terminal that hangs or dies with
|
|
# "could not read Username". The note here said "back to HTTPS when the repository is
|
|
# public", and it now is — verified with an anonymous `git ls-remote`.
|
|
#
|
|
# The change matters more than a URL swap. An SSH default cannot clone on a genuinely
|
|
# fresh machine: the key machine-setup generates there is brand new and Gitea has
|
|
# never seen it, so `--repo` was effectively mandatory on a first install. HTTPS needs
|
|
# no key and no agent, so the default now works on a blank box.
|
|
#
|
|
# If this ever goes private again, SSH is the answer and the constraint above is the
|
|
# reason — plus one more: the clone runs as the OWNER, and sudo drops SSH_AUTH_SOCK,
|
|
# so a passphrase-protected key has no agent to answer it.
|
|
OFFICER_REPO="${OFFICER_REPO:-https://gitea.officer.dev/officerdev/platform.git}"
|
|
|
|
platform_dir() { echo "${OFFICER_ROOT}/platform"; }
|
|
|
|
repo_exists() { [[ -d "$(platform_dir)/.git" ]]; }
|
|
|
|
repo_remote() { (cd "$(platform_dir)" 2>/dev/null && git remote get-url origin 2>/dev/null) || true; }
|
|
repo_branch() { (cd "$(platform_dir)" 2>/dev/null && git branch --show-current 2>/dev/null) || true; }
|
|
repo_is_dirty() { [[ -n "$(cd "$(platform_dir)" 2>/dev/null && git status --porcelain 2>/dev/null)" ]]; }
|
|
|
|
# Split an ssh:// URL into host and port, for the reachability check below.
|
|
repo_ssh_host() { sed -E 's|^ssh://[^@]*@([^:/]+).*|\1|' <<<"$1"; }
|
|
repo_ssh_port() { sed -nE 's|^ssh://[^@]*@[^:]+:([0-9]+)/.*|\1|p' <<<"$1"; }
|
|
|
|
# Can this account actually clone it?
|
|
#
|
|
# `git ls-remote` is the real question — not "does the host answer" but "can this
|
|
# account read this repository". Both prompts are disabled, because neither fails
|
|
# cleanly on its own: over https git asks for a username nobody is there to type,
|
|
# and over ssh it asks for a password or stops on host-key verification. With
|
|
# both off, an unreachable or unreadable repository is an immediate non-zero
|
|
# instead of a hang.
|
|
repo_reachable() {
|
|
as_owner "GIT_TERMINAL_PROMPT=0 \
|
|
GIT_SSH_COMMAND='ssh -o BatchMode=yes -o StrictHostKeyChecking=accept-new -o ConnectTimeout=8' \
|
|
timeout 20 git ls-remote '$1' >/dev/null 2>&1" /
|
|
}
|
|
|
|
# The https form of the same repository, for a machine with no key.
|
|
repo_https_url() {
|
|
sed -E 's|^ssh://[^@]*@([^:/]+)(:[0-9]+)?/|https://\1/|' <<<"$1"
|
|
}
|
|
|
|
clone_repo() {
|
|
local url="$1" dest
|
|
dest="$(platform_dir)"
|
|
install -d -m 0755 -o "$USERNAME" -g "$(user_group)" "$OFFICER_ROOT"
|
|
as_owner "GIT_TERMINAL_PROMPT=0 git clone '${url}' '${dest}'" /
|
|
}
|
|
|
|
pull_repo() { as_owner "git -C '$(platform_dir)' pull --ff-only" /; }
|
|
|
|
# -----------------------------------------------------------------------------
|
|
# Dependencies
|
|
# -----------------------------------------------------------------------------
|
|
#
|
|
# ── The lockfile is frozen, and that is the point ──
|
|
#
|
|
# bunfig.toml sets [install] frozenLockfile = true, so `bun install` resolves from
|
|
# bun.lock and nothing else. A package.json that disagrees with the lockfile is a
|
|
# hard failure rather than a quiet resolution — which is deliberate: the friction
|
|
# exists so that an unexplained lockfile change shows up in a diff. See the
|
|
# supply-chain note in CLAUDE.md.
|
|
#
|
|
# So a failure here is usually one of two things, and they need different
|
|
# answers: the lockfile genuinely disagrees with package.json, or node-pty failed
|
|
# to build. Both are reported as such rather than as "install failed".
|
|
|
|
deps_installed() { [[ -d "$(platform_dir)/node_modules" ]]; }
|
|
|
|
# node-pty has no Linux prebuild, so `bun install` compiles it every time. This is
|
|
# the artefact that proves it worked, and its absence is why the terminal sidecar
|
|
# would not start.
|
|
node_pty_built() { compgen -G "$(platform_dir)/node_modules/node-pty/build/Release/*.node" >/dev/null 2>&1; }
|
|
|
|
install_deps() { as_owner "cd '$(platform_dir)' && bun install 2>&1"; }
|