Skip to content

Commit 83550ee

Browse files
feat: publish ClickOnce
2 parents 5e7b910 + 83f5d86 commit 83550ee

File tree

6 files changed

+231
-49
lines changed

6 files changed

+231
-49
lines changed

.github/workflows/ci.yml

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,51 @@ jobs:
177177
fail_ci_if_error: true
178178

179179
arius_explorer_build:
180-
name: "🏗️ Explorer Build (stub)"
180+
name: "🚀 Explorer Build & Release"
181181
runs-on: windows-latest
182182
needs: arius_explorer_test
183+
if: github.event_name == 'push'
183184
steps:
184-
- name: "⏭️ Placeholder"
185-
run: echo "Arius.Explorer build pipeline to be implemented."
185+
- name: "📥 Checkout repository"
186+
uses: actions/checkout@v4
187+
with:
188+
fetch-depth: 0
189+
190+
- name: "🧰 Setup .NET"
191+
uses: actions/setup-dotnet@v4
192+
with:
193+
dotnet-version: 9.x
194+
195+
- name: "🧮 Determine version"
196+
run: |
197+
$csprojPath = "src/Arius.Explorer/Arius.Explorer.csproj"
198+
if (-not (Test-Path $csprojPath)) {
199+
throw "Unable to find $csprojPath"
200+
}
201+
202+
$content = Get-Content $csprojPath -Raw
203+
$match = [regex]::Match($content, '<Version>(?<version>[^<]+)</Version>')
204+
if (-not $match.Success) {
205+
throw "Unable to locate <Version> in $csprojPath"
206+
}
207+
208+
if (-not $env:GITHUB_RUN_NUMBER) {
209+
throw "GITHUB_RUN_NUMBER was not provided by the runner"
210+
}
211+
212+
$baseVersion = $match.Groups['version'].Value.Replace('$(GITHUB_RUN_NUMBER)', $env:GITHUB_RUN_NUMBER)
213+
$isPrerelease = $false
214+
if ($env:GITHUB_REF -eq 'refs/heads/main') {
215+
$version = $baseVersion
216+
} else {
217+
$version = "$baseVersion-prerelease"
218+
$isPrerelease = $true
219+
}
220+
221+
"VERSION=$version" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
222+
"IS_PRERELEASE=$isPrerelease" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
223+
224+
- name: "🚀 Publish ClickOnce"
225+
env:
226+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
227+
run: ./.github/workflows/release.ps1 -Version $env:VERSION

.github/workflows/release.ps1

Lines changed: 116 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,54 +2,90 @@
22

33
[CmdletBinding(PositionalBinding=$false)]
44
param (
5-
[switch]$OnlyBuild=$false
5+
[switch]$OnlyBuild = $false,
6+
[string]$Version
67
)
78

8-
$appName = "Arius.Explorer" # 👈 Replace with your application project name.
9-
$projDir = "src\Arius.UI" # 👈 Replace with your project directory (where .csproj resides).
10-
9+
$appName = "Arius.Explorer"
10+
$projDir = "src\Arius.Explorer"
1111
Set-StrictMode -version 2.0
1212
$ErrorActionPreference = "Stop"
1313

1414
Write-Output "Working directory: $pwd"
15-
1615
# Find MSBuild.
1716
$msBuildPath = & "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" `
1817
-latest -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe `
19-
-prerelease | select-object -first 1
18+
-prerelease | Select-Object -First 1
2019
Write-Output "MSBuild: $((Get-Command $msBuildPath).Path)"
2120

22-
# Load current Git tag.
23-
$tag = $(git describe --tags)
24-
Write-Output "Tag: $tag"
21+
# Determine version.
22+
$version = $null
23+
if ($PSBoundParameters.ContainsKey('Version') -and $null -ne $Version -and $Version.Trim().Length -gt 0) {
24+
$version = $Version.Trim()
25+
} elseif ($env:VERSION) {
26+
$version = $env:VERSION.Trim()
27+
}
28+
29+
if (-not $version) {
30+
throw "Unable to determine version. Provide -Version parameter or set VERSION environment variable."
31+
}
2532

