From df2353ac7fa74ddbbf30a1b7ac59a333202081d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20K=C3=B6hler?= Date: Thu, 23 Apr 2026 10:32:45 +0200 Subject: [PATCH 1/3] docs(windows): irm|iex one-liner like uv; remove NoStartMenu option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - README: irm … | iex + cmd.exe Bypass line; explain short bootstrap vs in-script work - install.ps1: always add Start Menu shortcut; drop -NoStartMenuShortcut and env - installation.rst + newsfragment 76.fixed aligned Made-with: Cursor --- README.md | 14 ++++++++++---- docs/installation.rst | 10 +++++----- newsfragments/76.fixed.md | 2 +- scripts/install.ps1 | 35 +++++++++++++---------------------- 4 files changed, 29 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index 022e57a..e96ef77 100644 --- a/README.md +++ b/README.md @@ -15,15 +15,21 @@ Releases ship as **Briefcase-generated** artifacts (for example ZIP/MSI on Windo ### Windows — install from GitHub (PowerShell) -Unsigned **MSI** can trigger **SmartScreen**; the release **portable `.zip`** (same app as the MSI) avoids the MSI path. When that `.zip` is attached to a release, you can install per-user under `%LOCALAPPDATA%\WyssGeneva\DBSAnnotator\app` and get a Start Menu shortcut with one line (from PowerShell; for a branch other than `main`, replace `main` in the URL): +Unsigned **MSI** can trigger **SmartScreen**; the release **portable `.zip`** (same app as the MSI) avoids the MSI path. When that `.zip` is attached to a release, you can install per-user under `%LOCALAPPDATA%\WyssGeneva\DBSAnnotator\app` and get a Start Menu shortcut. Same pattern as [uv’s installer](https://docs.astral.sh/uv/getting-started/installation/) (`irm` fetches the script, `iex` runs it); replace `main` in the URL if you need another branch. -**Note:** `iex` only passes its own parameters — script switches (for example ``-VersionTag v0.4.0a2``) are not the same call. For parameters, use a local copy of `scripts/install.ps1` or: ``& ([scriptblock]::Create((iwr -UseBasicParsing -UserAgent "DBSAnnotator-Install/1" -Uri "https://raw.githubusercontent.com/Brain-Modulation-Lab/DBSAnnotator/main/scripts/install.ps1").Content)) -VersionTag v0.4.0a2``. +In an **open PowerShell** window: ```powershell -iex (iwr -UseBasicParsing -UserAgent "DBSAnnotator-Install/1" -Uri "https://raw.githubusercontent.com/Brain-Modulation-Lab/DBSAnnotator/main/scripts/install.ps1").Content +irm https://raw.githubusercontent.com/Brain-Modulation-Lab/DBSAnnotator/main/scripts/install.ps1 | iex ``` -**No Start Menu shortcut:** set ``$env:DBS_ANNOTATOR_NO_START_MENU = "1"`` before the line above, or run with ``-NoStartMenuShortcut`` when using a script block / local `install.ps1`. +From **cmd.exe** (or if execution policy blocks scripts): + +```bat +powershell -ExecutionPolicy Bypass -NoProfile -Command "irm https://raw.githubusercontent.com/Brain-Modulation-Lab/DBSAnnotator/main/scripts/install.ps1 | iex" +``` + +That one-liner only **downloads and runs** `install.ps1`. The script itself then calls the GitHub API, downloads the app `.zip`, and unpacks it — same idea as uv: the bootstrap line is short; the work happens inside the script. Optional parameters (``-VersionTag``, ``-GitHubRepository``) are not available on the `iex` line; save `scripts/install.ps1` and run e.g. ``.\install.ps1 -VersionTag v0.4.0a2`` or use ``& ([scriptblock]::Create((irm 'https://.../install.ps1'))) -VersionTag v0.4.0a2``. The script picks the **newest** release that includes a `DBSAnnotator-*.zip` file (prereleases included). If your release has no `.zip` yet, tag again after [CD](.github/workflows/release.yml) has uploaded it, or use `-VersionTag vX.Y.Z` once that asset exists. diff --git a/docs/installation.rst b/docs/installation.rst index 60f50db..0b713f8 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -32,12 +32,12 @@ Steps b. Double-click to launch — no further steps needed. 4. **GitHub release with portable** ``.zip`` **(``DBSAnnotator-*.zip``):** to install - without using the unsigned MSI, run ``scripts/install.ps1`` (see the README - ``iex`` one-liner). Script parameters (for example ``-VersionTag``) need a local - file or ``& ([scriptblock]::Create((iwr …).Content)) …``. It unpacks under + without using the unsigned MSI, use the README one-liner + (``irm https://…/install.ps1 | iex``) or a saved copy of ``scripts/install.ps1`` + (use parameters such as ``-VersionTag`` only when you run a local file or a + script block; see the README). It unpacks under ``%LOCALAPPDATA%\\WyssGeneva\\DBSAnnotator\\app`` and adds a Start Menu - shortcut unless you set ``DBS_ANNOTATOR_NO_START_MENU`` or pass - ``-NoStartMenuShortcut``. + shortcut. .. note:: The first launch may take 5–10 seconds while Windows extracts bundled diff --git a/newsfragments/76.fixed.md b/newsfragments/76.fixed.md index c4ce3bf..cd940a7 100644 --- a/newsfragments/76.fixed.md +++ b/newsfragments/76.fixed.md @@ -1 +1 @@ -Fix `install.ps1` when run with `iex`: move install into a nested function so `$PSCmdlet` binds; document `iex` vs script parameters (`& ([scriptblock]::Create((iwr …).Content))` or local `install.ps1`). +Fix `install.ps1` when run with `iex`/`irm`: move install into a nested function so `$PSCmdlet` binds; document `irm … | iex` one-liner and script parameters; drop optional no–Start-Menu shortcut switch. diff --git a/scripts/install.ps1 b/scripts/install.ps1 index 9c5f5e9..aa95f83 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -1,14 +1,12 @@ #Requires -Version 5.1 -# Fetches DBSAnnotator-*.zip from GitHub Releases; installs to %LOCALAPPDATA%\WyssGeneva\DBSAnnotator\app. -# Optional: DBS_ANNOTATOR_NO_START_MENU=1 (truthy: 1, true, yes). Repo: DBS_ANNOTATOR_INSTALL_REPO. +# DBSAnnotator-*.zip from GitHub Releases → %LOCALAPPDATA%\WyssGeneva\DBSAnnotator\app + Start Menu shortcut. Override repo: DBS_ANNOTATOR_INSTALL_REPO. [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = "Medium")] param( [string] $GitHubRepository = $( if ($env:DBS_ANNOTATOR_INSTALL_REPO) { $env:DBS_ANNOTATOR_INSTALL_REPO } else { "Brain-Modulation-Lab/DBSAnnotator" } ), [string] $VersionTag = "", - [string] $InstallRoot = "", - [switch] $NoStartMenuShortcut + [string] $InstallRoot = "" ) Set-StrictMode -Version 3.0 @@ -21,14 +19,9 @@ function Install-DbsAnnotatorApp { if ($env:DBS_ANNOTATOR_INSTALL_REPO) { $env:DBS_ANNOTATOR_INSTALL_REPO } else { "Brain-Modulation-Lab/DBSAnnotator" } ), [string] $VersionTag = "", - [string] $InstallRoot = "", - [switch] $NoStartMenuShortcut + [string] $InstallRoot = "" ) - if ($env:DBS_ANNOTATOR_NO_START_MENU -match '^(1|true|yes)$') { - $NoStartMenuShortcut = $true - } - if ([string]::IsNullOrWhiteSpace($InstallRoot)) { $InstallRoot = Join-Path $env:LOCALAPPDATA "WyssGeneva\DBSAnnotator\app" } @@ -92,7 +85,7 @@ set -VersionTag to a tag that has the .zip, or add the .zip to the release manua Write-Host "Asset: $($asset.name) ($([math]::Round($asset.size / 1MB, 1)) MB)" Write-Host "Install: $InstallRoot" if ($WhatIfPreference) { - Write-Host "What if: would download, extract, copy files, add Start Menu shortcut (unless -NoStartMenuShortcut)." + Write-Host "What if: would download, extract, copy files, add Start Menu shortcut." return } if (-not $PSCmdlet.ShouldProcess($InstallRoot, "Install DBSAnnotator (overwrite if present)")) { @@ -129,17 +122,15 @@ set -VersionTag to a tag that has the .zip, or add the .zip to the release manua } $exe = Get-ChildItem -LiteralPath $InstallRoot -Recurse -Filter "DBSAnnotator.exe" -ErrorAction SilentlyContinue | Select-Object -First 1 if (-not $exe) { throw "DBSAnnotator.exe not found under $InstallRoot after install." } - if (-not $NoStartMenuShortcut) { - if ($PSCmdlet.ShouldProcess("Start Menu programs", "Create DBSAnnotator shortcut")) { - $programs = [Environment]::GetFolderPath("Programs") - if (-not (Test-Path $programs)) { New-Item -ItemType Directory -Path $programs -Force | Out-Null } - $wsh = New-Object -ComObject WScript.Shell - $lnk = $wsh.CreateShortcut((Join-Path $programs "DBSAnnotator.lnk")) - $lnk.TargetPath = $exe.FullName - $lnk.WorkingDirectory = $exe.DirectoryName - $lnk.IconLocation = $exe.FullName - $lnk.Save() | Out-Null - } + if ($PSCmdlet.ShouldProcess("Start Menu programs", "Create DBSAnnotator shortcut")) { + $programs = [Environment]::GetFolderPath("Programs") + if (-not (Test-Path $programs)) { New-Item -ItemType Directory -Path $programs -Force | Out-Null } + $wsh = New-Object -ComObject WScript.Shell + $lnk = $wsh.CreateShortcut((Join-Path $programs "DBSAnnotator.lnk")) + $lnk.TargetPath = $exe.FullName + $lnk.WorkingDirectory = $exe.DirectoryName + $lnk.IconLocation = $exe.FullName + $lnk.Save() | Out-Null } Write-Host "Done. Run: $($exe.FullName)" } finally { From 25db825c49a5f2656256f426e4d38f5d13abf5a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20K=C3=B6hler?= Date: Thu, 23 Apr 2026 10:48:46 +0200 Subject: [PATCH 2/3] Update documentation --- README.md | 21 +++++---------------- newsfragments/78.fixed.md | 1 + 2 files changed, 6 insertions(+), 16 deletions(-) create mode 100644 newsfragments/78.fixed.md diff --git a/README.md b/README.md index e96ef77..0f0832a 100644 --- a/README.md +++ b/README.md @@ -4,18 +4,17 @@ [Docs Health](https://github.com/Brain-Modulation-Lab/DBSAnnotator/actions/workflows/docs-health.yml) [Release Drafter](https://github.com/Brain-Modulation-Lab/DBSAnnotator/actions/workflows/release-drafter.yml) -A desktop application for annotating Deep Brain Stimulation (DBS) clinical programming sessions. Built for clinicians and researchers working with DBS systems (Medtronic Percept and others). +A desktop application for annotating Deep Brain Stimulation (DBS) programming sessions. Built for clinicians and researchers working with DBS systems. -**Version:** derived from `dbs_annotator.__version__` **Publisher:** Wyss Center for Bio and Neuroengineering (contact: [lucia.poma@wysscenter.ch](mailto:lucia.poma@wysscenter.ch)) ## For End Users -Releases ship as **Briefcase-generated** artifacts (for example ZIP/MSI on Windows and DMG on macOS). Follow the instructions for the artifact you downloaded. +You can find installation files for Windows (.msi), MacOS (.dmg) and Linux (.deb) under the [GitHub Releases](https://github.com/Brain-Modulation-Lab/DBSAnnotator/releases). +However, note that the files are unsigned, so that a warning might pop up during installation. To proceed with installation, you must accept the risk and continue. +In some cases, for example where your organization has strict settings, this might not be possible. In this case, try the install via PowerShell below. -### Windows — install from GitHub (PowerShell) - -Unsigned **MSI** can trigger **SmartScreen**; the release **portable `.zip`** (same app as the MSI) avoids the MSI path. When that `.zip` is attached to a release, you can install per-user under `%LOCALAPPDATA%\WyssGeneva\DBSAnnotator\app` and get a Start Menu shortcut. Same pattern as [uv’s installer](https://docs.astral.sh/uv/getting-started/installation/) (`irm` fetches the script, `iex` runs it); replace `main` in the URL if you need another branch. +### Windows — install via PowerShell In an **open PowerShell** window: @@ -29,13 +28,8 @@ From **cmd.exe** (or if execution policy blocks scripts): powershell -ExecutionPolicy Bypass -NoProfile -Command "irm https://raw.githubusercontent.com/Brain-Modulation-Lab/DBSAnnotator/main/scripts/install.ps1 | iex" ``` -That one-liner only **downloads and runs** `install.ps1`. The script itself then calls the GitHub API, downloads the app `.zip`, and unpacks it — same idea as uv: the bootstrap line is short; the work happens inside the script. Optional parameters (``-VersionTag``, ``-GitHubRepository``) are not available on the `iex` line; save `scripts/install.ps1` and run e.g. ``.\install.ps1 -VersionTag v0.4.0a2`` or use ``& ([scriptblock]::Create((irm 'https://.../install.ps1'))) -VersionTag v0.4.0a2``. - -The script picks the **newest** release that includes a `DBSAnnotator-*.zip` file (prereleases included). If your release has no `.zip` yet, tag again after [CD](.github/workflows/release.yml) has uploaded it, or use `-VersionTag vX.Y.Z` once that asset exists. - ### macOS / Linux — shell install (curl / wget) -When the release includes **raw** `.tar.gz` bundles (from CD) or a `.deb` / `.dmg`, you can install from the repo script (uses [GitHub Releases](https://github.com/Brain-Modulation-Lab/DBSAnnotator/releases); override repo with `DBS_ANNOTATOR_INSTALL_REPO` if needed): ```sh curl -LsSf https://raw.githubusercontent.com/Brain-Modulation-Lab/DBSAnnotator/main/scripts/install.sh | sh @@ -45,11 +39,6 @@ curl -LsSf https://raw.githubusercontent.com/Brain-Modulation-Lab/DBSAnnotator/m wget -qO- https://raw.githubusercontent.com/Brain-Modulation-Lab/DBSAnnotator/main/scripts/install.sh | sh ``` -Pin a tag: `DBS_ANNOTATOR_VERSION=v0.4.0a1 sh` or `./install.sh v0.4.0a1`. Preview only: `sh install.sh --dry-run`. - -- **Linux x86_64:** prefers `dbs-annotator_*_linux_x86_64-raw.tar.gz` (installs under `~/.local/lib/dbs-annotator` and symlinks `~/.local/bin/dbs-annotator`); otherwise `sudo dpkg -i` on the `.deb`. -- **macOS (arm64 CI build):** prefers `DBSAnnotator-*-macos-arm64-raw.tar.gz` into `/Applications` or `~/Applications`; otherwise copies from the `.dmg`. - ## What It Does The application guides you through a DBS programming session in three steps: diff --git a/newsfragments/78.fixed.md b/newsfragments/78.fixed.md new file mode 100644 index 0000000..50404da --- /dev/null +++ b/newsfragments/78.fixed.md @@ -0,0 +1 @@ +Simplify `install.ps1` and update README. From ff2dc74ee3389e8b11d1637a3bdbe4f5d4868678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Richard=20M=2E=20K=C3=B6hler?= Date: Thu, 23 Apr 2026 10:51:37 +0200 Subject: [PATCH 3/3] Revert newsfragment change --- newsfragments/77.fixed.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/newsfragments/77.fixed.md b/newsfragments/77.fixed.md index cd940a7..c4ce3bf 100644 --- a/newsfragments/77.fixed.md +++ b/newsfragments/77.fixed.md @@ -1 +1 @@ -Fix `install.ps1` when run with `iex`/`irm`: move install into a nested function so `$PSCmdlet` binds; document `irm … | iex` one-liner and script parameters; drop optional no–Start-Menu shortcut switch. +Fix `install.ps1` when run with `iex`: move install into a nested function so `$PSCmdlet` binds; document `iex` vs script parameters (`& ([scriptblock]::Create((iwr …).Content))` or local `install.ps1`).