Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions .github/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
<li><a href="#requirements">Requirements</a></li>
<li><a href="#build-and-run">Build and run</a></li>
<li><a href="#test">Test</a></li>
<li><a href="#install-a-release">Install a release</a></li>
<li><a href="#release">Release</a></li>
</ul>
</li>
Expand Down Expand Up @@ -115,16 +116,29 @@ To run only the unit tests:
Get-ChildItem tests -Recurse -Filter *.UnitTests.csproj | ForEach-Object { dotnet test $_.FullName -c Release }
```

### Install a release

Each [release](https://github.com/buning-software/kontext/releases) has a signed MSIX and `Kontext.cer`, the certificate it is signed with. Windows only installs the package once you trust that certificate.

1. Trust the certificate once, from an elevated PowerShell:

```powershell
Import-Certificate -FilePath .\Kontext.cer -CertStoreLocation Cert:\LocalMachine\TrustedPeople
```

2. Open the `.msix` and choose **Install**.

Kontext still keeps its data under `%LOCALAPPDATA%\Kontext`: the package turns off file redirection so your clones and worktrees stay visible to Explorer, terminals and IDEs.

### Release

Publishing a GitHub release tagged like `v1.2.3` runs the tests, then builds a signed, self-contained x64 MSIX and attaches it to the release together with `Kontext.cer`, the public certificate. The tag sets the package version. The workflow imports the certificate into the runner's certificate store and signs by thumbprint, which avoids the APPX0105 and APPX0107 warnings that come from pointing MSBuild at the `.pfx`. The signature is timestamped (DigiCert), so the package keeps verifying after the certificate expires. ARM64 is not built because the embedded terminal control only ships x64 binaries.

One-time setup:

* Signing uses the `CERTIFICATE_BASE64` (the `.pfx`, base64 encoded) and `CERTIFICATE_PASSWORD` secrets. They are organization secrets of `buning-software`, shared with the other Buning Software apps, and this repository has to be allowed to use them (organization Settings, Secrets and variables, Actions). The certificate subject must equal `Publisher` in `src/Kontext/Package.appxmanifest` (`CN=BuningSoftware`). To create a new certificate, for example when it expires, use `generate_certificate.ps1` in the [Surveil repository](https://github.com/buning-software/surveil), update both organization secrets, and never commit the `.pfx`.
* Signing uses the `CERTIFICATE_BASE64` (the `.pfx`, base64 encoded) and `CERTIFICATE_PASSWORD` secrets. They are organization secrets of `buning-software`, and this repository has to be allowed to use them (organization Settings, Secrets and variables, Actions). The certificate subject must equal `Publisher` in `src/Kontext/Package.appxmanifest` (`CN=BuningSoftware`). To create a new certificate, for example when it expires, generate a self-signed code-signing certificate with that subject, update both organization secrets, and never commit the `.pfx`.
* Set the repository variable `KONTEXT_GITHUB_CLIENT_ID`. An installed MSIX is read-only, so the client id has to be built in; the release fails without it.

To install a release, first trust `Kontext.cer` once (open it, choose Install Certificate, Local Machine, Trusted People), then open the `.msix`. Kontext still keeps its data under `%LOCALAPPDATA%\Kontext`: the package turns off file redirection so your clones and worktrees stay visible to Explorer, terminals and IDEs.

<!-- CONTRIBUTING -->
## Contributing
Expand Down
3 changes: 1 addition & 2 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
<PackageVersion Include="NUnit.Analyzers" Version="4.15.0" />
<PackageVersion Include="NUnit3TestAdapter" Version="6.3.1" />
<PackageVersion Include="Octokit" Version="14.0.0" />
<PackageVersion Include="WinUia" Version="0.2.0" />
<PackageVersion Include="WinUia.NUnit" Version="0.2.0" />
<PackageVersion Include="WinUia" Version="0.3.0" />
</ItemGroup>
</Project>
3 changes: 0 additions & 3 deletions tests/Kontext.UiTests/Kontext.UiTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
<ItemGroup>
<!-- Lets the tests find the exe they drive; KONTEXT_EXE overrides it. -->
<AssemblyMetadata Include="KontextBinDirectory" Value="$(KontextBinDirectory)" />
<!-- Every test is a UI test: serialised on the desktop and tagged Category=UI. -->
<AssemblyAttribute Include="WinUia.NUnit.UiTestAttribute" />
<!-- UI Automation requires MTA. -->
<AssemblyAttribute Include="NUnit.Framework.ApartmentAttribute">
<_Parameter1>System.Threading.ApartmentState.MTA</_Parameter1>
Expand All @@ -39,7 +37,6 @@
</PackageReference>
<PackageReference Include="NUnit3TestAdapter" />
<PackageReference Include="WinUia" />
<PackageReference Include="WinUia.NUnit" />
</ItemGroup>

<ItemGroup>
Expand Down
4 changes: 4 additions & 0 deletions tests/Kontext.UiTests/Tests/KontextFixture.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Kontext.UiTests.Application;
using WinUia;

namespace Kontext.UiTests.Tests;

Expand All @@ -24,4 +25,7 @@ public void CloseApp()
App.Dispose();
Data.Dispose();
}

protected static void Eventually(Func<bool> condition, string because = "", TimeSpan? timeout = null) =>
Assert.That(Poll.Until(condition, timeout), Is.True, because);
}