Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ jobs:
- name: Run legacy integration tests
run: python integration_tests.py

- name: Validate Linux shell scripts
if: runner.os == 'Linux'
run: |
sh -n setup.sh
sh -n run-unityscraper.sh
sh -n build_linux.sh
sh -n packaging/linux/install.sh
sh -n packaging/linux/uninstall.sh

windows-build:
name: Windows executable
runs-on: windows-latest
Expand Down Expand Up @@ -80,3 +89,50 @@ jobs:
dist/UnityScraper.exe
dist/UnityScraper.exe.sha256
if-no-files-found: error

linux-build:
name: Linux executable
runs-on: ubuntu-22.04
needs: test

steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip

- name: Install desktop build dependencies
run: |
sudo apt-get update
sudo apt-get install -y appstream desktop-file-utils python3-tk xvfb
python -m pip install -r requirements.txt pyinstaller

- name: Validate desktop metadata
run: |
sed -e 's|@EXEC@|/usr/bin/unityscraper|g' \
-e 's|@ICON@|io.github.trapemall.UnityScraper|g' \
packaging/linux/io.github.trapemall.UnityScraper.desktop \
> /tmp/io.github.trapemall.UnityScraper.desktop
desktop-file-validate /tmp/io.github.trapemall.UnityScraper.desktop
appstreamcli validate --no-net packaging/linux/io.github.trapemall.UnityScraper.metainfo.xml

- name: Build Linux bundle
run: ./build_linux.sh

- name: Smoke test graphical executable
run: |
set +e
xvfb-run -a timeout 8s dist/UnityScraper
status=$?
set -e
test "$status" -eq 124

- uses: actions/upload-artifact@v4
with:
name: UnityScraper-Linux-x86_64
path: |
dist/UnityScraper-Linux-x86_64.tar.gz
dist/UnityScraper-Linux-x86_64.tar.gz.sha256
if-no-files-found: error
114 changes: 91 additions & 23 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ permissions:
contents: write

jobs:
release:
runs-on: windows-latest
validate:
runs-on: ubuntu-22.04

steps:
- uses: actions/checkout@v4
Expand All @@ -20,43 +20,111 @@ jobs:
python-version: "3.12"
cache: pip

- name: Install build dependencies
run: python -m pip install -r requirements.txt pyinstaller
- name: Install dependencies
run: python -m pip install -r requirements.txt -r requirements-dev.txt

- name: Test
shell: pwsh
- name: Validate release
run: |
python scripts/check_version.py --tag "${{ github.ref_name }}"
python -m ruff check .
python tests.py
python integration_tests.py

windows:
runs-on: windows-latest
needs: validate

steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip

- name: Install build dependencies
run: python -m pip install -r requirements.txt pyinstaller

- name: Build executable
run: python -m PyInstaller --clean --noconfirm UnityScraper.spec

- name: Package release
- name: Package Windows release
shell: pwsh
run: |
Copy-Item README.md, CHANGELOG.md, LICENSE dist\
Compress-Archive `
-Path dist\UnityScraper.exe, dist\README.md, dist\CHANGELOG.md, dist\LICENSE `
-DestinationPath UnityScraper-Windows-x64.zip
New-Item -ItemType Directory -Path package | Out-Null
Copy-Item dist\UnityScraper.exe, README.md, CHANGELOG.md, LICENSE package\
Compress-Archive -Path package\* -DestinationPath UnityScraper-Windows-x64.zip
$hash = (Get-FileHash UnityScraper-Windows-x64.zip -Algorithm SHA256).Hash.ToLower()
"$hash *UnityScraper-Windows-x64.zip" | Set-Content UnityScraper-Windows-x64.zip.sha256

- uses: actions/upload-artifact@v4
with:
name: release-windows
path: |
UnityScraper-Windows-x64.zip
UnityScraper-Windows-x64.zip.sha256

linux:
runs-on: ubuntu-22.04
needs: validate

steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip

- name: Install desktop build dependencies
run: |
sudo apt-get update
sudo apt-get install -y appstream desktop-file-utils python3-tk
python -m pip install -r requirements.txt pyinstaller

- name: Validate desktop metadata
run: |
sed -e 's|@EXEC@|/usr/bin/unityscraper|g' \
-e 's|@ICON@|io.github.trapemall.UnityScraper|g' \
packaging/linux/io.github.trapemall.UnityScraper.desktop \
> /tmp/io.github.trapemall.UnityScraper.desktop
desktop-file-validate /tmp/io.github.trapemall.UnityScraper.desktop
appstreamcli validate --no-net packaging/linux/io.github.trapemall.UnityScraper.metainfo.xml

- name: Build Linux release
run: ./build_linux.sh

