ci: add MSYS2 Windows release workflow
This commit is contained in:
180
.gitea/workflows/build-windows-msys2-release.yml
Normal file
180
.gitea/workflows/build-windows-msys2-release.yml
Normal file
@@ -0,0 +1,180 @@
|
||||
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"
|
||||
Reference in New Issue
Block a user