chore: Add tool scripts

This commit is contained in:
4513ECHO 2026-04-28 19:36:24 +09:00
parent 63b0f92680
commit c9119ffeaf
9 changed files with 201 additions and 20 deletions

View file

@ -15,16 +15,13 @@ jobs:
cache: true
- run: vp build --mode prod
- name: Validate version
id: validate
run: |
tag_version="${GITHUB_REF#refs/tags/}"
manifest_version="$(jq -r .version < dist/manifest.json)"
if [[ "$tag_version" != "$manifest_version" ]]; then
echo "Version mismatch found: tag $tag_version, manifest $manifest_version"
exit 1
fi
vp exec node ./tool/validate_ci.ts
- uses: softprops/action-gh-release@v2
with:
draft: true
prerelease: ${{ steps.validate.outputs.prerelease == 'true' }}
working_directory: dist
files: |
main.js

View file

@ -11,10 +11,16 @@
"obsidian": "^1.12.3"
},
"devDependencies": {
"@optique/core": "^1.0.2",
"@optique/run": "^1.0.2",
"@types/node": "^25.6.0",
"@types/semver": "^7.7.1",
"dax": "^0.45.0",
"eslint-plugin-obsidianmd": "^0.2.4",
"semver": "^7.7.4",
"typescript": "~6.0.3",
"vite": "catalog:",
"vite-plus": "catalog:"
},
"packageManager": "pnpm@10.33.0"
"packageManager": "pnpm@10.33.2"
}

View file

