Breaking change. The monorepo's gitea host was previously inferred from the first target's subrepo_url, silently coupling the two and breaking on any multi-host setup (monorepo on host A, target on host B). v2.0.0 replaces the inference with a required josh.monorepo_url field that mirrors subrepo_url — same parsing, same SSH/HTTPS auth options, same shape. - schema_version: 2 is now required; v1 configs are rejected with a clear migration error - josh.monorepo_url is required; josh.monorepo_auth is optional (default https) - mono_auth_url() in lib/auth.sh mirrors subrepo_auth_url() - MONOREPO_API derives from monorepo_url's host instead of .[0].gitea_host; env-var override preserved as escape hatch - initial_import() and force-push call mono_auth_url() instead of building URLs inline - ADR-012 documents the rationale; CHANGELOG includes migration snippet Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.6 KiB
4.6 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. |
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.