Skip to content

Commit 5e89ba9

Browse files
authored
Merge pull request #5563 from tui-cs/release/v2.4.16
Release v2.4.16
2 parents 7f04ed8 + de95971 commit 5e89ba9

12 files changed

Lines changed: 704 additions & 240 deletions

File tree

.github/workflows/README.md

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -48,33 +48,17 @@ The repository uses multiple GitHub Actions workflows. What runs and when:
4848
3. Runs IntegrationTests with diagnostic output
4949
4. Uploads logs per-OS
5050

51-
### 4) Create Release (`.github/workflows/release.yml`)
52-
53-
- **Triggers**: `workflow_dispatch` (manual trigger from GitHub Actions UI)
54-
- **Inputs**:
55-
- `release_type`: Choose from `beta`, `rc`, or `stable`
56-
- `version_override`: (Optional) Specify exact version number, otherwise GitVersion calculates it
57-
- **Process**:
58-
1. Checks out `main` branch
59-
2. Determines version using GitVersion or override
60-
3. Creates annotated git tag (e.g., `v2.0.1-rc.1` or `v2.1.0`)
61-
4. Creates release commit with message
62-
5. Pushes tag and commit to repository
63-
6. Creates GitHub Release (marked as pre-release if not stable)
64-
7. Automatically triggers publish workflow (see below)
65-
- **Purpose**: Automates the release process to prevent manual errors
66-
67-
### 5) Publish to NuGet (`.github/workflows/publish.yml`)
51+
### 4) Publish to NuGet (`.github/workflows/publish.yml`)
6852

6953
- **Triggers**: push to `develop` and tags `v*` (ignores `**.md`)
7054
- Uses GitVersion to compute SemVer, builds Release, packs Terminal.Gui and Terminal.Gui.Interop.Spectre with symbols, and pushes both to NuGet.org using `NUGET_API_KEY`
71-
- **Automatically triggered** by the Create Release workflow when a new tag is pushed
55+
- **Automatically triggered** when a `v*` tag is pushed — typically by the **Finalize Release** workflow after a release PR (from **Prepare Release**) is merged into `main`
7256
- **Additional actions on tag push** (`v*`):
7357
- Triggers Terminal.Gui.templates repository update via repository_dispatch (requires `TEMPLATE_REPO_TOKEN` secret)
7458

75-
### 6) Build and publish API docs (`.github/workflows/api-docs.yml`)
59+
### 5) Build and publish API docs (`.github/workflows/api-docs.yml`)
7660

77-
- **Triggers**: push to `main`
61+
- **Triggers**: push to `develop`, and `workflow_dispatch`
7862
- Builds DocFX site on Windows and deploys to GitHub Pages
7963

8064

.github/workflows/release.yml

Lines changed: 0 additions & 144 deletions
This file was deleted.

CONTRIBUTING.md

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -336,23 +336,21 @@ foreach (Rune rune in text.EnumerateRunes ())
336336

337337
### Automated Release Workflow
338338

339-
Releases are now automated using GitHub Actions to prevent manual errors. To create a release:
339+
Releases are automated using GitHub Actions to prevent manual errors. The flow is PR-based: **Prepare Release** opens a release PR from `develop``main`, and merging it runs **Finalize Release**. To create a release:
340340

341341
1. **Navigate to Actions tab** in the GitHub repository
342-
2. **Select "Create Release" workflow** from the left sidebar
342+
2. **Select "Prepare Release" workflow** from the left sidebar
343343
3. **Click "Run workflow"** button
344344
4. **Configure release parameters:**
345-
- **Branch:** Ensure `main` is selected
346-
- **Release type:** Choose from `prealpha`, `alpha`, `beta`, `rc`, or `stable`
345+
- **Release type:** Choose from `beta`, `rc`, or `stable`
347346
- **Version override:** (Optional) Specify exact version (e.g., `2.0.0`), otherwise GitVersion calculates it automatically
348-
5. **Click "Run workflow"** to start the automated release process
349-
350-
The workflow will:
351-
- Create an annotated git tag (e.g., `v2.0.0-prealpha` or `v2.0.0`)
352-
- Create a release commit on `main`
353-
- Push the tag and commit to the repository
354-
- Create a GitHub Release
355-
- Automatically trigger the publish workflow to push the package to NuGet.org
347+
5. **Click "Run workflow"** to create the release PR
348+
349+
Prepare Release creates a `release/<tag>` branch — where `<tag>` is the full version tag, e.g. `release/v2.0.0` for a stable release or `release/v2.0.0-beta.1` for a pre-release — with the GitVersion label updated for the release type, and opens a PR into `main`. After CI passes, **review and merge that PR**. Merging triggers **Finalize Release**, which:
350+
- Creates an annotated git tag (e.g., `v2.0.0-beta.1` or `v2.0.0`)
351+
- Creates a GitHub Release with auto-generated notes
352+
- Opens a back-merge PR from `main``develop`
353+
- Triggers the publish workflow (via the `v*` tag) to push the package to NuGet.org
356354

