> **Status:** Planned (design sketch — not yet executed)
## Background
Several BlumeOps projects need to track upstream repositories while maintaining local modifications. Examples include a personal Quartz fork (for docs site customization) and potentially other tools where upstream changes need to flow in continuously.
The current approach — Forgejo auto-tracking mirrors — works for read-only copies but breaks down when we need to:
| `feature/*-upstream` | `upstream/main` | Cherry-picked/rebased feature for upstream PR | `upstream/main` (on demand) |
### What Goes in `blumeops` vs `feature/*`
**`blumeops` branch** — infrastructure-level changes that are permanent and BlumeOps-specific:
- Delete upstream CI workflows (`.github/workflows/`)
- Add `mise.toml` for local tooling
- Add or modify configuration for the BlumeOps environment
- Patch version pins or dependency overrides
**`feature/*` branches** — functional changes to the project itself:
- Bug fixes you want to contribute upstream
- New features or customizations
- Anything that could theoretically stand on its own as a PR to the upstream project
This separation ensures the `blumeops` branch stays small and conflict-resistant (infrastructure changes rarely conflict with upstream code changes), while feature branches carry the substantive modifications.
## Daily Rebase Workflow
A Forgejo Actions workflow runs on a schedule to keep `blumeops` rebased onto the latest upstream:
### Workflow Outline
```
trigger: cron (daily) or manual dispatch
1. Fetch upstream remote
2. Check if upstream/main has new commits since last rebase
3. If no new commits → exit early
4. Attempt: git rebase blumeops --onto upstream/main
5. If rebase succeeds:
a. Force-push blumeops
b. For each feature/* branch:
- Attempt rebase onto updated blumeops
- If success → force-push
- If conflict → skip, record failure
6. If rebase fails (conflict):
a. Abort rebase
b. Create or update a Forgejo issue with conflict details
c. Label the issue for visibility
```
### Conflict Reporting
When a rebase fails, the workflow creates (or updates) a Forgejo issue via the API:
Set `blumeops` as the default branch in Forgejo repository settings.
### Step 5: Add the Rebase Workflow
Add `.forgejo/workflows/rebase-upstream.yaml` to the `blumeops` branch. This workflow is itself a blumeops-specific patch — upstream doesn't have it.
### Step 6: Protect Branches
Configure Forgejo branch protection:
-`blumeops`: only the rebase workflow (and manual push) can force-push
-`upstream/main`: read-only (only updated by the rebase workflow's `git fetch`)
## The Upstream PR Path
When a feature is ready to be proposed upstream:
1. Create `feature/foo-upstream` from `upstream/main`
2. Cherry-pick or rebase `feature/foo` commits onto it (excluding any `blumeops`-specific commits)
3. Push to the fork on the upstream platform (e.g., GitHub)
4. Open PR from the fork to upstream
This branch is maintained independently — it does not participate in the daily rebase. It's a point-in-time snapshot for the PR. If the PR needs updates, rebase it manually.
## First Instance: Quartz Fork
Quartz (the documentation site generator) is the planned first fork and the primary motivation for this strategy.
Changes that are permanently BlumeOps-specific and would never go upstream:
- Remove `.github/` workflows
- Add `mise.toml` with pinned Node version
- Configure Quartz defaults for BlumeOps site metadata
### Feature Work (`feature/*` branches)
The key feature motivating this fork is **`last-reviewed` frontmatter support**. BlumeOps documentation uses a `last-reviewed` date in frontmatter to track documentation staleness (see `mise run docs-review`). Upstream Quartz has no awareness of this field. The fork enables:
- **Rendering `last-reviewed` in article headers** — display when a doc was last reviewed, making staleness visible to readers without running CLI tools
- **Staleness indicators** — visual styling (e.g., a warning banner) for docs where `last-reviewed` exceeds a threshold
- **Sorting/filtering by review date** — Quartz explorer or listing pages that surface docs needing attention
This is a strong upstream PR candidate — other Quartz users maintaining knowledge bases would benefit from custom frontmatter rendering. The `feature/last-reviewed` branch would be developed on the `blumeops` branch (for local use) with a parallel `feature/last-reviewed-upstream` branch rebased onto `upstream/main` for the PR.
### Integration with Dagger Docs Build
This fork directly supports the [[adopt-dagger-ci]] plan. Once the fork exists, the Dagger `build_docs` function switches from cloning upstream Quartz to using the fork:
This means the `build-blumeops.yaml` workflow automatically picks up fork customizations (like `last-reviewed` rendering) when building docs — no separate integration step needed. Local iteration via `dagger call build-docs` also uses the fork, so you can test Quartz customizations against actual BlumeOps content before pushing.
## Open Questions
- **Rebase vs merge:** This plan uses rebase for a clean linear history. Merge commits would avoid force-pushes but create a messier history. Rebase is preferred for small forks; revisit if the commit volume grows.
- **Notification mechanism:** Forgejo issues are proposed for conflict reporting. Alternatives: email, Slack webhook, Todoist task via API. Issues are preferred because they're visible in the forge and can carry discussion.
- **Feature branch automation:** The daily rebase of feature branches onto `blumeops` is aggressive — it means feature branches are force-pushed daily. An alternative is to only rebase feature branches on demand (manually or via workflow dispatch). Start with manual and automate later based on experience.
- **Multiple upstreams:** Some projects track multiple remotes (e.g., a CNCF project with a GitHub mirror and a self-hosted primary). The workflow should support configurable upstream remote URLs.
## Future Considerations
- **Renovate integration** — Renovate could watch upstream tags and open PRs to the `blumeops` branch when new releases are available, complementing the daily rebase with release-aware updates
- **Dagger integration** — forked projects that produce build artifacts can use the BlumeOps Dagger module for builds, sharing the same local iteration and CI patterns
- **Template repository** — once the pattern is proven with quartz, create a template repo or mise task that scaffolds the branch structure and rebase workflow for new forks