Files
chengnan/.gitea/workflows/build-windows-msys2-release.yml
luochen570 796a2b7712
Some checks failed
Cross Build Windows Release on Linux / cross-build-windows (push) Successful in 5m41s
Build Windows Release with MSYS2 / build-windows-msys2 (push) Has been cancelled
ci: add MSYS2 Windows release workflow
2026-05-30 13:36:59 +08:00

181 lines
7.0 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
name: Build Windows Release with MSYS2
on:
push:
branches:
- main
tags:
- 'v*'
pull_request:
branches:
- main
workflow_dispatch:
jobs:
build-windows-msys2:
# 需要 Gitea act_runner 运行在 Windows并且能访问 GitHub 以拉取 actions/checkout、msys2/setup-msys2、actions/upload-artifact。
# 如果你的 runner 使用了自定义标签,可以在 Gitea runner 配置中给它同时加上 windows 标签。
runs-on:
- windows
defaults:
run:
shell: msys2 {0}
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup MSYS2 build environment
uses: msys2/setup-msys2@v2
with:
msystem: UCRT64
update: true
install: >-
git
curl
zip
p7zip
mingw-w64-ucrt-x86_64-toolchain
mingw-w64-ucrt-x86_64-cmake
mingw-w64-ucrt-x86_64-ninja
mingw-w64-ucrt-x86_64-qt6-base
mingw-w64-ucrt-x86_64-opencv
- name: Configure
run: |
set -euo pipefail
cmake -S . -B build-windows-msys2 -G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH=/ucrt64
- name: Build
run: |
set -euo pipefail
cmake --build build-windows-msys2 --parallel "$(nproc)"
- name: Package
run: |
set -euo pipefail
APP_NAME="chengnan"
PACKAGE_NAME="chengnan-windows-x86_64-msys2"
PACKAGE_DIR="dist-windows-msys2/${PACKAGE_NAME}"
EXE="build-windows-msys2/${APP_NAME}.exe"
test -f "$EXE"
rm -rf dist-windows-msys2
mkdir -p "$PACKAGE_DIR"
cp "$EXE" "$PACKAGE_DIR/"
# 部署 Qt 运行时和插件。
if command -v windeployqt >/dev/null 2>&1; then
windeployqt --release --no-translations "$PACKAGE_DIR/${APP_NAME}.exe"
elif command -v windeployqt6 >/dev/null 2>&1; then
windeployqt6 --release --no-translations "$PACKAGE_DIR/${APP_NAME}.exe"
else
echo "windeployqt not found" >&2
exit 1
fi
# 收集 MinGW/MSYS2/OpenCV 运行时 DLL。ldd 会列出 exe/dll 依赖;循环几轮收集二级依赖。
for round in 1 2 3; do
while IFS= read -r binary; do
while IFS= read -r dll; do
[ -f "$dll" ] || continue
cp -n "$dll" "$PACKAGE_DIR/" || true
done < <(ldd "$binary" \
| awk '/=> \/ucrt64\/bin\// {print $3} /^\/ucrt64\/bin\// {print $1}' \
| sort -u)
done < <(find "$PACKAGE_DIR" -maxdepth 2 -type f \( -name '*.exe' -o -name '*.dll' \) | sort)
done
cat > "$PACKAGE_DIR/README.txt" <<'EOF'
chengnan Windows x86_64 MSYS2 发布包
运行方式:
1. 解压整个目录。
2. 双击 chengnan.exe 运行。
说明:
- 本目录由 Windows Runner 使用 MSYS2 UCRT64 构建生成。
- 本目录已包含 Qt、OpenCV 和 MinGW 运行时 DLL。
- 请不要只复制 chengnan.exe需保留同目录 DLL 和 Qt plugins 子目录。
EOF
(cd dist-windows-msys2 && 7z a -tzip "${PACKAGE_NAME}.zip" "${PACKAGE_NAME}" >/dev/null)
(cd dist-windows-msys2 && sha256sum "${PACKAGE_NAME}.zip" > "${PACKAGE_NAME}.zip.sha256")
# 当前 Gitea 上传入口约 60 秒会返回 502大文件按 15 MiB 分片上传。
ZIP="dist-windows-msys2/${PACKAGE_NAME}.zip"
split -b 15M -d -a 3 "$ZIP" "${ZIP}.part-"
(cd dist-windows-msys2 && sha256sum "${PACKAGE_NAME}.zip".part-* > "${PACKAGE_NAME}.zip.parts.sha256")
du -h "$ZIP" "${ZIP}".part-*
- name: Verify package
run: |
set -euo pipefail
test -s dist-windows-msys2/chengnan-windows-x86_64-msys2.zip
test -s dist-windows-msys2/chengnan-windows-x86_64-msys2.zip.part-000
test -s dist-windows-msys2/chengnan-windows-x86_64-msys2.zip.sha256
test -s dist-windows-msys2/chengnan-windows-x86_64-msys2.zip.parts.sha256
(cd dist-windows-msys2 && sha256sum -c chengnan-windows-x86_64-msys2.zip.sha256)
(cd dist-windows-msys2 && sha256sum -c chengnan-windows-x86_64-msys2.zip.parts.sha256)
7z l dist-windows-msys2/chengnan-windows-x86_64-msys2.zip | grep 'chengnan.exe'
limit=$((20 * 1024 * 1024))
for part in dist-windows-msys2/chengnan-windows-x86_64-msys2.zip.part-*; do
size="$(wc -c < "$part")"
echo "$(basename "$part") $size"
if [ "$size" -gt "$limit" ]; then
echo "$part is too large for the current Gitea upload path" >&2
exit 1
fi
done
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: chengnan-windows-x86_64-msys2
path: |
dist-windows-msys2/chengnan-windows-x86_64-msys2.zip
dist-windows-msys2/chengnan-windows-x86_64-msys2.zip.sha256
dist-windows-msys2/chengnan-windows-x86_64-msys2.zip.part-*
dist-windows-msys2/chengnan-windows-x86_64-msys2.zip.parts.sha256
if-no-files-found: error
- name: Upload package to Gitea Packages
if: ${{ github.event_name != 'pull_request' }}
env:
PACKAGE_TOKEN: ${{ secrets.PACKAGE_TOKEN }}
run: |
set -euo pipefail
PACKAGE_NAME="chengnan-windows-x86_64-msys2"
VERSION="${GITHUB_SHA:-manual}"
VERSION="${VERSION:0:10}"
OWNER="${GITHUB_REPOSITORY%%/*}"
API_BASE="${GITHUB_SERVER_URL:-https://git.luochen570.cn}/api/packages/${OWNER}/generic/chengnan/${VERSION}"
TOKEN="${PACKAGE_TOKEN:-${GITHUB_TOKEN:-}}"
test -n "$TOKEN"
upload_file() {
local src="$1"
local url="$2"
local status
status="$(curl --show-error --silent --location \
--header "Authorization: token ${TOKEN}" \
--upload-file "$src" \
--write-out '%{http_code}' \
--output /tmp/gitea-upload-response.txt \
"$url")"
if [ "$status" != "201" ] && [ "$status" != "200" ]; then
echo "Upload failed with HTTP ${status}: ${url}" >&2
cat /tmp/gitea-upload-response.txt >&2
exit 1
fi
}
for part in dist-windows-msys2/${PACKAGE_NAME}.zip.part-*; do
upload_file "$part" "${API_BASE}/$(basename "$part")"
done
upload_file "dist-windows-msys2/${PACKAGE_NAME}.zip.sha256" "${API_BASE}/${PACKAGE_NAME}.zip.sha256"
upload_file "dist-windows-msys2/${PACKAGE_NAME}.zip.parts.sha256" "${API_BASE}/${PACKAGE_NAME}.zip.parts.sha256"
echo "Package uploaded to: ${API_BASE}/"
echo "Download all ${PACKAGE_NAME}.zip.part-* files, then reconstruct with: cat ${PACKAGE_NAME}.zip.part-* > ${PACKAGE_NAME}.zip"