diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml index 0998b97..abcc595 100644 --- a/.github/workflows/build-and-release.yml +++ b/.github/workflows/build-and-release.yml @@ -1,6 +1,15 @@ name: Build and Release Plugin on: + pull_request: + paths: + - .github/workflows/build-and-release.yml + - package.json + - scripts/** + - vite.config.ts + - src/** + - backend/** + - public/** push: tags: - v*.*.* @@ -11,7 +20,7 @@ env: jobs: - release: + plugin-artifact: runs-on: ubuntu-latest permissions: @@ -19,28 +28,40 @@ jobs: steps: - name: Check out Git repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Install Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: 20 - name: Install Dependencies run: npm install - - name: Build - run: npm run build + - name: Build release layout + run: npm run build:release + + - name: Set artifact name + run: | + safe_ref="${GITHUB_REF_NAME//\//-}" + echo "PLUGIN_ARTIFACT=neuroglancer-plugin-${safe_ref}.zip" >> "$GITHUB_ENV" - name: Archive Release uses: thedoctor0/zip-release@0.7.5 with: type: 'zip' - filename: 'release.zip' + filename: ${{ env.PLUGIN_ARTIFACT }} directory: 'dist' + - name: Upload artifact for PR validation + uses: actions/upload-artifact@v4 + with: + name: ${{ env.PLUGIN_ARTIFACT }} + path: dist/${{ env.PLUGIN_ARTIFACT }} + - name: Upload Release + if: startsWith(github.ref, 'refs/tags/') uses: ncipollo/release-action@v1.12.0 with: - artifacts: "dist/release.zip" - token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + artifacts: dist/${{ env.PLUGIN_ARTIFACT }} + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.md b/README.md index 1d9176e..be3ba61 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ This plugin integrates a Neuroglancer interface into the [Ouroboros](https://github.com/We-Gold/ouroboros) medical imaging software. -To install it, open Ouroboros, open the Plugin Manager (`Ouroboros > Manage Plugins`), and add a plugin from the GitHub releases url: `https://github.com/We-Gold/neuroglancer-plugin/releases`. +To install it, open Ouroboros, open the Plugin Manager (`Ouroboros > Manage Plugins`), and add a plugin from the GitHub releases url: `https://github.com/ChengLabResearch/neuroglancer-plugin/releases`. Then restart the app and the plugin should be visible. @@ -19,4 +19,22 @@ Make sure Docker is installed and running. 1. `npm install` 2. `npm run dev` -To test in Ouroboros, run Ouroboros in development mode as well, and use the `Test Plugin` page to view the plugin. \ No newline at end of file +To test in Ouroboros, run Ouroboros in development mode as well, and use the `Test Plugin` page to view the plugin. + +### Release artifact + +Tagged releases publish `neuroglancer-plugin-.zip`. The archive root is the +same layout that Ouroboros expects inside its plugin folder: + +- `package.json` +- `index.html` +- `ngrefactor.html` +- `icon.svg` +- `compose.yml` +- frontend assets and runtime files +- `plugin-release.json` + +For production package preinstalls, unpack the archive to +`extra-resources/preinstalled-plugins/neuroglancer-plugin/` before building the +Ouroboros app package. On first launch, Ouroboros copies that folder into the +normal user-data plugin directory and detects it from `package.json`. diff --git a/package.json b/package.json index c2d8233..8b94198 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "dev-backend": "node backend-dev.cjs", "dev": "concurrently \"npm run dev-frontend\" \"npm run dev-backend\"", "build": "tsc -b && vite build", + "build:release": "npm run build && node scripts/write-release-manifest.mjs", "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview" }, diff --git a/scripts/write-release-manifest.mjs b/scripts/write-release-manifest.mjs new file mode 100644 index 0000000..7a00704 --- /dev/null +++ b/scripts/write-release-manifest.mjs @@ -0,0 +1,21 @@ +import { mkdir, readFile, writeFile } from 'node:fs/promises' +import { join } from 'node:path' + +const root = process.cwd() +const dist = join(root, 'dist') +const packageJson = JSON.parse(await readFile(join(root, 'package.json'), 'utf8')) + +const manifest = { + name: packageJson.name, + pluginName: packageJson.pluginName, + version: packageJson.version, + index: packageJson.index, + icon: packageJson.icon, + dockerCompose: packageJson.dockerCompose, + artifactName: `${packageJson.name}-${packageJson.version}.zip`, + commit: process.env.GITHUB_SHA ?? null, + ref: process.env.GITHUB_REF_NAME ?? null +} + +await mkdir(dist, { recursive: true }) +await writeFile(join(dist, 'plugin-release.json'), `${JSON.stringify(manifest, null, 2)}\n`)