Skip to content

Fix Qt6 source filename casing #120

Fix Qt6 source filename casing

Fix Qt6 source filename casing #120

Workflow file for this run

name: Build PySide6 Windows Release
on:
push:
branches:
- main
- master
- QT6
- qt6
tags:
- "v*"
pull_request:
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
PYTHON_VERSION: "3.11"
PYTHONUTF8: "1"
PYTHONUNBUFFERED: "1"
PYTHONDONTWRITEBYTECODE: "1"
PIP_DISABLE_PIP_VERSION_CHECK: "1"
QT_QPA_PLATFORM: "offscreen"
jobs:
build-windows:
name: Build and verify Windows x64 package
runs-on: windows-latest
timeout-minutes: 60
outputs:
build_name: ${{ steps.package.outputs.build_name }}
zip_name: ${{ steps.package.outputs.zip_name }}
artifact_name: ${{ steps.package.outputs.artifact_name }}
steps:
- name: Checkout source
uses: actions/checkout@v7
with:
ref: ${{ github.ref }}
fetch-depth: 0
persist-credentials: false
- name: Show selected ref and checked-out revision
shell: pwsh
run: |
Write-Host "event_name = ${{ github.event_name }}"
Write-Host "github.ref = ${{ github.ref }}"
Write-Host "github.ref_name = ${{ github.ref_name }}"
Write-Host "github.sha = ${{ github.sha }}"
Write-Host "workspace = $env:GITHUB_WORKSPACE"
git rev-parse --show-toplevel
git rev-parse HEAD
git branch --show-current
git status --short
Write-Host "Tracked root files:"
git ls-files | Sort-Object
- name: Validate exact repository paths
shell: pwsh
run: |
$requiredFiles = @(
"nfo_editor.py",
"nfo_editor_ui.py",
"nfo_editor_events.py",
"nfo_utils.py",
"cg_crop.py",
"cg_dedupe.py",
"cg_photo_wall.py",
"cg_rename.py",
"nfo_editor.spec",
"requirements.txt",
"requirements-build.txt",
"scripts/check_source_layout.py",
"scripts/qt_source_smoke.py",
"scripts/build_windows.ps1",
"scripts/check_windows_artifact.ps1"
)
$trackedFiles = @(git ls-files | ForEach-Object { $_.Replace("\", "/") })
$wrongCaseOrMissing = @(
$requiredFiles | Where-Object { -not ($trackedFiles -ccontains $_) }
)
if ($wrongCaseOrMissing.Count -gt 0) {
Write-Host "Tracked files with similar spelling:"
foreach ($expected in $wrongCaseOrMissing) {
$leaf = Split-Path -Leaf $expected
$trackedFiles |
Where-Object { (Split-Path -Leaf $_) -ieq $leaf } |
ForEach-Object { Write-Host " actual: $_" }
}
Write-Error (
"Required files are missing or use incorrect filename casing:`n - " +
($wrongCaseOrMissing -join "`n - ")
)
throw "Run scripts/fix_source_filename_case.ps1, commit, and push."
}
$rootNames = @(Get-ChildItem -Force | ForEach-Object { $_.Name })
if (-not ($rootNames -ccontains "img")) {
$actualImg = $rootNames | Where-Object { $_ -ieq "img" }
Write-Error "Expected directory exactly 'img'; actual match: $actualImg"
throw "Directory filename casing is incorrect."
}
Write-Host "All required paths and filename casing are correct."
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: ${{ env.PYTHON_VERSION }}
architecture: x64
cache: pip
cache-dependency-path: |
requirements.txt
requirements-build.txt
- name: Run repository layout validator
shell: pwsh
run: |
python scripts/check_source_layout.py
- name: Install runtime and build dependencies
shell: pwsh
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install -r requirements-build.txt
python -m pip check
python -c "import PySide6, qfluentwidgets, PyInstaller; print('PySide6:', PySide6.__version__); print('PyInstaller:', PyInstaller.__version__)"
- name: Reject legacy Qt bindings
shell: pwsh
run: |
@'
import importlib.util
import sys
forbidden = ("PyQt5", "PyQt6", "PySide2")
found = [name for name in forbidden if importlib.util.find_spec(name) is not None]
if found:
raise SystemExit(f"Legacy/foreign Qt bindings installed: {', '.join(found)}")
print("Only the PySide6 Qt binding is installed.")
'@ | python -
- name: Compile and run unit tests
shell: pwsh
run: |
python -m compileall -q .
python -m unittest discover -s tests -q
$lintFiles = @(
"nfo_editor.py",
"nfo_editor_ui.py",
"nfo_editor_events.py",
"nfo_utils.py",
"cg_crop.py",
"cg_dedupe.py",
"cg_photo_wall.py",
"cg_rename.py"
)
$lintFiles += Get-ChildItem tests -Filter "*.py" -File | ForEach-Object { $_.FullName }
$lintFiles += Get-ChildItem scripts -Filter "*.py" -File | ForEach-Object { $_.FullName }
python -m pyflakes @lintFiles
- name: Run source Qt startup smoke test
shell: pwsh
run: |
python scripts/qt_source_smoke.py
- name: Resolve package name
id: package
shell: pwsh
run: |
$shortSha = "${{ github.sha }}".Substring(0, 7)
if ("${{ github.ref_type }}" -eq "tag") {
$buildName = "${{ github.ref_name }}"
}
else {
$buildName = "dev-${{ github.run_number }}-$shortSha"
}
$zipName = "NFOTools-$buildName-windows-x64.zip"
$artifactName = "NFOTools-$buildName-windows-x64"
"BUILD_NAME=$buildName" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
"ZIP_NAME=$zipName" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
"build_name=$buildName" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
"zip_name=$zipName" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
"artifact_name=$artifactName" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
- name: Build PySide6 applications
shell: pwsh
run: |
./scripts/build_windows.ps1 -OutputRoot "dist/NFOTools"
- name: Check build contents and launch executables
shell: pwsh
run: |
./scripts/check_windows_artifact.ps1 -Root "dist/NFOTools" -RunSmokeTests
- name: Create release archive and checksum
shell: pwsh
run: |
if (Test-Path $env:ZIP_NAME) {
Remove-Item $env:ZIP_NAME -Force
}
Compress-Archive -Path "dist/NFOTools/*" -DestinationPath $env:ZIP_NAME -CompressionLevel Optimal
$hash = (Get-FileHash -Algorithm SHA256 $env:ZIP_NAME).Hash.ToLowerInvariant()
"$hash $env:ZIP_NAME" | Set-Content -Path "$env:ZIP_NAME.sha256" -Encoding ascii
if ((Get-Item $env:ZIP_NAME).Length -lt 1MB) {
throw "Release archive is unexpectedly small."
}
Write-Host "Archive: $env:ZIP_NAME"
Write-Host "SHA-256: $hash"
- name: Upload verified artifact
uses: actions/upload-artifact@v7
with:
name: ${{ steps.package.outputs.artifact_name }}
path: |
${{ steps.package.outputs.zip_name }}
${{ steps.package.outputs.zip_name }}.sha256
if-no-files-found: error
retention-days: 14
compression-level: 0
release:
name: Publish tagged release
if: github.event_name == 'push' && github.ref_type == 'tag'
needs: build-windows
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download verified build artifact
uses: actions/download-artifact@v8
with:
name: ${{ needs.build-windows.outputs.artifact_name }}
path: release
digest-mismatch: error
- name: Publish or update GitHub Release
shell: bash
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
TAG_NAME: ${{ github.ref_name }}
ZIP_NAME: ${{ needs.build-windows.outputs.zip_name }}
run: |
set -euo pipefail
cd release
test -s "$ZIP_NAME"
test -s "$ZIP_NAME.sha256"
sha256sum --check "$ZIP_NAME.sha256"
if gh release view "$TAG_NAME" >/dev/null 2>&1; then
gh release upload "$TAG_NAME" "$ZIP_NAME" "$ZIP_NAME.sha256" --clobber
else
gh release create "$TAG_NAME" "$ZIP_NAME" "$ZIP_NAME.sha256" \
--verify-tag \
--generate-notes \
--title "NFOTools $TAG_NAME"
fi