mirror of
https://github.com/TagStudioDev/TagStudio.git
synced 2026-07-08 15:14:40 +02:00
feat(ci)!: rework workflows and build processes
All Python setups route through one local action, and checks are much more conditional. There is more to be done, but this is a significant improvement in processing time and redundancy. As well, nightly builds are made (though not made as GitHub releases.. yet).
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
# SPDX-FileCopyrightText: (c) TagStudio Contributors
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
name: Setup Python
|
||||
description: Combination of Python setup actions
|
||||
|
||||
inputs:
|
||||
skip-setup:
|
||||
default: 'false'
|
||||
description: Whether to skip setup actions and only execute installs
|
||||
groups:
|
||||
description: Newline-separated list of dependency groups to install
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Setup Python install
|
||||
if: inputs.skip-setup != 'true'
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.12'
|
||||
|
||||
- name: Setup uv install
|
||||
if: inputs.skip-setup != 'true'
|
||||
uses: astral-sh/setup-uv@v8.2.0
|
||||
|
||||
- name: Run pip install (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
env:
|
||||
INPUT_GROUPS: ${{ inputs.groups }}
|
||||
UV_PYTHON_DOWNLOADS: never
|
||||
UV_SYSTEM_PYTHON: '1'
|
||||
shell: pwsh
|
||||
run: |
|
||||
if (![string]::IsNullOrEmpty(${env:INPUT_GROUPS})) {
|
||||
$groupArgs = -split ${env:INPUT_GROUPS} -replace '^', '--group='
|
||||
}
|
||||
|
||||
uv pip install . ${groupArgs}
|
||||
|
||||
- name: Run pip install (non-Windows)
|
||||
if: runner.os != 'Windows'
|
||||
env:
|
||||
INPUT_GROUPS: ${{ inputs.groups }}
|
||||
UV_PYTHON_DOWNLOADS: never
|
||||
UV_SYSTEM_PYTHON: '1'
|
||||
shell: bash
|
||||
run: |
|
||||
extra_args=()
|
||||
|
||||
if [ -n "${INPUT_GROUPS}" ]; then
|
||||
while IFS= read -r group; do
|
||||
if [ -n "${group}" ]; then
|
||||
extra_args+=("--group=${group}")
|
||||
fi
|
||||
done <<<"${INPUT_GROUPS}"
|
||||
fi
|
||||
|
||||
uv pip install . "${extra_args[@]}"
|
||||
@@ -0,0 +1,203 @@
|
||||
# SPDX-FileCopyrightText: (c) TagStudio Contributors
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
# TODO: This will be invoked by a 'Release' workflow in the future.
|
||||
---
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*
|
||||
schedule:
|
||||
# From: https://docs.github.com/en/actions/reference/workflows-and-actions/events-that-trigger-workflows#schedule
|
||||
# To decrease the chance of delay, schedule your workflow to run at a different time of the hour.
|
||||
- cron: 42 3 * * *
|
||||
timezone: America/Los_Angeles
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: sh
|
||||
|
||||
jobs:
|
||||
meta:
|
||||
name: Metadata
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
type: ${{ steps.meta.outputs.type }}
|
||||
version: ${{ steps.meta.outputs.version }}
|
||||
steps:
|
||||
- name: Set metadata
|
||||
id: meta
|
||||
run: |
|
||||
type=Nightly
|
||||
if [ "${GITHUB_REF_TYPE}" = tag ]; then
|
||||
case ${GITHUB_REF_NAME} in
|
||||
v*)
|
||||
type=Release
|
||||
case ${GITHUB_REF_NAME} in
|
||||
*-pr*) type=Pre-${type} ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
if [ ${type} = Nightly ]; then
|
||||
version=dev+$(date --iso-8601 | tr -d -)
|
||||
else
|
||||
version=${GITHUB_REF_NAME}
|
||||
fi
|
||||
|
||||
cat <<EOF >>"${GITHUB_OUTPUT}"
|
||||
type=${type}
|
||||
version=${version}
|
||||
EOF
|
||||
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: ${{ needs.meta.outputs.type != 'Nightly' }}
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-22.04
|
||||
os-label: Linux x86
|
||||
|
||||
- os: macos-15-intel
|
||||
os-label: macOS x86
|
||||
|
||||
- os: macos-15
|
||||
os-label: macOS ARM
|
||||
|
||||
- os: windows-2022
|
||||
os-label: Windows x86
|
||||
|
||||
name: Build${{ needs.meta.outputs.type && format(' {0}', needs.meta.outputs.type) }}${{ matrix.os-label && format(' ({0})', matrix.os-label) }}
|
||||
needs: meta
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
BUILD_PREFIX: tagstudio_${{ needs.meta.outputs.version }}
|
||||
steps:
|
||||
- name: Prepare build (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
$dir = "${env:RUNNER_TEMP}/upload"
|
||||
New-Item -Path ${dir} -ItemType Directory -Force
|
||||
|
||||
$os = ${env:RUNNER_OS}.ToLower()
|
||||
$arch = uname -m
|
||||
|
||||
$commonPath = "${dir}/${env:BUILD_PREFIX}_${os}_${arch}"
|
||||
Add-Content -Path ${env:GITHUB_ENV} -Value @"
|
||||
BUILD_ARTIFACT_DEFAULT=${commonPath}.zip
|
||||
BUILD_ARTIFACT_PORTABLE=${commonPath}_portable.zip
|
||||
"@ -Encoding utf8
|
||||
|
||||
- name: Prepare build (non-Windows)
|
||||
if: runner.os != 'Windows'
|
||||
run: |
|
||||
dir=${RUNNER_TEMP}/upload
|
||||
mkdir -p "${dir}"
|
||||
os=$(
|
||||
tr '[:upper:]' '[:lower:]' <<EOF
|
||||
${RUNNER_OS}
|
||||
EOF
|
||||
)
|
||||
arch=$(uname -m)
|
||||
|
||||
common_path=${dir}/${BUILD_PREFIX}_${os}_${arch}
|
||||
artifact_default=${common_path}.tar.gz
|
||||
if [ "${RUNNER_OS}" = macOS ]; then
|
||||
artifact_portable=
|
||||
else
|
||||
artifact_portable=${common_path}_portable.tar.gz
|
||||
fi
|
||||
cat <<EOF >>"${GITHUB_ENV}"
|
||||
BUILD_ARTIFACT_DEFAULT=${artifact_default}
|
||||
${artifact_portable:+BUILD_ARTIFACT_PORTABLE=${artifact_portable}}
|
||||
EOF
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Setup Python
|
||||
uses: ./.github/actions/setup-python
|
||||
with:
|
||||
groups: build
|
||||
|
||||
- parallel:
|
||||
- name: Run PyInstaller (Linux)
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
pyinstaller --distpath dist/default --workpath build/default scripts/tagstudio.spec
|
||||
tar czf "${BUILD_ARTIFACT_DEFAULT}" -C dist/default/tagstudio .
|
||||
|
||||
- name: Run PyInstaller (Linux portable)
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
pyinstaller --distpath dist/portable --workpath build/portable scripts/tagstudio.spec -- --portable
|
||||
tar czf "${BUILD_ARTIFACT_PORTABLE}" -C dist/portable tagstudio
|
||||
|
||||
- name: Run PyInstaller (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: |
|
||||
scripts/tagstudio.spec
|
||||
tar czf "${BUILD_ARTIFACT_DEFAULT}" -C dist TagStudio.app
|
||||
|
||||
- name: Run PyInstaller (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
PyInstaller --distpath dist/default --workpath build/default scripts/tagstudio.spec
|
||||
Compress-Archive -Path dist/default/TagStudio -DestinationPath ${env:BUILD_ARTIFACT_DEFAULT}
|
||||
|
||||
- name: Run PyInstaller (Windows portable)
|
||||
if: runner.os == 'Windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
PyInstaller --distpath dist/portable --workpath build/portable scripts/tagstudio.spec -- --portable
|
||||
Compress-Archive -Path dist/portable/TagStudio.exe -DestinationPath ${env:BUILD_ARTIFACT_PORTABLE}
|
||||
|
||||
- parallel:
|
||||
- name: Upload build artifact
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
path: ${{ env.BUILD_ARTIFACT_DEFAULT }}
|
||||
if-no-files-found: error
|
||||
# Short retention for 'Pre-Release' and 'Release' because they get uploaded to a GitHub release.
|
||||
retention-days: &upload-artifact-retention-days ${{ case(needs.meta.outputs.type == 'Nightly', '7', '1') }}
|
||||
archive: false
|
||||
|
||||
- name: Upload build artifact (portable)
|
||||
if: env.BUILD_ARTIFACT_PORTABLE != ''
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
path: ${{ env.BUILD_ARTIFACT_PORTABLE }}
|
||||
if-no-files-found: error
|
||||
retention-days: *upload-artifact-retention-days
|
||||
archive: false
|
||||
|
||||
upload:
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
name: Upload Builds to Release
|
||||
needs: [meta, build]
|
||||
if: needs.meta.outputs.type != 'Nightly'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Download build artifacts
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: ${{ runner.temp }}/download
|
||||
merge-multiple: 'true'
|
||||
skip-decompress: 'true'
|
||||
|
||||
- name: Upload build artifacts to release
|
||||
uses: softprops/action-gh-release@v3
|
||||
with:
|
||||
files: ${{ runner.temp }}/download/*
|
||||
@@ -0,0 +1,57 @@
|
||||
# SPDX-FileCopyrightText: (c) TagStudio Contributors
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
# TODO: In the future, docs will be built (but not published) for PRs.
|
||||
---
|
||||
name: Build Docs
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- .github/actions/setup-python/action.yml
|
||||
- .github/workflows/build_docs.yml
|
||||
- docs/**
|
||||
- CHANGELOG.md
|
||||
- mkdocs.yml
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: sh
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}
|
||||
cancel-in-progress: true
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
name: Publish Docs
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Setup Python
|
||||
uses: ./.github/actions/setup-python
|
||||
with:
|
||||
groups: docs
|
||||
|
||||
- name: Use cache
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
key: mkdocs-material-${{ github.run_id }}
|
||||
path: .cache
|
||||
restore-keys: |
|
||||
mkdocs-material-
|
||||
- name: Run mkdocs
|
||||
env:
|
||||
DISABLE_MKDOCS_2_WARNING: 'true'
|
||||
run: mkdocs gh-deploy --force
|
||||
@@ -0,0 +1,171 @@
|
||||
# SPDX-FileCopyrightText: (c) TagStudio Contributors
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
name: Checks (Python)
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths: &on_paths
|
||||
- .github/actions/setup-python/action.yml
|
||||
- .github/workflows/checks_python.yml
|
||||
- .editorconfig
|
||||
- pyproject.toml
|
||||
- pyrightconfig.json
|
||||
- pytest.ini
|
||||
- uv.lock
|
||||
- '**.py'
|
||||
push:
|
||||
paths: *on_paths
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: sh
|
||||
|
||||
jobs:
|
||||
run-conditions:
|
||||
name: Run Conditions
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
pyright: ${{ steps.run-conditions.outputs.pyright }}
|
||||
pytest: ${{ steps.run-conditions.outputs.pytest }}
|
||||
ruff: ${{ steps.run-conditions.outputs.ruff }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Check changed files
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v47.0.6
|
||||
with:
|
||||
files_yaml: |
|
||||
generic:
|
||||
- .github/workflows/checks_python.yml
|
||||
- pyproject.toml
|
||||
- uv.lock
|
||||
- '**.py'
|
||||
pyright:
|
||||
- .github/actions/setup-python/action.yml
|
||||
- pyrightconfig.json
|
||||
pytest:
|
||||
- .github/actions/setup-python/action.yml
|
||||
- pytest.ini
|
||||
ruff:
|
||||
- .editorconfig
|
||||
|
||||
- name: Set run conditions
|
||||
id: run-conditions
|
||||
run: |
|
||||
cat <<EOF >>"${GITHUB_OUTPUT}"
|
||||
pyright=${{ steps.changed-files.outputs.generic_any_changed || steps.changed-files.outputs.pyright_any_changed }}
|
||||
pytest=${{ steps.changed-files.outputs.generic_any_changed || steps.changed-files.outputs.pytest_any_changed }}
|
||||
ruff=${{ steps.changed-files.outputs.generic_any_changed || steps.changed-files.outputs.ruff_any_changed }}
|
||||
EOF
|
||||
|
||||
check-pyright:
|
||||
name: Pyright
|
||||
needs: run-conditions
|
||||
if: needs.run-conditions.outputs.pyright == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- &checkout
|
||||
name: Checkout repository
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Setup Python
|
||||
uses: ./.github/actions/setup-python
|
||||
with:
|
||||
groups: |
|
||||
pyright
|
||||
pytest
|
||||
|
||||
- name: Execute Pyright
|
||||
run: pyright
|
||||
|
||||
check-pytest:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- os: ubuntu-22.04
|
||||
os-label: Linux
|
||||
|
||||
- os: macos-latest
|
||||
os-label: macOS
|
||||
|
||||
- os: windows-2022
|
||||
os-label: Windows
|
||||
|
||||
name: pytest${{ matrix.os-label && format(' ({0})', matrix.os-label) }}
|
||||
needs: run-conditions
|
||||
if: needs.run-conditions.outputs.pytest == 'true'
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- *checkout
|
||||
|
||||
- name: Setup Python
|
||||
uses: ./.github/actions/setup-python
|
||||
with:
|
||||
groups: pytest
|
||||
|
||||
- name: Install system dependencies (Linux)
|
||||
if: runner.os == 'Linux'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
libegl1 \
|
||||
libgl1 \
|
||||
libopengl0 \
|
||||
libpulse0 \
|
||||
libxcb-cursor0 \
|
||||
libxcb-icccm4 \
|
||||
libxcb-image0 \
|
||||
libxcb-keysyms1 \
|
||||
libxcb-randr0 \
|
||||
libxcb-render-util0 \
|
||||
libxcb-xinerama0 \
|
||||
libxkbcommon-x11-0 \
|
||||
libyaml-dev \
|
||||
ripgrep \
|
||||
x11-utils
|
||||
|
||||
- name: Install system dependencies (macOS)
|
||||
if: runner.os == 'macOS'
|
||||
run: brew install ripgrep
|
||||
|
||||
- name: Install system dependencies (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
shell: pwsh
|
||||
run: choco install ripgrep
|
||||
|
||||
- name: Execute pytest (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
shell: pwsh
|
||||
run: pytest
|
||||
|
||||
- name: Execute pytest (non-Windows)
|
||||
if: runner.os != 'Windows'
|
||||
run: pytest
|
||||
|
||||
check-ruff:
|
||||
name: Ruff
|
||||
needs: run-conditions
|
||||
if: needs.run-conditions.outputs.ruff == 'true'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- *checkout
|
||||
|
||||
- parallel:
|
||||
- name: Run Ruff linter
|
||||
uses: astral-sh/ruff-action@v4.0.0
|
||||
|
||||
- name: Run Ruff formatter
|
||||
uses: astral-sh/ruff-action@v4.0.0
|
||||
with:
|
||||
args: format --check
|
||||
@@ -1,51 +0,0 @@
|
||||
# SPDX-FileCopyrightText: (c) TagStudio Contributors
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
---
|
||||
name: Publish Docs
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- .github/workflows/publish_docs.yaml
|
||||
- docs/**
|
||||
- mkdocs.yml
|
||||
- CHANGELOG.md
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
concurrency:
|
||||
group: publish-docs
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.12"
|
||||
cache: pip
|
||||
|
||||
- name: Install Python dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade uv
|
||||
uv pip install --system . --group mkdocs
|
||||
|
||||
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
|
||||
|
||||
- uses: actions/cache@v4
|
||||
with:
|
||||
key: mkdocs-material-${{ env.cache_id }}
|
||||
path: .cache
|
||||
restore-keys: |
|
||||
mkdocs-material-
|
||||
|
||||
- name: Execute mkdocs
|
||||
run: mkdocs gh-deploy --force
|
||||
@@ -1,31 +0,0 @@
|
||||
# SPDX-FileCopyrightText: (c) TagStudio Contributors
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
---
|
||||
name: Pyright
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
pyright:
|
||||
name: Run Pyright
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.12"
|
||||
cache: pip
|
||||
|
||||
- name: Install Python dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade uv
|
||||
uv pip install --system . --group pyright --group pytest
|
||||
|
||||
- name: Execute Pyright
|
||||
uses: jordemort/action-pyright@v1
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
reporter: ${{ github.event_name == 'pull_request' && 'github-pr-review' || 'github-check' }}
|
||||
@@ -1,70 +0,0 @@
|
||||
# SPDX-FileCopyrightText: (c) TagStudio Contributors
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
---
|
||||
name: pytest
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
pytest-linux:
|
||||
name: Run pytest (Linux)
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
- &checkout
|
||||
name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- &setup-python
|
||||
name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.12"
|
||||
cache: pip
|
||||
|
||||
- &install-dependencies
|
||||
name: Install Python dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade uv
|
||||
uv pip install --system . --group pytest
|
||||
|
||||
- name: Install system dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
libegl1 \
|
||||
libgl1 \
|
||||
libopengl0 \
|
||||
libpulse0 \
|
||||
libxcb-cursor0 \
|
||||
libxcb-icccm4 \
|
||||
libxcb-image0 \
|
||||
libxcb-keysyms1 \
|
||||
libxcb-randr0 \
|
||||
libxcb-render-util0 \
|
||||
libxcb-xinerama0 \
|
||||
libxkbcommon-x11-0 \
|
||||
libyaml-dev \
|
||||
ripgrep \
|
||||
x11-utils
|
||||
|
||||
- name: Execute pytest
|
||||
run: |
|
||||
xvfb-run pytest --cov-report xml --cov=tagstudio
|
||||
|
||||
pytest-windows:
|
||||
name: Run pytest (Windows)
|
||||
runs-on: windows-2025
|
||||
|
||||
steps:
|
||||
- *checkout
|
||||
- *setup-python
|
||||
- *install-dependencies
|
||||
|
||||
- name: Install system dependencies
|
||||
run: |
|
||||
choco install ripgrep
|
||||
|
||||
- name: Execute pytest
|
||||
run: |
|
||||
pytest
|
||||
@@ -1,156 +0,0 @@
|
||||
# SPDX-FileCopyrightText: (c) TagStudio Contributors
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
---
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v[0-9]+.[0-9]+.[0-9]+*
|
||||
|
||||
jobs:
|
||||
linux:
|
||||
strategy:
|
||||
matrix:
|
||||
build-type: ["", portable]
|
||||
include:
|
||||
- build-type: ""
|
||||
build-flag: ""
|
||||
suffix: ""
|
||||
- build-type: portable
|
||||
build-flag: --portable
|
||||
suffix: _portable
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.12"
|
||||
cache: pip
|
||||
|
||||
- name: Install Python dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade uv
|
||||
uv pip install --system . --group pyinstaller
|
||||
|
||||
- name: Execute PyInstaller
|
||||
run: |
|
||||
pyinstaller tagstudio.spec -- ${{ matrix.build-flag }}
|
||||
tar czfC dist/tagstudio_linux_x86_64${{ matrix.suffix }}.tar.gz dist tagstudio
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: tagstudio_linux_x86_64${{ matrix.suffix }}
|
||||
path: dist/tagstudio_linux_x86_64${{ matrix.suffix }}.tar.gz
|
||||
|
||||
macos:
|
||||
strategy:
|
||||
matrix:
|
||||
os-version: ["14", "15"]
|
||||
include:
|
||||
- os-version: "14"
|
||||
arch: x86_64
|
||||
- os-version: "15"
|
||||
arch: aarch64
|
||||
|
||||
runs-on: macos-${{ matrix.os-version }}
|
||||
|
||||
env:
|
||||
# INFO: Even though we run on 14, target towards compatibility
|
||||
MACOSX_DEPLOYMENT_TARGET: "11.0"
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.12"
|
||||
cache: pip
|
||||
|
||||
- name: Install Python dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade uv
|
||||
uv pip install --system . --group pyinstaller
|
||||
|
||||
- name: Execute PyInstaller
|
||||
run: |
|
||||
pyinstaller tagstudio.spec
|
||||
tar czfC dist/tagstudio_macos_${{ matrix.arch }}.tar.gz dist TagStudio.app
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: tagstudio_macos_${{ matrix.arch }}
|
||||
path: dist/tagstudio_macos_${{ matrix.arch }}.tar.gz
|
||||
|
||||
windows:
|
||||
strategy:
|
||||
matrix:
|
||||
build-type: ["", portable]
|
||||
include:
|
||||
- build-type: ""
|
||||
build-flag: ""
|
||||
suffix: ""
|
||||
file-end: ""
|
||||
- build-type: portable
|
||||
build-flag: --portable
|
||||
suffix: _portable
|
||||
file-end: .exe
|
||||
|
||||
runs-on: windows-2022
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.12"
|
||||
cache: pip
|
||||
|
||||
- name: Install Python dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade uv
|
||||
uv pip install --system . --group pyinstaller
|
||||
|
||||
- name: Execute PyInstaller
|
||||
run: |
|
||||
PyInstaller tagstudio.spec -- ${{ matrix.build-flag }}
|
||||
Compress-Archive -Path dist/TagStudio${{ matrix.file-end }} -DestinationPath dist/tagstudio_windows_x86_64${{ matrix.suffix }}.zip
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: tagstudio_windows_x86_64${{ matrix.suffix }}
|
||||
path: dist/tagstudio_windows_x86_64${{ matrix.suffix }}.zip
|
||||
|
||||
publish:
|
||||
needs: [linux, macos, windows]
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Fetch artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
|
||||
- name: Publish release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: |
|
||||
tagstudio_linux_x86_64/*
|
||||
tagstudio_linux_x86_64_portable/*
|
||||
tagstudio_macos_x86_64/*
|
||||
tagstudio_macos_aarch64/*
|
||||
tagstudio_windows_x86_64/*
|
||||
tagstudio_windows_x86_64_portable/*
|
||||
@@ -1,12 +0,0 @@
|
||||
# SPDX-FileCopyrightText: 2020 Free Software Foundation Europe e.V.
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
name: REUSE compliance check
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- name: REUSE Compliance Check
|
||||
uses: fsfe/reuse-action@v6
|
||||
@@ -0,0 +1,25 @@
|
||||
# SPDX-FileCopyrightText: (c) TagStudio Contributors
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
name: REUSE Compliance Check
|
||||
|
||||
on: [pull_request, push]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: sh
|
||||
|
||||
jobs:
|
||||
check:
|
||||
name: REUSE
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v7
|
||||
|
||||
- name: Run REUSE
|
||||
uses: fsfe/reuse-action@v6
|
||||
@@ -1,33 +0,0 @@
|
||||
# SPDX-FileCopyrightText: (c) TagStudio Contributors
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
---
|
||||
name: Ruff
|
||||
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
ruff-format:
|
||||
name: Run Ruff format
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Execute Ruff format
|
||||
uses: astral-sh/ruff-action@v3
|
||||
with:
|
||||
version: 0.15.17
|
||||
args: format --check
|
||||
|
||||
ruff-check:
|
||||
name: Run Ruff check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Execute Ruff check
|
||||
uses: astral-sh/ruff-action@v3
|
||||
with:
|
||||
version: 0.15.17
|
||||
args: check
|
||||
@@ -1,7 +1,6 @@
|
||||
# SPDX-FileCopyrightText: (c) TagStudio Contributors
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
|
||||
{
|
||||
buildPythonPackage,
|
||||
cmake,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# SPDX-FileCopyrightText: (c) TagStudio Contributors
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
|
||||
{
|
||||
autoPatchelfHook,
|
||||
buildPythonPackage,
|
||||
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env perl
|
||||
# SPDX-FileCopyrightText: (c) TagStudio Contributors
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use feature 'say';
|
||||
|
||||
# From: https://regex101.com/r/vkijKf/1
|
||||
if (($ARGV[0] // <STDIN>) =~ /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/) {
|
||||
foreach my $index (0 .. $#{^CAPTURE}) {
|
||||
say ${^CAPTURE}[$index] // "";
|
||||
}
|
||||
}
|
||||
Regular → Executable
+14
-8
@@ -1,17 +1,22 @@
|
||||
#!/usr/bin/env -S python -m PyInstaller
|
||||
# vi: ft=python
|
||||
# SPDX-FileCopyrightText: (c) TagStudio Contributors
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
|
||||
import argparse
|
||||
import platform
|
||||
from argparse import ArgumentParser
|
||||
from pathlib import Path
|
||||
from tomllib import load
|
||||
|
||||
from PyInstaller.building.api import COLLECT, EXE, PYZ
|
||||
from PyInstaller.building.build_main import Analysis
|
||||
from PyInstaller.building.osx import BUNDLE
|
||||
from tomllib import load
|
||||
|
||||
parser = ArgumentParser()
|
||||
# HACK: Without this, the script will fail if empty arguments are passed.
|
||||
parser.add_argument("_", nargs="*", help=argparse.SUPPRESS)
|
||||
parser.add_argument("--portable", action="store_true")
|
||||
options = parser.parse_args()
|
||||
|
||||
@@ -20,23 +25,24 @@ with open("pyproject.toml", "rb") as file:
|
||||
|
||||
system = platform.system()
|
||||
|
||||
project_root = Path("..", "src/tagstudio")
|
||||
name = pyproject["name"] if system == "Windows" else "tagstudio"
|
||||
icon = None
|
||||
if system == "Windows":
|
||||
icon = "src/tagstudio/resources/icon.ico"
|
||||
icon = Path(project_root, "resources/icon.ico")
|
||||
elif system == "Darwin":
|
||||
icon = "src/tagstudio/resources/icon.icns"
|
||||
icon = Path(project_root, "resources/icon.icns")
|
||||
|
||||
|
||||
datafiles = [
|
||||
("src/tagstudio/qt/*.json", "tagstudio/qt"),
|
||||
("src/tagstudio/qt/*.qrc", "tagstudio/qt"),
|
||||
("src/tagstudio/resources", "tagstudio/resources"),
|
||||
(f"{project_root}/qt/*.json", "tagstudio/qt"),
|
||||
(f"{project_root}/qt/*.qrc", "tagstudio/qt"),
|
||||
(f"{project_root}/resources", "tagstudio/resources"),
|
||||
]
|
||||
|
||||
a = Analysis(
|
||||
["src/tagstudio/main.py"],
|
||||
pathex=["src"],
|
||||
[Path(project_root, "main.py")],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=datafiles,
|
||||
hiddenimports=[],
|
||||
|
||||
Reference in New Issue
Block a user