Skip to content

chore: 🔧 allow git push/tag without prompting - #5

Merged
tomgrv merged 16 commits into
developfrom
claude/scripts-repo-devcontainer-pwvukn
Aug 27, 2026
Merged

chore: 🔧 allow git push/tag without prompting#5
tomgrv merged 16 commits into
developfrom
claude/scripts-repo-devcontainer-pwvukn

Conversation

@tomgrv

@tomgrv tomgrv commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds permissions.allow: ["Bash(git push:*)", "Bash(git tag:*)"] to .claude/settings.json so Claude Code sessions in this repo no longer prompt for git push/git tag.

🤖 Generated with Claude Code


Generated by Claude Code

claude added 16 commits August 27, 2026 06:55
lib/common.sh's log/ok/warn/die and its ERR trap duplicated ANSI-color
logging logic that now has a canonical home in zz_colors/zz_log at
https://github.com/tomgrv/scripts (already shared with
tomgrv/devcontainer-features' common-utils feature). Bootstrap zz_use
from there on first source and delegate to it instead, keeping every
existing call site (log/ok/warn/die) and die's exit-1 behavior unchanged.

Everything else in lib/common.sh (apt helpers, net_port/net_access,
dispatch_action, Helm/k3s helpers) stays local: it's vps-specific domain
logic, not duplicated anywhere. dispatch.sh's own standalone log/ok/warn/die
are intentionally left untouched too - it must stay a zero-dependency
POSIX sh entrypoint (curl | sudo sh) that works before the repo is even
cloned, so it can't assume network access to a second external repo.
Every feature (system, security, tailscale, cockpit, k3s, rancher,
dockermanager, argocd, epinio) moves from features/<name>/ to a
top-level <name>/, alongside two new folders for what used to be
lib/common.sh and lib/summary.sh: common/ and summary/ - both excluded
from dispatch.sh's feature discovery, but laid out the same way
(package.json + run.sh) so they're zz_use-able too.

This matches https://github.com/tomgrv/scripts' own one-folder-per-script
layout, which is what makes zz_use itself usable directly against this
repo: `zz_use perspikapps/vps/rancher` now fetches and installs any one
feature standalone, without cloning this repo or running dispatch.sh -
zz_use's [org/repo/]<tool>[@ref] syntax resolves perspikapps/vps as the
origin. Every feature's run.sh now bootstraps zz_use (if not already on
PATH) and does `zz_use perspikapps/vps/common; . common` instead of a
relative `source ../../lib/common.sh`, so it works the same way whether
invoked by dispatch.sh, standalone from a checkout, or zz_use-installed
from anywhere.

dispatch.sh, package.json (workspaces), and README.md updated throughout
for the new paths; package-lock.json regenerated. Added tests/ (bats):
syntax checks on every run.sh/dispatch.sh, a check that every feature's
run.sh has the new zz_use/common wiring, and coverage of common/run.sh's
pure logic (net_port/net_access/all_network_ports/feature_package_json/
dispatch_action) against a fixture tree - this repo had no test suite
before.
Every folder's package.json now has "bin": {"<name>": "run.sh"}, matching
the convention tomgrv/scripts uses for its own scripts and what
zz_use perspikapps/vps/<name> relies on - except tailscale/, which uses
"vps-tailscale" instead: tailscale/run.sh calls the real tailscale CLI
internally, so the bare name would let a zz_use-installed copy shadow the
actual binary it depends on.

Every feature's "dependencies" now also declares "@vps/common": "*" (a
real workspace dependency - every feature sources common/run.sh), on top
of any existing @vps/<feature> deps. Since common/ (and summary/) aren't
installable steps, dispatch.sh's feature_deps() now excludes them from
the dependencies it reads for auto-enable/--down-<step> refusal, so they
never get treated as toggleable steps despite being real dependencies.

common/package.json's own two dependencies (zz_colors, zz_log) live in
the separate tomgrv/scripts repo, not as workspace members here - listing
them as plain "dependencies" entries would make `npm install` try (and
fail) to resolve them from the registry. Documented instead under a new,
npm-ignored "zzUse" field.

