diff --git a/.githooks/pre-push b/.githooks/pre-push new file mode 100755 index 0000000..55a5a5a --- /dev/null +++ b/.githooks/pre-push @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +set -euo pipefail + +remote_name="${1:-}" +remote_url="${2:-}" + +if [[ "$remote_name" != "tubco" && "$remote_url" != *"git.tub.co"* ]]; then + exit 0 +fi + +allowed=0 + +while read -r local_ref local_sha remote_ref remote_sha; do + [[ -z "${local_ref:-}" ]] && continue + + case "$local_ref" in + refs/heads/release/tubco-*) + allowed=1 + ;; + refs/tags/tubco-baseline-*) + allowed=1 + ;; + *) + echo "Blocked push to 'tubco': '$local_ref' is not an approved customer ref." >&2 + echo "Allowed refs:" >&2 + echo " refs/heads/release/tubco-*" >&2 + echo " refs/tags/tubco-baseline-*" >&2 + echo "Use origin for normal product work." >&2 + exit 1 + ;; + esac +done + +if [[ "$allowed" -eq 0 ]]; then + echo "Blocked push to 'tubco': no approved TUBCO refs were detected." >&2 + exit 1 +fi + +exit 0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7855842..b1e5530 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -58,6 +58,17 @@ Default rule: - normal product work goes to `origin` - TUBCO pushes happen only when explicitly requested +Safety rules in this repo: +- plain `git push` should default to `origin` +- pushes to `tubco` are guarded by a repo-local `pre-push` hook +- only these refs should go to `tubco`: + - `release/tubco-*` + - `tubco-baseline-*` + +Authentication rule: +- prefer a personal access token for the `tubco` HTTPS remote +- do not rely on a reusable account password long term + ## Current Delivery Model - GitHub Actions is used for CI - the current test server is local/LAN-only diff --git a/backend/workflows/templates/workflows/developer_handbook.html b/backend/workflows/templates/workflows/developer_handbook.html index b763ee1..9296073 100644 --- a/backend/workflows/templates/workflows/developer_handbook.html +++ b/backend/workflows/templates/workflows/developer_handbook.html @@ -104,6 +104,7 @@
./scripts/git_remote_target.sh status

Use the helper above before pushing if there is any doubt about which remote should receive the change.

+

Plain git push should default to origin, and a repo-local pre-push hook blocks accidental pushes to tubco unless the ref is an approved TUBCO branch or baseline tag.

Customer release branches

@@ -696,6 +697,7 @@ docker compose restart worker
./scripts/git_remote_target.sh set-own-identity
 ./scripts/git_remote_target.sh set-tubco-identity

Switch between the normal commit identity and the TUBCO customer identity when needed.

+

For the TUBCO HTTPS remote, prefer a personal access token instead of a reusable account password.

Direct server deployment

diff --git a/scripts/git_remote_target.sh b/scripts/git_remote_target.sh index f77de3a..3bb715f 100755 --- a/scripts/git_remote_target.sh +++ b/scripts/git_remote_target.sh @@ -18,7 +18,8 @@ Usage: Commands: status - Show current branch, current commit, active local git identity, and configured remotes. + Show current branch, current commit, active local git identity, configured remotes, + and the local push-safety settings. push-origin [ref] Push a ref to the main product remote "origin". @@ -59,11 +60,20 @@ show_identity() { fi } +show_push_safety() { + local push_default hooks_path + push_default="$(git config --local --get remote.pushDefault || true)" + hooks_path="$(git config --local --get core.hooksPath || true)" + echo "remote.pushDefault: ${push_default:-}" + echo "core.hooksPath: ${hooks_path:-}" +} + case "${1:-}" in status) echo "Branch: $(current_branch)" echo "Commit: $(git rev-parse --short HEAD)" show_identity + show_push_safety echo echo "Remotes:" git remote -v