Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions .github/actions/install-slicer/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: install-slicer
author: Sebastien Goll (Kitware SAS)
description: Install 3D Slicer
inputs:
version:
description: Version of Slicer available at https://community.chocolatey.org/packages/3dslicer#versionhistory
default: ''
outputs:
slicer_executable:
description: Slicer executable
value: ${{ steps.slicer_exe.outputs.executable }}

runs:
using: composite
steps:
- name: Setting the permission
run: chmod +x "${{ github.action_path }}/downloader.sh"
shell: bash
- name: Download installer
run: |
"${{ github.action_path }}/downloader.sh" ${{ runner.os }}
shell: bash
- name: Get installer file
id: installer
run: |
installer=$(find "./installer" -maxdepth 1 -name "Slicer*" | head -n1 | xargs realpath)
echo "slicer_installer=$installer" >> $GITHUB_OUTPUT
shell: bash
- name: Windows Slicer install
id: win_install
if: ${{runner.os == 'Windows'}}
run: |
${{ steps.installer.outputs.slicer_installer }} //S
folder=$(find "C:/ProgramData/slicer.org" -maxdepth 1 -type d -name Slicer* -exec stat --format "%Y %n" {} + |sort -nr | head -n1 | cut -d' ' -f2-)
echo "executable=$folder/Slicer.exe" >> $GITHUB_OUTPUT
shell: bash
- name: Linux env setup
if: ${{ runner.os == 'Linux' }}
run: |
sudo apt-get install libglu1-mesa libpulse-mainloop-glib0 libnss3 libasound2t64 qt5dxcb-plugin libxcb-util1 xvfb
mkdir ./Slicer
export DISPLAY=:99
Xvfb :99 -screen 0 1920x1080x24 > /dev/null 2>&1 &
echo "DISPLAY=:99" >> $GITHUB_ENV
shell: bash
- name: Linux Slicer install
id: linux_install
if: ${{ runner.os == 'Linux' }}
run: |
tar xzf "${{ steps.installer.outputs.slicer_installer }}" -C "."
folder=$(find "." -maxdepth 1 -name "Slicer*" -type d | head -n1 | xargs realpath)
echo "executable=$folder/Slicer" >> $GITHUB_OUTPUT
shell: bash
- name: Max env setup
if: ${{ runner.os == 'macOS' }}
run: |
brew install expect
chmod +x "${{ github.action_path }}/macos_installer.exp"
shell: bash
- name: Mac Slicer install
if: ${{ runner.os == 'macOS' }}
id: mac_install
run: |
MOUNT_POINT=$("${{ github.action_path }}/macos_installer.exp" ${{ steps.installer.outputs.slicer_installer }} | grep -o '/Volumes/[^ ]*'| tr -d '\r\n')
cp -R "$MOUNT_POINT/Slicer.app" /Applications/
hdiutil detach "$MOUNT_POINT"
echo "executable=/Applications/Slicer.app/Contents/MacOS/Slicer" >> $GITHUB_OUTPUT
shell: bash
- id: slicer_exe
run: |
if [ ${{ runner.os }} == "Windows" ]; then
echo "executable=${{ steps.win_install.outputs.executable }}" >> $GITHUB_OUTPUT
elif [ ${{ runner.os }} == "Linux" ]; then
echo "executable=${{ steps.linux_install.outputs.executable }}" >> $GITHUB_OUTPUT
elif [ ${{ runner.os }} == "macOS" ]; then
echo "executable=${{ steps.mac_install.outputs.executable }}" >> $GITHUB_OUTPUT
fi
shell: bash
30 changes: 30 additions & 0 deletions .github/actions/install-slicer/downloader.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
if [ $1 == "Windows" ]; then
PACK_OS="win"
elif [ $1 == "Linux" ]; then
PACK_OS="linux"
elif [ $1 == "macOS" ]; then
PACK_OS="macosx"
fi

PACK_ARCH="amd64"
BASE_URL="https://slicer-packages.kitware.com/api/v1"

APP_ID=$(curl -s "$BASE_URL/app?name=Slicer&limit=1" | jq -r '.[0]._id')
echo "Application id found for Slicer: $APP_ID"

RELEASE_NAME=$(curl -s "$BASE_URL/app/$APP_ID/release?sort=meta.revision&sortdir=-1" | jq -r '.[0].lowerName')
echo "Realease name found: $RELEASE_NAME"

PACK=$(curl -s "$BASE_URL/app/$APP_ID/package?release_id_or_name=$RELEASE_NAME&os=$PACK_OS&arch=$PACK_ARCH&limit=1" | jq '.[0]')
PACK_ID=$(jq -r '._id' <<< "$PACK")
PACK_NAME=$(jq -r '.name' <<< "$PACK")
echo "Name of the package found: $PACK_NAME ($PACK_ID)"

mkdir -p installer

HEADER_TMP=$(mktemp)
curl -# -D "$HEADER_TMP" "$BASE_URL/item/$PACK_ID/download" -o file
CONTENT_DISPOSITION=$(grep -i '^Content-Disposition:' "$HEADER_TMP")
FILENAME=$(echo "$CONTENT_DISPOSITION" | sed -n 's/.*filename="\(.*\)".*/\1/p')
mv file "installer/$FILENAME"

17 changes: 17 additions & 0 deletions .github/actions/install-slicer/macos_installer.exp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/expect -f

set timeout 10
set dmg_file [lindex $argv 0]

