1+ name : Build and Release
2+
3+ on :
4+ push :
5+ tags :
6+ - ' v*.*.*' # Triggers on version tags like v1.0.0, v1.2.3, etc.
7+ workflow_dispatch : # Allows manual triggering
8+
9+ env :
10+ DOTNET_VERSION : ' 9.0.x'
11+ PROJECT_PATH : ' Desktop/Desktop.csproj'
12+ SOLUTION_PATH : ' OneBitSoftware.InputLanguageScreamer.sln'
13+
14+ jobs :
15+ build-and-release :
16+ runs-on : windows-latest
17+
18+ steps :
19+ - name : Checkout code
20+ uses : actions/checkout@v4
21+ with :
22+ fetch-depth : 0 # Fetch all history for proper versioning
23+
24+ - name : Setup .NET
25+ uses : actions/setup-dotnet@v4
26+ with :
27+ dotnet-version : ${{ env.DOTNET_VERSION }}
28+
29+ - name : Extract version from tag
30+ id : get_version
31+ shell : pwsh
32+ run : |
33+ if ($env:GITHUB_REF -match 'refs/tags/v(.*)') {
34+ $version = $matches[1]
35+ echo "VERSION=$version" >> $env:GITHUB_OUTPUT
36+ echo "TAG_NAME=v$version" >> $env:GITHUB_OUTPUT
37+ echo "Version: $version"
38+ } else {
39+ $version = "1.0.0"
40+ echo "VERSION=$version" >> $env:GITHUB_OUTPUT
41+ echo "TAG_NAME=v$version" >> $env:GITHUB_OUTPUT
42+ echo "No tag found, using default version: $version"
43+ }
44+
45+ - name : Update project version
46+ shell : pwsh
47+ run : |
48+ $version = "${{ steps.get_version.outputs.VERSION }}"
49+ $projectFile = "${{ env.PROJECT_PATH }}"
50+
51+ # Read the project file
52+ $content = Get-Content $projectFile -Raw
53+
54+ # Update version numbers
55+ $content = $content -replace '<AssemblyVersion>.*</AssemblyVersion>', "<AssemblyVersion>$version.0</AssemblyVersion>"
56+ $content = $content -replace '<FileVersion>.*</FileVersion>', "<FileVersion>$version.0</FileVersion>"
57+
58+ # Write back to file
59+ Set-Content $projectFile -Value $content -NoNewline
60+
61+ echo "Updated project version to $version"
62+
63+ - name : Restore dependencies
64+ run : dotnet restore ${{ env.SOLUTION_PATH }}
65+
66+ - name : Build solution
67+ run : dotnet build ${{ env.SOLUTION_PATH }} --configuration Release --no-restore
68+
69+ - name : Run tests (if any)
70+ run : dotnet test ${{ env.SOLUTION_PATH }} --configuration Release --no-build --verbosity normal
71+ continue-on-error : true # Continue even if no tests exist
72+
73+ - name : Publish Windows x64
74+ run : |
75+ dotnet publish ${{ env.PROJECT_PATH }} `
76+ --configuration Release `
77+ --runtime win-x64 `
78+ --self-contained true `
79+ --output ./publish/win-x64 `
80+ --verbosity normal
81+
82+ - name : Publish Windows x86
83+ run : |
84+ dotnet publish ${{ env.PROJECT_PATH }} `
85+ --configuration Release `
86+ --runtime win-x86 `
87+ --self-contained true `
88+ --output ./publish/win-x86 `
89+ --verbosity normal
90+
91+ - name : Publish Windows ARM64
92+ run : |
93+ dotnet publish ${{ env.PROJECT_PATH }} `
94+ --configuration Release `
95+ --runtime win-arm64 `
96+ --self-contained true `
97+ --output ./publish/win-arm64 `
98+ --verbosity normal
99+
100+ - name : Create release packages
101+ shell : pwsh
102+ run : |
103+ $version = "${{ steps.get_version.outputs.VERSION }}"
104+
105+ # Create release directory
106+ New-Item -ItemType Directory -Force -Path "./release"
107+
108+ # Package Windows x64
109+ Compress-Archive -Path "./publish/win-x64/*" -DestinationPath "./release/InputLanguageScreamer-v$version-win-x64.zip"
110+
111+ # Package Windows x86
112+ Compress-Archive -Path "./publish/win-x86/*" -DestinationPath "./release/InputLanguageScreamer-v$version-win-x86.zip"
113+
114+ # Package Windows ARM64
115+ Compress-Archive -Path "./publish/win-arm64/*" -DestinationPath "./release/InputLanguageScreamer-v$version-win-arm64.zip"
116+
117+ # Create portable package (just the executable and audio files)
118+ New-Item -ItemType Directory -Force -Path "./portable"
119+ Copy-Item "./publish/win-x64/Desktop.exe" -Destination "./portable/"
120+ Copy-Item "./publish/win-x64/Audio" -Destination "./portable/" -Recurse -Force
121+ Compress-Archive -Path "./portable/*" -DestinationPath "./release/InputLanguageScreamer-v$version-portable.zip"
122+
123+ echo "Created release packages:"
124+ Get-ChildItem "./release/" | ForEach-Object { echo " - $($_.Name)" }
125+
126+ - name : Generate release notes
127+ id : release_notes
128+ shell : pwsh
129+ run : |
130+ $version = "${{ steps.get_version.outputs.VERSION }}"
131+ $releaseNotes = @"
132+ # Input Language Screamer v$version
133+
134+ ## 🎵 What's New
135+
136+ This release includes the latest features and improvements for Input Language Screamer.
137+
138+ ## 📦 Downloads
139+
140+ Choose the appropriate package for your system:
141+
142+ - **Windows x64** (Recommended for most users): `InputLanguageScreamer-v$version-win-x64.zip`
143+ - **Windows x86** (32-bit systems): `InputLanguageScreamer-v$version-win-x86.zip`
144+ - **Windows ARM64** (ARM-based Windows devices): `InputLanguageScreamer-v$version-win-arm64.zip`
145+ - **Portable** (Minimal package): `InputLanguageScreamer-v$version-portable.zip`
146+
147+ ## 🚀 Installation
148+
149+ 1. Download the appropriate ZIP file for your system
150+ 2. Extract to your desired location
151+ 3. Add your MP3 audio files to the `Audio` folder
152+ 4. Run `Desktop.exe`
153+
154+ ## 🎵 Supported Audio Files
155+
156+ Place MP3 files in the `Audio` folder named after your languages:
157+ - `English.mp3` for English
158+ - `Bulgarian.mp3` for Bulgarian
159+ - `Spanish.mp3` for Spanish
160+ - etc.
161+
162+ ## 🔧 System Requirements
163+
164+ - Windows 10/11
165+ - .NET 9.0 Runtime (included in self-contained packages)
166+
167+ ## 📞 Support
168+
169+ - [Issues](https://github.com/OneBitSoftware/OneBitSoftware.InputLanguageScreamer/issues)
170+ - [Discussions](https://github.com/OneBitSoftware/OneBitSoftware.InputLanguageScreamer/discussions)
171+
172+ ---
173+ **Full Changelog**: https://github.com/OneBitSoftware/OneBitSoftware.InputLanguageScreamer/compare/v$version
174+ "@
175+
176+ # Save to file for GitHub release
177+ $releaseNotes | Out-File -FilePath "./release-notes.md" -Encoding UTF8
178+
179+ # Output for GitHub Actions (escape newlines)
180+ $escapedNotes = $releaseNotes -replace "`r`n", "%0A" -replace "`n", "%0A"
181+ echo "RELEASE_NOTES=$escapedNotes" >> $env:GITHUB_OUTPUT
182+
183+ - name : Create GitHub Release
184+ uses : softprops/action-gh-release@v1
185+ with :
186+ tag_name : ${{ steps.get_version.outputs.TAG_NAME }}
187+ name : Input Language Screamer ${{ steps.get_version.outputs.TAG_NAME }}
188+ body_path : ./release-notes.md
189+ draft : false
190+ prerelease : false
191+ files : |
192+ ./release/*.zip
193+ env :
194+ GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
195+
196+ - name : Upload build artifacts
197+ uses : actions/upload-artifact@v4
198+ with :
199+ name : build-artifacts-${{ steps.get_version.outputs.VERSION }}
200+ path : |
201+ ./release/*.zip
202+ ./release-notes.md
203+ retention-days : 30
204+
205+ - name : Build summary
206+ shell : pwsh
207+ run : |
208+ $version = "${{ steps.get_version.outputs.VERSION }}"
209+ echo "## 🎉 Build Summary" >> $env:GITHUB_STEP_SUMMARY
210+ echo "" >> $env:GITHUB_STEP_SUMMARY
211+ echo "✅ **Version**: $version" >> $env:GITHUB_STEP_SUMMARY
212+ echo "✅ **Build**: Successful" >> $env:GITHUB_STEP_SUMMARY
213+ echo "✅ **Platforms**: Windows x64, x86, ARM64" >> $env:GITHUB_STEP_SUMMARY
214+ echo "✅ **Release**: Created" >> $env:GITHUB_STEP_SUMMARY
215+ echo "" >> $env:GITHUB_STEP_SUMMARY
216+ echo "### 📦 Release Packages" >> $env:GITHUB_STEP_SUMMARY
217+ Get-ChildItem "./release/*.zip" | ForEach-Object {
218+ $size = [math]::Round($_.Length / 1MB, 2)
219+ echo "- **$($_.Name)** ($size MB)" >> $env:GITHUB_STEP_SUMMARY
220+ }
0 commit comments