From 38c3bf33ab7f2583b4851a4f5fa7dbce9c69b65f Mon Sep 17 00:00:00 2001 From: Hsdi Date: Sun, 15 Mar 2026 03:52:27 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=9E=84=E5=BB=BA=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E6=B5=81=EF=BC=8C=E4=BC=98=E5=8C=96Python=E5=AE=89?= =?UTF-8?q?=E8=A3=85=E5=92=8C=E4=BB=93=E5=BA=93=E5=85=8B=E9=9A=86=E6=AD=A5?= =?UTF-8?q?=E9=AA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/build-exe.yml | 193 +++++++++++++++++++++++++++++--- 1 file changed, 175 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build-exe.yml b/.github/workflows/build-exe.yml index 195d206..f0f965e 100644 --- a/.github/workflows/build-exe.yml +++ b/.github/workflows/build-exe.yml @@ -7,31 +7,188 @@ on: jobs: build: - runs-on: - labels: windows + 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 - uses: actions/checkout@v4 + - name: Checkout repository without Node + run: | + $ErrorActionPreference = "Stop" - - name: Set up Python 3.9.1 - uses: actions/setup-python@v5 - with: - python-version: "3.9.1" - architecture: "x64" + $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: | - python -m pip install --upgrade pip - python -m pip install pyinstaller keyboard pywin32 + $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: | - python -m PyInstaller --clean --noconfirm --onefile --windowed --name Shortcut_Sync_PotPlayer main.py + $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" - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: Shortcut_Sync_PotPlayer-windows - path: dist/Shortcut_Sync_PotPlayer.exe - if-no-files-found: error + 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"