From c3102e0d7fb89a42c9b29528c8985eb3cdada765 Mon Sep 17 00:00:00 2001 From: Jeff Huber Date: Wed, 2 Sep 2026 13:58:15 -0700 Subject: [PATCH] Harden install and upgrade docs --- README.md | 4 +- docs/install.md | 79 +++++++++++++++++++++++++++++++++++ docs/quickstart.md | 18 +++++++- docs/troubleshooting.md | 49 ++++++++++++++++++++++ docs/try-in-10-minutes.md | 19 ++++++++- tests/test_release_hygiene.py | 25 +++++++++++ 6 files changed, 191 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 3830efe6..e9be6b26 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,9 @@ observable. Install first from the [Install And Bootstrap](docs/install.md) matrix: pipx for laptops, uv tool installs for hosted agents or CI boxes, and an editable venv -for Code Mower contributors. All paths require Python 3.12 or newer. +for Code Mower contributors. All paths require Python 3.12 or newer. For +upgrades, record `command -v code-mower` and `code-mower --version` before and +after reinstalling, especially when switching between pipx and uv. | Path | Use When | Route | Guide | | --- | --- | --- | --- | diff --git a/docs/install.md b/docs/install.md index 96bae2f2..00b20fec 100644 --- a/docs/install.md +++ b/docs/install.md @@ -11,6 +11,36 @@ agent, then verify the installed command before touching a repository. | Hosted agent, CI box, or minimal Linux VM | `uv tool install` | The machine already uses uv, lacks pipx, or should avoid changing shell startup files. | | Code Mower contributor checkout | editable venv | You are changing Code Mower itself and need tests against this checkout. | +## Cold Install Vs Upgrade + +A cold install means this machine does not already have the `code-mower` +command on `PATH`. Pick one install path from the matrix, install the pinned +package, then verify both the command path and version: + +```bash +command -v code-mower +code-mower --version +``` + +An upgrade means `code-mower` already exists. Before changing it, record the +current command path and version, then choose whether this machine should keep +using the same installer or switch installers: + +```bash +command -v code-mower +code-mower --version +``` + +For an existing repository with older generated files, inspect setup drift +before copying new generated output into the repo: + +```bash +code-mower migration setup-drift --repo-path . --json +``` + +The drift report is read-only and metadata-only. It classifies generated setup +paths without including file contents or diffs. + ## Laptop Or Workstation Install with pipx and an explicit Python 3.12+ interpreter: @@ -35,6 +65,27 @@ To follow the newest prerelease instead of the pinned friendly-user beta: pipx install --python "$CODE_MOWER_PYTHON" --pip-args="--pre" code-mower ``` +To replace an existing pipx install with an exact beta, use `--force` so the +old venv cannot keep serving the previous package: + +```bash +PIP_NO_CACHE_DIR=1 pipx install --force --python "$CODE_MOWER_PYTHON" code-mower==0.8.0b1 +code-mower --version +``` + +For sandboxed agents that need pipx but should not write to the normal user +tool directories, set pipx directories explicitly before installing: + +```bash +export CODE_MOWER_AGENT_TOOLS="${RUNNER_TEMP:-$HOME/.cache}/code-mower-tools" +export PIPX_HOME="$CODE_MOWER_AGENT_TOOLS/pipx" +export PIPX_BIN_DIR="$CODE_MOWER_AGENT_TOOLS/bin" +export PIPX_LOG_DIR="$CODE_MOWER_AGENT_TOOLS/logs" +mkdir -p "$PIPX_HOME" "$PIPX_BIN_DIR" "$PIPX_LOG_DIR" +PIP_NO_CACHE_DIR=1 pipx install --force --python "$CODE_MOWER_PYTHON" code-mower==0.8.0b1 +"$PIPX_BIN_DIR/code-mower" --version +``` + ## Hosted Agent, CI Box, Or Minimal Linux VM Use uv when the environment does not have pipx or should stay isolated from the @@ -49,6 +100,34 @@ code-mower --version If the uv tool directory is not on `PATH`, use uv's printed path hint or run the installed command directly from the uv tool bin directory for that session. +To replace an existing uv tool install with an exact beta: + +```bash +uv tool install --python 3.12 --reinstall --refresh-package code-mower code-mower==0.8.0b1 +code-mower --version +``` + +## Switching Between pipx And uv + +Avoid leaving two different `code-mower` commands competing on `PATH`. If this +machine should switch from pipx to uv, first record the current path/version, +then uninstall or stop using the old command: + +```bash +command -v code-mower +code-mower --version +pipx uninstall code-mower +uv python install 3.12 +uv tool install --python 3.12 --reinstall --refresh-package code-mower code-mower==0.8.0b1 +hash -r +command -v code-mower +code-mower --version +``` + +If the old pipx command must stay for another agent, call the uv-installed +binary by its absolute path or adjust only that agent's `PATH`. Do not change a +shared workstation install while another builder owns an active PR branch. + ## Release Rehearsal Installs When validating a newly published beta, bypass installer caches before deciding diff --git a/docs/quickstart.md b/docs/quickstart.md index 3f2bf998..35cee731 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -37,11 +37,17 @@ For hosted agents or CI boxes without pipx: ```bash uv python install 3.12 uv tool install --python 3.12 code-mower==0.8.0b1 +code-mower --version ``` For a Code Mower source checkout, use `scripts/dev-python` and the editable venv path documented in [Install And Bootstrap](install.md#contributor-checkout). +For upgrades, do not assume the command on `PATH` changed. Run +`command -v code-mower` and `code-mower --version` before and after reinstall, +and follow [Cold Install Vs Upgrade](install.md#cold-install-vs-upgrade) when +moving between pipx and uv. + If `code-mower` is not on your path: ```bash @@ -79,7 +85,17 @@ Verify Codex: ```bash codex --version -codex "Reply with exactly: ok" +codex login status +codex exec --skip-git-repo-check --sandbox read-only "Reply with exactly: ok" +``` + +For non-interactive runner or hosted-agent auth, load the API key from a secret +store and pipe it into Codex without printing it: + +```bash +printf '%s\n' "$OPENAI_API_KEY" | codex login --with-api-key +codex login status +codex exec --skip-git-repo-check --sandbox read-only "Reply with exactly: ok" ``` Verify Claude: diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 6d5379c1..440f381c 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -71,6 +71,46 @@ scripts/dev-python -m unittest discover -s tests The wrapper resolves Python 3.12+ and refuses old system Python shims. +## Installed Version Or Command Path Looks Wrong + +After an upgrade, first check which installer is actually winning on `PATH`: + +```bash +command -v code-mower +code-mower --version +``` + +If pipx should own the command, reinstall the exact beta with cache bypass: + +```bash +export CODE_MOWER_PYTHON="$(command -v python3.12)" +PIP_NO_CACHE_DIR=1 pipx install --force --python "$CODE_MOWER_PYTHON" code-mower==0.8.0b1 +hash -r +code-mower --version +``` + +If uv should own the command, avoid leaving an older pipx command earlier on +`PATH`. Either uninstall the pipx copy or call the uv binary by its absolute +path: + +```bash +pipx uninstall code-mower +uv tool install --python 3.12 --reinstall --refresh-package code-mower code-mower==0.8.0b1 +hash -r +command -v code-mower +code-mower --version +``` + +For sandboxed agents using pipx, keep tool files out of the product checkout +unless that directory is intentionally ignored: + +```bash +export CODE_MOWER_AGENT_TOOLS="${RUNNER_TEMP:-$HOME/.cache}/code-mower-tools" +export PIPX_HOME="$CODE_MOWER_AGENT_TOOLS/pipx" +export PIPX_BIN_DIR="$CODE_MOWER_AGENT_TOOLS/bin" +export PIPX_LOG_DIR="$CODE_MOWER_AGENT_TOOLS/logs" +``` + ## GitHub Auth Or Private Repo Checks Fail Verify the GitHub CLI independently: @@ -105,6 +145,15 @@ output, treat it as audit infrastructure, not a code-review BLOCKED verdict. Retry once on the same head; if it repeats, keep the lane informational or record an owner decision before relying on it. +## Board URL Does Not Open From Another Machine + +`code-mower board serve --repo OWNER/REPO` binds to loopback by default. The +printed localhost URL is local to that laptop, runner, VM, or hosted-agent +container. Open it from the same environment, or create your own tunnel when +you intentionally want to view it elsewhere. The Board remains read-only and +does not upload data unless you separately run a cloud command such as +`code-mower cloud board-snapshot --yes`. + ## Cloud Upload Says The Token Is Missing After Restart `code-mower cloud setup --token-stdin` writes a private token profile under diff --git a/docs/try-in-10-minutes.md b/docs/try-in-10-minutes.md index 5cd3ffdd..9b99637e 100644 --- a/docs/try-in-10-minutes.md +++ b/docs/try-in-10-minutes.md @@ -15,15 +15,32 @@ private repository names. Code Mower requires Python 3.12 or newer. See [Install And Bootstrap](install.md) for pipx, uv, and contributor checkout -paths. The laptop path is: +paths, plus upgrade and pipx-to-uv migration details. + +Use this install matrix: + +| Environment | Command shape | +| --- | --- | +| Laptop/workstation | `pipx install --python "$CODE_MOWER_PYTHON" code-mower==0.8.0b1` | +| Hosted agent, CI box, or minimal Linux VM | `uv tool install --python 3.12 code-mower==0.8.0b1` | +| Code Mower contributor checkout | `scripts/dev-python -m venv .venv` then `.venv/bin/python -m pip install -e ".[test]"` | + +For a cold laptop install: ```bash python3.12 --version export CODE_MOWER_PYTHON="$(command -v python3.12)" pipx install --python "$CODE_MOWER_PYTHON" code-mower==0.8.0b1 +command -v code-mower code-mower --version ``` +For an existing install, first run `command -v code-mower` and +`code-mower --version`, then follow +[Cold Install Vs Upgrade](install.md#cold-install-vs-upgrade). If you switch +from pipx to uv, make sure the command on `PATH` is the one you meant to use +before running `init`. + `0.8.0b1` is a beta release. To follow the newest beta line instead of pinning this exact build: diff --git a/tests/test_release_hygiene.py b/tests/test_release_hygiene.py index f4a6c07f..1f1154e8 100644 --- a/tests/test_release_hygiene.py +++ b/tests/test_release_hygiene.py @@ -126,6 +126,31 @@ def test_codex_smoke_docs_use_supported_flags(self) -> None: self.assertNotIn("--ask-for-approval", text, msg=str(path)) self.assertIn("codex login --with-api-key", text, msg=str(path)) + def test_install_and_upgrade_docs_cover_agent_paths(self) -> None: + readme = (ROOT / "README.md").read_text(encoding="utf-8") + install = (ROOT / "docs/install.md").read_text(encoding="utf-8") + quickstart = (ROOT / "docs/quickstart.md").read_text(encoding="utf-8") + try_in_10 = (ROOT / "docs/try-in-10-minutes.md").read_text(encoding="utf-8") + troubleshooting = (ROOT / "docs/troubleshooting.md").read_text(encoding="utf-8") + + self.assertIn("Cold Install Vs Upgrade", install) + self.assertIn("Switching Between pipx And uv", install) + self.assertIn("uv tool install --python 3.12 --reinstall --refresh-package", install) + self.assertIn("pipx uninstall code-mower", install) + for env_name in ("PIPX_HOME", "PIPX_BIN_DIR", "PIPX_LOG_DIR"): + self.assertIn(env_name, install) + self.assertIn(env_name, troubleshooting) + self.assertIn("| Hosted agent, CI box, or minimal Linux VM |", try_in_10) + self.assertIn("command -v code-mower", readme) + self.assertIn("command -v code-mower", quickstart) + self.assertIn("codex login --with-api-key", quickstart) + self.assertIn("codex exec --skip-git-repo-check --sandbox read-only", quickstart) + self.assertIn("Board URL Does Not Open From Another Machine", troubleshooting) + self.assertIn( + "local to that laptop, runner, VM, or hosted-agent container", + " ".join(troubleshooting.split()), + ) + def test_ruff_static_rule_stage_is_intentional(self) -> None: pyproject = tomllib.loads((ROOT / "pyproject.toml").read_text(encoding="utf-8"))