spawn hdiutil attach "$dmg_file"

sleep 2
send "q\r"

expect {
"Agree Y/N?" {
send "y\r"
}
}

expect eof
23 changes: 23 additions & 0 deletions .github/actions/slicer-install-extensions/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: slicer-install-extensions
author: Sebastien Goll (Kitware SAS)
description: Install extensions for Slicer

inputs:
slicer_exe:
description: Slicer executable
required: true
additional_arguments:
description: Additional arguments for Slicer executable
default: '--no-main-window --no-splash'
extensions_name:
description: Extensions names to install
required: true

runs:
using: composite
steps:
- uses: ./.github/actions/slicer-run-python-script
with:
script: ${{ github.action_path }}/install_extensions.py
slicer_exe: ${{ inputs.slicer_exe }}
additional_arguments: ${{ inputs.additional_arguments }} ${{ inputs.extensions_name }}
15 changes: 15 additions & 0 deletions .github/actions/slicer-install-extensions/install_extensions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import sys
import slicer.util

if __name__ == '__main__':

extension_names = sys.argv[1:]
print("Found extensions: ", extension_names)

em = slicer.app.extensionsManagerModel()
em.setInteractive(False)

for name in extension_names:
em.installExtensionFromServer(name, False)

slicer.util.quit()
22 changes: 22 additions & 0 deletions .github/actions/slicer-install-python-packages/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: slicer-install-python-packages
author: Sebastien Goll (Kitware SAS)
description: Install python packages in Slicer's python environment

inputs:
slicer_exe:
description: Slicer directory
required: true
additional_arguments:
description: Additional arguments for Slicer executable
default: '--no-main-window --no-splash'
package_names:
description: Packages to install
required: true
runs:
using: composite
steps:
- uses: ./.github/actions/slicer-run-python-script
with:
script: ${{ github.action_path }}/install_py_packages.py
slicer_exe: ${{ inputs.slicer_exe }}
additional_arguments: ${{ inputs.additional_arguments }} ${{ inputs.package_names }}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import sys

import slicer.util

if __name__ == "__main__":

print("Packages found:",sys.argv[1:])

for package in sys.argv[1:]:
slicer.util.pip_install(package)
slicer.util.quit()
19 changes: 19 additions & 0 deletions .github/actions/slicer-run-python-script/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: slicer-run-python-script
author: Sebastien Goll (Kitware SAS)
description: Run a python script through Slicer
inputs:
slicer_exe:
description: Slicer executable
required: true
script:
description: Path to python to run
required: true
additional_arguments:
description: Additional arguments for Slicer executable
default: ''
runs:
using: composite
steps:
- run: |
"${{inputs.slicer_exe}}" --python-script "${{ inputs.script }}" ${{ inputs.additional_arguments }}
shell: bash
29 changes: 29 additions & 0 deletions .github/actions/slicer-run-python-tests/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: slicer-run-python-tests
author: Sebastien Goll (Kitware SAS)
description: Run python tests in Slicer

inputs:
slicer_exe:
description: Slicer directory
required: true
additional_arguments:
description: Additional arguments for Slicer executable
default: ''
tests_root_path:
description: Root path to search for tests
required: true
tests_name_pattern:
description: Pattern used to find test files
required: true
module_paths:
description: Paths to the tested modules
required: true

runs:
using: composite
steps:
- uses: ./.github/actions/slicer-run-python-script
with:
script: ${{ github.action_path }}/run_tests.py
slicer_exe: ${{ inputs.slicer_exe }}
additional_arguments: --additional-module-paths ${{ inputs.module_paths }} ${{ inputs.additional_arguments }} ${{ inputs.tests_root_path }} ${{ inputs.tests_name_pattern }}
17 changes: 17 additions & 0 deletions .github/actions/slicer-run-python-tests/run_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import sys
from pathlib import Path

import slicer.testing

if __name__ == "__main__":

if len(sys.argv) < 3:
raise AttributeError(f"run_tests.py requires 2 arguments, found {sys.argv[1:]}")

root = Path(sys.argv[1])
files = list(root.glob(sys.argv[2]))

print(f"Found {len(files)} test file(s).")

for file in files:
slicer.testing.runUnitTest(file.parent.as_posix(), file.stem)
16 changes: 16 additions & 0 deletions .github/python_scripts/install_python_dependencies.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from pathlib import Path

import slicer.util
import sys

if __name__ == '__main__':
sys.path.append(Path(__file__).parent.joinpath("../..").resolve().as_posix())

from MultiverSeg.SegmentEditorMultiverSegLib import InstallLogic, DependenciesLogic
DependenciesLogic.INTERACTIVE_MODE = False
InstallLogic.INTERACTIVE_MODE = False

DependenciesLogic.installTorchIfNeeded()
DependenciesLogic.installMultiverSegIfNeeded()
InstallLogic.downloadCheckpointsIfNeeded()
slicer.util.quit()
14 changes: 14 additions & 0 deletions .github/python_scripts/install_pytorch_module.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import sys
from pathlib import Path

import slicer.util



if __name__ == '__main__':
sys.path.append(Path(__file__).parent.joinpath("../..").resolve().as_posix())

from MultiverSeg.SegmentEditorMultiverSegLib import DependenciesLogic
DependenciesLogic.INTERACTIVE_MODE = False
DependenciesLogic.installPyTorchExtensionIfNeeded()
slicer.util.quit()
Loading