Extended tests/test-syntax.bats to cover all of the above; README.md's
"One folder per feature" section and common/README.md updated to match.
The previous commit's "bin": {"vps-tailscale": "run.sh"} in
tailscale/package.json didn't actually prevent the collision it was meant
to: zz_use has no awareness of package.json's "bin" field at all - it
always installs <name>/run.sh under the literal folder name <name> it
was asked for. zz_use perspikapps/vps/tailscale would still have
installed this feature's own script as "tailscale", shadowing the real
Tailscale CLI it calls internally.

Renamed the folder itself instead - the only thing zz_use actually keys
off. package.json's own "name" field stays "@vps/tailscale" (that's what
dispatch.sh reads for feature identity/CLI flags - --only-tailscale etc.
are unchanged), so only the folder differs from every other feature's own
name. Verified end-to-end against the real pushed branch: zz_use
perspikapps/vps/vps-tailscale now installs cleanly under that name, with
no "tailscale" binary ever created by it.

Simplified tests/test-syntax.bats accordingly (folder/bin names are
uniform again - no more special-casing) and added a guard test that no
package.json's bin ever uses the bare "tailscale" name.
1/ Every package.json's "name" and "dependencies" keys move from
@vps/<name> to @tomgrv/vps-<name>, matching the org scope used
elsewhere (tomgrv/scripts, tomgrv/devcontainer-features). Updated
dispatch.sh's feature_name()/pkg_deps() and common/run.sh's
feature_package_json() to match the new prefix; package-lock.json
regenerated; README and test fixtures updated throughout.

2/ Added a root setup.sh (mirroring tomgrv/scripts' own): a thin,
zero-prerequisite wrapper that installs zz_use by delegating to
tomgrv/scripts' setup.sh - the same "don't reimplement what you can
delegate to" reasoning that script itself uses for zz_use's bin-dir
logic. Every run.sh's bootstrap shrinks from a 3-line block embedding
the tomgrv/scripts URL directly to one line delegating to this repo's
own setup.sh instead:

    command -v zz_use >/dev/null 2>&1 || curl -fsSL "${VPS_SETUP_URL:-...}" | sh

so the tomgrv/scripts URL/env-var default now lives in exactly one
place. Documented the whole pattern in a new README section,
"Replicating this pattern in another repo", generic enough to copy into
a different codebase (this repo, tomgrv/devcontainer-features'
common-utils, and tomgrv/scripts itself already share this shape).

Extended tests/ to cover both: the new @tomgrv/vps-* dependency
declarations, and that every run.sh uses the centralized setup.sh
bootstrap rather than a duplicated tomgrv/scripts URL.
…patch.sh

Every feature's run.sh previously embedded its own
"command -v zz_use || curl ... setup.sh | sh" - one curl call per script.
Removed: dispatch.sh now runs setup.sh exactly once, up front (right
after the root check, before any feature runs), so zz_use is on PATH for
every feature's subprocess. Individual run.sh scripts no longer curl
anything themselves - they just fail fast with a one-line message
pointing at setup.sh if zz_use somehow still isn't there (e.g. run
standalone, outside dispatch.sh).

common/run.sh drops the bootstrap entirely: it's only ever reached by
sourcing from a caller that already passed this same check, so by the
time its own body runs, zz_use is guaranteed present.

