Repository navigation
Remove appveyor config #6
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 | |
| on: | |
| push: | |
| branches: [master] | |
| tags: ['v*'] | |
| workflow_dispatch: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| # a newer push to master supersedes the build in progress, while tag builds always run to the end | |
| cancel-in-progress: ${{ !startsWith(github.ref, 'refs/tags/') }} | |
| permissions: | |
| contents: read | |
| env: | |
| # without the key (e.g. in forks) the script prints a notice and the build goes on without the data | |
| CROWDIN_API_KEY: ${{ secrets.CROWDIN_API_KEY }} | |
| CROWDIN_PROJECT_ID: ${{ vars.CROWDIN_PROJECT_ID }} | |
| jobs: | |
| linux: | |
| name: Linux AppImage | |
| # the AppImage recipe bundles Ubuntu 22.04 packages, and the wx wheel is built for 22.04 as well | |
| runs-on: ubuntu-22.04 | |
| env: | |
| APPIMAGE_TOOL: appimage-builder-x86_64.AppImage | |
| # run AppImages by extracting them, so that the build does not depend on FUSE being usable | |
| APPIMAGE_EXTRACT_AND_RUN: 1 | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| # version numbers come from git describe, which needs the tags and the history leading to them | |
| fetch-depth: 0 | |
| filter: blob:none | |
| - name: Install system packages | |
| run: | | |
| sudo apt-get update | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get -y install \ | |
| libfuse2 \ | |
| libgtk-3-0 libsdl2-2.0-0 libwebkit2gtk-4.0-37 \ | |
| libgstreamer1.0-0 libgstreamer-plugins-base1.0-0 \ | |
| libnotify4 libtiff5 libjpeg-turbo8 libpcre2-32-0 \ | |
| libsm6 libxtst6 libxxf86vm1 libcurl4 libegl1 libgl1 | |
| - uses: astral-sh/setup-uv@v10.2.0 | |
| with: | |
| enable-cache: true | |
| cache-dependency-glob: uv.lock | |
| - name: Install dependencies | |
| run: | | |
| uv sync --frozen --no-default-groups --group wx-binary | |
| uv run --no-sync python -c "import wx; print(wx.version())" | |
| - name: Prepare pyfa data | |
| run: | | |
| uv export --frozen --no-default-groups --group wx-binary --no-hashes --format requirements-txt -o requirements-appimage.txt | |
| uv run --no-sync python -B scripts/compile_lang.py | |
| uv run --no-sync python -B scripts/dump_crowdin_progress.py | |
| uv run --no-sync python -B db_update.py | |
| version=$(uv run --no-sync python -B scripts/dump_version.py) | |
| echo "PYFA_VERSION=$version" >> "$GITHUB_ENV" | |
| - name: Build AppImage | |
| run: | | |
| curl --fail-with-body -o "$APPIMAGE_TOOL" -L https://github.com/AppImageCrafters/appimage-builder/releases/download/v1.1.0/appimage-builder-1.1.0-x86_64.AppImage | |
| chmod +x "$APPIMAGE_TOOL" | |
| mkdir -p build AppDir/opt/pyfa AppDir/usr/share/icons/hicolor/64x64/apps | |
| cp -r eos graphs gui imgs locale service utils eve.db config.py pyfa.py db_update.py README.md LICENSE version.yml AppDir/opt/pyfa/ | |
| cp imgs/gui/pyfa64.png AppDir/usr/share/icons/hicolor/64x64/apps/pyfa.png | |
| ./"$APPIMAGE_TOOL" --recipe dist_assets/linux/AppImageBuilder.yml | |
| - uses: actions/upload-artifact@v7 | |
| with: | |
| name: pyfa-linux | |
| path: pyfa-${{ env.PYFA_VERSION }}-linux.AppImage | |
| retention-days: 90 | |
| if-no-files-found: error | |
| windows: | |
| name: Windows | |
| runs-on: windows-2022 | |
| defaults: | |
| run: | |
| shell: pwsh | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 | |
| filter: blob:none | |
| - uses: actions/setup-python@v7 | |
| id: python | |
| with: | |
| python-version: '3.14' | |
| architecture: x64 | |
| - uses: astral-sh/setup-uv@v10.2.0 | |
| with: | |
| enable-cache: true | |
| cache-dependency-glob: uv.lock | |
| - name: Install dependencies | |
| run: uv sync --frozen --no-default-groups --group packaging --group wx-binary --python "${{ steps.python.outputs.python-path }}" | |
| - name: Prepare pyfa data | |
| run: | | |
| # otherwise only the exit code of the last command fails the step | |
| $PSNativeCommandUseErrorActionPreference = $true | |
| uv run --no-sync python scripts/compile_lang.py | |
| uv run --no-sync python scripts/dump_crowdin_progress.py | |
| uv run --no-sync python db_update.py | |
| $version = uv run --no-sync python scripts/dump_version.py | |
| "PYFA_VERSION=$version" >> $env:GITHUB_ENV | |
| - name: Build installer and zip | |
| run: | | |
| $PSNativeCommandUseErrorActionPreference = $true | |
| uv run --no-sync python -m PyInstaller --clean -y pyfa.spec | |
| # see pyfa-org/pyfa#1622 | |
| Copy-Item dist_assets\win\pyfa.exe.manifest dist\pyfa\ | |
| $appVersion = uv run --no-sync python -c "from packaging.version import Version; import yaml; print(Version(yaml.safe_load(open('version.yml'))['version']))" | |
| & "${env:ProgramFiles(x86)}\Inno Setup 6\ISCC.exe" dist_assets\win\pyfa-setup.iss ` | |
| "/dMyAppVersion=$appVersion" ` | |
| "/dMyAppDir=$env:GITHUB_WORKSPACE\dist\pyfa" ` | |
| "/dMyOutputDir=$env:GITHUB_WORKSPACE" ` | |
| "/dMyOutputFile=pyfa-$env:PYFA_VERSION-win" | |
| 7z a "pyfa-$env:PYFA_VERSION-win.zip" -r "$env:GITHUB_WORKSPACE\dist\pyfa\*" | |
| - uses: actions/upload-artifact@v7 | |
| with: | |
| name: pyfa-windows | |
| path: | | |
| pyfa-${{ env.PYFA_VERSION }}-win.exe | |
| pyfa-${{ env.PYFA_VERSION }}-win.zip | |
| retention-days: 90 | |
| if-no-files-found: error | |
| macos: | |
| name: macOS ${{ matrix.arch }} | |
| runs-on: ${{ matrix.runner }} | |
| strategy: | |
| # one architecture failing should not throw away the other one's build | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - arch: x86_64 | |
| runner: macos-15-intel | |
| platform: x86_64-apple-darwin | |
| - arch: arm64 | |
| runner: macos-15 | |
| platform: aarch64-apple-darwin | |
| env: | |
| # Oldest macOS the app has to run on. The runners are newer, and by default everything gets picked | |
| # or built for the runner's own version: uv chooses wheels for it, Homebrew's libraries are built for | |
| # it, and so is anything compiled here. The build fails if any bundled binary needs a newer one. | |
| MACOSX_DEPLOYMENT_TARGET: '12.0' | |
| # the runners come with Homebrew's Python, which is built for the runner's macOS; uv's own builds | |
| # target much older versions | |
| UV_PYTHON_PREFERENCE: only-managed | |
| steps: | |
| - uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 | |
| filter: blob:none | |
| - uses: astral-sh/setup-uv@v10.2.0 | |
| with: | |
| enable-cache: true | |
| cache-dependency-glob: uv.lock | |
| - name: Install dependencies | |
| # naming the platform makes uv choose wheels for MACOSX_DEPLOYMENT_TARGET instead of the runner's | |
| # macOS (numpy, for one, has separate wheels for macOS 14 and newer) | |
| run: uv sync --frozen --no-default-groups --group packaging --group wx-binary --python-platform ${{ matrix.platform }} | |
| - name: Prepare pyfa data | |
| run: | | |
| uv run --no-sync python scripts/compile_lang.py | |
| uv run --no-sync python scripts/dump_crowdin_progress.py | |
| uv run --no-sync python db_update.py | |
| version=$(uv run --no-sync python scripts/dump_version.py) | |
| echo "PYFA_VERSION=$version" >> "$GITHUB_ENV" | |
| - name: Build app | |
| run: | | |
| uv run --no-sync python -m PyInstaller -y --clean dist_assets/mac/pyfa.spec | |
| built=$(lipo -archs dist/pyfa.app/Contents/MacOS/pyfa) | |
| if [ "$built" != "${{ matrix.arch }}" ]; then | |
| echo "::error::expected a ${{ matrix.arch }} build, got: $built" | |
| exit 1 | |
| fi | |
| - name: Check the oldest macOS the app runs on | |
| # the bundled binaries needing the newest macOS decide it for the whole app | |
| run: | | |
| find dist/pyfa.app -type f \( -name '*.dylib' -o -name '*.so' -o -perm -u+x \) -print0 | | |
| while IFS= read -r -d '' file; do | |
| minos=$(otool -l "$file" 2>/dev/null | awk ' | |
| /LC_BUILD_VERSION/ { build = 1 } | |
| build && $1 == "minos" { print $2; exit } | |
| /LC_VERSION_MIN_MACOSX/ { legacy = 1 } | |
| legacy && $1 == "version" { print $2; exit }') | |
| if [ -n "$minos" ]; then echo "$minos ${file#dist/}"; fi | |
| done | sort -t. -k1,1n -k2,2n -k3,3n > minos.txt | |
| newest=$(tail -n 1 minos.txt | cut -d' ' -f1) | |
| echo "Binaries per minimum macOS version:" | |
| cut -d' ' -f1 minos.txt | uniq -c | |
| echo "The app needs macOS $newest or newer, because of:" | |
| awk -v version="$newest" '$1 == version' minos.txt | head -n 15 | |
| too_new=$(awk -v needed="$newest" -v target="$MACOSX_DEPLOYMENT_TARGET" 'BEGIN { | |
| split(needed, n, "."); split(target, t, ".") | |
| for (i = 1; i <= 3; i++) { | |
| if (n[i] + 0 > t[i] + 0) { print "yes"; exit } | |
| if (n[i] + 0 < t[i] + 0) { exit } | |
| } | |
| }') | |
| if [ -n "$too_new" ]; then | |
| echo "::error::the app needs macOS $newest, but has to run on macOS $MACOSX_DEPLOYMENT_TARGET (binaries listed above)" | |
| exit 1 | |
| fi | |
| - name: Package app | |
| run: (cd dist && zip -yr "pyfa-$PYFA_VERSION-mac-${{ matrix.arch }}.zip" pyfa.app) | |
| - uses: actions/upload-artifact@v7 | |
| with: | |
| name: pyfa-mac-${{ matrix.arch }} | |
| path: dist/pyfa-${{ env.PYFA_VERSION }}-mac-${{ matrix.arch }}.zip | |
| retention-days: 90 | |
| if-no-files-found: error | |
| release: | |
| name: Draft release | |
| if: startsWith(github.ref, 'refs/tags/') | |
| needs: [linux, windows, macos] | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: write | |
| steps: | |
| - uses: actions/download-artifact@v8 | |
| with: | |
| path: dist | |
| merge-multiple: true | |
| - name: Create the draft release | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| TAG: ${{ github.ref_name }} | |
| run: | | |
| ls -l dist | |
| if draft=$(gh release view "$TAG" --repo "$GITHUB_REPOSITORY" --json isDraft --jq .isDraft 2>/dev/null); then | |
| # a published release is never touched; a draft (e.g. from a re-run) gets its files replaced | |
| if [ "$draft" != "true" ]; then | |
| echo "::error::release $TAG is already published, not changing it" | |
| exit 1 | |
| fi | |
| gh release upload "$TAG" dist/* --repo "$GITHUB_REPOSITORY" --clobber | |
| else | |
| gh release create "$TAG" dist/* --repo "$GITHUB_REPOSITORY" --verify-tag --draft \ | |
| --title "pyfa $TAG" --notes "Release description" | |
| fi |