357355
## What NOT to Do
358356

GitVersion.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ branches:
3434
# Matches the main branch
3535
regex: ^main$
3636
# Uses an empty label for stable releases
37-
label: beta
37+
label: ''
3838
# Increments patch version (x.y.z+1) on commits
3939
increment: Patch
4040
# Specifies develop as the source branch

Terminal.Gui/Configuration/Settings/TuiConfigurationBuilder.cs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System.ComponentModel;
21
using System.Diagnostics.CodeAnalysis;
32
using System.Reflection;
43
using Microsoft.Extensions.Configuration;
@@ -168,7 +167,7 @@ public void ApplyToStaticFacades ()
168167

169168
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "Settings POCOs are simple types preserved by DynamicDependency in ConfigPropertyHostTypes.")]
170169
[UnconditionalSuppressMessage ("AOT", "IL3050", Justification = "Settings POCOs are simple types; no generic instantiation needed at runtime.")]
171-
private static void BindSection<T> (IConfiguration config, string sectionName, Action<T> apply) where T : new ()
170+
private static void BindSection<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] T> (IConfiguration config, string sectionName, Action<T> apply) where T : new ()
172171
{
173172
T settings = new ();
174173
IConfigurationSection section = config.GetSection (sectionName);
@@ -206,10 +205,10 @@ private static void BindThemeScalar (IConfiguration config)
206205

207206
/// <summary>
208207
/// Binds flat dotted keys (e.g. <c>Driver.Force16Colors</c>) from the configuration root to the
209-
/// corresponding properties on the settings POCO.
208+
/// corresponding properties on the settings POCO. <typeparamref name="T"/>'s public properties are
209+
/// preserved for trimming via the <see cref="DynamicallyAccessedMembersAttribute"/> on the type parameter.
210210
/// </summary>
211-
[UnconditionalSuppressMessage ("Trimming", "IL2026", Justification = "Settings POCOs are simple types preserved by DynamicDependency in ConfigPropertyHostTypes.")]
212-
private static void BindFlatDottedKeys<T> (IConfiguration config, string sectionName, T settings)
211+
private static void BindFlatDottedKeys<[DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicProperties)] T> (IConfiguration config, string sectionName, T settings)
213212
{
214213
string prefix = sectionName + ".";
215214

@@ -244,8 +243,12 @@ private static void BindFlatDottedKeys<T> (IConfiguration config, string section
244243
}
245244

246245
/// <summary>
247-
/// Converts a configuration string value to the target property type, using a fast path for the
248-
/// common scalar types and falling back to a <see cref="TypeConverter"/>.
246+
/// Converts a configuration string value to the target property type. Only the scalar types used by the
247+
/// settings POCOs are supported, so this path is trim/AOT-safe — it deliberately avoids
248+
/// <c>TypeDescriptor.GetConverter</c> (which is <see cref="RequiresUnreferencedCodeAttribute"/> /
249+
/// <see cref="RequiresDynamicCodeAttribute"/> and breaks NativeAOT/trimmed consumers). New non-scalar
250+
/// settings property types must be added here explicitly. Unsupported types return <see langword="null"/>
251+
/// and are skipped by <see cref="BindFlatDottedKeys{T}"/>.
249252
/// </summary>
250253
private static object? ConvertValue (string value, Type targetType)
251254
{
@@ -269,16 +272,14 @@ private static void BindFlatDottedKeys<T> (IConfiguration config, string section
269272
return value.Length > 0 ? new Rune (value [0]) : new Rune ('+');
270273
}
271274

272-
if (targetType.IsEnum)
275+
if (targetType == typeof (Key))
273276
{
274-
return Enum.Parse (targetType, value);
277+
return Key.TryParse (value, out Key key) ? key : null;
275278
}
276279

277-
TypeConverter converter = TypeDescriptor.GetConverter (targetType);
278-
279-
if (converter.CanConvertFrom (typeof (string)))
280+
if (targetType.IsEnum)
280281
{
281-
return converter.ConvertFromInvariantString (value);
282+
return Enum.Parse (targetType, value);
282283
}
283284

284285
return null;

Terminal.Gui/README.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Two workflows handle the release lifecycle:
5151
**Step 1 — [Prepare Release](../.github/workflows/prepare-release.yml)** (manual trigger):
5252
1. Go to **Actions → Prepare Release → Run workflow**.
5353
2. Pick the release type (`beta`, `rc`, `stable`) and optionally override the version.
54-
3. The workflow creates a `release/vX.Y.Z` branch from `develop`, updates the `GitVersion.yml` label, and opens a PR into `main`.
54+
3. The workflow creates a `release/<tag>` branch from `develop` — where `<tag>` is the full version tag, e.g. `release/v2.0.0` or `release/v2.0.0-beta.1` updates the `GitVersion.yml` label, and opens a PR into `main`.
5555
4. Review the PR — CI runs, branch protections apply.
5656

5757
**Step 2 — [Finalize Release](../.github/workflows/finalize-release.yml)** (automatic on PR merge):
@@ -110,8 +110,7 @@ All workflows are in [`.github/workflows/`](../.github/workflows/):
110110
|----------|---------|---------|
111111
| **[prepare-release.yml](../.github/workflows/prepare-release.yml)** | Manual dispatch | Creates a release PR from `develop``main` with label updates |
112112
| **[finalize-release.yml](../.github/workflows/finalize-release.yml)** | Release PR merged to `main` | Creates tag, GitHub Release, back-merge PR to `develop` |
113-
| **[publish.yml](../.github/workflows/publish.yml)** | Push to `main` or `develop`, version tags | Builds Release config, packs, and publishes to NuGet.org |
114-
| **[release.yml](../.github/workflows/release.yml)** | Manual dispatch | **(Legacy)** Direct tag-and-release on `main`; superseded by prepare/finalize |
113+
| **[publish.yml](../.github/workflows/publish.yml)** | Push to `develop`, or `v*` tags | Builds Release config, packs, and publishes to NuGet.org |
115114
| **[build-validation.yml](../.github/workflows/build-validation.yml)** | Push/PR to `main` or `develop` | Builds all configurations to validate compilation |
116115
| **[unit-tests.yml](../.github/workflows/unit-tests.yml)** | Push/PR to `main` or `develop` | Runs all unit tests |
117116
| **[api-docs.yml](../.github/workflows/api-docs.yml)** | Push to `develop` | Builds and deploys API docs to GitHub Pages |
@@ -135,7 +134,7 @@ These branches are **not** configured in `GitVersion.yml` (the config was remove
135134
## NuGet Package
136135

137136
- **Package**: [nuget.org/packages/Terminal.Gui](https://www.nuget.org/packages/Terminal.Gui)
138-
- **Auto-published** on every push to `main` or `develop` (pre-release versions from `develop`, stable versions from `main`)
137+
- **Auto-published** on every push to `develop` (pre-release versions) and on `v*` tag pushes (stable/pre-release versions tagged on `main`)
139138
- Pre-release versions (e.g., `2.1.0-develop.42`) are marked as pre-release on NuGet
140139

141140
### Local Package Development
@@ -154,7 +153,7 @@ dotnet build Terminal.Gui/Terminal.Gui.csproj -c Release
154153

155154
- **Live docs**: [tui-cs.github.io/Terminal.Gui](https://tui-cs.github.io/Terminal.Gui)
156155
- **DocFX source**: [`docfx/`](../docfx/) — see [`docfx/README.md`](../docfx/README.md) for local generation
157-
- **API docs** are auto-deployed to GitHub Pages on every push to `main`
156+
- **API docs** are auto-deployed to GitHub Pages on every push to `develop`
158157

159158
## Contributing
160159

0 commit comments

Comments
 (0)