mirror of
https://github.com/bitsofchris/openaugi-obsidian-plugin.git
synced 2026-07-22 05:46:42 +00:00
Codify the release process so we stop drifting version files and stop leaving the repo advertising a version with no published release (the inconsistency that plausibly got the plugin auto-removed from the store). - scripts/release.sh: one-shot, self-verifying release. Bumps manifest.json, package.json AND versions.json in lockstep, runs tests+build, pushes, tags (no v prefix), waits for CI, PUBLISHES the draft immediately, then verifies root manifest == released asset == tag. Includes a store-listing health check. - tests/version-consistency.test.ts: guard test — fails the build if the three version files ever disagree (catches a forgotten versions.json bump before tagging). - docs/PUBLISHING.md: rewritten script-first; adds versions.json (was omitted), the publish-immediately rule, and a 'if de-listed from the store' runbook (ask #plugin-dev, community.obsidian.md portal, the 'entry already exists' gotcha). - CLAUDE.md: quick-summary now points at the script and the three files. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
45 lines
1.8 KiB
TypeScript
45 lines
1.8 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import * as fs from 'fs';
|
|
import * as path from 'path';
|
|
|
|
// Guard test for the release contract. Obsidian resolves the "latest version"
|
|
// from manifest.json at the repo root, then downloads the GitHub release whose
|
|
// tag equals that version. If manifest.json / package.json / versions.json ever
|
|
// disagree, releases go out inconsistent — which is how the 0.6.0 release shipped
|
|
// with a stale package.json and a MISSING versions.json, and (plausibly) how the
|
|
// plugin got auto-removed from the community store. This test makes that drift a
|
|
// red build instead of a production incident. See docs/PUBLISHING.md.
|
|
|
|
const root = path.resolve(__dirname, '..');
|
|
const readJson = (rel: string) =>
|
|
JSON.parse(fs.readFileSync(path.join(root, rel), 'utf8'));
|
|
|
|
const SEMVER = /^\d+\.\d+\.\d+$/; // x.y.z only — no "v" prefix, no pre-release suffix
|
|
|
|
describe('version consistency (release contract)', () => {
|
|
const manifest = readJson('manifest.json');
|
|
const pkg = readJson('package.json');
|
|
const versions = readJson('versions.json');
|
|
|
|
it('manifest.json version is valid semver (x.y.z, no v prefix)', () => {
|
|
expect(manifest.version).toMatch(SEMVER);
|
|
});
|
|
|
|
it('package.json version matches manifest.json', () => {
|
|
expect(pkg.version).toBe(manifest.version);
|
|
});
|
|
|
|
it('versions.json contains the current manifest version', () => {
|
|
expect(Object.keys(versions)).toContain(manifest.version);
|
|
});
|
|
|
|
it('versions.json maps the current version to manifest.minAppVersion', () => {
|
|
expect(versions[manifest.version]).toBe(manifest.minAppVersion);
|
|
});
|
|
|
|
it('every versions.json key is valid semver', () => {
|
|
for (const v of Object.keys(versions)) {
|
|
expect(v, `versions.json key "${v}"`).toMatch(SEMVER);
|
|
}
|
|
});
|
|
});
|