Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f2b722176 | ||
|
|
7e83d5838e | ||
|
|
19a5b30ae1 | ||
|
|
12cbb22b5d | ||
|
|
2ee8eae642 | ||
|
|
a9e3f7aac9 | ||
|
|
d1983be415 | ||
|
|
732007edd8 | ||
|
|
628dda4adc | ||
|
|
bec0829d24 | ||
| 12291e0490 |
298
.gitea/workflows/windows-release.yml
Normal file
298
.gitea/workflows/windows-release.yml
Normal file
@@ -0,0 +1,298 @@
|
|||||||
|
name: windows-release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "v*"
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
version:
|
||||||
|
description: "Override app version (e.g. 0.5.0). Defaults to tag name without leading v."
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build_windows:
|
||||||
|
runs-on: windows-host
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: cmd
|
||||||
|
|
||||||
|
env:
|
||||||
|
QT_ROOT: C:\Qt\6.8.3\mingw_64
|
||||||
|
BUILD_DIR: build-ci
|
||||||
|
DIST_DIR: dist
|
||||||
|
BUILD_TYPE: Release
|
||||||
|
APP_EXE_NAME: TactileIpc3D.exe
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Init submodules
|
||||||
|
run: |
|
||||||
|
git submodule sync --recursive
|
||||||
|
git submodule update --init --recursive
|
||||||
|
|
||||||
|
- name: Resolve version
|
||||||
|
run: |
|
||||||
|
set "APP_VERSION=${{ inputs.version }}"
|
||||||
|
if "%APP_VERSION%"=="" (
|
||||||
|
if "%GITHUB_REF:~0,10%"=="refs/tags/" (
|
||||||
|
set "APP_VERSION=%GITHUB_REF_NAME%"
|
||||||
|
) else (
|
||||||
|
if exist "VERSION.txt" (
|
||||||
|
for /f "usebackq delims=" %%v in ("VERSION.txt") do set "APP_VERSION=%%v"
|
||||||
|
) else (
|
||||||
|
set "APP_VERSION=%GITHUB_REF_NAME%"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if "%APP_VERSION:~0,1%"=="v" set "APP_VERSION=%APP_VERSION:~1%"
|
||||||
|
echo APP_VERSION=%APP_VERSION%>> "%GITHUB_ENV%"
|
||||||
|
echo Using APP_VERSION=%APP_VERSION%
|
||||||
|
|
||||||
|
- name: Setup Qt env & sanity check
|
||||||
|
run: |
|
||||||
|
call "%QT_ROOT%\bin\qtenv2.bat"
|
||||||
|
echo ==== qmake / windeployqt ====
|
||||||
|
where qmake
|
||||||
|
qmake -v
|
||||||
|
where windeployqt
|
||||||
|
where g++
|
||||||
|
g++ --version
|
||||||
|
|
||||||
|
# ========= 这里二选一:CMake 或 qmake =========
|
||||||
|
# A) CMake 框架(推荐)
|
||||||
|
- name: Configure (CMake)
|
||||||
|
run: |
|
||||||
|
if defined GITHUB_WORKSPACE (
|
||||||
|
set "REPO_ROOT=%GITHUB_WORKSPACE%"
|
||||||
|
) else (
|
||||||
|
set "REPO_ROOT=%CD%"
|
||||||
|
)
|
||||||
|
set "BUILD_DIR_ABS=%REPO_ROOT%\%BUILD_DIR%"
|
||||||
|
call "%QT_ROOT%\bin\qtenv2.bat"
|
||||||
|
if exist "%BUILD_DIR_ABS%" rmdir /s /q "%BUILD_DIR_ABS%"
|
||||||
|
mkdir "%BUILD_DIR_ABS%"
|
||||||
|
cmake -S "%REPO_ROOT%" -B "%BUILD_DIR_ABS%" -G "MinGW Makefiles" ^
|
||||||
|
-DCMAKE_BUILD_TYPE=%BUILD_TYPE%
|
||||||
|
|
||||||
|
- name: Build (CMake)
|
||||||
|
run: |
|
||||||
|
if defined GITHUB_WORKSPACE (
|
||||||
|
set "REPO_ROOT=%GITHUB_WORKSPACE%"
|
||||||
|
) else (
|
||||||
|
set "REPO_ROOT=%CD%"
|
||||||
|
)
|
||||||
|
set "BUILD_DIR_ABS=%REPO_ROOT%\%BUILD_DIR%"
|
||||||
|
call "%QT_ROOT%\bin\qtenv2.bat"
|
||||||
|
cmake --build "%BUILD_DIR_ABS%" --config %BUILD_TYPE% -j 8
|
||||||
|
|
||||||
|
# # B) qmake 框架(如果你用 qmake,把上面 CMake 三步注释掉,启用下面)
|
||||||
|
# - name: Build (qmake)
|
||||||
|
# run: |
|
||||||
|
# call "%QT_ROOT%\bin\qtenv2.bat"
|
||||||
|
# if exist "%BUILD_DIR%" rmdir /s /q "%BUILD_DIR%"
|
||||||
|
# mkdir "%BUILD_DIR%"
|
||||||
|
# cd "%BUILD_DIR%"
|
||||||
|
# qmake ..
|
||||||
|
# mingw32-make -j 8
|
||||||
|
|
||||||
|
# ========= 找到 exe & 产物目录 =========
|
||||||
|
- name: Collect exe
|
||||||
|
run: |
|
||||||
|
call "%QT_ROOT%\bin\qtenv2.bat"
|
||||||
|
if defined GITHUB_WORKSPACE (
|
||||||
|
set "REPO_ROOT=%GITHUB_WORKSPACE%"
|
||||||
|
) else (
|
||||||
|
set "REPO_ROOT=%CD%"
|
||||||
|
)
|
||||||
|
|
||||||
|
set "DIST_ABS=%REPO_ROOT%\%DIST_DIR%"
|
||||||
|
if exist "%DIST_ABS%" rmdir /s /q "%DIST_ABS%"
|
||||||
|
mkdir "%DIST_ABS%"
|
||||||
|
|
||||||
|
set "BUILD_DIR_ABS=%REPO_ROOT%\%BUILD_DIR%"
|
||||||
|
set "RUNTIME_OUT_DIR=%BUILD_DIR_ABS%\out"
|
||||||
|
set "RUNTIME_OUT_DIR_CFG=%RUNTIME_OUT_DIR%\%BUILD_TYPE%"
|
||||||
|
|
||||||
|
if exist "%RUNTIME_OUT_DIR_CFG%\%APP_EXE_NAME%" (
|
||||||
|
set "RUNTIME_BASE=%RUNTIME_OUT_DIR_CFG%"
|
||||||
|
) else (
|
||||||
|
set "RUNTIME_BASE=%RUNTIME_OUT_DIR%"
|
||||||
|
)
|
||||||
|
|
||||||
|
if not exist "%RUNTIME_BASE%\%APP_EXE_NAME%" (
|
||||||
|
echo EXE not found: "%RUNTIME_BASE%\%APP_EXE_NAME%"
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
echo ==== copy app exe ====
|
||||||
|
copy /y "%RUNTIME_BASE%\%APP_EXE_NAME%" "%DIST_ABS%\%APP_EXE_NAME%"
|
||||||
|
|
||||||
|
echo ==== copy plugin dlls ====
|
||||||
|
if not exist "%DIST_ABS%\plugins\decoders" mkdir "%DIST_ABS%\plugins\decoders"
|
||||||
|
if not exist "%RUNTIME_BASE%\plugins\decoders\*.dll" (
|
||||||
|
echo Plugin DLLs not found: "%RUNTIME_BASE%\plugins\decoders\*.dll"
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
copy /y "%RUNTIME_BASE%\plugins\decoders\*.dll" "%DIST_ABS%\plugins\decoders\"
|
||||||
|
|
||||||
|
echo ==== copy OpenCV runtime dlls ====
|
||||||
|
set "OPENCV_LIB_DIR=%REPO_ROOT%\3rdpart\OpenCV\lib"
|
||||||
|
if not exist "%OPENCV_LIB_DIR%\libopencv_core4100.dll" (
|
||||||
|
echo OpenCV DLL not found: "%OPENCV_LIB_DIR%\libopencv_core4100.dll"
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
if not exist "%OPENCV_LIB_DIR%\libopencv_imgproc4100.dll" (
|
||||||
|
echo OpenCV DLL not found: "%OPENCV_LIB_DIR%\libopencv_imgproc4100.dll"
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
copy /y "%OPENCV_LIB_DIR%\libopencv_core4100.dll" "%DIST_ABS%\"
|
||||||
|
copy /y "%OPENCV_LIB_DIR%\libopencv_imgproc4100.dll" "%DIST_ABS%\"
|
||||||
|
|
||||||
|
echo Copied to %DIST_DIR%
|
||||||
|
dir "%DIST_ABS%"
|
||||||
|
|
||||||
|
- name: Deploy Qt runtime (windeployqt)
|
||||||
|
run: |
|
||||||
|
if defined GITHUB_WORKSPACE (
|
||||||
|
set "REPO_ROOT=%GITHUB_WORKSPACE%"
|
||||||
|
) else (
|
||||||
|
set "REPO_ROOT=%CD%"
|
||||||
|
)
|
||||||
|
set "DIST_ABS=%REPO_ROOT%\%DIST_DIR%"
|
||||||
|
call "%QT_ROOT%\bin\qtenv2.bat"
|
||||||
|
"%QT_ROOT%\bin\windeployqt.exe" "%DIST_ABS%\%APP_EXE_NAME%" ^
|
||||||
|
--release --compiler-runtime --no-translations
|
||||||
|
|
||||||
|
- name: Build installer (Inno Setup)
|
||||||
|
run: |
|
||||||
|
if defined GITHUB_WORKSPACE (
|
||||||
|
set "REPO_ROOT=%GITHUB_WORKSPACE%"
|
||||||
|
) else (
|
||||||
|
set "REPO_ROOT=%CD%"
|
||||||
|
)
|
||||||
|
set "DIST_ABS=%REPO_ROOT%\%DIST_DIR%"
|
||||||
|
set "ISS_FILE=%REPO_ROOT%\installer\TactileIpc3D.iss"
|
||||||
|
|
||||||
|
if not exist "%ISS_FILE%" (
|
||||||
|
echo Inno Setup script not found: "%ISS_FILE%"
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
if not exist "%DIST_ABS%" (
|
||||||
|
echo Dist dir not found: "%DIST_ABS%"
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
where iscc || (echo ISCC not found & exit /b 1)
|
||||||
|
iscc /DMyAppVersion=%APP_VERSION% /DSourceDir="%DIST_ABS%" /DOutputDir="%DIST_ABS%" "%ISS_FILE%"
|
||||||
|
|
||||||
|
# (可选)打包 zip
|
||||||
|
- name: Zip package
|
||||||
|
run: |
|
||||||
|
if defined GITHUB_WORKSPACE (
|
||||||
|
set "REPO_ROOT=%GITHUB_WORKSPACE%"
|
||||||
|
) else (
|
||||||
|
set "REPO_ROOT=%CD%"
|
||||||
|
)
|
||||||
|
set "DIST_ABS=%REPO_ROOT%\%DIST_DIR%"
|
||||||
|
powershell -NoProfile -Command ^
|
||||||
|
"if (Test-Path '%DIST_ABS%.zip') { Remove-Item -Force '%DIST_ABS%.zip' }; " ^
|
||||||
|
"Compress-Archive -Path '%DIST_ABS%\*' -DestinationPath '%DIST_ABS%.zip'"
|
||||||
|
|
||||||
|
- name: Publish Gitea Release
|
||||||
|
if: startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch'
|
||||||
|
shell: powershell
|
||||||
|
env:
|
||||||
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||||
|
run: |
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
$token = $env:GITEA_TOKEN
|
||||||
|
if (-not $token) { throw "GITEA_TOKEN is not set. Please add it in repo secrets." }
|
||||||
|
|
||||||
|
$api = $env:GITEA_API_URL
|
||||||
|
if (-not $api) { $api = $env:GITHUB_API_URL }
|
||||||
|
if (-not $api) {
|
||||||
|
if ($env:GITEA_SERVER_URL) { $api = "$($env:GITEA_SERVER_URL)/api/v1" }
|
||||||
|
elseif ($env:GITHUB_SERVER_URL) { $api = "$($env:GITHUB_SERVER_URL)/api/v1" }
|
||||||
|
}
|
||||||
|
if (-not $api) { throw "API URL not found. Set GITEA_API_URL or GITEA_SERVER_URL." }
|
||||||
|
|
||||||
|
$repo = $env:GITHUB_REPOSITORY
|
||||||
|
if (-not $repo) { $repo = $env:GITEA_REPOSITORY }
|
||||||
|
if (-not $repo) { throw "Repository not found in env." }
|
||||||
|
|
||||||
|
$ref = $env:GITHUB_REF
|
||||||
|
$isTag = $false
|
||||||
|
if ($ref) { $isTag = $ref.StartsWith("refs/tags/") }
|
||||||
|
if ($isTag) {
|
||||||
|
$tag = $env:GITHUB_REF_NAME
|
||||||
|
} else {
|
||||||
|
$tag = "v$($env:APP_VERSION)"
|
||||||
|
}
|
||||||
|
if (-not $tag) { throw "Release tag not found." }
|
||||||
|
|
||||||
|
$owner, $repoName = $repo.Split("/")
|
||||||
|
if (-not $owner -or -not $repoName) { throw "Invalid repo format: $repo" }
|
||||||
|
|
||||||
|
$headers = @{ Authorization = "token $token" }
|
||||||
|
|
||||||
|
# Get or create release
|
||||||
|
$release = $null
|
||||||
|
try {
|
||||||
|
$release = Invoke-RestMethod -Method Get -Headers $headers -Uri "$api/repos/$owner/$repoName/releases/tags/$tag"
|
||||||
|
} catch {
|
||||||
|
$release = $null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not $release) {
|
||||||
|
$body = @{
|
||||||
|
tag_name = $tag
|
||||||
|
name = $tag
|
||||||
|
draft = $false
|
||||||
|
prerelease = $false
|
||||||
|
}
|
||||||
|
if (-not $isTag) {
|
||||||
|
$body.target_commitish = $env:GITHUB_SHA
|
||||||
|
}
|
||||||
|
$body = $body | ConvertTo-Json
|
||||||
|
$release = Invoke-RestMethod -Method Post -Headers $headers -ContentType "application/json" -Body $body -Uri "$api/repos/$owner/$repoName/releases"
|
||||||
|
}
|
||||||
|
|
||||||
|
$releaseId = $release.id
|
||||||
|
if (-not $releaseId) { throw "Release ID not found." }
|
||||||
|
|
||||||
|
# Resolve dist dir
|
||||||
|
$repoRoot = $env:GITHUB_WORKSPACE
|
||||||
|
if (-not $repoRoot) { $repoRoot = (Get-Location).Path }
|
||||||
|
$distDir = Join-Path $repoRoot $env:DIST_DIR
|
||||||
|
if (-not (Test-Path $distDir)) { throw "Dist dir not found: $distDir" }
|
||||||
|
|
||||||
|
$installer = Get-ChildItem -Path $distDir -Filter "TactileIpc3D-Setup-*.exe" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
||||||
|
if (-not $installer) { throw "Installer not found in $distDir" }
|
||||||
|
|
||||||
|
$zipPath = Join-Path $repoRoot "$($env:DIST_DIR).zip"
|
||||||
|
$assets = @($installer.FullName)
|
||||||
|
if (Test-Path $zipPath) { $assets += $zipPath }
|
||||||
|
|
||||||
|
# Delete existing assets with same name
|
||||||
|
$existing = Invoke-RestMethod -Method Get -Headers $headers -Uri "$api/repos/$owner/$repoName/releases/$releaseId/assets"
|
||||||
|
$existingMap = @{}
|
||||||
|
foreach ($a in $existing) { $existingMap[$a.name] = $a.id }
|
||||||
|
|
||||||
|
foreach ($asset in $assets) {
|
||||||
|
$name = [System.IO.Path]::GetFileName($asset)
|
||||||
|
if ($existingMap.ContainsKey($name)) {
|
||||||
|
$assetId = $existingMap[$name]
|
||||||
|
Invoke-RestMethod -Method Delete -Headers $headers -Uri "$api/repos/$owner/$repoName/releases/assets/$assetId"
|
||||||
|
}
|
||||||
|
$uploadUrl = "$api/repos/$owner/$repoName/releases/$releaseId/assets?name=$name"
|
||||||
|
& curl.exe -sS -X POST -H "Authorization: token $token" -F "attachment=@$asset" $uploadUrl
|
||||||
|
if ($LASTEXITCODE -ne 0) { throw "Upload failed for $name" }
|
||||||
|
}
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -24,7 +24,6 @@ qmlcache_loader.cpp
|
|||||||
|
|
||||||
# Binaries
|
# Binaries
|
||||||
*.exe
|
*.exe
|
||||||
*.dll
|
|
||||||
*.so
|
*.so
|
||||||
*.dylib
|
*.dylib
|
||||||
*.a
|
*.a
|
||||||
|
|||||||
BIN
3rdpart/OpenCV/lib/libopencv_core4100.dll
Normal file
BIN
3rdpart/OpenCV/lib/libopencv_core4100.dll
Normal file
Binary file not shown.
BIN
3rdpart/OpenCV/lib/libopencv_imgproc4100.dll
Normal file
BIN
3rdpart/OpenCV/lib/libopencv_imgproc4100.dll
Normal file
Binary file not shown.
@@ -1,9 +1,15 @@
|
|||||||
#define MyAppName "TactileIpc3D"
|
#define MyAppName "TactileIpc3D"
|
||||||
|
#ifndef MyAppVersion
|
||||||
#define MyAppVersion "0.5.0"
|
#define MyAppVersion "0.5.0"
|
||||||
|
#endif
|
||||||
#define MyAppPublisher "TactileIpc3D"
|
#define MyAppPublisher "TactileIpc3D"
|
||||||
#define MyAppExeName "TactileIpc3D.exe"
|
#define MyAppExeName "TactileIpc3D.exe"
|
||||||
#define SourceDir "..\\build\Desktop_Qt_6_8_3_MinGW_64_bit-Release\\out\Release"
|
#ifndef SourceDir
|
||||||
|
#define SourceDir "..\\dist"
|
||||||
|
#endif
|
||||||
|
#ifndef OutputDir
|
||||||
#define OutputDir "..\\dist"
|
#define OutputDir "..\\dist"
|
||||||
|
#endif
|
||||||
#define AssetsDir "assets"
|
#define AssetsDir "assets"
|
||||||
#define AppIconFile AssetsDir + "\\App.ico"
|
#define AppIconFile AssetsDir + "\\App.ico"
|
||||||
#define WizardSmallFile AssetsDir + "\\WizardSmall.bmp"
|
#define WizardSmallFile AssetsDir + "\\WizardSmall.bmp"
|
||||||
|
|||||||
Reference in New Issue
Block a user