Files
Shortcut_Sync_PotPlayer/.github/workflows/build-exe.yml

195 lines
6.5 KiB
YAML

name: Build Windows EXE
on:
push:
branches: ["main"]
workflow_dispatch:
jobs:
build:
runs-on: windows
defaults:
run:
shell: powershell
env:
REPO_URL: https://git.hsdi.cc/Hsdi/Shortcut_Sync_PotPlayer.git
PYTHON_DIRNAME: python-3.9.1
SOURCE_DIRNAME: Shortcut_Sync_PotPlayer-src
OUTPUT_SUBDIR: gitea-builds\Shortcut_Sync_PotPlayer
CI_USER: ${{ secrets.CI_USER }}
CI_TOKEN: ${{ secrets.CI_TOKEN }}
steps:
- name: Checkout repository without Node
run: |
$ErrorActionPreference = "Stop"
$tempRoot = if ($env:RUNNER_TEMP) { $env:RUNNER_TEMP } else { $env:TEMP }
$sourceDir = Join-Path $tempRoot $env:SOURCE_DIRNAME
$repoUrl = $env:REPO_URL
$refName = "${{ gitea.ref_name }}"
$ref = "${{ gitea.ref }}"
if (-not $refName) {
if ($ref -match "^refs/heads/(.+)$") {
$refName = $Matches[1]
} elseif ($ref -match "^refs/tags/(.+)$") {
$refName = $Matches[1]
} else {
$refName = "main"
}
}
if (Test-Path $sourceDir) {
Remove-Item -Path $sourceDir -Recurse -Force
}
New-Item -ItemType Directory -Path $sourceDir | Out-Null
$cloneAttempts = @()
$cloneAttempts += @{
Name = "anonymous"
Args = @("clone", "--depth", "1", "--branch", $refName, $repoUrl, $sourceDir)
}
if ($env:CI_USER -and $env:CI_TOKEN) {
$basicAuth = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $env:CI_USER, $env:CI_TOKEN)))
$cloneAttempts += @{
Name = "basic-auth"
Args = @(
"-c",
"http.extraHeader=Authorization: Basic $basicAuth",
"clone",
"--depth",
"1",
"--branch",
$refName,
$repoUrl,
$sourceDir
)
}
}
$cloned = $false
foreach ($attempt in $cloneAttempts) {
Write-Host "Trying clone mode: $($attempt.Name)"
try {
& git @($attempt.Args)
if ($LASTEXITCODE -eq 0) {
$cloned = $true
break
}
} catch {
Write-Warning $_
}
if (Test-Path $sourceDir) {
Remove-Item -Path $sourceDir -Recurse -Force
}
New-Item -ItemType Directory -Path $sourceDir | Out-Null
}
if (-not $cloned) {
throw "Repository checkout failed. If this repository is private, add Actions secrets CI_USER and CI_TOKEN."
}
& git -C $sourceDir rev-parse HEAD
- name: Install Python 3.9.1 without Node
run: |
$ErrorActionPreference = "Stop"
$tempRoot = if ($env:RUNNER_TEMP) { $env:RUNNER_TEMP } else { $env:TEMP }
$pythonRoot = Join-Path $tempRoot $env:PYTHON_DIRNAME
$pythonExe = Join-Path $pythonRoot "python.exe"
$installerPath = Join-Path $tempRoot "python-3.9.1-amd64.exe"
$needsInstall = $true
if (Test-Path $pythonExe) {
$versionOutput = & $pythonExe --version 2>&1
if ($versionOutput -match "^Python 3\.9\.1$") {
$needsInstall = $false
}
}
if ($needsInstall) {
if (Test-Path $pythonRoot) {
Remove-Item -Path $pythonRoot -Recurse -Force
}
Invoke-WebRequest -Uri "https://www.python.org/ftp/python/3.9.1/python-3.9.1-amd64.exe" -OutFile $installerPath
Start-Process -FilePath $installerPath -ArgumentList @(
"/quiet",
"InstallAllUsers=0",
"PrependPath=0",
"Include_test=0",
"Include_pip=1",
"Shortcuts=0",
"AssociateFiles=0",
"CompileAll=0",
"TargetDir=$pythonRoot"
) -Wait -NoNewWindow
}
if (-not (Test-Path $pythonExe)) {
throw "Python 3.9.1 install failed: python.exe not found."
}
$versionOutput = & $pythonExe --version 2>&1
if ($versionOutput -notmatch "^Python 3\.9\.1$") {
throw "Expected Python 3.9.1, got: $versionOutput"
}
Write-Host $versionOutput
- name: Install dependencies
run: |
$ErrorActionPreference = "Stop"
$tempRoot = if ($env:RUNNER_TEMP) { $env:RUNNER_TEMP } else { $env:TEMP }
$pythonRoot = Join-Path $tempRoot $env:PYTHON_DIRNAME
$pythonExe = Join-Path $pythonRoot "python.exe"
& $pythonExe -m pip install --upgrade pip
& $pythonExe -m pip install pyinstaller keyboard pywin32
- name: Build EXE
run: |
$ErrorActionPreference = "Stop"
$tempRoot = if ($env:RUNNER_TEMP) { $env:RUNNER_TEMP } else { $env:TEMP }
$pythonRoot = Join-Path $tempRoot $env:PYTHON_DIRNAME
$sourceDir = Join-Path $tempRoot $env:SOURCE_DIRNAME
$pythonExe = Join-Path $pythonRoot "python.exe"
Set-Location $sourceDir
& $pythonExe -m PyInstaller --clean --noconfirm --onefile --windowed --name Shortcut_Sync_PotPlayer main.py
- name: Save build output on runner
run: |
$ErrorActionPreference = "Stop"
$tempRoot = if ($env:RUNNER_TEMP) { $env:RUNNER_TEMP } else { $env:TEMP }
$sourceDir = Join-Path $tempRoot $env:SOURCE_DIRNAME
$outputRoot = Join-Path $env:USERPROFILE $env:OUTPUT_SUBDIR
$distExe = Join-Path $sourceDir "dist\Shortcut_Sync_PotPlayer.exe"
if (-not (Test-Path $distExe)) {
throw "Build output not found: $distExe"
}
$runId = "${{ gitea.run_number }}"
if (-not $runId) {
$runId = (Get-Date -Format "yyyyMMdd-HHmmss")
}
$outputDir = Join-Path $outputRoot ("run-" + $runId)
New-Item -ItemType Directory -Path $outputDir -Force | Out-Null
$exePath = Join-Path $outputDir "Shortcut_Sync_PotPlayer.exe"
$zipPath = Join-Path $outputDir "Shortcut_Sync_PotPlayer.zip"
Copy-Item -Path $distExe -Destination $exePath -Force
Compress-Archive -Path $distExe -DestinationPath $zipPath -Force
Write-Host "EXE saved to: $exePath"
Write-Host "ZIP saved to: $zipPath"