feat: sync Obsidian plugin metadata and add versioning script

This commit is contained in:
Erik van der Boom 2026-05-04 01:18:20 +02:00
parent c880eec15f
commit bb4481ef1e
5 changed files with 105 additions and 5 deletions

View file

@ -121,6 +121,7 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v6
@ -143,19 +144,44 @@ jobs:
# as required by the Obsidian community plugin format.
run: npm run bundle --workspace=obsidian-plugin
- name: Sync Obsidian manifest metadata from tag
run: |
VERSION="${GITHUB_REF_NAME#v}"
npm run obsidian:sync-version -- "$VERSION"
- name: Package Obsidian plugin zip
# Obsidian community plugins are installed by dropping main.js + manifest.json
# (+ optional styles.css) into the vault plugins folder. We zip them for the release.
run: |
VERSION="${GITHUB_REF_NAME#v}"
# Stamp manifest.json version to match the release tag
jq --arg v "$VERSION" '.version = $v' obsidian-plugin/manifest.json > tmp.json && mv tmp.json obsidian-plugin/manifest.json
mkdir -p obsidian-plugin/dist
cp obsidian-plugin/out/main.js obsidian-plugin/dist/main.js
cp obsidian-plugin/manifest.json obsidian-plugin/dist/manifest.json
cd obsidian-plugin/dist
zip "../../bindery-obsidian-${VERSION}.zip" main.js manifest.json
- name: Create PR to sync Obsidian release metadata on main
uses: peter-evans/create-pull-request@v7
with:
commit-message: "chore(obsidian): sync metadata for ${{ github.ref_name }}"
branch: "chore/obsidian-sync-${{ github.ref_name }}"
delete-branch: true
title: "chore(obsidian): sync manifests for ${{ github.ref_name }}"
body: |
This automated PR keeps Obsidian plugin metadata in sync with the tagged release.
Updated files:
- manifest.json
- obsidian-plugin/manifest.json
- obsidian-plugin/versions.json
Triggered by release tag `${{ github.ref_name }}`.
base: main
add-paths: |
manifest.json
obsidian-plugin/manifest.json
obsidian-plugin/versions.json
- name: Upload Obsidian plugin zip to release
uses: softprops/action-gh-release@v3
with:

View file

@ -5,6 +5,6 @@
"minAppVersion": "1.12.7",
"description": "Typography formatting and multi-format export for book projects written in Markdown.",
"author": "Erik van der Boom",
"authorUrl": "https://github.com/evdboom/Bindery",
"authorUrl": "https://evdboom.nl/projects/bindery",
"isDesktopOnly": true
}

View file

@ -5,6 +5,6 @@
"minAppVersion": "1.12.7",
"description": "Typography formatting and multi-format export for book projects written in Markdown.",
"author": "Erik van der Boom",
"authorUrl": "https://github.com/evdboom/Bindery",
"authorUrl": "https://evdboom.nl/projects/bindery",
"isDesktopOnly": true
}

View file

@ -11,6 +11,7 @@
"scripts": {
"build": "npm run build -ws --if-present",
"test": "npm run test -ws --if-present",
"build:core": "npm run build --workspace=bindery-core"
"build:core": "npm run build --workspace=bindery-core",
"obsidian:sync-version": "node ./scripts/sync-obsidian-version.mjs"
}
}

View file

@ -0,0 +1,73 @@
#!/usr/bin/env node
import { readFileSync, writeFileSync } from "node:fs";
import { resolve } from "node:path";
const AUTHOR_URL = "https://evdboom.nl/projects/bindery";
function parseJson(filePath) {
return JSON.parse(readFileSync(filePath, "utf8"));
}
function writeJson(filePath, value) {
writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`, "utf8");
}
function sortSemverKeys(keys) {
return [...keys].sort((a, b) => {
const pa = a.split(".").map(Number);
const pb = b.split(".").map(Number);
for (let i = 0; i < Math.max(pa.length, pb.length); i += 1) {
const na = Number.isFinite(pa[i]) ? pa[i] : 0;
const nb = Number.isFinite(pb[i]) ? pb[i] : 0;
if (na !== nb) {
return na - nb;
}
}
return 0;
});
}
function requireVersionArg() {
const raw = process.argv[2] || process.env.RELEASE_VERSION || process.env.GITHUB_REF_NAME || "";
const normalized = raw.replace(/^v/, "").trim();
if (!/^\d+\.\d+\.\d+$/.test(normalized)) {
throw new Error(`Expected version like 1.2.3, got: ${raw || "<empty>"}`);
}
return normalized;
}
const repoRoot = process.cwd();
const rootManifestPath = resolve(repoRoot, "manifest.json");
const pluginManifestPath = resolve(repoRoot, "obsidian-plugin", "manifest.json");
const versionsPath = resolve(repoRoot, "obsidian-plugin", "versions.json");
const version = requireVersionArg();
const rootManifest = parseJson(rootManifestPath);
const pluginManifest = parseJson(pluginManifestPath);
const versions = parseJson(versionsPath);
rootManifest.version = version;
pluginManifest.version = version;
rootManifest.authorUrl = AUTHOR_URL;
pluginManifest.authorUrl = AUTHOR_URL;
const minAppVersion = pluginManifest.minAppVersion || rootManifest.minAppVersion;
if (!minAppVersion) {
throw new Error("Unable to determine minAppVersion from manifests.");
}
if (!versions[version]) {
versions[version] = minAppVersion;
}
const sortedVersions = {};
for (const key of sortSemverKeys(Object.keys(versions))) {
sortedVersions[key] = versions[key];
}
writeJson(rootManifestPath, rootManifest);
writeJson(pluginManifestPath, pluginManifest);
writeJson(versionsPath, sortedVersions);
console.log(`Synced Obsidian metadata for version ${version}`);