diff --git a/plugs/plug-manager/plugmanager.ts b/plugs/plug-manager/plugmanager.ts index 3cde16df..98de908b 100644 --- a/plugs/plug-manager/plugmanager.ts +++ b/plugs/plug-manager/plugmanager.ts @@ -38,17 +38,28 @@ export async function updatePlugsCommand() { for (const plugUri of plugList) { const [protocol, ...rest] = plugUri.split(":"); - const plugNameMatch = /\/([^\/]+)\.plug\.js$/.exec(plugUri); - if (!plugNameMatch) { - console.error( - "Could not extract plug name from ", - plugUri, - "ignoring...", - ); - continue; - } + let plugName: string; + if (protocol == "ghr") { + // For GitHub Release, the plug is expected to be named same as repository + plugName = rest[0].split("/")[1]; // skip repo owner + // Strip "silverbullet-foo" into "foo" (multiple plugs follow this convention) + if (plugName.startsWith("silverbullet-")) { + plugName = plugName.slice("silverbullet-".length); + } + } else { + // Other URIs are expected to contain the file .plug.js at the end + const plugNameMatch = /\/([^\/]+)\.plug\.js$/.exec(plugUri); + if (!plugNameMatch) { + console.error( + "Could not extract plug name from ", + plugUri, + "ignoring...", + ); + continue; + } - const plugName = plugNameMatch[1]; + plugName = plugNameMatch[1]; + } const manifests = await events.dispatchEvent( `get-plug:${protocol}`, @@ -141,20 +152,51 @@ export async function getPlugGithubRelease( identifier: string, ): Promise { let [owner, repo, version] = identifier.split("/"); + let releaseInfo: any = {}; + let req: Response; if (!version || version === "latest") { - console.log("fetching the latest version"); - const req = await fetch( + console.log(`Fetching release manifest of latest version for ${repo}`); + req = await fetch( `https://api.github.com/repos/${owner}/${repo}/releases/latest`, ); - if (req.status !== 200) { - throw new Error( - `Could not fetch latest relase manifest from ${identifier}}`, - ); - } - const result = await req.json(); - version = result.name; + } else { + console.log(`Fetching release manifest of version ${version} for ${repo}`); + req = await fetch( + `https://api.github.com/repos/${owner}/${repo}/releases/tags/${version}`, + ); } + if (req.status !== 200) { + throw new Error( + `Could not fetch release manifest from ${identifier}`, + ); + } + releaseInfo = await req.json(); + version = releaseInfo.tag_name; + + let assetName: string | undefined; + const shortName = repo.startsWith("silverbullet-") + ? repo.slice("silverbullet-".length) + : undefined; + for (const asset of releaseInfo.assets ?? []) { + if (asset.name === `${repo}.plug.js`) { + assetName = asset.name; + break; + } + // Support plug like foo.plug.js are in repo silverbullet-foo + if (shortName && asset.name === `${shortName}.plug.js`) { + assetName = asset.name; + break; + } + } + if (!assetName) { + throw new Error( + `Could not find "${repo}.plug.js"` + + (shortName ? ` or "${shortName}.plug.js"` : "") + + ` in release ${version}`, + ); + } + const finalUrl = - `//github.com/${owner}/${repo}/releases/download/${version}/${repo}.plug.js`; + `//github.com/${owner}/${repo}/releases/download/${version}/${assetName}`; return getPlugHTTPS(finalUrl); } diff --git a/website/Plug Management.md b/website/Plug Management.md index b699b7ca..a6fe5af5 100644 --- a/website/Plug Management.md +++ b/website/Plug Management.md @@ -8,4 +8,4 @@ The [[Plugs/Editor]] plug has support for the following URI prefixes for plugs: * `https:` loading plugs via HTTPS, e.g. `[https://](https://raw.githubusercontent.com/silverbulletmd/silverbullet-github/main/github.plug.js)` * `github:org/repo/file.plug.js` internally rewritten to a `https` url as above. -* `ghr:org/repo/version` to fetch a plug from a Github release +* `ghr:org/repo/version` to fetch a plug from a Github release. Will fetch latest version, if it was omitted. diff --git a/website/Plugs/Development.md b/website/Plugs/Development.md index 6caa728d..420e3d96 100644 --- a/website/Plugs/Development.md +++ b/website/Plugs/Development.md @@ -48,4 +48,6 @@ Once you’re happy with your plug, you can distribute it in various ways: - You can put it on github by simply committing the resulting `.plug.js` file there and instructing users to point to by adding `- github:yourgithubuser/yourrepo/yourplugname.plug.js` to their `PLUGS` file - Add a release in your github repo and instruct users to add the release as `- ghr:yourgithubuser/yourrepo` or if they need a specific release `- ghr:yourgithubuser/yourrepo/release-name` + - You need to upload the plug file as asset in the release, with a name matching your repository, e.g, `yourrepo.plug.js` + - If your repository name starts with "silverbullet-", like `silverbullet-foo`, both `silverbullet-foo.plug.js` and `foo.plug.js` asset names will be tried - You can put it on any other web server, and tell people to load it via https, e.g., `- https://mydomain.com/mypugname.plug.js`.