Found and fixed a real bug this exposed under end-to-end testing:
common/run.sh's VPS_SETUP_ROOT was computed from its own BASH_SOURCE[0]
(wherever zz_use last installed it, e.g. /usr/local/bin/common) instead
of the calling script's location - since zz_use perspikapps/vps/common
always (re)installs rather than reusing a local checkout's sibling
common/run.sh (explicit org/repo requests never skip as "already
available"), this broke feature_package_json/net_port/all_network_ports
even inside a normal dispatch.sh run from a full checkout. Fixed to use
BASH_SOURCE[1] (the caller's location), matching the pattern net_port/
net_access already used.

Updated README.md's "Layout", standalone-run, and "Replicating this
pattern in another repo" sections to match; extended tests/ with two new
checks (no run.sh curls setup.sh itself; dispatch.sh bootstraps zz_use
exactly once).
Removed comments that only restated what the following line already
does, historical/rationale narration (why a decision was made, links to
external docs), and header "Env vars:" blocks duplicating README's env
var tables - keeping just a one-line pointer to README instead. Every
run.sh's header comment shrinks to a single line.

Kept: every runtime log/warn/die message an operator actually sees while
running the script (these are the usability payload, not noise) -
including the detailed failure diagnostics in argocd/epinio's helm
timeout handling and dispatch.sh's TAILSCALE_AUTHKEY guard. Kept the
handful of comments that explain a genuinely non-obvious gotcha
(random_password's SIGPIPE/pipefail interaction, the ERR trap, the
BASH_SOURCE[1] indirection in VPS_SETUP_ROOT) but compressed them to one
line each.

Also fixed a real doc gap this exposed: setup.sh's own trimmed comment
was the only place documenting its ZZ_SCRIPTS_REF/ZZ_SCRIPTS_SETUP_URL
override env vars - moved that one line to README's Layout section
instead of just dropping it.

~230 lines removed across dispatch.sh, setup.sh, common/run.sh, and
every feature's run.sh; behavior unchanged (bats/shellcheck/sh -n all
still pass).
Missed in the previous rationalization pass - the test name already
says what it checks.
Removes the log()/warn()/die() wrapper functions from common/run.sh
(ok() is kept - it's not a thin proxy the same way) and updates every
call site across the feature scripts to call zz_log i/w/e directly,
adding an explicit exit 1 where die() previously did. dispatch.sh's
own independent log/warn/die are untouched since it must stay a
zero-dependency POSIX sh entrypoint that runs before zz_use exists.
…ch.sh

setup.sh now execs package.json's "main" (dispatch.sh) after
installing zz_use, forwarding args through - so `curl setup.sh | sh
-s -- --only-rancher` behaves the same as calling dispatch.sh
directly. dispatch.sh's own zz_use bootstrap now forwards "$@" the
same way when it falls back to setup.sh, and the check moved earlier
(right after the OS check) so a fresh install doesn't re-run the
interactive menu twice. Matches the shared setup.sh pattern now used
across tomgrv/scripts and tomgrv/devcontainer-features.
Avoids colliding with other repos' own SETUP_DIR-shaped env vars by
keeping this script's local var under the zz_ namespace convention.
A curl | sh pipeline's exit status is sh's, not curl's, so a failed
download would go unnoticed under set -e. Download to a temp file
and run that instead - same fix applied to the scripting devcontainer
feature's copy of this template (tomgrv/devcontainer-features#139).
Same hardening as tomgrv/scripts's copy of this template: reject
absolute paths and ".." segments in "main" before using it to build
a file path, and invoke sh with "--" for defense in depth.
- common/run.sh: feature_package_json()/all_network_ports() now only
  scan directories that have a run.sh alongside package.json, so a
  checked-out node_modules/ (thousands of unrelated package.json
  files) is no longer traversed/jq-parsed on every call.
- README: fix a leftover "tailscale/" reference (folder is
  vps-tailscale/), clarify that curl | sh only bootstraps zz_use
  without a local checkout to find package.json/dispatch.sh in, and
  note the jq prerequisite in the standalone zz_use example.
- tests: fixture dirs get a run.sh to match the new filter, plus a
  regression test asserting node_modules/* ports are skipped.
@github-actions github-actions Bot changed the title chore: allow git push/tag without prompting chore: 🔧 allow git push/tag without prompting Aug 27, 2026

tomgrv commented Aug 27, 2026

Copy link
Copy Markdown
Contributor Author

validate-pr-secret is failing here for the same reason as on #4: tomgrv/actions/check-secret's gitleaks step requires a GITLEAKS_LICENSE org secret for organization accounts, which still isn't set on perspikapps. Not something fixable from this PR's diff - needs an org owner to add a GITLEAKS_LICENSE secret (from gitleaks.io) to the perspikapps org or this repo.


Generated by Claude Code

@tomgrv
tomgrv marked this pull request as ready for review August 27, 2026 19:07
@tomgrv
tomgrv merged commit ee4c1e0 into develop Aug 27, 2026
4 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants