Skip to content

Python 3.15 (Faster startup with auto-lazy imports) #1359

Python 3.15 (Faster startup with auto-lazy imports)

Python 3.15 (Faster startup with auto-lazy imports) #1359

Workflow file for this run

# https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions
name: Lint and build
on:
workflow_dispatch: # Allows manual builds
inputs:
excludeBuildNumber:
description: "Exclude build number"
required: true
default: false
type: boolean
push:
branches:
- main
paths:
- ".github/workflows/lint-and-build.yml"
- "src/**"
- "scripts/**"
- "*.toml"
- "uv.lock"
pull_request:
branches:
- main
paths:
- ".github/workflows/lint-and-build.yml"
- "src/**"
- "scripts/**"
- "*.toml"
- "uv.lock"
permissions:
contents: read
env:
GITHUB_HEAD_REPOSITORY: ${{ github.event.pull_request.head.repo.full_name }}
GITHUB_EXCLUDE_BUILD_NUMBER: ${{ inputs.excludeBuildNumber }}
UV_NO_SYNC: true # Avoid accidentally pulling in dependency-groups with uv run
APPIMAGE_EXTRACT_AND_RUN: true # Avoid needing libfuse2
concurrency:
# Cancel previous runs for the same PR
# Don't cancel successive pushes to main
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
defaults:
run:
shell: pwsh
jobs:
PySentry:
runs-on: ubuntu-slim
steps:
- uses: actions/checkout@v6
- uses: astral-sh/setup-uv@v7
- run: uvx pysentry-rs --sources=pypa,pypi,osv --forbid-unmaintained
# Single source of truth for the shipped Python version(s).
# GitHub Actions has no length() and `strategy` can't read `env`, so the matrix and the
# "more than one Python version" flag are both derived here and consumed via `needs`.
Setup:
runs-on: ubuntu-slim
outputs:
python-versions: ${{ steps.set.outputs.python-versions }}
include-python-version-tag: ${{ steps.set.outputs.include-python-version-tag }}
steps:
- id: set
# Only the Python version(s) we plan on shipping matter.
run: |
$pythonVersions = @('3.14', '3.15')
"python-versions=$($pythonVersions | ConvertTo-Json -Compress -AsArray)" >> $Env:GITHUB_OUTPUT
"include-python-version-tag=$(if ($pythonVersions.Count -gt 1) { '-IncludePythonVersionTag' })" >> $Env:GITHUB_OUTPUT
Pyright:
needs: Setup
runs-on: ${{ matrix.os }}
env:
# Prevent accidentally slower type-checking due to missing arm wheels.
# Fail rather than accidentally compile C/binary extensions from sdist.
UV_NO_BUILD: ${{ !(matrix.python-version == '3.15' && matrix.os == 'windows-latest') }} # winrt-Windows no wheels for 3.15 yet
# Per-package no-binary overrides no-build, allowing
# known pure-Python source-only dependencies to still build.
# The Build job intentionally builds some binary packages from source.
UV_NO_BINARY_PACKAGE: >-
keyboard PyAutoGUI beslogic-ruff-config
${{ matrix.python-version == '3.15' && 'RapidFuzz Levenshtein' || '' }}
# TODO: ^ Remove these exceptions once 3.15 wheels are released
strategy:
fail-fast: false
# Pyright is version and platform sensible
matrix:
# windows arm runner slower as long as opencv doesn't provide windows arm64 wheels
os: [windows-latest, ubuntu-24.04-arm]
python-version: ${{ fromJson(needs.Setup.outputs.python-versions) }}
steps:
- uses: actions/checkout@v6
- name: Set up uv for Python ${{ matrix.python-version }}
uses: astral-sh/setup-uv@v7
with:
python-version: ${{ matrix.python-version }}
activate-environment: true
- run: scripts/install.ps1
- name: Analysing the code with Pyright
uses: jakebailey/pyright-action@v3
with:
version: PATH
working-directory: src/
python-version: ${{ matrix.python-version }}
Build:
needs: Setup
runs-on: ${{ matrix.os }}
outputs:
AUTOSPLIT_VERSION: ${{ steps.artifact_vars.outputs.AUTOSPLIT_VERSION }}
strategy:
fail-fast: false
matrix:
os: [windows-latest, windows-11-arm, ubuntu-24.04, ubuntu-24.04-arm]
python-version: ${{ fromJson(needs.Setup.outputs.python-versions) }}
wine-compat: [""]
include:
- os: windows-latest
python-version: "3.14"
wine-compat: "-WineCompat"
- os: windows-latest
python-version: "3.15"
wine-compat: "-WineCompat"
steps:
- uses: actions/checkout@v6
with:
fetch-depth: 2 # Needed for automatic version-bump check
# region https://github.com/pyinstaller/pyinstaller/issues/9204
- name: Set up Python for PyInstaller tk issue on Linux
if: ${{ startsWith(matrix.os, 'ubuntu') }}
uses: actions/setup-python@v6
with:
allow-prereleases: true
python-version: ${{ matrix.python-version }}
- name: Set up uv for Python ${{ matrix.python-version }}
uses: astral-sh/setup-uv@v7
with:
# On ARM64, uv defaults to x86_64 Python, force it to aarch64.
# https://github.com/astral-sh/uv/issues/12906#issuecomment-3587439179
#
# On Ubuntu use the global Python install (null) for reason above
python-version: >-
${{ (!startsWith(matrix.os, 'ubuntu')
&& format('{0}-{1}', matrix.python-version, endsWith(matrix.os, 'arm') && 'aarch64' || 'x86_64'))
|| null }}
# endregion
- run: scripts/install.ps1 ${{ matrix.wine-compat }}
- run: scripts/build.ps1 ${{ matrix.wine-compat }} ${{ needs.Setup.outputs.include-python-version-tag }}
- name: Run test suite
# pywinctl/pymonctl connect to the X display at import-time, hence xvfb
run: >-
${{ startsWith(matrix.os, 'ubuntu') && 'xvfb-run --auto-servernum' || '' }}
uv run -m unittest discover --start-directory tests --verbose
- name: Extract AutoSplit version
id: artifact_vars
working-directory: src
run: | # This also serves as a sanity check for imports
$Env:AUTOSPLIT_VERSION=uv run python -c "import utils; print(utils.AUTOSPLIT_VERSION)"
echo "AUTOSPLIT_VERSION=$Env:AUTOSPLIT_VERSION" >> $Env:GITHUB_OUTPUT
echo "OS=$([System.Runtime.InteropServices.RuntimeInformation]::RuntimeIdentifier)" >> $Env:GITHUB_OUTPUT
- name: Upload Build Artifact
uses: actions/upload-artifact@v7
with:
name: >
AutoSplit v${{ steps.artifact_vars.outputs.AUTOSPLIT_VERSION }} for ${{
steps.artifact_vars.outputs.OS }}${{ matrix.wine-compat }} (Python ${{
matrix.python-version }})
path: dist/AutoSplit*
if-no-files-found: error
- name: Upload Build logs
uses: actions/upload-artifact@v7
with:
name: >
Build logs for ${{ steps.artifact_vars.outputs.OS }}${{ matrix.wine-compat }} (Python
${{ matrix.python-version }})
path: |
build/AutoSplit*/*.toc
build/AutoSplit*/*.txt
build/AutoSplit*/*.html
if-no-files-found: error
Merge-Build-Artifacts:
needs: Build
runs-on: ubuntu-slim
steps:
- name: Merge all executables into a single artifact
uses: actions/upload-artifact/merge@v7
with:
name: AutoSplit v${{ needs.Build.outputs.AUTOSPLIT_VERSION }}
# Only the executables, not the per-OS build logs. Keep the individual downloads
pattern: AutoSplit v*
Release-Template:
needs: [Setup, Build]
runs-on: ubuntu-slim
steps:
- name: Annotate release template URL
run: |
$version = "v${{ needs.Build.outputs.AUTOSPLIT_VERSION }}"
$pythonBullet = if ('${{ needs.Setup.outputs.include-python-version-tag }}') {
"- Python: This is the Python version bundled with AutoSplit. Try the newer version, it should be functionally identical, with a marginal performance boost. If you have any issue with it, please [report it here](https://github.com/Toufool/AutoSplit/issues) or on the Discord server and use an older Python version in the mean time."
}
else { '' }
$body = [uri]::EscapeDataString(((@'
# Which Asset should I download?
{{PYTHON}}
- `arm64` vs `x64`: [Check your Processor Platform Architecture](https://www.checkadevice.com/tests/system/) (note that `x86_64`==`x64` and `aarch64`==`arm64`). If you're still unsure, `x64` will work either way. `arm64` should be more efficient.
- WineCompat: This is for running the Windows executable under Wine on Linux
'@).Replace('{{PYTHON}}', $pythonBullet).Trim() -replace "`n", ''))
# ^ Removing newline from template because GitHub will actually decode %0A
echo "::notice::${{ github.server_url }}/${{ github.repository }}/releases/new?target=main&tag=$version&title=$version&body=$body"