updated tests after fixing constraints #22
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Build Installer | |
on: | |
push: | |
branches: | |
- '**' | |
pull_request: | |
branches: | |
- '**' | |
jobs: | |
# Job 1: Check code quality and consistency | |
code-quality: | |
strategy: | |
matrix: | |
os: [ubuntu-latest] | |
python-version: ['3.12'] | |
runs-on: ${{ matrix.os }} | |
steps: | |
- name: Checkout repository | |
uses: actions/checkout@v4 | |
with: | |
fetch-depth: '0' # full history with tags to get the version number by versioningit | |
- name: Set up Python ${{ matrix.python-version }} | |
uses: actions/setup-python@v5 | |
with: | |
python-version: ${{ matrix.python-version }} | |
- name: Install Python dependencies | |
# Install 'validate-pyproject' for checking pyproject.toml | |
# Install 'ruff' for code linting and formatting | |
# Install 'nbqa' for quality assurance of Jupyter notebooks | |
run: pip install 'validate-pyproject[all]' ruff nbqa | |
- name: Install npm dependencies | |
# Install 'prettier' for code formatting of Markdown, YAML, etc. files | |
# Install 'prettier-plugin-toml' plugin for code formatting of TOML files | |
run: npm install prettier prettier-plugin-toml --save-dev --save-exact | |
# # Check the validity of pyproject.toml | |
# - name: Check validity of pyproject.toml | |
# id: check_pyproject | |
# continue-on-error: true | |
# run: validate-pyproject pyproject.toml | |
# Check code linting with Ruff in the project root | |
- name: Check code linting | |
id: check_code_linting | |
continue-on-error: true | |
run: ruff check . | |
- name: Suggestion to fix code linting issues (for *.py files) | |
if: steps.check_code_linting.outcome == 'failure' | |
run: | |
echo "In project root run 'ruff check . --fix' and commit changes to | |
fix issues." | |
# Check code formatting with Ruff in the project root | |
- name: Check code formatting | |
id: check_code_formatting | |
continue-on-error: true | |
run: ruff format . --check | |
- name: Suggestion to fix code formatting issues (for *.py files) | |
if: steps.check_code_formatting.outcome == 'failure' | |
run: | |
echo "In project root run 'ruff format .' and commit changes to fix | |
issues." | |
# Check formatting of Markdown, YAML, TOML, etc. files with Prettier in the project root | |
- name: Check formatting of Markdown, YAML, TOML, etc. files | |
id: check_others_formatting | |
continue-on-error: true | |
run: npx prettier . --check --config=prettierrc.toml | |
- name: Suggestion to fix non-code formatting issues (for *.md, etc.) | |
if: steps.check_others_formatting.outcome == 'failure' | |
run: | |
echo "In project root run 'npx prettier . --write | |
--config=prettierrc.toml' and commit changes to fix issues." | |
- name: Force fail if any of the previous steps failed | |
if: | | |
steps.check_pyproject.outcome == 'failure' || | |
steps.check_code_linting.outcome == 'failure' || | |
steps.check_code_formatting.outcome == 'failure' || | |
steps.check_notebooks.outcome == 'failure' || | |
steps.check_others_formatting.outcome == 'failure' | |
run: exit 1 | |
# Job 2: Build the installer | |
build-installer: | |
timeout-minutes: 80 | |
runs-on: ${{ matrix.os }} | |
strategy: | |
fail-fast: false | |
matrix: | |
os: [ubuntu-22.04, ubuntu-24.04, windows-2022, macos-13, macos-14] # [ubuntu-22.04, windows-2022, macos-13, flyci-macos-14-m2] | |
steps: | |
- name: Check-out repository | |
uses: actions/checkout@v4 | |
- name: Set up Python environment | |
uses: actions/setup-python@v5 | |
with: | |
python-version: '3.11' | |
- name: Upgrade package installer for Python | |
run: python -m pip install --upgrade pip | |
- name: Install Python dependences | |
run: | | |
python -m pip install flit | |
flit install --only-deps # Install the dependencies, but not the EasyDiffractionApp package itself | |
- name: Add extra info to pyproject.toml | |
run: python utils.py --update | |
- name: Declare env variables on push only | |
if: github.event_name == 'push' | |
shell: bash | |
run: echo "BRANCH_NAME=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV | |
- name: Declare env variables on pull_request only | |
if: github.event_name == 'pull_request' | |
shell: bash | |
run: echo "BRANCH_NAME=$GITHUB_HEAD_REF" >> $GITHUB_ENV | |
- name: Declare env variables on push and pull_request | |
shell: bash | |
run: | | |
echo "MATRIX_OS=${{ matrix.os }}" >> $GITHUB_ENV | |
echo "RUNNER_OS=${{ runner.os }}" >> $GITHUB_ENV | |
echo "RUNNER_ARCH=${{ runner.arch }}" >> $GITHUB_ENV | |
echo "TEMP_ARTIFACT_SUFFIX=$(python utils.py --get release.app_name)" >> $GITHUB_ENV | |
echo "APP_NAME=$(python utils.py --get release.app_name)" >> $GITHUB_ENV | |
echo "PACKAGE_NAME=$(python utils.py --get project.name)" >> $GITHUB_ENV | |
echo "PACKAGE_PATH=$GITHUB_WORKSPACE/$(python utils.py --get project.name)" >> $GITHUB_ENV | |
echo "PACKAGE_VERSION=$(python utils.py --get project.version)" >> $GITHUB_ENV | |
echo "RELEASE_TAG=$(python utils.py --get ci.app.info.release_tag)" >> $GITHUB_ENV | |
echo "RELEASE_TITLE=$(python utils.py --get ci.app.info.release_title)" >> $GITHUB_ENV | |
echo "SCRIPTS_PATH=$(python utils.py --get ci.project.subdirs.scripts)" >> $GITHUB_ENV | |
echo "DISTRIBUTION_PATH=$(python utils.py --get ci.project.subdirs.distribution)" >> $GITHUB_ENV | |
echo "DOWNLOAD_PATH=$(python utils.py --get ci.project.subdirs.download)" >> $GITHUB_ENV | |
echo "QTIFW_PATH=$(python utils.py --get ci.qtifw.setup.installation_path.${{ runner.os }})" >> $GITHUB_ENV | |
echo "PYTHON_PACKAGES_PATH=$(python utils.py --get ci.cache.python_packages_path)" >> $GITHUB_ENV | |
echo "GIT_INSTALL_URL=git+$GITHUB_SERVER_URL/$GITHUB_REPOSITORY@${{ env.BRANCH_NAME }}" >> $GITHUB_ENV | |
- name: Declare dependent env variables on push and pull_request | |
shell: bash | |
run: | | |
echo "SETUP_EXE_PATH=$(python ${{ env.SCRIPTS_PATH }}/Config.py ${{ env.BRANCH_NAME }} ${{ matrix.os }} setup_exe_path)" >> $GITHUB_ENV | |
- name: Create python resources file | |
run: | |
pyside6-rcc ${{ env.PACKAGE_PATH }}/resources.qrc -o ${{ | |
env.PACKAGE_PATH }}/resources.py | |
- name: Set up screen (Linux) | |
if: runner.os == 'Linux' | |
run: | | |
sudo apt-get update | |
sudo apt-get install libxcb-xinerama0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xfixes0 libxcb-shape0 libxcb-cursor0 | |
sudo apt-get install libpulse-mainloop-glib0 | |
sudo apt-get install libxkbcommon-x11-0 | |
sudo apt-get install libegl1-mesa-dev | |
Xvfb :0 -screen 0 1920x1080x24 -ac & | |
echo "DISPLAY=:0" >> $GITHUB_ENV | |
# Method 1: | |
# Not working since Oct 2023. VMware is replaced by VirtualBox | |
# "/Library/Application Support/VMware Tools/vmware-resolutionSet" 1920 1080 | |
# system_profiler SPDisplaysDataType | grep Resolution | |
# Method 2: | |
# Worked on macOS 12.6.9, but the default resolution already was 1920x1080: https://github.com/easyScience/EasyDiffractionBeta/actions/runs/6575129372/job/17861583655 | |
# Fails on macOS 12.7, where default resolution is 1176x885: https://github.com/easyScience/EasyDiffractionBeta/actions/runs/6576347514/job/17865526935 | |
# Works on macOS 13.6, where default resolution is again 1920x1080: https://github.com/easyScience/EasyDiffractionBeta/actions/runs/6576486407/job/17866007760 | |
# brew install screenresolution | |
# screenresolution list | |
# screenresolution get | |
# screenresolution set 1920x1080x32@30 | |
# screenresolution get | |
- name: Set up screen (macOS, not flyci) | |
if: matrix.os == 'macos-13' # runner.os == 'macOS' | |
run: | | |
system_profiler SPDisplaysDataType | grep Resolution | |
- name: Set up screen (Windows) | |
if: runner.os == 'Windows' | |
run: | | |
Set-DisplayResolution -Width 1920 -Height 1080 -Force | |
Get-DisplayResolution | |
- name: Run app in testmode and quit | |
shell: bash | |
run: python ${{ env.PACKAGE_NAME }}/main.py --testmode | |
- name: Run screenshots comparison tests | |
run: pytest tests/gui --color=yes | |
- name: Upload zipped GUI tests screenshots | |
if: always() | |
uses: actions/upload-artifact@v4 | |
with: | |
name: build-installer_screenshots_${{ matrix.os }} # desired name (without .zip) of the zip file to be uploaded | |
path: | |
| # all files from these paths are zipped into file with name from above | |
tests/gui/screenshots | |
.tests/image_diff | |
if-no-files-found: 'error' | |
compression-level: 0 | |
- name: Create freezed python app bundle with PyInstaller | |
run: python ${{ env.SCRIPTS_PATH }}/FreezeApp.py | |
- name: Create offline app installer from freezed app bundle with QtIFW | |
run: > | |
python ${{ env.SCRIPTS_PATH }}/MakeInstaller.py ${{ env.BRANCH_NAME }} | |
${{ matrix.os }} | |
- name: Sign, notarize and staple offline app installer (macOS) | |
if: | | |
runner.os == 'macOS' && github.event_name == 'push' && | |
(env.BRANCH_NAME == 'master' || env.BRANCH_NAME == 'develop') | |
run: > | |
python ${{ env.SCRIPTS_PATH }}/SignAppInstaller.py ${{ env.BRANCH_NAME | |
}} ${{ matrix.os }} ${{ secrets.APPLE_CERT_DATA }} ${{ | |
secrets.APPLE_CERT_PASSWORD }} ${{ secrets.APPLE_NOTARY_USER }} ${{ | |
secrets.APPLE_NOTARY_PASSWORD }} | |
- name: Sign offline app installer (Windows) | |
if: | | |
runner.os == 'Windows' && github.event_name == 'push' && | |
(env.BRANCH_NAME == 'master' || env.BRANCH_NAME == 'develop') | |
uses: lando/code-sign-action@v2 | |
with: | |
file: ${{ env.SETUP_EXE_PATH }} | |
certificate-data: ${{ secrets.WINDOZE_CERT_DATA }} | |
certificate-password: ${{ secrets.WINDOZE_CERT_PASSWORD }} | |
keylocker-host: ${{ secrets.KEYLOCKER_HOST }} | |
keylocker-api-key: ${{ secrets.KEYLOCKER_API_KEY }} | |
keylocker-cert-sha1-hash: ${{ secrets.KEYLOCKER_CERT_SHA1_HASH }} | |
- name: Create zip archive of offline app installer for distribution | |
run: > | |
python ${{ env.SCRIPTS_PATH }}/ZipAppInstaller.py ${{ env.BRANCH_NAME | |
}} ${{ matrix.os }} | |
- name: Upload double-zipped offline app installer for the next job step | |
uses: actions/upload-artifact@v4 | |
with: | |
name: zipped-app-installer_${{ matrix.os }}-${{ runner.arch }} # zip of another zip | |
path: ${{ env.DISTRIBUTION_PATH }}/*.zip | |
compression-level: 0 # no compression | |
if-no-files-found: error | |
retention-days: 10 | |
- name: | |
Upload zipped offline app installer to GitHub releases (non-master | |
branch) | |
if: github.event_name == 'push' && env.BRANCH_NAME != 'master' | |
uses: ncipollo/release-action@v1 | |
with: | |
draft: true | |
prerelease: true | |
allowUpdates: true | |
replacesArtifacts: true | |
token: ${{ secrets.GITHUB_TOKEN }} | |
artifacts: '${{ env.DISTRIBUTION_PATH }}/*.zip' | |
tag: ${{ env.BRANCH_NAME }} | |
name: ${{ env.BRANCH_NAME }} | |
bodyFile: 'RELEASE.md' | |
- name: | |
Upload zipped offline app installer to GitHub releases (master branch) | |
if: github.event_name == 'push' && env.BRANCH_NAME == 'master' | |
uses: ncipollo/release-action@v1 | |
with: | |
draft: true | |
prerelease: true | |
allowUpdates: true | |
replacesArtifacts: true | |
token: ${{ secrets.GITHUB_TOKEN }} | |
artifacts: '${{ env.DISTRIBUTION_PATH }}/*.zip' | |
tag: ${{ env.RELEASE_TAG }} | |
name: ${{ env.RELEASE_TITLE }} | |
bodyFile: 'RELEASE.md' | |
#- name: Upload online app installer to repository via FTP (master branch) | |
# if: github.event_name == 'push' && env.BRANCH_NAME == 'master' | |
# run: > | |
# python ${{ env.SCRIPTS_PATH }}/UploadToFtp.py | |
# ${{ env.BRANCH_NAME }} ${{ matrix.os }} | |
# ${{ secrets.APP_REPO_FTP_PASSWORD }} | |
# Job 3: Test the installer | |
test-installer: | |
needs: build-installer | |
timeout-minutes: 15 | |
runs-on: ${{ matrix.os }} | |
strategy: | |
fail-fast: false | |
matrix: | |
os: [ubuntu-22.04, ubuntu-24.04, windows-2022, macos-13, macos-14] # [ubuntu-22.04, windows-2022, macos-13, flyci-macos-14-m2] | |
steps: | |
- name: Check-out repository | |
uses: actions/checkout@v4 | |
- name: Set up Python environment | |
uses: actions/setup-python@v5 | |
with: | |
python-version: '3.11' | |
- name: Upgrade package installer for Python | |
run: python -m pip install --upgrade pip | |
- name: Install Python dependences | |
run: | | |
python -m pip install flit | |
flit install --only-deps # Install the dependencies, but not the EasyDiffractionApp package itself | |
- name: Declare env variables on push only | |
if: github.event_name == 'push' | |
shell: bash | |
run: echo "BRANCH_NAME=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV | |
- name: Declare env variables on pull_request only | |
if: github.event_name == 'pull_request' | |
shell: bash | |
run: echo "BRANCH_NAME=$GITHUB_HEAD_REF" >> $GITHUB_ENV | |
- name: Add extra info to pyproject.toml | |
run: python utils.py --update | |
- name: Declare env variables on push and pull_request | |
shell: bash | |
run: | | |
echo "SCRIPTS_PATH=$(python utils.py --get ci.project.subdirs.scripts)" >> $GITHUB_ENV | |
- name: Set up screen (Linux) | |
if: runner.os == 'Linux' | |
run: | | |
sudo apt-get update | |
sudo apt-get install libxcb-xinerama0 libxcb-icccm4 libxcb-image0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-xfixes0 libxcb-shape0 libxcb-cursor0 | |
sudo apt-get install libpulse-mainloop-glib0 | |
sudo apt-get install libxkbcommon-x11-0 | |
sudo apt-get install libegl1-mesa-dev | |
Xvfb :0 -screen 0 1920x1080x24 -ac & | |
echo "DISPLAY=:0" >> $GITHUB_ENV | |
# Method 1: | |
# Not working since Oct 2023. VMware is replaced by VirtualBox | |
# "/Library/Application Support/VMware Tools/vmware-resolutionSet" 1920 1080 | |
# system_profiler SPDisplaysDataType | grep Resolution | |
# Method 2: | |
# Worked on macOS 12.6.9, but the default resolution already was 1920x1080: https://github.com/easyScience/EasyDiffractionBeta/actions/runs/6575129372/job/17861583655 | |
# Fails on macOS 12.7, where default resolution is 1176x885: https://github.com/easyScience/EasyDiffractionBeta/actions/runs/6576347514/job/17865526935 | |
# Works on macOS 13.6, where default resolution is again 1920x1080: https://github.com/easyScience/EasyDiffractionBeta/actions/runs/6576486407/job/17866007760 | |
# brew install screenresolution | |
# screenresolution list | |
# screenresolution get | |
# screenresolution set 1920x1080x32@30 | |
# screenresolution get | |
- name: Set up screen (macOS, not flyci) | |
if: matrix.os == 'macos-13' # runner.os == 'macOS' | |
run: | | |
system_profiler SPDisplaysDataType | grep Resolution | |
- name: Set up screen (Windows) | |
if: runner.os == 'Windows' | |
run: | | |
Set-DisplayResolution -Width 1920 -Height 1080 -Force | |
Get-DisplayResolution | |
- name: | |
Download zipped offline app installer from from the previous job step | |
uses: actions/download-artifact@v4 | |
with: | |
name: zipped-app-installer_${{ matrix.os }}-${{ runner.arch }} # zip of another zip | |
- name: Unzip archive with offline app installer for distribution | |
run: > | |
python ${{ env.SCRIPTS_PATH }}/UnzipAppInstaller.py ${{ | |
env.BRANCH_NAME }} ${{ matrix.os }} | |
- name: Make dir for .desktop file (Linux) | |
if: runner.os == 'Linux' | |
run: mkdir -p ~/.local/share/applications/ | |
- name: Install app | |
run: > | |
python ${{ env.SCRIPTS_PATH }}/InstallApp.py ${{ env.BRANCH_NAME }} | |
${{ matrix.os }} | |
- name: Check app istallation is done | |
run: python ${{ env.SCRIPTS_PATH }}/CheckAppExists.py | |
- name: Run app in testmode and quit (macOS & Linux) | |
if: runner.os != 'Windows' # disabled because it can't exit app and one can't see what is going on there (no GitHub logging)... | |
run: python ${{ env.SCRIPTS_PATH }}/RunApp.py --testmode | |
- name: Run screenshots comparison tests | |
if: runner.os != 'Windows' # disabled as didn't run app in test in the previous step | |
run: pytest tests/gui --color=yes | |
- name: Upload zipped GUI tests screenshots | |
if: always() | |
uses: actions/upload-artifact@v4 | |
with: | |
name: test-installer_screenshots_${{ matrix.os }} # desired name (without .zip) of the zip file to be uploaded | |
path: | |
| # all files from these paths are zipped into file with name from above | |
tests/gui/screenshots | |
.tests/image_diff | |
if-no-files-found: 'error' | |
compression-level: 0 |