Skip to content

Fix default window sizes and extensions config table #1018

Fix default window sizes and extensions config table

Fix default window sizes and extensions config table #1018

Workflow file for this run

#
# DO NOT MODIFY! AUTO-GENERATED FROM:
# .github/workflows/ci/workflow_template.yml
#
name: CI
on:
push:
branches:
- 'main'
- 'maintenance/*'
tags:
- 'v*'
pull_request:
types:
- opened
- reopened
- synchronize
defaults:
run:
# Powershell on Windows? No thank you...
shell: bash --noprofile --norc -eo pipefail .github/workflows/ci/helpers.sh . {0}
jobs:
# Job: Analyze {{{
analyze:
name: Analyze
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Calculate skip cache keys
id: set_cache
run: |
job_cache_extra_deps=(); job_id=test_linux; job_name='Test (Linux)'; job_needs=(); job_os=Linux; job_platform=ubuntu-22.04; job_python=3.13.3; job_reqs=(reqs/dist.txt reqs/test.txt); job_skip_cache_name=skip_test_linux_py-3.13.3_ubuntu-22.04; job_skip_cache_path=.skip_cache_test_linux; job_skiplists=(job_test os_linux); job_test_args='-p no:pytest-qt --ignore=test/gui_qt'; job_type=test; job_variant=Linux; analyze_set_job_skip_cache_key
job_cache_extra_deps=(osx/deps.sh); job_id=test_macos; job_name='Test (macOS)'; job_needs=(); job_os=macOS; job_platform=macos-15; job_python=3.13.3; job_reqs=(reqs/dist.txt reqs/test.txt); job_skip_cache_name=skip_test_macos_py-3.13.3_macos-15; job_skip_cache_path=.skip_cache_test_macos; job_skiplists=(job_test os_macos); job_test_args='-p no:pytest-qt --ignore=test/gui_qt'; job_type=test; job_variant=macOS; analyze_set_job_skip_cache_key
job_cache_extra_deps=(); job_id=test_windows; job_name='Test (Windows)'; job_needs=(); job_os=Windows; job_platform=windows-2022; job_python=3.13.3; job_reqs=(reqs/dist.txt reqs/test.txt); job_skip_cache_name=skip_test_windows_py-3.13.3_windows-2022; job_skip_cache_path=.skip_cache_test_windows; job_skiplists=(job_test os_windows); job_test_args='-p no:pytest-qt --ignore=test/gui_qt'; job_type=test; job_variant=Windows; analyze_set_job_skip_cache_key
job_cache_extra_deps=(); job_id=test_python_latest_supported; job_name='Test (Python Latest Supported)'; job_needs=(); job_os=Linux; job_platform=ubuntu-latest; job_python=3.13.3; job_reqs=(reqs/dist.txt reqs/test.txt); job_skip_cache_name=skip_test_python_latest_supported_py-3.13.3_ubuntu-latest; job_skip_cache_path=.skip_cache_test_python_latest_supported; job_skiplists=(job_test os_linux os_macos os_windows); job_test_args='-p no:pytest-qt --ignore=test/gui_qt'; job_type=test; job_variant='Python Latest Supported'; analyze_set_job_skip_cache_key
job_cache_extra_deps=(); job_id=test_python_312; job_name='Test (Python 3.12)'; job_needs=(); job_os=Linux; job_platform=ubuntu-latest; job_python=3.12; job_reqs=(reqs/dist.txt reqs/test.txt); job_skip_cache_name=skip_test_python_312_py-3.12_ubuntu-latest; job_skip_cache_path=.skip_cache_test_python_312; job_skiplists=(job_test os_linux os_macos os_windows); job_test_args='-p no:pytest-qt --ignore=test/gui_qt'; job_type=test; job_variant='Python 3.12'; analyze_set_job_skip_cache_key
job_cache_extra_deps=(); job_id=test_python_311; job_name='Test (Python 3.11)'; job_needs=(); job_os=Linux; job_platform=ubuntu-latest; job_python=3.11; job_reqs=(reqs/dist.txt reqs/test.txt); job_skip_cache_name=skip_test_python_311_py-3.11_ubuntu-latest; job_skip_cache_path=.skip_cache_test_python_311; job_skiplists=(job_test os_linux os_macos os_windows); job_test_args='-p no:pytest-qt --ignore=test/gui_qt'; job_type=test; job_variant='Python 3.11'; analyze_set_job_skip_cache_key
job_cache_extra_deps=(); job_id=test_python_310; job_name='Test (Python 3.10)'; job_needs=(); job_os=Linux; job_platform=ubuntu-latest; job_python=3.10; job_reqs=(reqs/dist.txt reqs/test.txt); job_skip_cache_name=skip_test_python_310_py-3.10_ubuntu-latest; job_skip_cache_path=.skip_cache_test_python_310; job_skiplists=(job_test os_linux os_macos os_windows); job_test_args='-p no:pytest-qt --ignore=test/gui_qt'; job_type=test; job_variant='Python 3.10'; analyze_set_job_skip_cache_key
job_cache_extra_deps=(); job_id=test_qt_gui; job_name='Test (Qt GUI)'; job_needs=(); job_os=Linux; job_platform=ubuntu-22.04; job_python=3.13.3; job_reqs=(reqs/dist.txt reqs/dist_extra_gui_qt.txt reqs/test.txt); job_skip_cache_name=skip_test_qt_gui_py-3.13.3_ubuntu-22.04; job_skip_cache_path=.skip_cache_test_qt_gui; job_skiplists=(job_test_gui_qt); job_test_args=test/gui_qt; job_type=test_gui_qt; job_variant='Qt GUI'; analyze_set_job_skip_cache_key
job_cache_extra_deps=(); job_id=test_packaging; job_name='Test (Packaging)'; job_needs=(); job_os=Linux; job_platform=ubuntu-latest; job_python=3.13.3; job_reqs=(reqs/packaging.txt reqs/setup.txt); job_skip_cache_name=skip_test_packaging_py-3.13.3_ubuntu-latest; job_skip_cache_path=.skip_cache_test_packaging; job_skiplists=(job_test_packaging); job_type=test_packaging; job_variant=Packaging; analyze_set_job_skip_cache_key
job_cache_extra_deps=(); job_id=test_code_quality; job_name='Test (Code Quality)'; job_needs=(); job_os=Linux; job_platform=ubuntu-latest; job_python=3.13.3; job_reqs=(reqs/code_quality.txt); job_skip_cache_name=skip_test_code_quality_py-3.13.3_ubuntu-latest; job_skip_cache_path=.skip_cache_test_code_quality; job_type=test_code_quality; job_variant='Code Quality'; analyze_set_job_skip_cache_key
job_cache_extra_deps=('reqs/dist_*.txt' linux/appimage/deps.sh); job_id=build_linux; job_name='Build (Linux)'; job_needs=(test_linux); job_os=Linux; job_platform=ubuntu-22.04; job_python=3.13.3; job_reqs=(reqs/build.txt reqs/setup.txt); job_skip_cache_name=skip_build_linux_py-3.13.3_ubuntu-22.04; job_skip_cache_path=.skip_cache_build_linux; job_skiplists=(job_build os_linux); job_type=build; job_variant=Linux; analyze_set_job_skip_cache_key
job_cache_extra_deps=('reqs/dist_*.txt' osx/deps.sh); job_id=build_macos_app; job_name='Build (macOS App)'; job_needs=(test_macos); job_os=macOS; job_platform=macos-15; job_python=3.13.3; job_reqs=(reqs/build.txt reqs/setup.txt); job_skip_cache_name=skip_build_macos_app_py-3.13.3_macos-15; job_skip_cache_path=.skip_cache_build_macos_app; job_skiplists=(job_build os_macos); job_type=build; job_variant='macOS App'; analyze_set_job_skip_cache_key
job_cache_extra_deps=('reqs/dist_*.txt' osx/deps.sh); job_id=notarize_macos_app; job_name='Notarize (macOS App)'; job_needs=(build_macos_app); job_os=macOS; job_platform=macos-15; job_python=3.13.3; job_reqs=(reqs/build.txt reqs/setup.txt); job_skip_cache_name=skip_notarize_macos_app_py-3.13.3_macos-15; job_skip_cache_path=.skip_cache_notarize_macos_app; job_skiplists=(job_build os_macos); job_type=notarize; job_variant='macOS App'; analyze_set_job_skip_cache_key
job_cache_extra_deps=('reqs/dist_*.txt' osx/deps.sh); job_id=build_macos_dmg; job_name='Build (macOS DMG)'; job_needs=(build_macos_app notarize_macos_app); job_os=macOS; job_platform=macos-15; job_python=3.13.3; job_reqs=(reqs/build.txt reqs/setup.txt); job_skip_cache_name=skip_build_macos_dmg_py-3.13.3_macos-15; job_skip_cache_path=.skip_cache_build_macos_dmg; job_skiplists=(job_build os_macos); job_type=build; job_variant='macOS DMG'; analyze_set_job_skip_cache_key
job_cache_extra_deps=('reqs/dist_*.txt' osx/deps.sh); job_id=notarize_macos_dmg; job_name='Notarize (macOS DMG)'; job_needs=(build_macos_dmg); job_os=macOS; job_platform=macos-15; job_python=3.13.3; job_reqs=(reqs/build.txt reqs/setup.txt); job_skip_cache_name=skip_notarize_macos_dmg_py-3.13.3_macos-15; job_skip_cache_path=.skip_cache_notarize_macos_dmg; job_skiplists=(job_build os_macos); job_type=notarize; job_variant='macOS DMG'; analyze_set_job_skip_cache_key
job_cache_extra_deps=('reqs/dist_*.txt' windows/dist_deps.sh); job_id=build_windows; job_name='Build (Windows)'; job_needs=(test_windows); job_os=Windows; job_platform=windows-2022; job_python=3.13.3; job_reqs=(reqs/build.txt reqs/setup.txt); job_skip_cache_name=skip_build_windows_py-3.13.3_windows-2022; job_skip_cache_path=.skip_cache_build_windows; job_skiplists=(job_build os_windows); job_type=build; job_variant=Windows; analyze_set_job_skip_cache_key
- name: Check skip cache for Test (Linux)
uses: actions/cache@v3
with:
path: .skip_cache_test_linux
key: 0_check_${{ steps.set_cache.outputs.test_linux_skip_cache_key }}_${{ github.run_id }}
restore-keys:
0_${{ steps.set_cache.outputs.test_linux_skip_cache_key }}
- name: Check skip cache for Test (macOS)
uses: actions/cache@v3
with:
path: .skip_cache_test_macos
key: 0_check_${{ steps.set_cache.outputs.test_macos_skip_cache_key }}_${{ github.run_id }}
restore-keys:
0_${{ steps.set_cache.outputs.test_macos_skip_cache_key }}
- name: Check skip cache for Test (Windows)
uses: actions/cache@v3
with:
path: .skip_cache_test_windows
key: 0_check_${{ steps.set_cache.outputs.test_windows_skip_cache_key }}_${{ github.run_id }}
restore-keys:
0_${{ steps.set_cache.outputs.test_windows_skip_cache_key }}
- name: Check skip cache for Test (Python Latest Supported)
uses: actions/cache@v3
with:
path: .skip_cache_test_python_latest_supported
key: 0_check_${{ steps.set_cache.outputs.test_python_latest_supported_skip_cache_key }}_${{ github.run_id }}
restore-keys:
0_${{ steps.set_cache.outputs.test_python_latest_supported_skip_cache_key }}
- name: Check skip cache for Test (Python 3.12)
uses: actions/cache@v3
with:
path: .skip_cache_test_python_312
key: 0_check_${{ steps.set_cache.outputs.test_python_312_skip_cache_key }}_${{ github.run_id }}
restore-keys:
0_${{ steps.set_cache.outputs.test_python_312_skip_cache_key }}
- name: Check skip cache for Test (Python 3.11)
uses: actions/cache@v3
with:
path: .skip_cache_test_python_311
key: 0_check_${{ steps.set_cache.outputs.test_python_311_skip_cache_key }}_${{ github.run_id }}
restore-keys:
0_${{ steps.set_cache.outputs.test_python_311_skip_cache_key }}
- name: Check skip cache for Test (Python 3.10)
uses: actions/cache@v3
with:
path: .skip_cache_test_python_310
key: 0_check_${{ steps.set_cache.outputs.test_python_310_skip_cache_key }}_${{ github.run_id }}
restore-keys:
0_${{ steps.set_cache.outputs.test_python_310_skip_cache_key }}
- name: Check skip cache for Test (Qt GUI)
uses: actions/cache@v3
with:
path: .skip_cache_test_qt_gui
key: 0_check_${{ steps.set_cache.outputs.test_qt_gui_skip_cache_key }}_${{ github.run_id }}
restore-keys:
0_${{ steps.set_cache.outputs.test_qt_gui_skip_cache_key }}
- name: Check skip cache for Test (Packaging)
uses: actions/cache@v3
with:
path: .skip_cache_test_packaging
key: 0_check_${{ steps.set_cache.outputs.test_packaging_skip_cache_key }}_${{ github.run_id }}
restore-keys:
0_${{ steps.set_cache.outputs.test_packaging_skip_cache_key }}
- name: Check skip cache for Test (Code Quality)
uses: actions/cache@v3
with:
path: .skip_cache_test_code_quality
key: 0_check_${{ steps.set_cache.outputs.test_code_quality_skip_cache_key }}_${{ github.run_id }}
restore-keys:
0_${{ steps.set_cache.outputs.test_code_quality_skip_cache_key }}
- name: Check skip cache for Build (Linux)
uses: actions/cache@v3
with:
path: .skip_cache_build_linux
key: 0_check_${{ steps.set_cache.outputs.build_linux_skip_cache_key }}_${{ github.run_id }}
restore-keys:
0_${{ steps.set_cache.outputs.build_linux_skip_cache_key }}
- name: Check skip cache for Build (macOS App)
uses: actions/cache@v3
with:
path: .skip_cache_build_macos_app
key: 0_check_${{ steps.set_cache.outputs.build_macos_app_skip_cache_key }}_${{ github.run_id }}
restore-keys:
0_${{ steps.set_cache.outputs.build_macos_app_skip_cache_key }}
- name: Check skip cache for Notarize (macOS App)
uses: actions/cache@v3
with:
path: .skip_cache_notarize_macos_app
key: 0_check_${{ steps.set_cache.outputs.notarize_macos_app_skip_cache_key }}_${{ github.run_id }}
restore-keys:
0_${{ steps.set_cache.outputs.notarize_macos_app_skip_cache_key }}
- name: Check skip cache for Build (macOS DMG)
uses: actions/cache@v3
with:
path: .skip_cache_build_macos_dmg
key: 0_check_${{ steps.set_cache.outputs.build_macos_dmg_skip_cache_key }}_${{ github.run_id }}
restore-keys:
0_${{ steps.set_cache.outputs.build_macos_dmg_skip_cache_key }}
- name: Check skip cache for Notarize (macOS DMG)
uses: actions/cache@v3
with:
path: .skip_cache_notarize_macos_dmg
key: 0_check_${{ steps.set_cache.outputs.notarize_macos_dmg_skip_cache_key }}_${{ github.run_id }}
restore-keys:
0_${{ steps.set_cache.outputs.notarize_macos_dmg_skip_cache_key }}
- name: Check skip cache for Build (Windows)
uses: actions/cache@v3
with:
path: .skip_cache_build_windows
key: 0_check_${{ steps.set_cache.outputs.build_windows_skip_cache_key }}_${{ github.run_id }}
restore-keys:
0_${{ steps.set_cache.outputs.build_windows_skip_cache_key }}
- name: Set outputs
id: set_ouputs
run: |
analyze_set_release_info
job_cache_extra_deps=(); job_id=test_linux; job_name='Test (Linux)'; job_needs=(); job_os=Linux; job_platform=ubuntu-22.04; job_python=3.13.3; job_reqs=(reqs/dist.txt reqs/test.txt); job_skip_cache_name=skip_test_linux_py-3.13.3_ubuntu-22.04; job_skip_cache_path=.skip_cache_test_linux; job_skiplists=(job_test os_linux); job_test_args='-p no:pytest-qt --ignore=test/gui_qt'; job_type=test; job_variant=Linux; analyze_set_job_skip_job
job_cache_extra_deps=(osx/deps.sh); job_id=test_macos; job_name='Test (macOS)'; job_needs=(); job_os=macOS; job_platform=macos-15; job_python=3.13.3; job_reqs=(reqs/dist.txt reqs/test.txt); job_skip_cache_name=skip_test_macos_py-3.13.3_macos-15; job_skip_cache_path=.skip_cache_test_macos; job_skiplists=(job_test os_macos); job_test_args='-p no:pytest-qt --ignore=test/gui_qt'; job_type=test; job_variant=macOS; analyze_set_job_skip_job
job_cache_extra_deps=(); job_id=test_windows; job_name='Test (Windows)'; job_needs=(); job_os=Windows; job_platform=windows-2022; job_python=3.13.3; job_reqs=(reqs/dist.txt reqs/test.txt); job_skip_cache_name=skip_test_windows_py-3.13.3_windows-2022; job_skip_cache_path=.skip_cache_test_windows; job_skiplists=(job_test os_windows); job_test_args='-p no:pytest-qt --ignore=test/gui_qt'; job_type=test; job_variant=Windows; analyze_set_job_skip_job
job_cache_extra_deps=(); job_id=test_python_latest_supported; job_name='Test (Python Latest Supported)'; job_needs=(); job_os=Linux; job_platform=ubuntu-latest; job_python=3.13.3; job_reqs=(reqs/dist.txt reqs/test.txt); job_skip_cache_name=skip_test_python_latest_supported_py-3.13.3_ubuntu-latest; job_skip_cache_path=.skip_cache_test_python_latest_supported; job_skiplists=(job_test os_linux os_macos os_windows); job_test_args='-p no:pytest-qt --ignore=test/gui_qt'; job_type=test; job_variant='Python Latest Supported'; analyze_set_job_skip_job
job_cache_extra_deps=(); job_id=test_python_312; job_name='Test (Python 3.12)'; job_needs=(); job_os=Linux; job_platform=ubuntu-latest; job_python=3.12; job_reqs=(reqs/dist.txt reqs/test.txt); job_skip_cache_name=skip_test_python_312_py-3.12_ubuntu-latest; job_skip_cache_path=.skip_cache_test_python_312; job_skiplists=(job_test os_linux os_macos os_windows); job_test_args='-p no:pytest-qt --ignore=test/gui_qt'; job_type=test; job_variant='Python 3.12'; analyze_set_job_skip_job
job_cache_extra_deps=(); job_id=test_python_311; job_name='Test (Python 3.11)'; job_needs=(); job_os=Linux; job_platform=ubuntu-latest; job_python=3.11; job_reqs=(reqs/dist.txt reqs/test.txt); job_skip_cache_name=skip_test_python_311_py-3.11_ubuntu-latest; job_skip_cache_path=.skip_cache_test_python_311; job_skiplists=(job_test os_linux os_macos os_windows); job_test_args='-p no:pytest-qt --ignore=test/gui_qt'; job_type=test; job_variant='Python 3.11'; analyze_set_job_skip_job
job_cache_extra_deps=(); job_id=test_python_310; job_name='Test (Python 3.10)'; job_needs=(); job_os=Linux; job_platform=ubuntu-latest; job_python=3.10; job_reqs=(reqs/dist.txt reqs/test.txt); job_skip_cache_name=skip_test_python_310_py-3.10_ubuntu-latest; job_skip_cache_path=.skip_cache_test_python_310; job_skiplists=(job_test os_linux os_macos os_windows); job_test_args='-p no:pytest-qt --ignore=test/gui_qt'; job_type=test; job_variant='Python 3.10'; analyze_set_job_skip_job
job_cache_extra_deps=(); job_id=test_qt_gui; job_name='Test (Qt GUI)'; job_needs=(); job_os=Linux; job_platform=ubuntu-22.04; job_python=3.13.3; job_reqs=(reqs/dist.txt reqs/dist_extra_gui_qt.txt reqs/test.txt); job_skip_cache_name=skip_test_qt_gui_py-3.13.3_ubuntu-22.04; job_skip_cache_path=.skip_cache_test_qt_gui; job_skiplists=(job_test_gui_qt); job_test_args=test/gui_qt; job_type=test_gui_qt; job_variant='Qt GUI'; analyze_set_job_skip_job
job_cache_extra_deps=(); job_id=test_packaging; job_name='Test (Packaging)'; job_needs=(); job_os=Linux; job_platform=ubuntu-latest; job_python=3.13.3; job_reqs=(reqs/packaging.txt reqs/setup.txt); job_skip_cache_name=skip_test_packaging_py-3.13.3_ubuntu-latest; job_skip_cache_path=.skip_cache_test_packaging; job_skiplists=(job_test_packaging); job_type=test_packaging; job_variant=Packaging; analyze_set_job_skip_job
job_cache_extra_deps=(); job_id=test_code_quality; job_name='Test (Code Quality)'; job_needs=(); job_os=Linux; job_platform=ubuntu-latest; job_python=3.13.3; job_reqs=(reqs/code_quality.txt); job_skip_cache_name=skip_test_code_quality_py-3.13.3_ubuntu-latest; job_skip_cache_path=.skip_cache_test_code_quality; job_type=test_code_quality; job_variant='Code Quality'; analyze_set_job_skip_job
job_cache_extra_deps=('reqs/dist_*.txt' linux/appimage/deps.sh); job_id=build_linux; job_name='Build (Linux)'; job_needs=(test_linux); job_os=Linux; job_platform=ubuntu-22.04; job_python=3.13.3; job_reqs=(reqs/build.txt reqs/setup.txt); job_skip_cache_name=skip_build_linux_py-3.13.3_ubuntu-22.04; job_skip_cache_path=.skip_cache_build_linux; job_skiplists=(job_build os_linux); job_type=build; job_variant=Linux; analyze_set_job_skip_job
job_cache_extra_deps=('reqs/dist_*.txt' osx/deps.sh); job_id=build_macos_app; job_name='Build (macOS App)'; job_needs=(test_macos); job_os=macOS; job_platform=macos-15; job_python=3.13.3; job_reqs=(reqs/build.txt reqs/setup.txt); job_skip_cache_name=skip_build_macos_app_py-3.13.3_macos-15; job_skip_cache_path=.skip_cache_build_macos_app; job_skiplists=(job_build os_macos); job_type=build; job_variant='macOS App'; analyze_set_job_skip_job
job_cache_extra_deps=('reqs/dist_*.txt' osx/deps.sh); job_id=notarize_macos_app; job_name='Notarize (macOS App)'; job_needs=(build_macos_app); job_os=macOS; job_platform=macos-15; job_python=3.13.3; job_reqs=(reqs/build.txt reqs/setup.txt); job_skip_cache_name=skip_notarize_macos_app_py-3.13.3_macos-15; job_skip_cache_path=.skip_cache_notarize_macos_app; job_skiplists=(job_build os_macos); job_type=notarize; job_variant='macOS App'; analyze_set_job_skip_job
job_cache_extra_deps=('reqs/dist_*.txt' osx/deps.sh); job_id=build_macos_dmg; job_name='Build (macOS DMG)'; job_needs=(build_macos_app notarize_macos_app); job_os=macOS; job_platform=macos-15; job_python=3.13.3; job_reqs=(reqs/build.txt reqs/setup.txt); job_skip_cache_name=skip_build_macos_dmg_py-3.13.3_macos-15; job_skip_cache_path=.skip_cache_build_macos_dmg; job_skiplists=(job_build os_macos); job_type=build; job_variant='macOS DMG'; analyze_set_job_skip_job
job_cache_extra_deps=('reqs/dist_*.txt' osx/deps.sh); job_id=notarize_macos_dmg; job_name='Notarize (macOS DMG)'; job_needs=(build_macos_dmg); job_os=macOS; job_platform=macos-15; job_python=3.13.3; job_reqs=(reqs/build.txt reqs/setup.txt); job_skip_cache_name=skip_notarize_macos_dmg_py-3.13.3_macos-15; job_skip_cache_path=.skip_cache_notarize_macos_dmg; job_skiplists=(job_build os_macos); job_type=notarize; job_variant='macOS DMG'; analyze_set_job_skip_job
job_cache_extra_deps=('reqs/dist_*.txt' windows/dist_deps.sh); job_id=build_windows; job_name='Build (Windows)'; job_needs=(test_windows); job_os=Windows; job_platform=windows-2022; job_python=3.13.3; job_reqs=(reqs/build.txt reqs/setup.txt); job_skip_cache_name=skip_build_windows_py-3.13.3_windows-2022; job_skip_cache_path=.skip_cache_build_windows; job_skiplists=(job_build os_windows); job_type=build; job_variant=Windows; analyze_set_job_skip_job
outputs:
is_release: ${{ steps.set_ouputs.outputs.is_release }}
release_type: ${{ steps.set_ouputs.outputs.release_type }}
test_linux_skip_job: ${{ steps.set_ouputs.outputs.test_linux_skip_job }}
test_linux_skip_cache_key: ${{ steps.set_cache.outputs.test_linux_skip_cache_key }}
test_macos_skip_job: ${{ steps.set_ouputs.outputs.test_macos_skip_job }}
test_macos_skip_cache_key: ${{ steps.set_cache.outputs.test_macos_skip_cache_key }}
test_windows_skip_job: ${{ steps.set_ouputs.outputs.test_windows_skip_job }}
test_windows_skip_cache_key: ${{ steps.set_cache.outputs.test_windows_skip_cache_key }}
test_python_latest_supported_skip_job: ${{ steps.set_ouputs.outputs.test_python_latest_supported_skip_job }}
test_python_latest_supported_skip_cache_key: ${{ steps.set_cache.outputs.test_python_latest_supported_skip_cache_key }}
test_python_312_skip_job: ${{ steps.set_ouputs.outputs.test_python_312_skip_job }}
test_python_312_skip_cache_key: ${{ steps.set_cache.outputs.test_python_312_skip_cache_key }}
test_python_311_skip_job: ${{ steps.set_ouputs.outputs.test_python_311_skip_job }}
test_python_311_skip_cache_key: ${{ steps.set_cache.outputs.test_python_311_skip_cache_key }}
test_python_310_skip_job: ${{ steps.set_ouputs.outputs.test_python_310_skip_job }}
test_python_310_skip_cache_key: ${{ steps.set_cache.outputs.test_python_310_skip_cache_key }}
test_qt_gui_skip_job: ${{ steps.set_ouputs.outputs.test_qt_gui_skip_job }}
test_qt_gui_skip_cache_key: ${{ steps.set_cache.outputs.test_qt_gui_skip_cache_key }}
test_packaging_skip_job: ${{ steps.set_ouputs.outputs.test_packaging_skip_job }}
test_packaging_skip_cache_key: ${{ steps.set_cache.outputs.test_packaging_skip_cache_key }}
test_code_quality_skip_job: ${{ steps.set_ouputs.outputs.test_code_quality_skip_job }}
test_code_quality_skip_cache_key: ${{ steps.set_cache.outputs.test_code_quality_skip_cache_key }}
build_linux_skip_job: ${{ steps.set_ouputs.outputs.build_linux_skip_job }}
build_linux_skip_cache_key: ${{ steps.set_cache.outputs.build_linux_skip_cache_key }}
build_macos_app_skip_job: ${{ steps.set_ouputs.outputs.build_macos_app_skip_job }}
build_macos_app_skip_cache_key: ${{ steps.set_cache.outputs.build_macos_app_skip_cache_key }}
notarize_macos_app_skip_job: ${{ steps.set_ouputs.outputs.notarize_macos_app_skip_job }}
notarize_macos_app_skip_cache_key: ${{ steps.set_cache.outputs.notarize_macos_app_skip_cache_key }}
build_macos_dmg_skip_job: ${{ steps.set_ouputs.outputs.build_macos_dmg_skip_job }}
build_macos_dmg_skip_cache_key: ${{ steps.set_cache.outputs.build_macos_dmg_skip_cache_key }}
notarize_macos_dmg_skip_job: ${{ steps.set_ouputs.outputs.notarize_macos_dmg_skip_job }}
notarize_macos_dmg_skip_cache_key: ${{ steps.set_cache.outputs.notarize_macos_dmg_skip_cache_key }}
build_windows_skip_job: ${{ steps.set_ouputs.outputs.build_windows_skip_job }}
build_windows_skip_cache_key: ${{ steps.set_cache.outputs.build_windows_skip_cache_key }}
release_skip_job: ${{ steps.set_ouputs.outputs.release_skip_job }}
# }}}
# Job: Test (Linux) {{{
test_linux:
name: Test (Linux)
runs-on: ubuntu-22.04
needs: [analyze, ]
if: >-
!cancelled()
&& needs.analyze.outputs.test_linux_skip_job == 'no'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.13.3'
- name: Set cache name
id: set_cache
run: setup_cache_name '3.13.3' 'ubuntu-22.04'
- name: Setup cache
uses: actions/cache@v4
with:
path: .cache
key: 0_${{ steps.set_cache.outputs.cache_name }}_${{ hashFiles('reqs/constraints.txt', 'reqs/dist.txt', 'reqs/test.txt') }}
- name: Setup Python environment
run: setup_python_env -c reqs/constraints.txt -r reqs/dist.txt -r reqs/test.txt
# Test {{{
- name: Run tests
run: run_tests -p no:pytest-qt --ignore=test/gui_qt
# }}}
- name: Update skip cache 1
uses: actions/cache@v4
with:
path: .skip_cache_test_linux
key: 0_${{ needs.analyze.outputs.test_linux_skip_cache_key }}
- name: Update skip cache 2
run: run_eval "echo 'https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID' >'.skip_cache_test_linux'"
- name: List cache contents
run: list_cache
# }}}
# Job: Test (macOS) {{{
test_macos:
name: Test (macOS)
runs-on: macos-15
needs: [analyze, ]
if: >-
!cancelled()
&& needs.analyze.outputs.test_macos_skip_job == 'no'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set cache name
id: set_cache
run: setup_cache_name '3.13.3' 'macos-15'
- name: Setup cache
uses: actions/cache@v4
with:
path: .cache
key: 0_${{ steps.set_cache.outputs.cache_name }}_${{ hashFiles('reqs/constraints.txt', 'reqs/dist.txt', 'reqs/test.txt', 'osx/deps.sh') }}
# To support older macOS versions, setup Python from an official installer.
- name: Setup Python
run: setup_osx_python '3.13.3'
- name: Setup Python environment
run: setup_python_env -c reqs/constraints.txt -r reqs/dist.txt -r reqs/test.txt
# Test {{{
- name: Run tests
run: run_tests -p no:pytest-qt --ignore=test/gui_qt
# }}}
- name: Update skip cache 1
uses: actions/cache@v4
with:
path: .skip_cache_test_macos
key: 0_${{ needs.analyze.outputs.test_macos_skip_cache_key }}
- name: Update skip cache 2
run: run_eval "echo 'https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID' >'.skip_cache_test_macos'"
- name: List cache contents
run: list_cache
# }}}
# Job: Test (Windows) {{{
test_windows:
name: Test (Windows)
runs-on: windows-2022
needs: [analyze, ]
if: >-
!cancelled()
&& needs.analyze.outputs.test_windows_skip_job == 'no'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.13.3'
# On Windows, ensure we use a tar compatible
# with the one used in the analyze job.
- name: Fix tar
run: rm C:/Windows/System32/tar
- name: Set cache name
id: set_cache
run: setup_cache_name '3.13.3' 'windows-2022'
- name: Setup cache
uses: actions/cache@v4
with:
path: .cache
key: 0_${{ steps.set_cache.outputs.cache_name }}_${{ hashFiles('reqs/constraints.txt', 'reqs/dist.txt', 'reqs/test.txt') }}
- name: Setup Python environment
run: setup_python_env -c reqs/constraints.txt -r reqs/dist.txt -r reqs/test.txt
# Test {{{
- name: Run tests
run: run_tests -p no:pytest-qt --ignore=test/gui_qt
# }}}
- name: Update skip cache 1
uses: actions/cache@v4
with:
path: .skip_cache_test_windows
key: 0_${{ needs.analyze.outputs.test_windows_skip_cache_key }}
- name: Update skip cache 2
run: run_eval "echo 'https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID' >'.skip_cache_test_windows'"
- name: List cache contents
run: list_cache
# }}}
# Job: Test (Python Latest Supported) {{{
test_python_latest_supported:
name: Test (Python Latest Supported)
runs-on: ubuntu-latest
needs: [analyze, ]
if: >-
!cancelled()
&& needs.analyze.outputs.test_python_latest_supported_skip_job == 'no'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.13.3'
- name: Set cache name
id: set_cache
run: setup_cache_name '3.13.3' 'ubuntu-latest'
- name: Setup cache
uses: actions/cache@v4
with:
path: .cache
key: 0_${{ steps.set_cache.outputs.cache_name }}_${{ hashFiles('reqs/constraints.txt', 'reqs/dist.txt', 'reqs/test.txt') }}
- name: Setup Python environment
run: setup_python_env -c reqs/constraints.txt -r reqs/dist.txt -r reqs/test.txt
# Test {{{
- name: Run tests
run: run_tests -p no:pytest-qt --ignore=test/gui_qt
# }}}
- name: Update skip cache 1
uses: actions/cache@v4
with:
path: .skip_cache_test_python_latest_supported
key: 0_${{ needs.analyze.outputs.test_python_latest_supported_skip_cache_key }}
- name: Update skip cache 2
run: run_eval "echo 'https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID' >'.skip_cache_test_python_latest_supported'"
- name: List cache contents
run: list_cache
# }}}
# Job: Test (Python 3.12) {{{
test_python_312:
name: Test (Python 3.12)
runs-on: ubuntu-latest
needs: [analyze, ]
if: >-
!cancelled()
&& needs.analyze.outputs.test_python_312_skip_job == 'no'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Set cache name
id: set_cache
run: setup_cache_name '3.12' 'ubuntu-latest'
- name: Setup cache
uses: actions/cache@v4
with:
path: .cache
key: 0_${{ steps.set_cache.outputs.cache_name }}_${{ hashFiles('reqs/constraints.txt', 'reqs/dist.txt', 'reqs/test.txt') }}
- name: Setup Python environment
run: setup_python_env -c reqs/constraints.txt -r reqs/dist.txt -r reqs/test.txt
# Test {{{
- name: Run tests
run: run_tests -p no:pytest-qt --ignore=test/gui_qt
# }}}
- name: Update skip cache 1
uses: actions/cache@v4
with:
path: .skip_cache_test_python_312
key: 0_${{ needs.analyze.outputs.test_python_312_skip_cache_key }}
- name: Update skip cache 2
run: run_eval "echo 'https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID' >'.skip_cache_test_python_312'"
- name: List cache contents
run: list_cache
# }}}
# Job: Test (Python 3.11) {{{
test_python_311:
name: Test (Python 3.11)
runs-on: ubuntu-latest
needs: [analyze, ]
if: >-
!cancelled()
&& needs.analyze.outputs.test_python_311_skip_job == 'no'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Set cache name
id: set_cache
run: setup_cache_name '3.11' 'ubuntu-latest'
- name: Setup cache
uses: actions/cache@v4
with:
path: .cache
key: 0_${{ steps.set_cache.outputs.cache_name }}_${{ hashFiles('reqs/constraints.txt', 'reqs/dist.txt', 'reqs/test.txt') }}
- name: Setup Python environment
run: setup_python_env -c reqs/constraints.txt -r reqs/dist.txt -r reqs/test.txt
# Test {{{
- name: Run tests
run: run_tests -p no:pytest-qt --ignore=test/gui_qt
# }}}
- name: Update skip cache 1
uses: actions/cache@v4
with:
path: .skip_cache_test_python_311
key: 0_${{ needs.analyze.outputs.test_python_311_skip_cache_key }}
- name: Update skip cache 2
run: run_eval "echo 'https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID' >'.skip_cache_test_python_311'"
- name: List cache contents
run: list_cache
# }}}
# Job: Test (Python 3.10) {{{
test_python_310:
name: Test (Python 3.10)
runs-on: ubuntu-latest
needs: [analyze, ]
if: >-
!cancelled()
&& needs.analyze.outputs.test_python_310_skip_job == 'no'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: Set cache name
id: set_cache
run: setup_cache_name '3.10' 'ubuntu-latest'
- name: Setup cache
uses: actions/cache@v4
with:
path: .cache
key: 0_${{ steps.set_cache.outputs.cache_name }}_${{ hashFiles('reqs/constraints.txt', 'reqs/dist.txt', 'reqs/test.txt') }}
- name: Setup Python environment
run: setup_python_env -c reqs/constraints.txt -r reqs/dist.txt -r reqs/test.txt
# Test {{{
- name: Run tests
run: run_tests -p no:pytest-qt --ignore=test/gui_qt
# }}}
- name: Update skip cache 1
uses: actions/cache@v4
with:
path: .skip_cache_test_python_310
key: 0_${{ needs.analyze.outputs.test_python_310_skip_cache_key }}
- name: Update skip cache 2
run: run_eval "echo 'https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID' >'.skip_cache_test_python_310'"
- name: List cache contents
run: list_cache
# }}}
# Job: Test (Qt GUI) {{{
test_qt_gui:
name: Test (Qt GUI)
runs-on: ubuntu-22.04
needs: [analyze, ]
if: >-
!cancelled()
&& needs.analyze.outputs.test_qt_gui_skip_job == 'no'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.13.3'
- name: Set cache name
id: set_cache
run: setup_cache_name '3.13.3' 'ubuntu-22.04'
- name: Setup cache
uses: actions/cache@v4
with:
path: .cache
key: 0_${{ steps.set_cache.outputs.cache_name }}_${{ hashFiles('reqs/constraints.txt', 'reqs/dist.txt', 'reqs/dist_extra_gui_qt.txt', 'reqs/test.txt') }}
- name: Install system dependencies
run: apt_get_install cmake libdbus-1-dev libdbus-glib-1-dev libudev-dev libusb-1.0-0-dev libegl-dev libxkbcommon-x11-0
- name: Setup Python environment
run: setup_python_env -c reqs/constraints.txt -r reqs/dist.txt -r reqs/dist_extra_gui_qt.txt -r reqs/test.txt
- name: Build UI
run: python setup.py build_ui
# Test {{{
- name: Run tests
run: run_tests test/gui_qt
# }}}
- name: Update skip cache 1
uses: actions/cache@v4
with:
path: .skip_cache_test_qt_gui
key: 0_${{ needs.analyze.outputs.test_qt_gui_skip_cache_key }}
- name: Update skip cache 2
run: run_eval "echo 'https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID' >'.skip_cache_test_qt_gui'"
- name: List cache contents
run: list_cache
# }}}
# Job: Test (Packaging) {{{
test_packaging:
name: Test (Packaging)
runs-on: ubuntu-latest
needs: [analyze, ]
if: >-
!cancelled()
&& needs.analyze.outputs.test_packaging_skip_job == 'no'
steps:
- name: Checkout
uses: actions/checkout@v4
with:
# We need the whole history for patching the version.
fetch-depth: 0
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.13.3'
- name: Set cache name
id: set_cache
run: setup_cache_name '3.13.3' 'ubuntu-latest'
- name: Setup cache
uses: actions/cache@v4
with:
path: .cache
key: 0_${{ steps.set_cache.outputs.cache_name }}_${{ hashFiles('reqs/constraints.txt', 'reqs/packaging.txt', 'reqs/setup.txt') }}
- name: Setup Python environment
run: setup_python_env -c reqs/constraints.txt -r reqs/packaging.txt -r reqs/setup.txt
- name: Patch version
id: set_version
run: |
python setup.py patch_version
echo "version=$(python setup.py --version)" >> $GITHUB_OUTPUT
# Test packaging {{{
- name: Run packaging sanity checks
run: packaging_checks
- name: Archive artifact (sdist)
if: needs.analyze.outputs.is_release == 'yes'
uses: actions/upload-artifact@v4
with:
name: Source
path: dist/*.tar.gz
- name: Archive artifact (wheel)
if: needs.analyze.outputs.is_release == 'yes'
uses: actions/upload-artifact@v4
with:
name: Wheel
path: dist/*.whl
- name: Generate translations catalogs archive
if: needs.analyze.outputs.is_release == 'yes'
run: generate_translations_catalogs_archive
- name: Archive artifact (translations catalogs)
if: needs.analyze.outputs.is_release == 'yes'
uses: actions/upload-artifact@v4
with:
name: Translations Catalogs
path: dist/*-messages.zip
# }}}
- name: Update skip cache 1
uses: actions/cache@v4
with:
path: .skip_cache_test_packaging
key: 0_${{ needs.analyze.outputs.test_packaging_skip_cache_key }}
- name: Update skip cache 2
run: run_eval "echo 'https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID' >'.skip_cache_test_packaging'"
- name: List cache contents
run: list_cache
outputs:
version: ${{ steps.set_version.outputs.version }}
# }}}
# Job: Test (Code Quality) {{{
test_code_quality:
name: Test (Code Quality)
runs-on: ubuntu-latest
needs: [analyze, ]
if: >-
!cancelled()
&& needs.analyze.outputs.test_code_quality_skip_job == 'no'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.13.3'
- name: Set cache name
id: set_cache
run: setup_cache_name '3.13.3' 'ubuntu-latest'
- name: Setup cache
uses: actions/cache@v4
with:
path: .cache
key: 0_${{ steps.set_cache.outputs.cache_name }}_${{ hashFiles('reqs/constraints.txt', 'reqs/code_quality.txt') }}
- name: Setup Python environment
run: setup_python_env -c reqs/constraints.txt -r reqs/code_quality.txt
- name: Run Ruff (format check)
run: ruff format --check .
- name: Update skip cache 1
uses: actions/cache@v4
with:
path: .skip_cache_test_code_quality
key: 0_${{ needs.analyze.outputs.test_code_quality_skip_cache_key }}
- name: Update skip cache 2
run: run_eval "echo 'https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID' >'.skip_cache_test_code_quality'"
- name: List cache contents
run: list_cache
# }}}
# Job: Build (Linux) {{{
build_linux:
name: Build (Linux)
runs-on: ubuntu-22.04
needs: [analyze, test_linux]
if: >-
!cancelled()
&& (needs.test_linux.result == 'success' || needs.test_linux.result == 'skipped')
&& needs.analyze.outputs.build_linux_skip_job == 'no'
steps:
- name: Checkout
uses: actions/checkout@v4
with:
# We need the whole history for patching the version.
fetch-depth: 0
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.13.3'
- name: Set cache name
id: set_cache
run: setup_cache_name '3.13.3' 'ubuntu-22.04'
- name: Setup cache
uses: actions/cache@v4
with:
path: .cache
key: 0_${{ steps.set_cache.outputs.cache_name }}_${{ hashFiles('reqs/constraints.txt', 'reqs/build.txt', 'reqs/setup.txt', 'reqs/dist_*.txt', 'linux/appimage/deps.sh') }}
- name: Install system dependencies
run: apt_get_install cmake libdbus-1-dev libdbus-glib-1-dev libudev-dev libusb-1.0-0-dev libegl-dev libxkbcommon-x11-0
- name: Setup Python environment
run: setup_python_env -c reqs/constraints.txt -r reqs/build.txt -r reqs/setup.txt
- name: Patch version
id: set_version
run: |
python setup.py patch_version
# Build {{{
- name: Build distribution (Linux AppImage)
run: python setup.py -q bdist_appimage --no-update-tools
- name: Archive artifact (Linux AppImage)
uses: actions/upload-artifact@v4
with:
name: Linux AppImage
path: dist/*.AppImage
# }}}
- name: Update skip cache 1
uses: actions/cache@v4
with:
path: .skip_cache_build_linux
key: 0_${{ needs.analyze.outputs.build_linux_skip_cache_key }}
- name: Update skip cache 2
run: run_eval "echo 'https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID' >'.skip_cache_build_linux'"
- name: List cache contents
run: list_cache
# }}}
# Job: Build (macOS App) {{{
build_macos_app:
name: Build (macOS App)
runs-on: macos-15
needs: [analyze, test_macos]
if: >-
!cancelled()
&& (needs.test_macos.result == 'success' || needs.test_macos.result == 'skipped')
&& needs.analyze.outputs.build_macos_app_skip_job == 'no'
steps:
- name: Checkout
uses: actions/checkout@v4
with:
# We need the whole history for patching the version.
fetch-depth: 0
- name: Set cache name
id: set_cache
run: setup_cache_name '3.13.3' 'macos-15'
- name: Setup cache
uses: actions/cache@v4
with:
path: .cache
key: 0_${{ steps.set_cache.outputs.cache_name }}_${{ hashFiles('reqs/constraints.txt', 'reqs/build.txt', 'reqs/setup.txt', 'reqs/dist_*.txt', 'osx/deps.sh') }}
# To support older macOS versions, setup Python from an official installer.
- name: Setup Python
run: setup_osx_python '3.13.3'
- name: Setup Python environment
run: setup_python_env -c reqs/constraints.txt -r reqs/build.txt -r reqs/setup.txt
- name: Patch version
id: set_version
run: |
python setup.py patch_version
# Build {{{
- name: Build distribution (macOS app)
run: python setup.py -q bdist_app
- name: Pack app as tar (preserve symlinks)
run: |
rm -f dist/Plover.app.tgz
tar -C dist -czf dist/Plover.app.tgz Plover.app
- name: Save app tarball to internal cache
uses: actions/cache/save@v4
with:
path: dist/Plover.app.tgz
key: 0_macos-app-raw-${{ github.run_id }}
# }}}
- name: Update skip cache 1
uses: actions/cache@v4
with:
path: .skip_cache_build_macos_app
key: 0_${{ needs.analyze.outputs.build_macos_app_skip_cache_key }}
- name: Update skip cache 2
run: run_eval "echo 'https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID' >'.skip_cache_build_macos_app'"
- name: List cache contents
run: list_cache
# }}}
# Job: Notarize (macOS App) {{{
notarize_macos_app:
name: Notarize (macOS App)
environment: production
runs-on: macos-15
needs: [analyze, build_macos_app]
if: >-
!cancelled()
&& (needs.build_macos_app.result == 'success' || needs.build_macos_app.result == 'skipped')
&& needs.analyze.outputs.notarize_macos_app_skip_job == 'no'
env:
# Code signing
MACOS_CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
MACOS_CODESIGN_CERT_P12_BASE64: ${{ secrets.MACOS_CODESIGN_CERT_P12_BASE64 }}
MACOS_CODESIGN_CERT_PASSWORD: ${{ secrets.MACOS_CODESIGN_CERT_PASSWORD }}
MACOS_TEMP_KEYCHAIN_NAME: plover-build
MACOS_TEMP_KEYCHAIN_PASSWORD: ${{ secrets.MACOS_TEMP_KEYCHAIN_PASSWORD }}
# Notarization
MACOS_NOTARIZE_ENABLED: ${{ secrets.MACOS_NOTARIZE_ENABLED || '0' }}
MACOS_NOTARIZE_TEAM_ID: ${{ secrets.MACOS_NOTARIZE_TEAM_ID }}
MACOS_NOTARIZE_KEY_ID: ${{ secrets.MACOS_NOTARIZE_KEY_ID }}
MACOS_NOTARIZE_ISSUER_ID: ${{ secrets.MACOS_NOTARIZE_ISSUER_ID }}
MACOS_NOTARIZE_KEY_CONTENTS: ${{ secrets.MACOS_NOTARIZE_KEY_CONTENTS }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set cache name
id: set_cache
run: setup_cache_name '3.13.3' 'macos-15'
- name: Setup cache
uses: actions/cache@v4
with:
path: .cache
key: 0_${{ steps.set_cache.outputs.cache_name }}_${{ hashFiles('reqs/constraints.txt', 'reqs/build.txt', 'reqs/setup.txt', 'reqs/dist_*.txt', 'osx/deps.sh') }}
# Notarize {{{
- name: Restore app tarball from internal cache
uses: actions/cache/restore@v4
with:
path: dist/Plover.app.tgz
key: 0_macos-app-raw-${{ github.run_id }}
- name: Extract app tarball
run: |
mkdir -p dist
tar -C dist -xzf dist/*.tgz
- name: Install Developer ID certificate into temporary keychain
if: ${{ env.MACOS_NOTARIZE_ENABLED == '1' }}
run: install_dev_id_cert_into_temp_keychain
- name: Set codesign keychain env
run: echo "MACOS_CODESIGN_KEYCHAIN=${MACOS_TEMP_KEYCHAIN_NAME}.keychain" >> $GITHUB_ENV
- name: Notarize & staple app
run: |
chmod +x osx/notarize_app.sh
./osx/notarize_app.sh dist/*.app
- name: Cleanup temporary keychain
if: ${{ always() && env.MACOS_NOTARIZE_ENABLED == '1' }}
run: cleanup_dev_id_temp_keychain
- name: Repack notarized app as tar
run: |
rm -f dist/Plover.app.tgz
tar -C dist -czf dist/Plover.app.tgz Plover.app
- name: Save notarized app tarball to internal cache
uses: actions/cache/save@v4
with:
path: dist/Plover.app.tgz
key: 0_macos-app-notarized-${{ github.run_id }}
# }}}
- name: Update skip cache 1
uses: actions/cache@v4
with:
path: .skip_cache_notarize_macos_app
key: 0_${{ needs.analyze.outputs.notarize_macos_app_skip_cache_key }}
- name: Update skip cache 2
run: run_eval "echo 'https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID' >'.skip_cache_notarize_macos_app'"
- name: List cache contents
run: list_cache
# }}}
# Job: Build (macOS DMG) {{{
build_macos_dmg:
name: Build (macOS DMG)
runs-on: macos-15
needs: [analyze, build_macos_app, notarize_macos_app]
if: >-
!cancelled()
&& (needs.build_macos_app.result == 'success' || needs.build_macos_app.result == 'skipped')
&& (needs.notarize_macos_app.result == 'success' || needs.notarize_macos_app.result == 'skipped')
&& needs.analyze.outputs.build_macos_dmg_skip_job == 'no'
steps:
- name: Checkout
uses: actions/checkout@v4
with:
# We need the whole history for patching the version.
fetch-depth: 0
- name: Set cache name
id: set_cache
run: setup_cache_name '3.13.3' 'macos-15'
- name: Setup cache
uses: actions/cache@v4
with:
path: .cache
key: 0_${{ steps.set_cache.outputs.cache_name }}_${{ hashFiles('reqs/constraints.txt', 'reqs/build.txt', 'reqs/setup.txt', 'reqs/dist_*.txt', 'osx/deps.sh') }}
# To support older macOS versions, setup Python from an official installer.
- name: Setup Python
run: setup_osx_python '3.13.3'
- name: Setup Python environment
run: setup_python_env -c reqs/constraints.txt -r reqs/build.txt -r reqs/setup.txt
- name: Patch version
id: set_version
run: |
python setup.py patch_version
# Build {{{
- name: Restore app tarball from internal cache (prefer notarized)
uses: actions/cache/restore@v4
with:
path: dist/Plover.app.tgz
key: 0_macos-app-notarized-${{ github.run_id }}
restore-keys: 0_macos-app-raw-${{ github.run_id }}
- name: Extract app tarball
run: |
mkdir -p dist
tgz="$(ls -1 dist/*.tgz)"
echo "Using: $tgz"
tar -C dist -xzf "$tgz"
- name: Ensure app exists
run: test -d dist/*.app
- name: Build distribution (macOS DMG from existing app)
run: python setup.py -q bdist_dmg --skip-app-build
- name: Upload artifact (macOS DMG)
uses: actions/upload-artifact@v4
with:
name: macOS DMG
path: dist/*.dmg
overwrite: true
# }}}
- name: Update skip cache 1
uses: actions/cache@v4
with:
path: .skip_cache_build_macos_dmg
key: 0_${{ needs.analyze.outputs.build_macos_dmg_skip_cache_key }}
- name: Update skip cache 2
run: run_eval "echo 'https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID' >'.skip_cache_build_macos_dmg'"
- name: List cache contents
run: list_cache
# }}}
# Job: Notarize (macOS DMG) {{{
notarize_macos_dmg:
name: Notarize (macOS DMG)
environment: production
runs-on: macos-15
needs: [analyze, build_macos_dmg]
if: >-
!cancelled()
&& (needs.build_macos_dmg.result == 'success' || needs.build_macos_dmg.result == 'skipped')
&& needs.analyze.outputs.notarize_macos_dmg_skip_job == 'no'
env:
# Code signing
MACOS_CODESIGN_IDENTITY: ${{ secrets.MACOS_CODESIGN_IDENTITY }}
MACOS_CODESIGN_CERT_P12_BASE64: ${{ secrets.MACOS_CODESIGN_CERT_P12_BASE64 }}
MACOS_CODESIGN_CERT_PASSWORD: ${{ secrets.MACOS_CODESIGN_CERT_PASSWORD }}
MACOS_TEMP_KEYCHAIN_NAME: plover-build
MACOS_TEMP_KEYCHAIN_PASSWORD: ${{ secrets.MACOS_TEMP_KEYCHAIN_PASSWORD }}
# Notarization
MACOS_NOTARIZE_ENABLED: ${{ secrets.MACOS_NOTARIZE_ENABLED || '0' }}
MACOS_NOTARIZE_TEAM_ID: ${{ secrets.MACOS_NOTARIZE_TEAM_ID }}
MACOS_NOTARIZE_KEY_ID: ${{ secrets.MACOS_NOTARIZE_KEY_ID }}
MACOS_NOTARIZE_ISSUER_ID: ${{ secrets.MACOS_NOTARIZE_ISSUER_ID }}
MACOS_NOTARIZE_KEY_CONTENTS: ${{ secrets.MACOS_NOTARIZE_KEY_CONTENTS }}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set cache name
id: set_cache
run: setup_cache_name '3.13.3' 'macos-15'
- name: Setup cache
uses: actions/cache@v4
with:
path: .cache
key: 0_${{ steps.set_cache.outputs.cache_name }}_${{ hashFiles('reqs/constraints.txt', 'reqs/build.txt', 'reqs/setup.txt', 'reqs/dist_*.txt', 'osx/deps.sh') }}
# Notarize {{{
- name: Download artifact (macOS DMG)
uses: actions/download-artifact@v4
with:
name: macOS DMG
path: dist
pattern: "*.dmg"
- name: Install Developer ID certificate into temporary keychain
if: ${{ env.MACOS_NOTARIZE_ENABLED == '1' }}
run: install_dev_id_cert_into_temp_keychain
- name: Set codesign keychain env
run: echo "MACOS_CODESIGN_KEYCHAIN=${MACOS_TEMP_KEYCHAIN_NAME}.keychain" >> $GITHUB_ENV
- name: Notarize & staple DMG
run: |
chmod +x osx/notarize_dmg.sh
./osx/notarize_dmg.sh dist/*.dmg
- name: Cleanup temporary keychain
if: ${{ always() && env.MACOS_NOTARIZE_ENABLED == '1' }}
run: cleanup_dev_id_temp_keychain
- name: Upload artifact (macOS DMG)
uses: actions/upload-artifact@v4
with:
name: macOS DMG
path: dist/*.dmg
overwrite: true
# }}}
- name: Update skip cache 1
uses: actions/cache@v4
with:
path: .skip_cache_notarize_macos_dmg
key: 0_${{ needs.analyze.outputs.notarize_macos_dmg_skip_cache_key }}
- name: Update skip cache 2
run: run_eval "echo 'https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID' >'.skip_cache_notarize_macos_dmg'"
- name: List cache contents
run: list_cache
# }}}
# Job: Build (Windows) {{{
build_windows:
name: Build (Windows)
runs-on: windows-2022
needs: [analyze, test_windows]
if: >-
!cancelled()
&& (needs.test_windows.result == 'success' || needs.test_windows.result == 'skipped')
&& needs.analyze.outputs.build_windows_skip_job == 'no'
steps:
- name: Checkout
uses: actions/checkout@v4
with:
# We need the whole history for patching the version.
fetch-depth: 0
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.13.3'
# On Windows, ensure we use a tar compatible
# with the one used in the analyze job.
- name: Fix tar
run: rm C:/Windows/System32/tar
- name: Set cache name
id: set_cache
run: setup_cache_name '3.13.3' 'windows-2022'
- name: Setup cache
uses: actions/cache@v4
with:
path: .cache
key: 0_${{ steps.set_cache.outputs.cache_name }}_${{ hashFiles('reqs/constraints.txt', 'reqs/build.txt', 'reqs/setup.txt', 'reqs/dist_*.txt', 'windows/dist_deps.sh') }}
- name: Setup Python environment
run: setup_python_env -c reqs/constraints.txt -r reqs/build.txt -r reqs/setup.txt
- name: Patch version
id: set_version
run: |
python setup.py patch_version
# Build {{{
- name: Build distributions (Windows)
run: |
# Note: we avoid using the WSL bash (which does not work).
bash="$(cygpath -w -a "$(which bash)")"
python setup.py -q bdist_win -t -z -i --bash="$bash"
- name: Archive artifact (Windows Installer)
uses: actions/upload-artifact@v4
with:
name: Windows Installer
path: dist/*.exe
- name: Archive artifact (Windows ZIP)
uses: actions/upload-artifact@v4
with:
name: Windows ZIP
path: dist/*.zip
# }}}
- name: Update skip cache 1
uses: actions/cache@v4
with:
path: .skip_cache_build_windows
key: 0_${{ needs.analyze.outputs.build_windows_skip_cache_key }}
- name: Update skip cache 2
run: run_eval "echo 'https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID' >'.skip_cache_build_windows'"
- name: List cache contents
run: list_cache
# }}}
# Job: Release {{{
release:
name: Release
environment: release
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write
needs: [analyze, test_linux, test_macos, test_windows, test_python_latest_supported, test_python_312, test_python_311, test_python_310, test_qt_gui, test_packaging, test_code_quality, build_linux, build_macos_app, notarize_macos_app, build_macos_dmg, notarize_macos_dmg, build_windows]
if: >-
!cancelled()
&& needs.test_linux.result == 'success'
&& needs.test_macos.result == 'success'
&& needs.test_windows.result == 'success'
&& needs.test_python_latest_supported.result == 'success'
&& needs.test_python_312.result == 'success'
&& needs.test_python_311.result == 'success'
&& needs.test_python_310.result == 'success'
&& needs.test_qt_gui.result == 'success'
&& needs.test_packaging.result == 'success'
&& needs.test_code_quality.result == 'success'
&& needs.build_linux.result == 'success'
&& needs.build_macos_app.result == 'success'
&& needs.notarize_macos_app.result == 'success'
&& needs.build_macos_dmg.result == 'success'
&& needs.notarize_macos_dmg.result == 'success'
&& needs.build_windows.result == 'success'
&& needs.analyze.outputs.release_skip_job == 'no'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: 3.13.3
- name: Install dependencies
run: |
run apt_get_install -qq pandoc
run "$python" -m pip install -c reqs/constraints.txt -r reqs/release.txt
- name: Download artifacts
uses: actions/download-artifact@v4
with:
path: dist
- name: Publish GitHub release (${{ needs.analyze.outputs.release_type }})
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_TYPE: ${{ needs.analyze.outputs.release_type }}
RELEASE_VERSION: ${{ needs.test_packaging.outputs.version }}
run: publish_github_release
- name: Collect Python distributions for PyPI
run: |
mkdir -p dist/pypi
cp dist/Source/*.tar.gz dist/pypi/
cp dist/Wheel/*.whl dist/pypi/
- name: Publish release to PyPI (Trusted Publishing)
if: needs.analyze.outputs.release_type == 'tagged'
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: dist/pypi
skip-existing: true
# }}}