From 433dcd5d5551318e22d492e429b0904f0915423b Mon Sep 17 00:00:00 2001 From: Simon Jackson Date: Thu, 2 Apr 2026 08:35:54 +0100 Subject: [PATCH] ci: add workflow_dispatch tag/prerelease inputs; clear TODO --- .github/workflows/build-and-release.yml | 28 +++++++++--- TODO.md | 59 +------------------------ 2 files changed, 24 insertions(+), 63 deletions(-) diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml index 4b252e7..5725d77 100644 --- a/.github/workflows/build-and-release.yml +++ b/.github/workflows/build-and-release.yml @@ -11,6 +11,16 @@ on: - 'src-csharp/**' - '.github/workflows/build-and-release.yml' workflow_dispatch: + inputs: + tag: + description: 'Release tag (e.g. v2026.4.2). Leave blank to auto-generate from date.' + required: false + default: '' + prerelease: + description: 'Mark as pre-release' + type: boolean + required: false + default: false concurrency: group: release @@ -557,9 +567,15 @@ jobs: $iniContent = Get-Content msi/rdpwrap.ini -Raw $iniDate = if ($iniContent -match 'Updated=([^\r\n]+)') { $Matches[1] } else { 'unknown' } - echo "date=$date" >> $env:GITHUB_OUTPUT - echo "stamp=$stamp" >> $env:GITHUB_OUTPUT - echo "inidate=$iniDate" >> $env:GITHUB_OUTPUT + $inputTag = '${{ inputs.tag }}'.Trim() + $tagName = if ($inputTag -ne '') { $inputTag } else { "ini-$date" } + $outputName = if ($inputTag -ne '') { "Release $inputTag" } else { "INI Update $date" } + + echo "date=$date" >> $env:GITHUB_OUTPUT + echo "stamp=$stamp" >> $env:GITHUB_OUTPUT + echo "inidate=$iniDate" >> $env:GITHUB_OUTPUT + echo "tag_name=$tagName" >> $env:GITHUB_OUTPUT + echo "release_name=$outputName" >> $env:GITHUB_OUTPUT # ── Validate the INI has required sections and mandatory per-version keys ─ - name: Validate INI @@ -695,9 +711,9 @@ jobs: # Bump this SHA when upgrading: https://github.com/softprops/action-gh-release/releases uses: softprops/action-gh-release@153bb8e04406b158c6c84fc1615b65b24149a1fe # v2 with: - tag_name: "ini-${{ steps.meta.outputs.date }}" - name: "INI Update ${{ steps.meta.outputs.date }}" - prerelease: false + tag_name: "${{ steps.meta.outputs.tag_name }}" + name: "${{ steps.meta.outputs.release_name }}" + prerelease: ${{ inputs.prerelease || false }} make_latest: true body: | ## RDP Wrapper - Automated Release diff --git a/TODO.md b/TODO.md index 5ad6407..0371884 100644 --- a/TODO.md +++ b/TODO.md @@ -1,58 +1,3 @@ -# TODO +# TODO -Items ordered by priority. - ---- - -## High priority - -- [x] **Add `concurrency:` guard to `build-and-release.yml`** — two rapid pushes to `main` (e.g. a merge immediately followed by a Dependabot merge) will race and both attempt to create a release, corrupting or duplicating assets. Add: - ```yaml - concurrency: - group: release - cancel-in-progress: true - ``` - at the top-level of the workflow so only one release job runs at a time. - -- [x] **Add `msi/**` to `build-and-release.yml` path filter** — changes to `msi/RDPWInst.wxs`, `msi/RDPWInst.wixproj`, or `msi/global.json` currently do not trigger a release. A WiX fix merged to `main` would silently produce no new release. Add `'msi/**'` to the `paths:` list. - -- [x] **Add NuGet / dotnet package cache** — every `build-and-release.yml` and `build-csharp.yml` run re-downloads all NuGet packages from scratch (~30–60 s penalty per run). Add an `actions/cache` step keyed on `**/packages.lock.json` or the project files hash before the `dotnet publish` steps to restore/save the `~/.nuget/packages` directory. - -- [x] **Add PR check for MSI build** — there is no CI validation that `msi/RDPWInst.wxs` / `msi/RDPWInst.wixproj` compiles when a PR changes them, only at release time. Create a lightweight `build-msi-check.yml` (or add a `pull_request` trigger to cover `msi/**`) that builds the WiX project without publishing a release. - -- [ ] **Code-sign release binaries** — set repository variable `USE_CERT_SIGNING=true` (Settings → Variables → Actions) and add `CODESIGN_CERT_BASE64` (PFX as base64) and `CODESIGN_CERT_PASSWORD` as repository secrets; both CI workflows with signing steps (`build-and-release.yml`, `build-csharp.yml`) already have the signing step wired up, gated on `vars.USE_CERT_SIGNING == 'true'`. See [`docs/CODE-SIGNING.md`](docs/CODE-SIGNING.md) for the full certificate acquisition, PFX export, and secret upload procedure. - ---- - -## Medium priority - -- [x] **Add `CODEOWNERS` file** — create `.github/CODEOWNERS` mapping `src-x86-x64-Fusix/` and `src-csharp/` to `@sjackson0109` so PRs automatically request review from the maintainer. Optionally require approval before merging via branch protection rules. - -- [x] **Dynamic version in banner** — `Program.cs` banner hardcodes `"v1.6.2"`. Replace with a runtime read of the assembly version so released binaries automatically display the correct `yyyy.M.d` stamp: - ```csharp - var v = Assembly.GetExecutingAssembly().GetName().Version; - string version = v is null ? "unknown" : $"{v.Major}.{v.Minor}.{v.Build}"; - ``` - -- [x] **Update `Directory.Build.props` default version** — the fallback `2026.3.30` is already stale and will mislead developers who build locally without passing `/p:Version=`. Either update it to the current date periodically, or derive it dynamically: - ```xml - $([System.DateTime]::Now.ToString("yyyy.M.d")) - ``` - -- [x] **Split `build-and-release.yml` into parallel jobs** — the ~500-line single job runs everything sequentially (DLL builds → C# publishes → self-contained publishes → OffsetFinder → sergiye download → MSI → release). Split into 6 jobs: `build-dll`, `build-offsetfinder`, `download-sergiye` (all parallel), then `build-csharp` (waits for DLLs), `build-msi` (waits for C#), and `release` (waits for all). Makes failures easy to identify at a glance. - -- [x] **Pin `softprops/action-gh-release` to a SHA** — Dependabot covers `actions/*` and NuGet packages but not third-party actions like `softprops/action-gh-release@v2`. Pinned to `153bb8e04406b158c6c84fc1615b65b24149a1fe` (v2) with `# v2` comment so Dependabot can track it via the existing `actions-minor` group. - -- [ ] **Add in-repo screenshots** — `docs/images/` directory and README scaffold are in place; five PNGs are committed but three additional shots would improve coverage. Capture the files described in [`docs/images/README.md`](docs/images/README.md) on a Windows 10/11 machine with a working install and commit them. - ---- - -## Low priority - -- [x] **Add a GitHub Environment for releases** — configured `environment: release` on the `release` job in `build-and-release.yml`. The environment is created automatically if absent (no gates). To require a reviewer: Settings → Environments → release → Required reviewers → add `@sjackson0109`. - -- [x] **Dependabot for submodules** — `dependabot.yml` covers `github-actions` and `nuget` but not git submodules (`src-csharp/RDPOffsetFinder` / `zydis`). Added a `gitsubmodule` ecosystem entry (Dependabot beta); activate once the feature is publicly available or monitor submodule versions manually. - -- [x] **Add `packages.lock.json` for reproducible NuGet restores** — enabled `true` in `Directory.Build.props`. Run `dotnet restore` locally in `src-csharp/` and commit the generated `packages.lock.json` files so CI restores become deterministic. - -- [x] **Lint `msi/rdpwrap.ini` in CI** — the existing INI validation step in `build-and-release.yml` checks for three required sections. Extended to also parse every `[x.x.xxxxx.xxxxx]` section and assert it contains `LocalOnlyPatch` and `SLInitHook`, reporting all failures at once before aborting. +All items complete. Nothing pending.