Skip to content

不是 GitHub Actions 统一限制,而是每个 Action 开发者自己决定的参数类型。 如果 Action 定义参数为 type… #21

不是 GitHub Actions 统一限制,而是每个 Action 开发者自己决定的参数类型。 如果 Action 定义参数为 type…

不是 GitHub Actions 统一限制,而是每个 Action 开发者自己决定的参数类型。 如果 Action 定义参数为 type… #21

name: Build and Release with Nuitka
# 触发条件:
# - 推送代码到 main/master 分支(日常测试)
# - 创建针对 main/master 的 PR(测试)
# - 推送以 v 开头的标签(如 v1.0.0)时,自动构建并发布 Release
on:
push:
branches: [ "main", "master" ]
tags:
- "v*"
pull_request:
branches: [ "main", "master" ]
jobs:
build:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
runs-on: ${{ matrix.os }}
# 必须的权限:允许上传 Artifact,release 任务需要写入 Release
permissions:
contents: write
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
# 缓存 pip 依赖(加速构建)
- name: Cache pip dependencies
uses: actions/cache@v3
with:
path: |
~/.cache/pip
~\AppData\Local\pip\Cache
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
# 安装 Nuitka 和 zstandard(支持 onefile 压缩)
# 如果有 requirements.txt,也一并安装
- name: Install Nuitka and dependencies
run: |
pip install --upgrade pip
pip install nuitka zstandard
if [ -f requirements.txt ]; then
pip install -r requirements.txt
fi
shell: bash
# Linux 需要系统 Tkinter 库
- name: Install Tkinter (Linux)
if: runner.os == 'Linux'
run: |
sudo apt update
sudo apt install -y python3-tk
shell: bash
# ------------------------------------------------------------------
# 步骤1:检测主脚本文件
# 逻辑:优先使用仓库变量 MAIN_SCRIPT,否则在常见文件名列表中查找
# 如果找不到,则终止工作流并报错
# ------------------------------------------------------------------
- name: Detect main script file
id: detect_main
run: |
# 如果设置了仓库变量 MAIN_SCRIPT,直接使用
if [ -n "${{ vars.MAIN_SCRIPT }}" ]; then
MAIN_SCRIPT="${{ vars.MAIN_SCRIPT }}"
echo "✅ 使用仓库变量 MAIN_SCRIPT: $MAIN_SCRIPT"
else
echo "ℹ️ 未设置 MAIN_SCRIPT 变量,尝试自动检测常见入口文件..."
candidates=("main.py" "app.py" "run.py" "start.py" "cli.py" "program.py")
found=""
for name in "${candidates[@]}"; do
if [ -f "$name" ]; then
found="$name"
echo "✅ 找到入口文件: $name"
break
fi
done
if [ -z "$found" ]; then
echo "❌ 错误:未找到任何常见入口文件,请设置仓库变量 MAIN_SCRIPT 指定主文件"
exit 1
fi
MAIN_SCRIPT="$found"
fi
echo "main_script=$MAIN_SCRIPT" >> $GITHUB_OUTPUT
shell: bash
# ------------------------------------------------------------------
# 步骤2:检测图标文件(仅 Windows 需要)
# 如果存在 file.ico,则设置 HAS_ICON=true,否则 false
# ------------------------------------------------------------------
- name: Check for icon file (Windows)
if: runner.os == 'Windows'
id: check_icon
run: |
if (Test-Path file.ico) {
echo "HAS_ICON=true" >> $env:GITHUB_OUTPUT
echo "✅ 图标文件 file.ico 存在,将添加图标参数"
} else {
echo "HAS_ICON=false" >> $env:GITHUB_OUTPUT
echo "ℹ️ 图标文件 file.ico 不存在,跳过图标参数"
}
shell: pwsh
# ------------------------------------------------------------------
# Windows 构建步骤
# 根据 HAS_ICON 决定是否添加图标参数
# 注意:PowerShell 命令中不能有内联注释,注释已放在上方
# ------------------------------------------------------------------
- name: Build with Nuitka (Windows)
if: runner.os == 'Windows'
run: |
$iconParam = if ("${{ steps.check_icon.outputs.HAS_ICON }}" -eq "true") { "--windows-icon-from-ico=file.ico" } else { "" }
nuitka --standalone --onefile `
--assume-yes-for-downloads `
--enable-plugin=tk-inter `
--output-dir=dist `
$iconParam `
--include-data-file=white_files.json=white_files.json `
${{ steps.detect_main.outputs.main_script }}
shell: pwsh
# ------------------------------------------------------------------
# Linux 构建步骤(不需要图标参数)
# ------------------------------------------------------------------
- name: Build with Nuitka (Linux)
if: runner.os == 'Linux'
run: |
nuitka --standalone --onefile \
--enable-plugin=tk-inter \
--output-dir=dist \
--include-data-file=white_files.json=white_files.json \
${{ steps.detect_main.outputs.main_script }}
shell: bash
# 调试:列出 dist 目录内容,确认生成的文件名
- name: List dist directory
if: always()
run: |
echo "=== Dist directory contents ==="
ls -la dist/ || echo "dist/ not found"
shell: bash
# 上传构建产物到 Actions Artifacts(临时存储)
- name: Upload artifacts to Actions
uses: actions/upload-artifact@v4
with:
name: PythonSizeCruncher-${{ runner.os }}
# 使用通配符捕获任何 .exe 和 .bin 文件,避免硬编码文件名
path: |
dist/*.exe
dist/*.bin
if-no-files-found: error
# ----------------------------------------------------------------------
# Release 任务:仅在推送标签时执行
# ----------------------------------------------------------------------
release:
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
if: startsWith(github.ref, 'refs/tags/')
steps:
# 下载所有平台的 Artifacts 到当前工作目录下的 artifacts 文件夹
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
merge-multiple: true
# 调试:列出下载的文件,确认文件名
- name: Verify downloaded files
run: ls -la artifacts/
# 创建 Release 并上传所有可执行文件(通配符方式)
# 说明:
# - Windows 可执行文件:artifacts/*.exe
# - Linux 可执行文件(已包含在 .bin 中):artifacts/*.bin
# | Action | 参数 | 支持的语法 |
# | ----------------------------- | ------- | ------------------------------ |
# | `actions/upload-artifact` | `path` | **支持两种** ✅ 数组 `[]` 或多行字符串 `\|` |
# | `softprops/action-gh-release` | `files` | **仅支持** 多行字符串 `\|` ❌ 不支持数组 |
# | `actions/checkout` | 大多数参数 | 普通字符串 |
- name: Create Release and Upload Assets
uses: softprops/action-gh-release@v2
with:
files: |
artifacts/*.exe
artifacts/*.bin
tag_name: ${{ github.ref_name }}
name: Release ${{ github.ref_name }}
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}