Merge pull request #162 from aaronsb/delivery/release-strategy-adr

docs: ADR-300 single-branch release strategy + retire defunct PR guidance
This commit is contained in:
Aaron Bockelie 2026-05-16 11:40:32 -05:00 committed by GitHub
commit 3cd6a1cb27
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 133 additions and 48 deletions

View file

@ -356,60 +356,38 @@ async getFile(path: string): Promise<ObsidianFileResponse> {
- **Migration Success**: Smooth transition for existing users
- **Plugin Directory**: Successful submission and approval
## Obsidian Community Plugin Submission
## Obsidian Community Plugin Distribution
### Maintaining PR During Review Process
> **Historical note:** Obsidian previously required a pull request against the
> `obsidianmd/obsidian-releases` repo (editing `community-plugins.json`) plus a
> manual "keep the PR alive" refresh dance. **That process is defunct.**
> Obsidian moved submission and maintenance to the community developer portal
> (community.obsidian.md). Do not recreate the `obsidian-releases` fork
> workflow — there is no PR to maintain anymore.
While waiting for Obsidian team review (typically 2-6 weeks), keep the PR active:
### How distribution works now
#### "I'm Not Dead Yet" PR Refresh Procedure
The portal scans this repo's **GitHub Releases**. For the plugin to be
scanned and distributed:
When the PR has been idle and needs to show activity, or when validation checks need to be refreshed:
- There must be a **stable (non-prerelease) "Latest" release** whose tag
exactly matches the `version` field in `manifest.json`.
- Release tags use **no `v` prefix**`0.11.21`, not `v0.11.21`. The release
workflow already produces the correct format.
- `versions.json` must contain a `"<version>": "<minAppVersion>"` entry
matching `manifest.json` (`make release-*` maintains this).
- Releases ship as **prereleases by default**, and a prerelease is invisible
to the portal. Run `make promote` to flip the proven release to
stable + "Latest". This is the step that makes the directory (and the MCPB
`releases/latest/download/...` link) pick up the new version.
```bash
# 1. Navigate to the obsidian-releases fork
cd /home/aaron/Projects/app/obsidian-releases
### Validating before publishing
# 2. Fetch latest upstream changes
git fetch upstream
# 3. Hard reset to upstream (clean slate)
git reset --hard upstream/master
# 4. Edit community-plugins.json to add plugin entry at the END
# Add your plugin entry after the LAST plugin in the current list
# (The bot checks that new entries are at the end)
# 5. Commit and push to trigger validation
git add community-plugins.json
git commit -m "chore: Update PR with latest upstream changes"
git push --force origin master
```
**Key Points:**
- Always add your plugin entry at the **END** of `community-plugins.json` (after the current last plugin)
- Do NOT try to preserve your original queue position - the bot now requires entries at the end
- The validation bot triggers automatically within a few minutes after pushing
- This shows the PR is actively maintained and not abandoned
- Can be done periodically (e.g., monthly) to keep PR visible
#### Validation Bot Requirements
- Plugin entry MUST be at the end of the list
- `authorUrl` should be your GitHub profile (not Obsidian website)
- `fundingUrl` should be your sponsors page or removed if not applicable
- All checks must pass before human review begins
#### Benefits of Active Development During Review
- Shows ongoing maintenance and commitment
- Allows continuous improvement based on BRAT user feedback
- Keeps PR current with upstream changes
- Demonstrates plugin stability through multiple versions
- Prevents PR from being auto-closed due to inactivity
#### Release Tag Format
- **Important**: Obsidian requires release tags WITHOUT 'v' prefix
- Use `0.5.4` not `v0.5.4`
- GitHub Actions workflow configured to create correct format
The developer portal offers a **"preview a branch scan"** that accepts a
branch, tag, or commit SHA — use it to confirm a release candidate passes
Obsidian's checks *before* running `make promote`. Treat it as a
validation/dry-run tool: end-user installs and updates still come from the
matching stable release tag's assets, not from a scanned branch.
## Important Notes

View file

@ -30,3 +30,10 @@ _MCP tool design, semantic operations, graph operations, formatters_
| ADR | Title | Status |
|-----|-------|--------|
| [ADR-200](./tools/ADR-200-close-cli-parity-gaps-add-daily-notes-tasks-templates-and-properties-operations.md) | Close CLI parity gaps — add daily notes, tasks, templates, and properties operations | Draft |
## Delivery
_Build, release, versioning, community plugin submission_
| ADR | Title | Status |
|-----|-------|--------|
| [ADR-300](./delivery/ADR-300-single-branch-release-strategy-with-prerelease-promote.md) | Single-branch release strategy with prerelease/promote | Accepted |

View file

@ -0,0 +1,100 @@
---
status: Accepted
date: 2026-05-16
deciders:
- aaronsb
- claude
related: []
---
# ADR-300: Single-branch release strategy with prerelease/promote
## Context
Obsidian retired the `obsidianmd/obsidian-releases` pull-request submission
process and moved community-plugin submission/maintenance to the developer
portal at community.obsidian.md. After migration, our listing reported
"No release matches your manifest version" even though tag `0.11.21` existed
with correct (no-`v`-prefix) format and matching `versions.json` entry. The
cause: the portal only scans the latest **stable** GitHub release, and
`0.11.21` was flagged as a prerelease while `0.11.20` was the latest stable.
`make promote` resolved it.
This raised a broader question: should we add a dedicated long-lived
**release branch** for the Obsidian community, letting `main` move fast
(prereleases, experimental work) while a slower branch holds only
community-blessed commits?
Investigation established two facts:
1. `main` is already release-safe. Pushing to `main` triggers no release;
`release.yml` is `workflow_dispatch`-only. Releases are deliberate acts.
2. Releases ship as **prereleases by default**; the portal and auto-update
users only ever see the one release deliberately promoted via
`make promote`.
The deciding question was whether `main` carries work that must *never*
reach a community release (permanent divergence) or merely "not yet"
(temporal lag). The answer: **same code, slower cadence** — nothing on
`main` is permanently excluded from community releases; the community simply
gets blessed commits later.
## Decision
Maintain a **single `main` branch**. Do **not** introduce a release branch
for the Obsidian community.
Decouple our development cadence from community expectations **temporally,
not structurally**:
- Work proceeds on `main`. `make release-*` cuts prereleases at any cadence;
BRAT testers ride these with no community impact.
- When a prerelease is proven, `make promote` flips it to stable + "Latest".
That release — and only that release — is what the Obsidian directory and
auto-update users receive.
- "Slower community cadence" is expressed as **promoting less often than we
prerelease**. The gap between latest prerelease and latest promoted release
*is* the decoupling.
- Promotion is a deliberate bless gate, not reflexive. The portal's
"preview a branch scan" (branch/tag/SHA) may be pointed at a candidate tag
as a pre-promote validation check — it is a dry-run tool, not a
distribution channel.
## Consequences
### Positive
- No version-file divergence. `package.json`, `manifest.json`,
`versions.json`, `src/version.ts` have one source of truth on `main`.
- No cross-branch cherry-pick discipline or recurring version-bump merge
conflicts.
- Decoupling is achieved with the mechanism that already exists; no new
process to learn or maintain.
### Negative
- The fast/slow boundary lives in human discipline (when to `make promote`)
rather than in branch structure. A reflexive promote collapses the
decoupling.
### Neutral
- Requires that `make promote` remain a conscious, infrequent act relative
to prerelease cadence.
- If the relationship ever changes to *permanent* divergence (community-only
metadata, gated-out features), this decision must be revisited — a release
branch would then be justified and this ADR superseded.
## Alternatives Considered
- **Dedicated Obsidian community release branch.** A long-lived branch
holding only blessed commits, releases cut from it, `main` racing ahead.
Rejected: for "same code, slower cadence" it reproduces — at the cost of
permanent version-file divergence and cherry-pick discipline — a
decoupling the prerelease/promote flow already provides for free. Its only
genuine value is permanent divergence between `main` and community builds,
which does not apply here.
- **Stable-by-default releases (drop prerelease default).** Removes the
`make promote` step. Rejected: eliminates the bake-in-prerelease safety
valve that BRAT testing depends on; every release would hit all users and
the directory immediately.