@ -31,18 +31,36 @@ importers:
specifier: ^1.12.3
version: 1.12.3(@codemirror/state@6.6.0)(@codemirror/view@6.41.1)
devDependencies:
'@optique/core':
specifier: ^1.0.2
version: 1.0.2
'@optique/run':
specifier: ^1.0.2
version: 1.0.2
'@types/node':
specifier: ^25.6.0
version: 25.6.0
'@types/semver':
specifier: ^7.7.1
version: 7.7.1
dax:
specifier: ^0.45.0
version: 0.45.0
eslint-plugin-obsidianmd:
specifier: ^0.2.4
version: 0.2.4(@eslint/js@9.39.4)(@eslint/json@0.14.0)(@typescript-eslint/parser@8.58.1(eslint@9.39.4)(typescript@6.0.3))(eslint@9.39.4)(obsidian@1.12.3(@codemirror/state@6.6.0)(@codemirror/view@6.41.1))(typescript-eslint@8.58.1(eslint@9.39.4)(typescript@6.0.3))
semver:
specifier: ^7.7.4
version: 7.7.4
typescript:
specifier: ~6.0.3
version: 6.0.3
vite:
specifier: npm:@voidzero-dev/vite-plus-core@latest
version: '@voidzero-dev/vite-plus-core@0.1.19(typescript@6.0.3)(yaml@2.8.3)'
version: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(typescript@6.0.3)(yaml@2.8.3)'
vite-plus:
specifier: 'catalog:'
version: 0.1.19(@voidzero-dev/vite-plus-core@0.1.19(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3)(yaml@2.8.3)
version: 0.1.19(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3)(yaml@2.8.3)
packages:
@ -55,6 +73,12 @@ packages:
'@codemirror/view@6.41.1':
resolution: {integrity: sha512-ToDnWKbBnke+ZLrP6vgTTDScGi5H37YYuZGniQaBzxMVdtCxMrslsmtnOvbPZk4RX9bvkQqnWR/WS/35tJA0qg==}
'@deno/shim-deno-test@0.5.0':
resolution: {integrity: sha512-4nMhecpGlPi0cSzT67L+Tm+GOJqvuk8gqHBziqcUQOarnuIax1z96/gJHCSIz2Z0zhxE6Rzwb3IZXPtFh51j+w==}
'@deno/shim-deno@0.19.2':
resolution: {integrity: sha512-q3VTHl44ad8T2Tw2SpeAvghdGOjlnLPDNO2cpOxwMrBE/PVas6geWpbpIgrM+czOCH0yejp0yi8OaTuB+NU40Q==}
'@eslint-community/eslint-utils@4.9.1':
resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@ -151,6 +175,14 @@ packages:
resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
engines: {node: '>= 8'}
'@optique/core@1.0.2':
resolution: {integrity: sha512-znsqMmjAdeOgSJzdJlpZpgAscojwQmeQYXzYnuEKllz5VCj6WyEkdzU4QuvJQtWQY3ve2taXwudEBRur0VHBOQ==}
engines: {bun: '>=1.2.0', deno: '>=2.3.0', node: '>=20.0.0'}
'@optique/run@1.0.2':
resolution: {integrity: sha512-0Wc+zC8SLGV8zXQX+pk+o0c6wE/ddx/36CHZ0toTh5lApsjruUuGhqbxvljerAAG5un1xQbOLxzksBVC6UPgSg==}
engines: {bun: '>=1.2.0', deno: '>=2.3.0', node: '>=20.0.0'}
'@oxc-project/runtime@0.126.0':
resolution: {integrity: sha512-oksjxfqDNmIYMGlIgLzYgnz5YjZax27RtQezsPpKEGo9AC5LOaIGHsivCCeaAWdCtPnRyjZXM/7svreCC8kZVQ==}
engines: {node: ^20.19.0 || >=22.12.0}
@ -469,6 +501,12 @@ packages:
'@types/node@20.12.12':
resolution: {integrity: sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==}
'@types/node@25.6.0':
resolution: {integrity: sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==}
'@types/semver@7.7.1':
resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==}
'@types/tern@0.23.9':
resolution: {integrity: sha512-ypzHFE/wBzh+BlH6rrBgS5I/Z7RD21pGhZ2rltb/+ZrVM1awdZwjx7hE5XfuYgHWk9uvV5HLZN3SloevCAp3Bw==}
@ -848,6 +886,9 @@ packages:
resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==}
engines: {node: '>= 0.4'}
dax@0.45.0:
resolution: {integrity: sha512-y/47GKisPkHCtkDQVr3yfJEtVTuXqMVXhU4Au8Xrzu4s+s9eQUBGuCFHBwrfUrsry0Or6NyusHl0DSi6qj7/4w==}
debug@3.2.7:
resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==}
peerDependencies:
@ -1339,6 +1380,10 @@ packages:
isexe@2.0.0:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
isexe@3.1.5:
resolution: {integrity: sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==}
engines: {node: '>=18'}
iterator.prototype@1.1.5:
resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==}
engines: {node: '>= 0.4'}
@ -1911,6 +1956,9 @@ packages:
undici-types@5.26.5:
resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
undici-types@7.19.2:
resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==}
uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
@ -1943,6 +1991,11 @@ packages:
engines: {node: '>= 8'}
hasBin: true
which@4.0.0:
resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==}
engines: {node: ^16.13.0 || >=18.0.0}
hasBin: true
word-wrap@1.2.5:
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
engines: {node: '>=0.10.0'}
@ -1994,6 +2047,13 @@ snapshots:
style-mod: 4.1.3
w3c-keyname: 2.2.8
'@deno/shim-deno-test@0.5.0': {}
'@deno/shim-deno@0.19.2':
dependencies:
'@deno/shim-deno-test': 0.5.0
which: 4.0.0
'@eslint-community/eslint-utils@4.9.1(eslint@9.39.4)':
dependencies:
eslint: 9.39.4
@ -2096,6 +2156,12 @@ snapshots:
'@nodelib/fs.scandir': 2.1.5
fastq: 1.20.1
'@optique/core@1.0.2': {}
'@optique/run@1.0.2':
dependencies:
'@optique/core': 1.0.2
'@oxc-project/runtime@0.126.0': {}
'@oxc-project/types@0.126.0': {}
@ -2266,6 +2332,12 @@ snapshots:
dependencies:
undici-types: 5.26.5
'@types/node@25.6.0':
dependencies:
undici-types: 7.19.2
'@types/semver@7.7.1': {}
'@types/tern@0.23.9':
dependencies:
'@types/estree': 1.0.8
@ -2413,13 +2485,14 @@ snapshots:
'@typescript-eslint/types': 8.58.1
eslint-visitor-keys: 5.0.1
'@voidzero-dev/vite-plus-core@0.1.19(typescript@6.0.3)(yaml@2.8.3)':
'@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(typescript@6.0.3)(yaml@2.8.3)':
dependencies:
'@oxc-project/runtime': 0.126.0
'@oxc-project/types': 0.126.0
lightningcss: 1.32.0
postcss: 8.5.10
optionalDependencies:
'@types/node': 25.6.0
fsevents: 2.3.3
typescript: 6.0.3
yaml: 2.8.3
@ -2442,11 +2515,11 @@ snapshots:
'@voidzero-dev/vite-plus-linux-x64-musl@0.1.19':
optional: true
'@voidzero-dev/vite-plus-test@0.1.19(@voidzero-dev/vite-plus-core@0.1.19(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3)(yaml@2.8.3)':
'@voidzero-dev/vite-plus-test@0.1.19(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3)(yaml@2.8.3)':
dependencies:
'@standard-schema/spec': 1.1.0
'@types/chai': 5.2.3
'@voidzero-dev/vite-plus-core': 0.1.19(typescript@6.0.3)(yaml@2.8.3)
'@voidzero-dev/vite-plus-core': 0.1.19(@types/node@25.6.0)(typescript@6.0.3)(yaml@2.8.3)
es-module-lexer: 1.7.0
obug: 2.1.1
pixelmatch: 7.1.0
@ -2456,8 +2529,10 @@ snapshots:
tinybench: 2.9.0
tinyexec: 1.1.1
tinyglobby: 0.2.16
vite: '@voidzero-dev/vite-plus-core@0.1.19(typescript@6.0.3)(yaml@2.8.3)'
vite: '@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(typescript@6.0.3)(yaml@2.8.3)'
ws: 8.20.0
optionalDependencies:
'@types/node': 25.6.0
transitivePeerDependencies:
- '@arethetypeswrong/core'
- '@tsdown/css'
@ -2665,6 +2740,11 @@ snapshots:
es-errors: 1.3.0
is-data-view: 1.0.2
dax@0.45.0:
dependencies:
'@deno/shim-deno': 0.19.2
undici-types: 5.26.5
debug@3.2.7:
dependencies:
ms: 2.1.3
@ -3305,6 +3385,8 @@ snapshots:
isexe@2.0.0: {}
isexe@3.1.5: {}
iterator.prototype@1.1.5:
dependencies:
define-data-property: 1.1.4
@ -3953,15 +4035,17 @@ snapshots:
undici-types@5.26.5: {}
undici-types@7.19.2: {}
uri-js@4.4.1:
dependencies:
punycode: 2.3.1
vite-plus@0.1.19(@voidzero-dev/vite-plus-core@0.1.19(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3)(yaml@2.8.3):
vite-plus@0.1.19(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3)(yaml@2.8.3):
dependencies:
'@oxc-project/types': 0.126.0
'@voidzero-dev/vite-plus-core': 0.1.19(typescript@6.0.3)(yaml@2.8.3)
'@voidzero-dev/vite-plus-test': 0.1.19(@voidzero-dev/vite-plus-core@0.1.19(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3)(yaml@2.8.3)
'@voidzero-dev/vite-plus-core': 0.1.19(@types/node@25.6.0)(typescript@6.0.3)(yaml@2.8.3)
'@voidzero-dev/vite-plus-test': 0.1.19(@types/node@25.6.0)(@voidzero-dev/vite-plus-core@0.1.19(@types/node@25.6.0)(typescript@6.0.3)(yaml@2.8.3))(typescript@6.0.3)(yaml@2.8.3)
oxfmt: 0.45.0
oxlint: 1.60.0(oxlint-tsgolint@0.21.1)
oxlint-tsgolint: 0.21.1
@ -4051,6 +4135,10 @@ snapshots:
dependencies:
isexe: 2.0.0
which@4.0.0:
dependencies:
isexe: 3.1.5
word-wrap@1.2.5: {}
ws@8.20.0: {}

View file

@ -12,4 +12,3 @@ peerDependencyRules:
allowedVersions:
vite: "*"
vitest: "*"
tagVersionPrefix: ""

37
tool/bump_version.ts Normal file
View file

@ -0,0 +1,37 @@
import { object } from "@optique/core/constructs";
import { argument, option } from "@optique/core/primitives";
import { choice, string } from "@optique/core/valueparser";
import { optional } from "@optique/core/modifiers";
import { run } from "@optique/run";
import $ from "dax";
import semver from "semver";
import manifest from "../manifest.json" with { type: "json" };
const parser = object({
release: argument(choice(semver.RELEASE_TYPES)),
preId: optional(option("--preid", string())),
dryRun: option("--dry-run"),
});
const config = run(parser, { help: "option" });
$.setPrintCommand(true);
const incremented = new semver.SemVer(manifest.version).inc(config.release, config.preId).version;
const patch = `
diff --git a/manifest.json b/manifest.json
--- a/manifest.json
+++ b/manifest.json
@@ -1 +1 @@
- "version": "${manifest.version}",
+ "version": "${incremented}",
`;
if (config.dryRun) {
console.log(patch);
process.exit(0);
}
await $`git apply --cached --index --unidiff-zero`.stdinText(patch);
await $`git commit -m "chore: Bump version to ${incremented}"`;
await $`git tag -a ${incremented} -m ${incremented}`;

29
tool/test_local.ts Normal file
View file

@ -0,0 +1,29 @@
import { object } from "@optique/core/constructs";
import { option } from "@optique/core/primitives";
import { run } from "@optique/run";
import $ from "dax";
const parser = object({
reload: option("--reload"),
});
const config = run(parser, { help: "option" });
$.setPrintCommand(true);
const isRunning = await $`obsidian eval code=true`.stderr("null").timeout(1000).noThrow().text();
if (isRunning !== "=> true") {
console.log("Obsidian is not running");
process.exit(1);
}
const vault = await $`obsidian vault info=path`.stderr("null").text();
const configDir = await $`obsidian eval code=app.vault.configDir`
.stderr("null")
.text()
.then((text) => text.replace(/^=>\s*/, ""));
const pluginDir = $.path(vault).join(configDir, "plugins", "embed-plus");
await $`cp dist/* ${pluginDir}`;
if (config.reload) {
await $`obsidian plugin:reload id=embed-plus`.stderr("null");
}

14
tool/validate_ci.ts Normal file
View file

@ -0,0 +1,14 @@
import $ from "dax";
import semver from "semver";
import manifest from "../manifest.json" with { type: "json" };
$.setPrintCommand(true);
const tag = process.env.GITHUB_REF?.replace("refs/tags/", "") ?? "";
if (manifest.version !== tag) {
await $`echo "::error::Version mismatch: manifest version ${manifest.version} does not match tag ${tag}"`;
process.exit(1);
}
const version = new semver.SemVer(manifest.version);
await $`echo prerelease=${version.prerelease.length > 0} > "$GITHUB_OUTPUT"`;

View file

@ -3,7 +3,7 @@
"target": "es2025",
"module": "esnext",
"lib": ["es2025", "dom"],
"types": ["vite/client"],
"types": ["vite/client", "node"],
"skipLibCheck": true,
/* Bundler mode */
@ -21,6 +21,5 @@
"noFallthroughCasesInSwitch": true,
"exactOptionalPropertyTypes": true,
"noUncheckedIndexedAccess": true
},
"include": ["src"]
}
}

View file

@ -43,6 +43,9 @@ function copyManifest(): Plugin {
const manifest = JSON.parse(
await this.fs.readFile(join(root, "manifest.json"), { encoding: "utf8" }),
);
if (mode !== "prod") {
manifest.version += "+dev";
}
this.emitFile({
type: "asset",
fileName: "manifest.json",
@ -92,4 +95,13 @@ export default defineConfig({
},
},
},
run: {
tasks: {
"bump-version": { command: "node ./tool/bump_version.ts" },
"test-local": {
command: "node ./tool/test_local.ts",
input: ["dist/main.js", "dist/manifest.json", "dist/styles.css"],
},
},
},
});