Harden split-repo publish script with credential-helper auth

This commit is contained in:
Joshua 2026-02-17 20:50:59 -08:00
parent 27b5900205
commit 7ef7c662f3
3 changed files with 74 additions and 19 deletions

View File

@ -102,7 +102,7 @@ README.md
## Scripts ## Scripts
1. `scripts/publish_split_repos.sh` - creates/pushes `launcher`, `governance`, `contracts` repos using a Gitea PAT. 1. `scripts/publish_split_repos.sh` - creates/pushes `launcher`, `governance`, `contracts` repos using either a provided Gitea PAT or git credential-helper auth for `git.workvsg.com`.
## Internationalization ## Internationalization

View File

@ -1,12 +1,12 @@
# Repo Split Publish Runbook # Repo Split Publish Runbook
Use this runbook after valid Gitea API credentials (username + PAT) are available. Use this runbook after valid Gitea credentials are available (PAT or git credential-helper username/password).
## Local Seed Repos (already initialized) ## Local Seed Repos (already initialized)
1. `launcher` at `/Users/vsg/Documents/VSG Codex/launcher` (commit `b716b52`) 1. `launcher` at `/Users/vsg/Documents/VSG Codex/launcher` (commit `caf06d2`)
2. `governance` at `/Users/vsg/Documents/VSG Codex/governance` (commit `12d5e7c`) 2. `governance` at `/Users/vsg/Documents/VSG Codex/governance` (commit `823f201`)
3. `contracts` at `/Users/vsg/Documents/VSG Codex/contracts` (commit `082b29b`) 3. `contracts` at `/Users/vsg/Documents/VSG Codex/contracts` (commit `dbac2f0`)
## Create Remote Repos ## Create Remote Repos
@ -24,13 +24,20 @@ curl -fsSL -H "Authorization: token <TOKEN>" -H "Content-Type: application/json"
Repeat for `governance` and `contracts`. Repeat for `governance` and `contracts`.
Or run the helper: Or run the helper with PAT:
```bash ```bash
cd "/Users/vsg/Documents/VSG Codex/web" cd "/Users/vsg/Documents/VSG Codex/web"
./scripts/publish_split_repos.sh <gitea_pat> ./scripts/publish_split_repos.sh <gitea_pat>
``` ```
Or run it without arguments to use git credential helper auth for `git.workvsg.com`:
```bash
cd "/Users/vsg/Documents/VSG Codex/web"
./scripts/publish_split_repos.sh
```
## Push Local Seed Repos ## Push Local Seed Repos
```bash ```bash

View File

@ -1,15 +1,57 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -euo pipefail set -euo pipefail
if [[ $# -lt 1 ]]; then usage() {
echo "Usage: $0 <gitea_pat> [org] [host]" >&2 echo "Usage: $0 [gitea_pat] [org] [host]" >&2
exit 1 echo "If gitea_pat is omitted, script tries git credential helper for host auth." >&2
fi }
TOKEN="$1" TOKEN="${1:-}"
ORG="${2:-edut}" ORG="${2:-edut}"
HOST="${3:-git.workvsg.com}" HOST="${3:-git.workvsg.com}"
ROOT="/Users/vsg/Documents/VSG Codex" ROOT="/Users/vsg/Documents/VSG Codex"
AUTH_MODE=""
AUTH_USERNAME=""
AUTH_PASSWORD=""
init_auth() {
if [[ -n "$TOKEN" ]]; then
AUTH_MODE="token"
return
fi
local cred user pass
cred=$(printf 'protocol=https\nhost=%s\n\n' "$HOST" | git credential fill || true)
user=$(printf '%s\n' "$cred" | awk -F= '/^username=/{print $2}')
pass=$(printf '%s\n' "$cred" | awk -F= '/^password=/{print $2}')
if [[ -n "$user" && -n "$pass" ]]; then
AUTH_MODE="basic"
AUTH_USERNAME="$user"
AUTH_PASSWORD="$pass"
return
fi
usage
echo "No PAT provided and no git credentials found for ${HOST}." >&2
exit 1
}
curl_api() {
local method="$1"
local url="$2"
local data="${3:-}"
local -a cmd=(curl -sS -w "%{http_code}" -o /tmp/edut_api.out -X "$method")
if [[ "$AUTH_MODE" == "token" ]]; then
cmd+=(-H "Authorization: token ${TOKEN}")
else
cmd+=(-u "${AUTH_USERNAME}:${AUTH_PASSWORD}")
fi
if [[ -n "$data" ]]; then
cmd+=(-H 'Content-Type: application/json' -d "$data")
fi
cmd+=("$url")
"${cmd[@]}"
}
create_repo() { create_repo() {
local name="$1" local name="$1"
@ -18,20 +60,24 @@ create_repo() {
local api="https://${HOST}/api/v1/repos/${ORG}/${name}" local api="https://${HOST}/api/v1/repos/${ORG}/${name}"
local status local status
status=$(curl -sS -o /tmp/repo_check_${name}.json -w "%{http_code}" \ status=$(curl_api "GET" "$api")
-H "Authorization: token ${TOKEN}" \
"$api")
if [[ "$status" == "200" ]]; then if [[ "$status" == "200" ]]; then
echo "Repo ${ORG}/${name} already exists" echo "Repo ${ORG}/${name} already exists"
return return
fi fi
if [[ "$status" != "404" ]]; then
echo "Repo check failed for ${ORG}/${name} (status=${status})" >&2
cat /tmp/edut_api.out >&2 || true
exit 1
fi
curl -fsSL \ status=$(curl_api "POST" "https://${HOST}/api/v1/orgs/${ORG}/repos" "{\"name\":\"${name}\",\"private\":${private},\"description\":\"${desc}\"}")
-H "Authorization: token ${TOKEN}" \ if [[ "$status" != "201" && "$status" != "200" ]]; then
-H 'Content-Type: application/json' \ echo "Repo create failed for ${ORG}/${name} (status=${status})" >&2
-X POST "https://${HOST}/api/v1/orgs/${ORG}/repos" \ cat /tmp/edut_api.out >&2 || true
-d "{\"name\":\"${name}\",\"private\":${private},\"description\":\"${desc}\"}" >/tmp/repo_create_${name}.json exit 1
fi
echo "Created repo ${ORG}/${name}" echo "Created repo ${ORG}/${name}"
} }
@ -51,6 +97,8 @@ wire_and_push() {
echo "Pushed ${local_dir} -> ${remote_url}" echo "Pushed ${local_dir} -> ${remote_url}"
} }
init_auth
create_repo "launcher" "true" "EDUT free launcher shell and wallet onboarding app" create_repo "launcher" "true" "EDUT free launcher shell and wallet onboarding app"
create_repo "governance" "true" "EDUT deterministic governance runtime" create_repo "governance" "true" "EDUT deterministic governance runtime"
create_repo "contracts" "false" "EDUT membership and entitlement contracts" create_repo "contracts" "false" "EDUT membership and entitlement contracts"