Skip to content

Commit c6e1861

Browse files
authored
build: distribute windows installer (#90)
1 parent 7235caf commit c6e1861

File tree

7 files changed

+128
-45
lines changed

7 files changed

+128
-45
lines changed

.github/workflows/release.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ on:
66
jobs:
77
create_release:
88
name: Create release
9+
outputs:
10+
upload_url: ${{ steps.create_release.outputs.upload_url }}
911
runs-on: ubuntu-latest
1012
steps:
1113
- name: Create release
@@ -16,6 +18,30 @@ jobs:
1618
with:
1719
release_name: ${{ github.ref }}
1820
tag_name: ${{ github.ref }}
21+
publish_windows:
22+
name: Publish Windows
23+
needs:
24+
- create_release
25+
runs-on: windows-latest
26+
steps:
27+
- name: Checkout repository
28+
uses: actions/checkout@v4
29+
- name: Publish Windows
30+
run: dotnet publish --configuration "Release" --runtime "win-${{ matrix.architecture }}" --self-contained "false" ".\src\AzureAppConfigurationEmulator\AzureAppConfigurationEmulator.csproj"
31+
- name: Create installer
32+
run: . "${env:ProgramFiles(x86)}\Inno Setup 6\iscc.exe" "/DArchitecture=${{ matrix.architecture }}" ".\setup.iss"
33+
- name: Upload release asset
34+
env:
35+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36+
uses: actions/upload-release-asset@v1
37+
with:
38+
asset_content_type: application/vnd.microsoft.portable-executable
39+
asset_name: azure-app-configuration-emulator-windows-${{ matrix.architecture }}.exe
40+
asset_path: .\Output\mysetup.exe
41+
upload_url: ${{ needs.create_release.outputs.upload_url }}
42+
strategy:
43+
matrix:
44+
architecture: [arm64, x64]
1945
push_to_registry:
2046
name: Push to registry
2147
needs:

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,12 +338,18 @@ openssl req -x509 -out ./emulator.crt -keyout ./emulator.key -newkey rsa:2048 -n
338338

339339
The port for HTTPS must be set using the environment variable [`ASPNETCORE_HTTPS_PORTS`](https://learn.microsoft.com/aspnet/core/security/enforcing-ssl#port-configuration).
340340

341+
The paths for the certificate and key must be set using the environment variables `Kestrel__Certificates__Default__Path` and `Kestrel__Certificates__Default__KeyPath` respectively.
342+
343+
The certificate and key must be [mounted](https://docs.docker.com/storage/bind-mounts) into the container at the paths that are set above.
344+
341345
```yaml
342346
services:
343347
azure-app-configuration-emulator:
344348
environment:
345349
- ASPNETCORE_HTTP_PORTS=8080
346350
- ASPNETCORE_HTTPS_PORTS=8081
351+
- Kestrel__Certificates__Default__Path=/usr/local/share/azureappconfigurationemulator/emulator.crt
352+
- Kestrel__Certificates__Default__KeyPath=/usr/local/share/azureappconfigurationemulator/emulator.key
347353
image: tnc1997/azure-app-configuration-emulator
348354
volumes:
349355
- ./emulator.crt:/usr/local/share/azureappconfigurationemulator/emulator.crt:ro

setup.iss

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#define MyAppName "Emulator for Azure App Configuration"
2+
#define MyAppVersion "1.0.0"
3+
#define MyAppPublisher "Thomas Clark"
4+
#define MyAppURL "https://azureappconfigurationemulator.thomasclark.app"
5+
#define MyAppExeName "AzureAppConfigurationEmulator.exe"
6+
7+
[Setup]
8+
AppId={{7D09D62B-09DF-4C36-8736-96FE3BEE4830}
9+
AppName={#MyAppName}
10+
AppPublisher={#MyAppPublisher}
11+
AppPublisherURL={#MyAppURL}
12+
AppSupportURL={#MyAppURL}
13+
AppUpdatesURL={#MyAppURL}
14+
AppVersion={#MyAppVersion}
15+
#if Architecture == "arm64"
16+
ArchitecturesAllowed=arm64
17+
#elif Architecture == "x64"
18+
ArchitecturesAllowed=x64
19+
#endif
20+
ArchitecturesInstallIn64BitMode=arm64 x64
21+
DefaultDirName={autopf}\{#MyAppName}
22+
LicenseFile=LICENSE
23+
PrivilegesRequiredOverridesAllowed=dialog
24+
SolidCompression=yes
25+
WizardStyle=modern
26+
27+
[Languages]
28+
Name: "english"; MessagesFile: "compiler:Default.isl"
29+
30+
[Tasks]
31+
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
32+
33+
[Files]
34+
Source: "src\AzureAppConfigurationEmulator\bin\Release\net8.0\win-{#Architecture}\publish\*"; DestDir: "{app}"; Flags: createallsubdirs ignoreversion recursesubdirs
35+
36+
[Icons]
37+
Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
38+
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
39+
40+
[Run]
41+
Filename: "{tmp}\aspnetcore-runtime.exe"; Parameters: "/install /quiet /norestart"; Check: AspNetCoreRuntimeNeedsInstall
42+
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
43+
44+
[Code]
45+
var
46+
DownloadPage: TDownloadWizardPage;
47+
function AspNetCoreRuntimeNeedsInstall: Boolean;
48+
var
49+
FileName: String;
50+
Output: AnsiString;
51+
ResultCode: Integer;
52+
begin
53+
Result := True;
54+
FileName := ExpandConstant('{tmp}\dotnet.txt');
55+
if Exec(ExpandConstant('{cmd}'), '/C dotnet --list-runtimes > "' + FileName + '" 2>&1', '', SW_HIDE, ewWaitUntilTerminated, ResultCode) and (ResultCode = 0) then
56+
if LoadStringFromFile(FileName, Output) then
57+
if Pos('Microsoft.AspNetCore.App 8.0', Output) > 0 then
58+
Result := False;
59+
end;
60+
procedure InitializeWizard;
61+
begin
62+
DownloadPage := CreateDownloadPage(SetupMessage(msgWizardPreparing), SetupMessage(msgPreparingDesc), nil);
63+
end;
64+
function NextButtonClick(CurPageID: Integer): Boolean;
65+
begin
66+
if CurPageID = wpReady then
67+
begin
68+
DownloadPage.Clear;
69+
#if Architecture == "arm64"
70+
DownloadPage.Add('https://download.visualstudio.microsoft.com/download/pr/ee1b10d3-aca1-4ae0-b74a-97bd30fa6d2d/87e7a62e9f5438342b66e673d422cd57/aspnetcore-runtime-8.0.6-win-arm64.exe', 'aspnetcore-runtime.exe', '');
71+
#elif Architecture == "x64"
72+
DownloadPage.Add('https://download.visualstudio.microsoft.com/download/pr/38b32fc8-8070-4f14-bd52-65505fddc5ff/50e6cf3b7505eee02c3b3db8ea46ffe3/aspnetcore-runtime-8.0.6-win-x64.exe', 'aspnetcore-runtime.exe', '');
73+
#endif
74+
DownloadPage.Show;
75+
try
76+
try
77+
DownloadPage.Download;
78+
Result := True;
79+
except
80+
if not DownloadPage.AbortedByUser then
81+
SuppressibleMsgBox(AddPeriod(GetExceptionMessage), mbCriticalError, MB_OK, IDOK);
82+
Result := False;
83+
end;
84+
finally
85+
DownloadPage.Hide;
86+
end;
87+
end else
88+
Result := True;
89+
end;

src/AzureAppConfigurationEmulator/Common/HostingExtensions.cs

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,9 @@
1-
using System.Security.Cryptography.X509Certificates;
21
using AzureAppConfigurationEmulator.Data;
32

43
namespace AzureAppConfigurationEmulator.Common;
54

65
public static class HostingExtensions
76
{
8-
public static string SslCertificatePath { get; } = Environment.OSVersion.Platform switch
9-
{
10-
PlatformID.Win32S => @"C:\ProgramData\Azure App Configuration Emulator\emulator.crt",
11-
PlatformID.Win32Windows => @"C:\ProgramData\Azure App Configuration Emulator\emulator.crt",
12-
PlatformID.Win32NT => @"C:\ProgramData\Azure App Configuration Emulator\emulator.crt",
13-
PlatformID.WinCE => @"C:\ProgramData\Azure App Configuration Emulator\emulator.crt",
14-
PlatformID.Unix => "/usr/local/share/azureappconfigurationemulator/emulator.crt",
15-
PlatformID.MacOSX => "/usr/local/share/azureappconfigurationemulator/emulator.crt",
16-
_ => throw new ArgumentOutOfRangeException()
17-
};
18-
19-
public static string SslCertificateKeyPath { get; } = Environment.OSVersion.Platform switch
20-
{
21-
PlatformID.Win32S => @"C:\ProgramData\Azure App Configuration Emulator\emulator.key",
22-
PlatformID.Win32Windows => @"C:\ProgramData\Azure App Configuration Emulator\emulator.key",
23-
PlatformID.Win32NT => @"C:\ProgramData\Azure App Configuration Emulator\emulator.key",
24-
PlatformID.WinCE => @"C:\ProgramData\Azure App Configuration Emulator\emulator.key",
25-
PlatformID.Unix => "/usr/local/share/azureappconfigurationemulator/emulator.key",
26-
PlatformID.MacOSX => "/usr/local/share/azureappconfigurationemulator/emulator.key",
27-
_ => throw new ArgumentOutOfRangeException()
28-
};
29-
30-
public static IWebHostBuilder ConfigureKestrel(this IWebHostBuilder builder)
31-
{
32-
return builder.ConfigureKestrel(options =>
33-
{
34-
if (File.Exists(SslCertificatePath) && File.Exists(SslCertificateKeyPath))
35-
{
36-
options.ConfigureHttpsDefaults(options =>
37-
{
38-
options.ServerCertificate = X509Certificate2.CreateFromPemFile(SslCertificatePath, SslCertificateKeyPath);
39-
});
40-
}
41-
});
42-
}
43-
447
public static void InitializeDatabase(this IApplicationBuilder app)
458
{
469
using var scope = app.ApplicationServices.GetRequiredService<IServiceScopeFactory>().CreateScope();

src/AzureAppConfigurationEmulator/Data/SqliteDbConnectionFactory.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ public class SqliteDbConnectionFactory(IConfiguration? configuration = null) : I
99

1010
private static string DatabasePath { get; } = Environment.OSVersion.Platform switch
1111
{
12-
PlatformID.Win32S => @"C:\ProgramData\Azure App Configuration Emulator\emulator.db",
13-
PlatformID.Win32Windows => @"C:\ProgramData\Azure App Configuration Emulator\emulator.db",
14-
PlatformID.Win32NT => @"C:\ProgramData\Azure App Configuration Emulator\emulator.db",
15-
PlatformID.WinCE => @"C:\ProgramData\Azure App Configuration Emulator\emulator.db",
16-
PlatformID.Unix => "/var/lib/azureappconfigurationemulator/emulator.db",
17-
PlatformID.MacOSX => "/var/lib/azureappconfigurationemulator/emulator.db",
12+
PlatformID.Win32S => Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Thomas Clark", "Emulator for Azure App Configuration", "emulator.db"),
13+
PlatformID.Win32Windows => Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Thomas Clark", "Emulator for Azure App Configuration", "emulator.db"),
14+
PlatformID.Win32NT => Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Thomas Clark", "Emulator for Azure App Configuration", "emulator.db"),
15+
PlatformID.WinCE => Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Thomas Clark", "Emulator for Azure App Configuration", "emulator.db"),
16+
PlatformID.Unix => Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "azureappconfigurationemulator", "emulator.db"),
17+
PlatformID.MacOSX => Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "azureappconfigurationemulator", "emulator.db"),
1818
_ => throw new ArgumentOutOfRangeException()
1919
};
2020

src/AzureAppConfigurationEmulator/Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ FROM build AS publish
99
RUN dotnet publish "./src/AzureAppConfigurationEmulator/AzureAppConfigurationEmulator.csproj" --configuration Release --output /app/publish
1010

1111
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS final
12+
ENV ConnectionStrings__DefaultConnection="Data Source=/var/lib/azureappconfigurationemulator/emulator.db"
1213
WORKDIR /app
1314
COPY --from=publish /app/publish .
1415
ENTRYPOINT ["dotnet", "AzureAppConfigurationEmulator.dll"]

src/AzureAppConfigurationEmulator/Program.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,6 @@
8787
builder.Services.AddSingleton<IDbParameterFactory, SqliteDbParameterFactory>();
8888
builder.Services.AddSingleton<IEventGridEventFactory, HttpContextEventGridEventFactory>();
8989

90-
builder.WebHost.ConfigureKestrel();
91-
9290
var app = builder.Build();
9391

9492
app.Map("/_explorer", app =>

0 commit comments

Comments
 (0)