summaryrefslogtreecommitdiff
path: root/.github
diff options
context:
space:
mode:
Diffstat (limited to '.github')
-rw-r--r--.github/workflows/package-win.yml255
1 files changed, 255 insertions, 0 deletions
diff --git a/.github/workflows/package-win.yml b/.github/workflows/package-win.yml
new file mode 100644
index 0000000..082f098
--- /dev/null
+++ b/.github/workflows/package-win.yml
@@ -0,0 +1,255 @@
+name: Windows Installer Packaging
+
+on:
+ release:
+ types: [published]
+ workflow_dispatch:
+ inputs:
+ tag_name:
+ description: 'Release Tag (e.g., v1.0.0). Leave empty to use "latest".'
+ required: false
+ default: ''
+
+jobs:
+ package-windows:
+ runs-on: windows-latest
+ permissions:
+ contents: write
+ steps:
+ - name: Checkout Repository
+ uses: actions/checkout@v4
+
+ - name: Install NSIS
+ run: choco install nsis
+
+ - name: Get Version from Cargo.toml
+ id: get_version
+ shell: pwsh
+ run: |
+ # Extract version line from Cargo.toml
+ $VersionLine = Get-Content Cargo.toml | Select-String '^version\s*=\s*"(.*)"'
+ if ($VersionLine.Matches.Success) {
+ $Version = $VersionLine.Matches.Groups[1].Value
+ Write-Host "Found version in Cargo.toml: $Version"
+ "version=$Version" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
+ } else {
+ Write-Error "Could not find version in Cargo.toml"
+ exit 1
+ }
+
+ - name: Determine Release Tag
+ id: get_tag
+ shell: pwsh
+ env:
+ GH_TOKEN: ${{ secrets.RELEASE_TOKEN }}
+ run: |
+ # 1. Try manual input
+ $TAG = "${{ inputs.tag_name }}"
+
+ # 2. Try release event payload
+ if (-not $TAG) { $TAG = "${{ github.event.release.tag_name }}" }
+
+ # 3. Fallback to latest release if still empty
+ if (-not $TAG) {
+ Write-Host "No tag provided, fetching latest release..."
+ $TAG = $(gh release view --json tagName --jq .tagName)
+ }
+
+ if (-not $TAG) {
+ Write-Error "Could not determine release tag."
+ exit 1
+ }
+
+ Write-Host "Using Tag for download: $TAG"
+ "tag=$TAG" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
+
+ - name: Download Release Assets
+ env:
+ GH_TOKEN: ${{ secrets.RELEASE_TOKEN }}
+ run: |
+ $TAG = "${{ steps.get_tag.outputs.tag }}"
+ gh release download $TAG -p "mikusays-windows-*.exe"
+
+ - name: Generate NSIS Script
+ shell: pwsh
+ run: |
+ $Version = "${{ steps.get_version.outputs.version }}"
+ $InstallerName = "mikusays-windows-inst-any-$Version.exe"
+ Write-Host "Installer will be named: $InstallerName"
+
+ # Prepend 0. to Cargo version for NSIS (e.g. "1.0.0" -> "0.1.0.0")
+ $NsisVersion = "0.$Version"
+ Write-Host "NSIS Internal Version: $NsisVersion"
+
+ $nsisContent = @'
+ !include "MUI2.nsh"
+ !include "LogicLib.nsh"
+ !include "x64.nsh"
+ !include "WinVer.nsh"
+
+ Name "Mikusays"
+ OutFile "__OUTFILE__"
+ Unicode True
+
+ ; --- Metadata & Versioning ---
+ VIProductVersion "__NSISVERSION__"
+ VIAddVersionKey "ProductName" "Mikusays"
+ VIAddVersionKey "CompanyName" "xxanqw"
+ VIAddVersionKey "LegalCopyright" "© xxanqw"
+ VIAddVersionKey "FileDescription" "Mikusays Installer"
+ VIAddVersionKey "FileVersion" "__VERSION__"
+ VIAddVersionKey "ProductVersion" "__VERSION__"
+
+ ; Install to AppData\Local\Programs\mikusays (User Context)
+ RequestExecutionLevel user
+ InstallDir "$LOCALAPPDATA\Programs\mikusays"
+
+ !define MUI_ABORTWARNING
+ !insertmacro MUI_PAGE_WELCOME
+ !insertmacro MUI_PAGE_INSTFILES
+ !insertmacro MUI_PAGE_FINISH
+ !insertmacro MUI_UNPAGE_CONFIRM
+ !insertmacro MUI_UNPAGE_INSTFILES
+ !insertmacro MUI_LANGUAGE "English"
+
+ Section "Install"
+ SetOutPath "$INSTDIR"
+
+ ; Architecture Detection
+ ReadEnvStr $0 "PROCESSOR_ARCHITECTURE"
+ ${If} $0 == "ARM64"
+ File "/oname=mikusays.exe" "mikusays-windows-aarch64.exe"
+ ${Else}
+ File "/oname=mikusays.exe" "mikusays-windows-x86_64.exe"
+ ${EndIf}
+
+ WriteUninstaller "$INSTDIR\uninstall.exe"
+
+ ; Add to PATH (Simple Registry Append)
+ ReadRegStr $0 HKCU "Environment" "Path"
+ ${StrContains} $1 "$INSTDIR" "$0"
+ ${If} $1 == ""
+ WriteRegExpandStr HKCU "Environment" "Path" "$0;$INSTDIR"
+ SendMessage ${HWND_BROADCAST} ${WM_SETTINGCHANGE} 0 "STR:Environment" /TIMEOUT=5000
+ ${EndIf}
+ SectionEnd
+
+ Section "Uninstall"
+ Delete "$INSTDIR\mikusays.exe"
+ Delete "$INSTDIR\uninstall.exe"
+ RMDir "$INSTDIR"
+
+ ; Remove from PATH (Simple String Replacement)
+ ReadRegStr $0 HKCU "Environment" "Path"
+ ${StrRep} $0 "$0" ";$INSTDIR" ""
+ ${StrRep} $0 "$0" "$INSTDIR;" ""
+ ${StrRep} $0 "$0" "$INSTDIR" ""
+ WriteRegExpandStr HKCU "Environment" "Path" "$0"
+ SendMessage ${HWND_BROADCAST} ${WM_SETTINGCHANGE} 0 "STR:Environment" /TIMEOUT=5000
+ SectionEnd
+
+ ; --- Helper Macros ---
+ !macro StrContains ResultVar Needle Haystack
+ Push "${Haystack}"
+ Push "${Needle}"
+ Call StrContains
+ Pop "${ResultVar}"
+ !macroend
+
+ Function StrContains
+ Exch $R1
+ Exch
+ Exch $R0
+ Push $R2
+ Push $R3
+ Push $R4
+ Push $R5
+ StrLen $R2 $R0
+ StrLen $R3 $R1
+ StrCpy $R5 ""
+ Loop:
+ StrCpy $R4 $R0 $R3
+ StrCmp $R4 $R1 Found
+ StrCpy $R0 $R0 "" 1
+ StrLen $R2 $R0
+ IntCmp $R2 $R3 Loop Loop End
+ Found:
+ StrCpy $R5 "1"
+ End:
+ Pop $R5
+ Pop $R4
+ Pop $R3
+ Pop $R2
+ Pop $R0
+ Pop $R1
+ Exch $R5
+ FunctionEnd
+
+ !macro StrRep ResultVar String SubString RepString
+ Push "${String}"
+ Push "${SubString}"
+ Push "${RepString}"
+ Call StrRep
+ Pop "${ResultVar}"
+ !macroend
+
+ Function StrRep
+ Exch $R2
+ Exch
+ Exch $R1
+ Exch
+ Exch $R0
+ Push $R3
+ Push $R4
+ Push $R5
+ Push $R6
+ Push $R7
+ StrCpy $R3 0
+ StrLen $R4 $R1
+ StrLen $R6 $R0
+ Start:
+ StrCpy $R5 $R0 $R4 $R3
+ StrCmp $R5 $R1 Found
+ IntOp $R3 $R3 + 1
+ IntCmp $R3 $R6 End End Start
+ Found:
+ StrCpy $R5 $R0 $R3
+ IntOp $R7 $R3 + $R4
+ StrCpy $R7 $R0 "" $R7
+ StrCpy $R0 "$R5$R2$R7"
+ StrLen $R6 $R0
+ IntOp $R3 $R3 + $R4
+ Goto Start
+ End:
+ Pop $R7
+ Pop $R6
+ Pop $R5
+ Pop $R4
+ Pop $R3
+ Pop $R2
+ Pop $R1
+ Exch $R0
+ FunctionEnd
+
+ !define StrContains `!insertmacro StrContains`
+ !define StrRep `!insertmacro StrRep`
+ '@
+
+ # Replace placeholders
+ $nsisContent = $nsisContent.Replace("__OUTFILE__", $InstallerName)
+ $nsisContent = $nsisContent.Replace("__NSISVERSION__", $NsisVersion)
+ $nsisContent = $nsisContent.Replace("__VERSION__", $Version)
+
+ Set-Content -Path installer.nsi -Value $nsisContent
+
+ - name: Compile Installer
+ run: makensis installer.nsi
+
+ - name: Upload Installer to Release
+ env:
+ GH_TOKEN: ${{ secrets.RELEASE_TOKEN }}
+ run: |
+ $TAG = "${{ steps.get_tag.outputs.tag }}"
+ $Version = "${{ steps.get_version.outputs.version }}"
+ $InstallerName = "mikusays-windows-inst-any-$Version.exe"
+ gh release upload $TAG $InstallerName --clobber