Files
josh-sync/docs/config-reference.md
SBPro dc2cdea360 Release 2.2.0 — unified onboard strategy + safety hardening
Folds `josh-sync adopt` into `josh-sync onboard <target>` as the adopt
strategy alongside the original reset flow. Strategy resolves by
precedence: --mode flag > targets[].history_lock config (preserve|rewrite)
> auto-detect via `git ls-remote --heads`. `josh-sync adopt` is kept as
a thin alias. Adds the new `targets[].history_lock` config field
(validated at parse time) and folds `<target>/adopt.json` state into
`<target>/onboard.json` with a `.strategy` field; legacy state files
are read with a backward-compat fallback.

Safety hardening (from a multi-angle review of the unification):
- auto-detect distinguishes auth/network failure from empty repo
- resume validates --mode against the strategy saved in state
- `josh-sync adopt` rejects a conflicting --mode in the forwarded args
- missing import-PR lookup dies in both strategies (was WARN+continue
  for reset, which could create duplicate import PRs on resume)
- --restart durably removes the legacy adopt.json from the state branch
- adopt_branch is now a subshell function (EXIT trap can't clobber callers)
- strategy value validated after resolve/load (reset|adopt)
- --mode with missing/empty value dies with a usage hint
- migrate-pr against an adopt-strategy target dies with a specific hint
- reset importing asserts archived_url is present (no "null" → git clone)

End-to-end + CLI bats coverage added (tests/unit/adopt_e2e.bats,
tests/unit/cli.bats). 72 tests, shellcheck clean.

Makefile dist bundle header now correctly interpolates VERSION and
line count.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 03:32:04 +01:00

5.1 KiB

Configuration Reference

Full reference for .josh-sync.yml fields and environment variables.

.josh-sync.yml Structure

schema_version: 2   # required since v2.0.0
josh:               # josh-proxy + monorepo settings (required)
targets:            # sync targets (required, at least 1)
bot:                # bot identity for sync commits (required)

schema_version

Type Required Description
integer Yes Must be 2 for josh-sync v2.x configs. v1 configs are rejected; see Changelog v2.0.0 for migration.

josh Section

Field Type Required Description
proxy_url string Yes Josh-proxy URL, no trailing slash. Must start with http:// or https://.
monorepo_path string Yes Repository path as josh-proxy sees it (e.g., org/monorepo).
monorepo_url string Yes Monorepo git clone URL — git@host:org/repo.git (SSH), ssh://..., or https://host/org/repo.git. The gitea host is derived from this URL and used for the PR API and direct clones, decoupled from any target's host.
monorepo_auth string No (default "https") Clone auth method: "https" (injects ${SYNC_BOT_USER}:${SYNC_BOT_TOKEN} into the URL) or "ssh" (uses the user's ssh-agent / ~/.ssh/config). PR creation always uses GITEA_TOKEN regardless.

targets[] Section

Each target maps a monorepo subfolder to an external subrepo.

Field Type Required Default Description
name string Yes Unique target identifier. Used in CLI commands and state tracking.
subfolder string Yes Monorepo subfolder path (e.g., services/billing).
josh_filter string No :/<subfolder> Josh filter expression. Auto-derived from subfolder if omitted. Must start with :.
subrepo_url string Yes External subrepo Git URL. Supports HTTPS (https://...), SSH (git@host:path), and ssh:// formats.
subrepo_auth string No "https" Auth method: "https" or "ssh".
subrepo_token_var string No "SUBREPO_TOKEN" Name of the env var holding the HTTPS token for this target.
subrepo_ssh_key_var string No "SUBREPO_SSH_KEY" Name of the env var holding the SSH private key for this target.
branches object Yes Branch mapping: mono_branch: subrepo_branch. Each key-value pair syncs those branches bidirectionally.
forward_only string[] No [] Branches that only sync mono → subrepo, never reverse.
exclude string[] No [] File/directory patterns to exclude from sync via josh :exclude filter. Excluded files exist only in the monorepo, never in the subrepo. See Excluding Files.
history_lock string No (auto-detect) Onboarding strategy hint. "preserve" selects the non-destructive adopt strategy (keeps subrepo history via an adoption merge — ADR-013); "rewrite" selects the destructive reset strategy (force-pushes josh-filtered history). When omitted, josh-sync onboard auto-detects: subrepos with branches → adopt, empty subrepos → reset. The CLI flag --mode={reset,adopt} overrides this.

bot Section

Field Type Required Description
name string Yes Git author name for sync commits.
email string Yes Git author email for sync commits.
trailer string Yes Git trailer key for loop prevention (e.g., Josh-Sync-Origin).

Environment Variables

Credentials

Variable Purpose Default
SYNC_BOT_USER Bot's Git username
SYNC_BOT_TOKEN API token for monorepo access and josh-proxy HTTPS auth
SUBREPO_TOKEN HTTPS token for subrepo access Falls back to SYNC_BOT_TOKEN
SUBREPO_SSH_KEY SSH private key content (not a file path) for subrepo access

Per-target credential overrides

Set subrepo_token_var or subrepo_ssh_key_var in a target's config to read credentials from a different env var:

targets:
  - name: "auth"
    subrepo_token_var: "AUTH_REPO_TOKEN"    # reads from $AUTH_REPO_TOKEN
    subrepo_ssh_key_var: "AUTH_SSH_KEY"      # reads from $AUTH_SSH_KEY

Resolution order: per-target env var → default env var (SUBREPO_TOKEN / SUBREPO_SSH_KEY) → SYNC_BOT_TOKEN fallback.

Runtime

Variable Purpose Default
JOSH_SYNC_TARGET Restrict sync to a single target All targets
JOSH_SYNC_STATE_BRANCH Name of the orphan branch for state storage josh-sync-state
JOSH_SYNC_DEBUG Enable verbose logging (1 to enable) 0
MONOREPO_API Override the monorepo gitea PR API URL. Escape hatch for custom API endpoints; rarely needed. https://{monorepo_url's host}/api/v1/repos/{monorepo_path}

JSON Schema

The config file can be validated against the JSON Schema at schema/config-schema.json.