diff --git a/README.md b/README.md index 5afd4ac..0ddf800 100644 --- a/README.md +++ b/README.md @@ -510,6 +510,42 @@ When two venfork commands race the config update, the losing one's push is rejec That means concurrent runs are normally invisible to the user — both updates land. Only after sustained contention (3 lease failures in a row) does venfork surface the error and ask you to re-run the command. Don't `--force` the config branch by hand to "fix" a transient lease failure; that's exactly the data-loss path the lease prevents. +#### Consumers reading `venfork-config` directly + +Because every config-mutating command replaces (rather than appends to) the `venfork-config` branch tip, **a plain refspec fetch is rejected as non-fast-forward**: + +```bash +# This FAILS after any venfork config update: +git fetch origin venfork-config:venfork-config +# ! [rejected] venfork-config -> venfork-config (non-fast-forward) +``` + +Tools that maintain a long-lived local clone and read the config branch must use a **forced refspec**: + +```bash +# Force-update the local ref — safe because the branch is intentionally replaced: +git fetch origin +venfork-config:venfork-config +# or equivalently: +git fetch --force origin venfork-config:venfork-config +``` + +**Preferred approach — use the venfork library helpers:** The `readVenforkConfigFromRepo` and `fetchVenforkConfig` functions exported from the `venfork` package handle this internally (they read via `FETCH_HEAD` / a fresh clone without touching any local ref), so you never hit the non-fast-forward edge case: + +```js +import { readVenforkConfigFromRepo } from 'venfork'; + +// Always returns the current remote config — no local-ref management needed. +const config = await readVenforkConfigFromRepo('/path/to/mirror-clone'); +``` + +Or, if you don't have a local clone: + +```js +import { fetchVenforkConfig } from 'venfork'; + +const config = await fetchVenforkConfig('github-org/private-mirror'); +``` + ## Complete Workflow ### Initial Setup diff --git a/package.json b/package.json index aa0ce6d..ef1c24b 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,11 @@ "bin": { "venfork": "./dist/index.js" }, + "exports": { + ".": "./dist/lib.js" + }, "scripts": { - "build": "bun build ./src/index.ts --outdir ./dist --target node", + "build": "bun build ./src/index.ts ./src/lib.ts --outdir ./dist --target node", "compile": "bun build ./src/index.ts --compile --outfile ./dist/venfork", "dev": "bun run ./src/index.ts", "test": "bun test", diff --git a/src/lib.ts b/src/lib.ts new file mode 100644 index 0000000..c4207a8 --- /dev/null +++ b/src/lib.ts @@ -0,0 +1,23 @@ +/** + * Venfork public library API. + * + * Downstream tools (bots, CI scripts, triage automation) should use + * these exports to read venfork config instead of fetching the + * `venfork-config` branch directly. Both helpers handle the + * force-push semantics of the config branch internally: they never + * update a local ref, so they are safe to call from a long-lived + * clone without ever hitting a non-fast-forward rejection. + */ +export { + fetchVenforkConfig, + readVenforkConfigFromRepo, +} from './config.js'; + +export type { + PulledIssue, + PulledPr, + ShippedBranch, + ShippedIssue, + VenforkConfig, + VenforkConfigPatch, +} from './config.js';