26-
# Parse tag into a three-number version.
27-
$version = $tag.Split('-')[0].TrimStart('v')
28-
$version = "$version.0"
29-
Write-Output "Version: $version"
33+
$baseVersion = $version.Split('-', 2)[0]
34+
$versionParts = $baseVersion -split '\.'
35+
$numericParts = @()
36+
foreach ($part in $versionParts) {
37+
if ($part -notmatch '^[0-9]+$') {
38+
throw "Version segment '$part' is not numeric. Unable to derive ClickOnce version from '$version'."
39+
}
40+
$numericParts += $part
41+
}
42+
if ($numericParts.Length -gt 4) {
43+
$numericParts = $numericParts[0..3]
44+
}
45+
while ($numericParts.Length -lt 4) {
46+
$numericParts += '0'
47+
}
48+
$normalizedVersion = ($numericParts -join '.')
49+
$applicationRevision = $numericParts[-1]
50+
Write-Output "Version: $normalizedVersion"
3051

3152
# Clean output directory.
3253
$publishDir = "bin/publish"
3354
$outDir = "$projDir/$publishDir"
3455
if (Test-Path $outDir) {
35-
Remove-Item -Path $outDir -Recurse
56+
Remove-Item -Path $outDir -Recurse -Force
3657
}
3758

59+
$outDirFullPath = $null
60+
3861
# Publish the application.
3962
Push-Location $projDir
4063
try {
4164
Write-Output "Restoring:"
42-
# dotnet restore -r win-x64 ## this does not play well with <ItemGroup Condition="'$(Configuration)'=='Release'">
4365
dotnet build -r win-x64 -c Release
4466
Write-Output "Publishing:"
4567
$msBuildVerbosityArg = "/v:m"
4668
if ($env:CI) {
4769
$msBuildVerbosityArg = ""
4870
}
49-
& $msBuildPath /target:publish /p:PublishProfile=ClickOnceProfile `
50-
/p:ApplicationVersion=$version /p:Configuration=Release `
51-
/p:PublishDir=$publishDir /p:PublishUrl=$publishDir `
52-
$msBuildVerbosityArg
71+
$msbuildArgs = @(
72+
'/target:publish',
73+
'/p:PublishProfile=ClickOnceProfile',
74+
"/p:ApplicationVersion=$normalizedVersion",
75+
"/p:ApplicationRevision=$applicationRevision",
76+
'/p:Configuration=Release',
77+
"/p:PublishDir=$publishDir",
78+
"/p:PublishUrl=$publishDir",
79+
'/p:SignManifests=false'
80+
)
81+
82+
if ($msBuildVerbosityArg) {
83+
$msbuildArgs += $msBuildVerbosityArg
84+
}
85+
86+
& $msBuildPath @msbuildArgs
87+
88+
$outDirFullPath = (Resolve-Path $publishDir).Path
5389

5490
# Measure publish size.
5591
$publishSize = (Get-ChildItem -Path "$publishDir/Application Files" -Recurse |
@@ -62,7 +98,7 @@ finally {
6298

6399
if ($OnlyBuild) {
64100
Write-Output "Build finished."
65-
exit
101+
return
66102
}
67103

68104
# Clone `gh-pages` branch.
@@ -74,28 +110,72 @@ if (-Not (Test-Path $ghPagesDir)) {
74110

75111
Push-Location $ghPagesDir
76112
try {
77-
# Remove previous application files.
78-
Write-Output "Removing previous files..."
79-
if (Test-Path "Application Files") {
80-
Remove-Item -Path "Application Files" -Recurse
113+
if ($env:GITHUB_TOKEN) {
114+
$originUrl = git remote get-url origin
115+
if (-not $originUrl) {
116+
$originUrl = "https://github.com/${env:GITHUB_REPOSITORY}"
117+
}
118+
119+
if ($originUrl -like 'https://*') {
120+
$authUrl = $originUrl -replace '^https://', "https://x-access-token:${env:GITHUB_TOKEN}@"
121+
} else {
122+
$authUrl = "https://x-access-token:${env:GITHUB_TOKEN}@github.com/${env:GITHUB_REPOSITORY}"
123+
}
124+
125+
git remote set-url origin $authUrl | Out-Null
126+
}
127+
128+
if (-not (git config user.email)) {
129+
git config user.email "github-actions@github.com"
81130
}
82-
if (Test-Path "$appName.application") {
83-
Remove-Item -Path "$appName.application"
131+
if (-not (git config user.name)) {
132+
git config user.name "github-actions"
84133
}
85134

86-
# Copy new application files.
87-
Write-Output "Copying new files..."
88-
Copy-Item -Path "../$outDir/Application Files","../$outDir/$appName.application" `
89-
-Destination . -Recurse
135+
$deployRoot = Join-Path (Get-Location) 'explorer'
136+
if (-not (Test-Path $deployRoot)) {
137+
New-Item -ItemType Directory -Path $deployRoot | Out-Null
138+
}
139+
140+
Push-Location $deployRoot
141+
try {
142+
# Remove previous application files.
143+
Write-Output "Removing previous files..."
144+
if (Test-Path "Application Files") {
145+
Remove-Item -Path "Application Files" -Recurse -Force
146+
}
147+
if (Test-Path "$appName.application") {
148+
Remove-Item -Path "$appName.application" -Force
149+
}
150+
151+
if (-not $outDirFullPath) {
152+
throw "Publish directory was not resolved."
153+
}
154+
155+
# Copy new application files.
156+
Write-Output "Copying new files..."
157+
$appFilesPath = Join-Path $outDirFullPath 'Application Files'
158+
$manifestPath = Join-Path $outDirFullPath "$appName.application"
159+
Copy-Item -Path $appFilesPath,$manifestPath -Destination . -Recurse -Force
160+
}
161+
finally {
162+
Pop-Location
163+
}
90164

91165
# Stage and commit.
92166
Write-Output "Staging..."
93167
git add -A
94-
Write-Output "Committing..."
95-
git commit -m "Update to v$version"
96-
97-
# Push.
98-
git push
99-
} finally {
168+
$status = git status --porcelain
169+
if (-not $status) {
170+
Write-Output "No changes to commit."
171+
} else {
172+
Write-Output "Committing..."
173+
git commit -m "Update to v$normalizedVersion"
174+
175+
# Push.
176+
git push
177+
}
178+
}
179+
finally {
100180
Pop-Location
101181
}

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ publish/
185185
# Note: Comment the next line if you want to checkin your web deploy settings,
186186
# but database connection strings (with potential passwords) will be unencrypted
187187
*.pubxml
188+
!src/Arius.Explorer/Properties/PublishProfiles/ClickOnceProfile.pubxml
188189
*.publishproj
189190

