77 lines
3.1 KiB
Markdown
77 lines
3.1 KiB
Markdown
|
|
# ADR-010: Onboard Workflow with Checkpoint/Resume
|
||
|
|
|
||
|
|
**Status:** Accepted
|
||
|
|
**Date:** 2026-02
|
||
|
|
|
||
|
|
## Context
|
||
|
|
|
||
|
|
Onboarding an existing subrepo into the monorepo is a multi-step process that involves human interaction (renaming repos, merging PRs). The full flow is:
|
||
|
|
|
||
|
|
1. Prerequisites: rename existing repo, create new empty repo
|
||
|
|
2. Import: copy subrepo content into monorepo, create import PR(s)
|
||
|
|
3. Wait: human merges the import PR(s)
|
||
|
|
4. Reset: force-push josh-filtered history to the new empty repo
|
||
|
|
5. (Optional) Migrate open PRs from archived repo
|
||
|
|
|
||
|
|
Each step can fail or be interrupted. The process may span hours or days (waiting for PR review). If interrupted, restarting from scratch wastes work and can create duplicate PRs.
|
||
|
|
|
||
|
|
### Alternatives considered
|
||
|
|
|
||
|
|
1. **Single-shot script**: Run all steps in sequence. If interrupted, must restart from scratch. Duplicate PRs if import step is re-run.
|
||
|
|
|
||
|
|
2. **Manual step-by-step commands**: `import`, then manually run `reset`. Simple but error-prone — users may forget steps or run them out of order.
|
||
|
|
|
||
|
|
3. **Checkpoint/resume with persistent state**: Track the current step and intermediate results (PR numbers, reset branches) in persistent state. On re-run, resume from the last completed step.
|
||
|
|
|
||
|
|
## Decision
|
||
|
|
|
||
|
|
Implement `josh-sync onboard` as a checkpoint/resume workflow with state stored on the `josh-sync-state` branch at `<target>/onboard.json`.
|
||
|
|
|
||
|
|
### State machine
|
||
|
|
|
||
|
|
```
|
||
|
|
start → importing → waiting-for-merge → resetting → complete
|
||
|
|
```
|
||
|
|
|
||
|
|
Each transition is persisted before proceeding. Re-running `josh-sync onboard <target>` reads the current step and resumes.
|
||
|
|
|
||
|
|
### State schema
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"step": "waiting-for-merge",
|
||
|
|
"archived_api": "https://host/api/v1/repos/org/repo-archived",
|
||
|
|
"archived_url": "git@host:org/repo-archived.git",
|
||
|
|
"archived_auth": "ssh",
|
||
|
|
"import_prs": { "main": 42 },
|
||
|
|
"reset_branches": ["main"],
|
||
|
|
"migrated_prs": [
|
||
|
|
{ "old_number": 5, "new_number": 12, "title": "Fix login" }
|
||
|
|
],
|
||
|
|
"timestamp": "2026-02-10T14:30:00Z"
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Per-branch progress
|
||
|
|
|
||
|
|
Import and reset both iterate over branches. Progress is saved after each branch, so interruption mid-iteration resumes at the next unprocessed branch.
|
||
|
|
|
||
|
|
### PR migration
|
||
|
|
|
||
|
|
`josh-sync migrate-pr` is a separate command that reads onboard state (for the archived repo URL) and tracks migrated PRs. It uses `git apply --3way` for resilient patch application — the subrepo's content is identical after reset, so patches apply cleanly.
|
||
|
|
|
||
|
|
## Consequences
|
||
|
|
|
||
|
|
**Positive:**
|
||
|
|
- Safe to interrupt at any point — no duplicate work on resume
|
||
|
|
- Per-branch tracking prevents duplicate import PRs or redundant resets
|
||
|
|
- Archived repo URL stored in state — `migrate-pr` can operate independently
|
||
|
|
- `--restart` flag allows starting over if state is corrupted
|
||
|
|
- Human-friendly — prints instructions at each step
|
||
|
|
|
||
|
|
**Negative:**
|
||
|
|
- State management adds complexity (read/write onboard state, step validation)
|
||
|
|
- Interactive steps (`read -r`) are not suitable for fully automated pipelines
|
||
|
|
- Onboard state persists on the state branch even after completion (minor clutter)
|
||
|
|
- The step machine is linear — cannot skip steps or run them out of order
|