# welcome-to-codevalet-as-a-contributor # # Recipe definitions for the contributor onboarding flow. # Implementation lives in scripts/; each script has corresponding # tests under tests/. set shell := ["bash", "-euo", "pipefail", "-c"] set dotenv-load := true set positional-arguments # Default: show the onboarding plan and the recipe list. default: @just welcome @echo "" @just --list # Full interactive onboarding. Accepts --headless / --no-browser. Honours FORGE_SETUP_YES=1. setup *args: @bash scripts/setup.sh {{args}} # Print the onboarding plan. welcome: @echo "================================================================" @echo " Welcome to codevalet." @echo "================================================================" @echo "" @echo " just setup # full onboarding flow" @echo " just setup --headless # same, without opening a browser" @echo " just next-steps # print the orchestrator's onboarding plan" @echo " just run-next-steps # execute that plan (== just contributor-setup" @echo " # inside the orchestrator checkout)" @echo " just relogin # switch Gitea user on this machine" @echo " just --list # every available recipe" # Check prerequisites (tools + Python version + PATH hygiene). doctor: @bash scripts/doctor.sh # Create .env from .env.example the first time. Never overwrites. init-env: @if [ -f .env ]; then \ echo "[init-env] .env already exists; leaving it alone."; \ else \ cp .env.example .env; \ echo "[init-env] wrote .env"; \ echo "[init-env] EDIT IT NOW and fill in the 1 blank marked (ASK): FORGE_GITEA_USERNAME."; \ fi # Ping Gitea /api/v1/version to confirm FORGE_GITEA_URL is reachable. check-gitea: @test -n "${FORGE_GITEA_URL:-}" \ || { echo "[error] FORGE_GITEA_URL unset: run 'just init-env' and edit .env"; exit 1; } @echo "[check-gitea] GET $FORGE_GITEA_URL/api/v1/version" @curl -fsS --max-time 10 ${FORGE_INSECURE_TLS:+-k} "$FORGE_GITEA_URL/api/v1/version" \ | python3 -c 'import json,sys; d=json.load(sys.stdin); print("[check-gitea] Gitea version:", d.get("version","?"))' @echo "[check-gitea] OK: Gitea reachable." # Browser OAuth2 (PKCE) login. Reuses a live token; runs the flow otherwise. login: @bash scripts/forge_login.sh # Like `just login`, but prints the URL instead of opening a browser. login-headless: @bash scripts/forge_login.sh --no-browser # Clear stored Gitea tokens (keeps the credential helper installed and the orchestrator-gateway fields). Run `just login` afterwards to sign in as a different user. logout: @python3 scripts/forge_auth.py logout # `just logout` + `just login` in one step. Equivalent to switching users. relogin: @bash scripts/forge_login.sh --force # Open Gitea's "Authorized OAuth2 Applications" page to revoke a stale grant. Resolves the "different scope" failure mode (see docs/oauth-grant-scope-mismatch.md). revoke-grant: @bash scripts/revoke_grant.sh # Force a token refresh (normally automatic inside the credential helper). refresh: @python3 scripts/forge_auth.py refresh --force # Print the current OAuth state (paths, whether the token is live). status: @python3 scripts/forge_auth.py status # git ls-remote against FORGE_ORCHESTRATOR_REPO_URL to confirm access. check-access: @test -n "${FORGE_ORCHESTRATOR_REPO_URL:-}" \ || { echo "[error] FORGE_ORCHESTRATOR_REPO_URL unset: run 'just init-env' and edit .env"; exit 1; } @echo "[check-access] git ls-remote $FORGE_ORCHESTRATOR_REPO_URL" @GIT_TERMINAL_PROMPT=0 GCM_INTERACTIVE=Never \ GIT_ASKPASS='' SSH_ASKPASS='' \ VSCODE_GIT_ASKPASS_MAIN='' VSCODE_GIT_ASKPASS_NODE='' \ VSCODE_GIT_ASKPASS_EXTRA_ARGS='' VSCODE_GIT_IPC_HANDLE='' \ DISPLAY='' WAYLAND_DISPLAY='' \ git ls-remote "$FORGE_ORCHESTRATOR_REPO_URL" HEAD >/dev/null 2>&1 \ && { \ echo "[check-access] OK: orchestrator reachable."; \ } || { \ echo "[check-access] FAILED. Likely causes:"; \ echo " - 'just login' has not completed yet"; \ echo " - stored refresh token expired; run 'just relogin'"; \ echo " - Gitea account is not yet in the org"; \ echo " - FORGE_ORCHESTRATOR_REPO_URL in .env is wrong"; \ exit 1; \ } # Clone the orchestrator into FORGE_WORKSPACE_ROOT (idempotent). clone-orchestrator: @test -n "${FORGE_ORCHESTRATOR_REPO_URL:-}" \ || { echo "[error] FORGE_ORCHESTRATOR_REPO_URL unset: run 'just init-env' and edit .env"; exit 1; } @bash -c 'set -euo pipefail; \ root="${FORGE_WORKSPACE_ROOT:-.}"; \ mkdir -p "$root"; \ name="$(basename "$FORGE_ORCHESTRATOR_REPO_URL" .git)"; \ dest="$root/$name"; \ if [ -d "$dest/.git" ]; then \ echo "[clone-orchestrator] already cloned at: $dest"; \ else \ echo "[clone-orchestrator] cloning into: $dest"; \ export GIT_TERMINAL_PROMPT=0 GCM_INTERACTIVE=Never; \ unset GIT_ASKPASS SSH_ASKPASS \ VSCODE_GIT_ASKPASS_MAIN VSCODE_GIT_ASKPASS_NODE \ VSCODE_GIT_ASKPASS_EXTRA_ARGS VSCODE_GIT_IPC_HANDLE \ DISPLAY WAYLAND_DISPLAY; \ if [ -n "${FORGE_ORCHESTRATOR_BRANCH:-}" ]; then \ git clone --branch "$FORGE_ORCHESTRATOR_BRANCH" "$FORGE_ORCHESTRATOR_REPO_URL" "$dest" \ || { echo "[clone-orchestrator] FAILED. Run \"just login\" (or \"just relogin\" if expired) and retry." >&2; exit 1; }; \ else \ git clone "$FORGE_ORCHESTRATOR_REPO_URL" "$dest" \ || { echo "[clone-orchestrator] FAILED. Run \"just login\" (or \"just relogin\" if expired) and retry." >&2; exit 1; }; \ fi; \ fi; \ echo; \ echo "[clone-orchestrator] orchestrator is at:"; \ echo " $dest"; \ echo; \ echo "Next: cd into it and follow its README (or run \"just next-steps\")."' # Print the contributor onboarding plan from the orchestrator's manifest. next-steps *args: @bash scripts/next_steps.sh {{args}} # Exec the orchestrator's `just contributor-setup`; forwards all flags. run-next-steps *args: @bash scripts/next_steps.sh --run {{args}} # Remove the credential helper and repo-managed fields from client-auth.json. uninstall: @bash scripts/uninstall.sh # Run the full test suite. test: @echo "[test] running Python unit tests..." @python3 -m unittest discover -t . -s tests -p 'test_*.py' -v @echo "" @echo "[test] running shell integration tests..." @bash tests/test_forge_auth_integration.sh @echo "" @echo "[test] running setup.sh argument / headless-wiring test..." @bash tests/test_setup_args.sh @echo "" @echo "[test] running doctor.sh fix-command test..." @bash tests/test_doctor.sh @echo "" @echo "[test] running next_steps.sh manifest-driven test..." @bash tests/test_next_steps.sh