Skip to content

Commit

Permalink
Github action for automatic generation of nightly releases (invesaliu…
Browse files Browse the repository at this point in the history
…s#814)

* Added bundle files to generate .exe

* Added icons to windows install wizard

* First version to automatically add to nightly release

* Temporarily removed plugins

* Test to nightly release - to try fix setup

* Fix plugin path after installation
  • Loading branch information
paulojamorim authored Jul 30, 2024
1 parent 1d49c5d commit 9400fda
Show file tree
Hide file tree
Showing 10 changed files with 517 additions and 2 deletions.
102 changes: 102 additions & 0 deletions .github/workflows/bundles.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
name: generate bundles

on: [push]

jobs:
build-win64:
name: run on windows
runs-on: windows-latest

steps:
- uses: actions/checkout@v4
with:
submodules: true

- name: Put current date into a variable
run: |
$DATE=& Get-Date -format yyyy-MM-dd
echo "DATE=$DATE" >> $env:GITHUB_ENV
- name: Put current commit hash in a variable
run: |
$COMMIT=$(git rev-parse HEAD)
echo "COMMIT=$COMMIT" >> $env:GITHUB_ENV
- name: Output1
run: |
echo "${{ env.DATE }}"
echo "Commit: ${{ env.COMMIT }}"
- name: Setup VC++ 2022 (17.0)
uses: ilammy/msvc-dev-cmd@v1.13.0
with:
vsversion: '17.0'
arch: 'x64'

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11.2'
cache: 'pip'

- name: Upgrade pip and enable wheel support
run: python -m pip install --upgrade pip setuptools wheel

- name: Install InVesalius requirements
run: pip install -r requirements.txt

- name: Compile InVesalius Cython parts
run: |
python3 setup.py build_ext --inplace
python3 setup.py build_plugins
- uses: suisei-cn/actions-download-file@818d6b7dc8fe73f2f924b6241f2b1134ca1377d9
id: pyinstaller
name: Download pyinstaller
with:
url: "https://github.com/pyinstaller/pyinstaller/archive/refs/tags/v6.9.0.zip"
target: ./pyinstaller/

- name: Extract pyinstaller file
uses: ihiroky/extract-action@v1
with:
file_path: ./pyinstaller/v6.9.0.zip
extract_dir: ./pyinstaller/

- name: Compile pyinstaller bootloader
run: |
cd ./pyinstaller/pyinstaller-6.9.0/bootloader/
python3 ./waf distclean all
cd ..
pip install .
- name: Generate InVesalius .exe file
run: |
cp ./bundle_tools/win/app.spec ./
pyinstaller app.spec --clean --noconfirm
mkdir installer
- name: Generate InVesalius installer
uses: Minionguyjpro/Inno-Setup-Action@v1.2.2
with:
path: ./bundle_tools/win/generate_installer.iss
options: /F"invesalius-3.1.99998_nightly_win64"

- name: Show files
run: |
cd ./installer
dir
- name: Update Nightly Release
uses: andelf/nightly-release@main
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: nightly
name: 'Nightly'
draft: false
prerelease: ${{ (github.event_name == 'workflow_dispatch' && github.event.inputs.is-pre-release) || (github.event_name == 'schedule')}}
body: |
This is a nightly release InVesalius.
It's unstable compared to the official releases, **use it with caution**!
files: installer/invesalius-3.1.99998_nightly_win64.exe
190 changes: 190 additions & 0 deletions bundle_tools/win/app.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
# -*- mode: python ; coding: utf-8 -*-

#--------- custom -----------------------------------------------------------------

#take VTK files
import os
import sys
import glob
from pathlib import Path

SOURCE_DIR = Path("./").resolve()
print("SOURCE_DIR", SOURCE_DIR)

from PyInstaller.utils.hooks import get_module_file_attribute, collect_dynamic_libs
from PyInstaller.compat import is_win

python_dir = os.path.dirname(sys.executable)
site_packages = os.path.join(python_dir,'Lib','site-packages')


def check_extension(item):
exts = ['exe','pyc','__pycache__']
for ext in exts:
if ext in item:
return True
return False



def get_all_files(dirName):
# create a list of file and sub directories
# names in the given directory
listOfFile = os.listdir(dirName)
allFiles = list()
# Iterate over all the entries
for entry in listOfFile:
# Create full path
fullPath = os.path.join(dirName, entry)
# If entry is a directory then get the list of files in this directory
if os.path.isdir(fullPath):
allFiles = allFiles + get_all_files(fullPath)
else:
allFiles.append(fullPath)

return allFiles


libraries = []

#get all files in vtkmodules installation
vtk_files = get_all_files(os.path.join(site_packages,'vtkmodules'))

libraries.append((os.path.join(site_packages,'vtk.py'),'.'))

#define destiny as vtkmodules
for v in vtk_files:
if not(check_extension(v)):
#take only folder name and remove first '\\'
dest_dir = os.path.dirname(v.replace(site_packages,''))[1:]
libraries.append((v, dest_dir))

#add interpolation module (pyinstaller not take automatically)
libraries.append((glob.glob(os.path.join(SOURCE_DIR,'invesalius_cy',\
'interpolation.*.pyd'))[0],'invesalius_cy'))

#add plaidml modules and files
#libraries.append((os.path.join(python_dir,'library','bin','plaidml.dll'),'library\\bin'))
#
#plaidml_files = get_all_files(os.path.join(python_dir,'share','plaidml'))
#
#for v in plaidml_files:
# if not(check_extension(v)):
# #take only folder name and remove first '\\'
# dest_dir = os.path.dirname(v.replace(python_dir,''))[1:]
# libraries.append((v, dest_dir))
#
#
#plaidml_files = get_all_files(os.path.join(site_packages,'plaidml'))
#
#for v in plaidml_files:
# if not(check_extension(v)):
# #take only folder name and remove first '\\'
# dest_dir = os.path.dirname(v.replace(site_packages,''))[1:]
# libraries.append((v, dest_dir))

# -- data files -----

data_files = []

#Add models and weights from A.I folder
ai_data = get_all_files(os.path.join('ai'))
for ai in ai_data:
dest_dir = os.path.dirname(ai)
data_files.append((ai,dest_dir))

#Add licences
data_files.append(('LICENSE.pt.txt','.'))
data_files.append(('LICENSE.txt','.'))

#Add user guides
data_files.append(('docs\\user_guide_en.pdf','docs'))
data_files.append(('docs\\user_guide_pt_BR.pdf','docs'))

#Add icons
icons_files = glob.glob(os.path.join(SOURCE_DIR,'icons','*'))

for ic in icons_files:
data_files.append((ic,'icons'))

#Add locale
locale_data = get_all_files(os.path.join('locale'))
for ld in locale_data:
dest_dir = os.path.dirname(ld)
data_files.append((ld,dest_dir))

#Add neuro navegation files
neuro_data = get_all_files(os.path.join('navigation'))
for nd in neuro_data:
dest_dir = os.path.dirname(nd)
data_files.append((nd,dest_dir))

#Add presets files
preset_data = get_all_files(os.path.join('presets'))
for pd in preset_data:
dest_dir = os.path.dirname(pd)
data_files.append((pd,dest_dir))

#Add sample files
sample_data = get_all_files(os.path.join('samples'))
for sd in sample_data:
dest_dir = os.path.dirname(sd)
data_files.append((sd,dest_dir))

#---------------------------------------------------------------------------------

block_cipher = None


#'wx.lib.pubsub.core.listenerbase','wx.lib.pubsub.core.kwargs',\
#'wx.lib.pubsub.core.kwargs.publisher', 'wx.lib.pubsub.core.topicmgrimpl',\
#'wx.lib.pubsub.core.kwargs.topicmgrimpl', 'wx.lib.pubsub.core.publisherbase',\
#'wx.lib.pubsub.core.topicargspecimpl','wx.lib.pubsub.core.kwargs.listenerbase',\
#'wx.lib.pubsub.core.kwargs.publishermixin',\
#'wx.lib.pubsub.core.kwargs.listenerimpl',\
#'wx.lib.pubsub.core.kwargs.topicargspecimpl',\
#'wx._core'

a = Analysis(['app.py'],
pathex=[SOURCE_DIR],
binaries=libraries,
datas=data_files,
hiddenimports=['scipy._lib.messagestream','skimage.restoration._denoise',\
'scipy.linalg', 'scipy.linalg.blas', 'scipy.interpolate',\
'pywt._extensions._cwt','skimage.filters.rank.core_cy_3d',\
'encodings','setuptools'], #,'keras','plaidml.keras','plaidml.keras.backend'
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)

exe = EXE(pyz,
a.scripts,
[],
exclude_binaries=True,
name='InVesalius 3.1',
icon='./icons/invesalius.ico',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
console=True )
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True,
upx_exclude=[],
name='app')




#print("1 >>>>>>>>>> ",a.zipped_data)
#print("2 >>>>>>>>>> ",a.pure)
Loading

0 comments on commit 9400fda

Please sign in to comment.