- uses: actions/upload-artifact@v4
with:
name: release-linux
path: |
dist/UnityScraper-Linux-x86_64.tar.gz
dist/UnityScraper-Linux-x86_64.tar.gz.sha256

publish:
runs-on: ubuntu-latest
needs: [windows, linux]

steps:
- uses: actions/download-artifact@v4
with:
pattern: release-*
path: release
merge-multiple: true

- name: Publish GitHub release
shell: pwsh
env:
GH_TOKEN: ${{ github.token }}
run: |
$arguments = @(
"release", "create", "${{ github.ref_name }}",
"UnityScraper-Windows-x64.zip",
"UnityScraper-Windows-x64.zip.sha256",
"--title", "UnityScraper ${{ github.ref_name }}",
"--generate-notes",
"--verify-tag"
args=(
release create "${{ github.ref_name }}"
release/*
--repo "${{ github.repository }}"
--title "UnityScraper ${{ github.ref_name }}"
--generate-notes
--verify-tag
)
if ("${{ github.ref_name }}" -match "-") {
$arguments += "--prerelease"
}
& gh @arguments
if [[ "${{ github.ref_name }}" == *-* ]]; then
args+=(--prerelease)
fi
gh "${args[@]}"
12 changes: 8 additions & 4 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ Normal Windows data:
Portable mode uses `UnityScraperData` beside the application when a
`portable.mode` marker is present.

Linux follows the XDG Base Directory specification and separates data,
configuration, cache, and logs under `XDG_DATA_HOME`, `XDG_CONFIG_HOME`,
`XDG_CACHE_HOME`, and `XDG_STATE_HOME`.

Bundled read-only assets are resolved through `app_paths.resource_path`, which
works in source and PyInstaller one-file builds.

Expand All @@ -127,7 +131,7 @@ See [SECURITY.md](SECURITY.md) for reporting and operational guidance.

## Packaging

`UnityScraper.spec` is the canonical PyInstaller definition. Assets and modules
loaded indirectly by the GUI are listed explicitly. GitHub Actions validates a
Windows one-file build on pull requests and publishes ZIP/checksum artifacts for
version tags.
`UnityScraper.spec` is the canonical cross-platform PyInstaller definition.
Assets and modules loaded indirectly by the GUI are listed explicitly. GitHub
Actions validates Windows and Linux one-file builds on pull requests. Version
tags publish a Windows ZIP and Linux tarball with separate SHA-256 files.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,23 @@ Notable changes to UnityScraper are documented here. The project follows

### Added

- Native Linux desktop support with XDG data, configuration, cache, and state
directories.
- Linux x86_64 release bundle with user-level installation, application-menu
integration, AppStream metadata, and safe uninstallation.
- Linux source setup, launcher, packaging script, platform tests, and dedicated
support documentation.
- Parallel Windows and Linux CI artifacts and tag-driven release publishing.
- Authenticated remote REST API mode and validated configuration updates.
- Cross-platform CI with Windows executable smoke builds.
- Tagged-release packaging with SHA-256 checksums.
- Contributor, security, community, and architecture documentation.

### Changed

- PyInstaller configuration and desktop entry point now support Windows and
Linux from the same source tree.
- Knowledge source snapshots use the platform cache directory.
- Repository-generated executables are published through releases and CI
artifacts instead of being committed to source control.
- Source checkouts use normal application storage unless the user creates a
Expand Down
16 changes: 16 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,25 @@ python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt -r requirements-dev.txt
```

Linux:

```bash
python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt -r requirements-dev.txt
```

Run the desktop application:

```powershell
.\.venv\Scripts\python.exe desktop_app.py
```

On Linux:

```bash
.venv/bin/python desktop_app.py
```

Run validation:

```powershell
Expand All @@ -34,6 +47,9 @@ Run validation:
.\.venv\Scripts\python.exe tests.py
```

Replace `.\.venv\Scripts\python.exe` with `.venv/bin/python` on Linux. Validate
changed shell scripts with `sh -n`.

## Pull Requests

- Branch from the current `main`.
Expand Down
8 changes: 8 additions & 0 deletions DOCS_INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
- [Advanced Features](ADVANCED_FEATURES.md) - rate limits, resume, diagnostics,
portable mode, API, and conversion
- [REST API](API.md) - authentication, endpoints, configuration, and safety
- [Linux Support](LINUX.md) - installation, XDG storage, desktop integration,
uninstallation, and troubleshooting
- [Project Status](PROJECT_STATUS.md) - completed work, boundaries, and roadmap
- [Changelog](CHANGELOG.md) - release history

Expand All @@ -36,3 +38,9 @@ Windows packaging:
```powershell
powershell -ExecutionPolicy Bypass -File .\build_windows.ps1
```

Linux packaging:

```bash
./build_linux.sh
```
Loading
Loading