190191
# Microsoft Azure Web App publish settings. Comment the next line if you want to
@@ -236,7 +237,6 @@ ClientBin/
236237
*.dbmdl
237238
*.dbproj.schemaview
238239
*.jfm
239-
*.pfx
240240
*.publishsettings
241241
orleans.codegen.cs
242242

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
[![Arius Release](https://github.com/woutervanranst/Arius/actions/workflows/release.yml/badge.svg)](https://github.com/woutervanranst/Arius/actions/workflows/release.yml)
1010
[![Docker](https://img.shields.io/docker/v/woutervanranst/arius?logo=docker&label=Docker)](https://hub.docker.com/r/woutervanranst/arius)
1111
[![Arius.Core Version](https://img.shields.io/nuget/v/WouterVanRanst.Arius.Core?logo=nuget)](https://www.nuget.org/packages/WouterVanRanst.Arius.Core)
12-
[![ClickOnce](https://img.shields.io/badge/Windows-ClickOnce-dsfs?logo=windows&logoColor=lightblue)](https://woutervanranst.github.io/Arius/Arius.Explorer.application)
12+
[![ClickOnce](https://img.shields.io/badge/Windows-ClickOnce-dsfs?logo=windows&logoColor=lightblue)](https://woutervanranst.github.io/Arius/explorer/Arius.Explorer.application)
1313

1414
Arius is a lightweight archival solution, specifically built to leverage the Azure Blob Archive tier.
1515

src/Arius.Explorer/Arius.Explorer.csproj

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

3-
<PropertyGroup>
4-
<OutputType>WinExe</OutputType>
5-
<TargetFramework>net9.0-windows</TargetFramework>
6-
7-
<UseWPF>true</UseWPF>
3+
<PropertyGroup>
4+
<OutputType>WinExe</OutputType>
5+
<TargetFramework>net9.0-windows</TargetFramework>
6+
7+
<UseWPF>true</UseWPF>
88

99
<ApplicationIcon>Resources\iceberg.ico</ApplicationIcon> <!--Windows Application icon-->
1010
<!--<PackageIcon>Resources\iceberg.ico</PackageIcon> --><!--Nuget package icon-->
@@ -15,9 +15,24 @@
1515
<AssemblyName>Arius.Explorer</AssemblyName>
1616
<Title>Arius Explorer</Title>
1717
<!--<PackageId>Arius.Explorer</PackageId>-->
18-
<Product>Arius Explorer</Product>
19-
<EnableDefaultApplicationDefinition>false</EnableDefaultApplicationDefinition>
20-
</PropertyGroup>
18+
<Product>Arius Explorer</Product>
19+
<EnableDefaultApplicationDefinition>false</EnableDefaultApplicationDefinition>
20+
</PropertyGroup>
21+
22+
<!--
23+
Version information
24+
Keep the ClickOnce version aligned with the workflow run number just like Arius.Cli does.
25+
When running inside GitHub Actions we use the automatically incrementing
26+
GITHUB_RUN_NUMBER as the patch component. When building locally the variable is not
27+
defined, so we fall back to a descriptive "local" suffix to make it obvious that the
28+
build did not originate from CI.
29+
-->
30+
<PropertyGroup Condition="'$(GITHUB_RUN_NUMBER)' != ''">
31+
<Version>5.0.$(GITHUB_RUN_NUMBER)</Version>
32+
</PropertyGroup>
33+
<PropertyGroup Condition="'$(GITHUB_RUN_NUMBER)' == ''">
34+
<Version>5.0.0-local</Version>
35+
</PropertyGroup>
2136

2237
<ItemGroup>
2338
<PackageReference Include="Microsoft.Extensions.Hosting" />
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<!--
3+
https://go.microsoft.com/fwlink/?LinkID=208121.
4+
-->
5+
<Project>
6+
<PropertyGroup>
7+
<ApplicationRevision>0</ApplicationRevision>
8+
<ApplicationVersion>5.0.0.*</ApplicationVersion>
9+
<BootstrapperEnabled>True</BootstrapperEnabled>
10+
<Configuration>Release</Configuration>
11+
<CreateDesktopShortcut>True</CreateDesktopShortcut>
12+
<CreateWebPageOnPublish>True</CreateWebPageOnPublish>
13+
<GenerateManifests>true</GenerateManifests>
14+
<Install>True</Install>
15+
<InstallFrom>Web</InstallFrom>
16+
<InstallUrl>https://woutervanranst.github.io/Arius/explorer/</InstallUrl>
17+
<IsRevisionIncremented>True</IsRevisionIncremented>
18+
<IsWebBootstrapper>True</IsWebBootstrapper>
19+
<MapFileExtensions>True</MapFileExtensions>
20+
<OpenBrowserOnPublish>False</OpenBrowserOnPublish>
21+
<Platform>Any CPU</Platform>
22+
<ProductName>Arius</ProductName>
23+
<PublishDir>bin\Release\net9.0-windows\app.publish\</PublishDir>
24+
<PublishProtocol>ClickOnce</PublishProtocol>
25+
<PublishReadyToRun>False</PublishReadyToRun>
26+
<PublishSingleFile>False</PublishSingleFile>
27+
<PublishUrl>bin\publish\</PublishUrl>
28+
<PublisherName>Blue Software</PublisherName>
29+
<SelfContained>False</SelfContained>
30+
<SignManifests>False</SignManifests>
31+
<SkipPublishVerification>false</SkipPublishVerification>
32+
<SupportUrl>https://github.com/woutervanranst/Arius</SupportUrl>
33+
<TargetFramework>net9.0-windows</TargetFramework>
34+
<UpdateEnabled>True</UpdateEnabled>
35+
<UpdateMode>Foreground</UpdateMode>
36+
<UpdateRequired>False</UpdateRequired>
37+
<WebPageFileName>Publish.html</WebPageFileName>
38+
</PropertyGroup>
39+
<ItemGroup>
40+
<BootstrapperPackage Include="Microsoft.NetCore.DesktopRuntime.9.0.x64">
41+
<Install>true</Install>
42+
<ProductName>.NET Desktop Runtime 9.0 (x64)</ProductName>
43+
</BootstrapperPackage>
44+
</ItemGroup>
45+
</Project>

0 commit comments

Comments
 (0)