From 11442d2e8e849cceb328141a643e9f8c1a2fce4f Mon Sep 17 00:00:00 2001 From: David Burg <12040431+daviburg@users.noreply.github.com> Date: Fri, 28 Aug 2026 09:49:20 -0700 Subject: [PATCH 1/2] Fix issue #181: regenerate Plumsail for enum normalization collision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The frozen 2026-08-28 ARM swagger snapshot (cache manifest SHA256 ED9C3FB8911D0F28C8D5038CE33ABEE38F7265D186249C8C66CC5C4B7B7CF2C8) shows Plumsail's Timezone enum contains both Etc/GMT+N and Etc/GMT-N for the same N. These normalize to the same C# identifier (EtcGMTN), causing the pre-fix generator to silently drop the alphabetically-later -N value. Comparison methodology: BPM worktree built twice — once from true pre-fix base d5cb672 (no reserved-name fix, no normalization-collision fix; binary SHA256 61D177482F51C722...) and once from the full-fix tip 07b2718 (binary SHA256 D22694EB1113337C...). Both ran against the same frozen 99-file cache with the 100-connector filter matching all checked-in SDK clients. Of the 97 connectors that generated at both commits (MsGraphGroupsAndUsers failed at both; ConnectorNames/ManagedConnectors skipped by filter), PlumsailExtensions.cs was the only file with a non-encoding-artifact difference. 96 connector clients are byte-identical. The eleven historically-affected connectors (Blackbaudaltruconsti, Blackbaudcrmconstitu, Dataflows, Documentscorepackapi, Dynamicssmbsaas, Etsy, Iaconnectmsoffice, Meisterplan, Powerassist, Tabscannerreceiptocr, Workpoint365) are not present in the current catalog. Changes: - PlumsailExtensions.cs: regenerated from BPM 07b2718 with frozen cache; EtcGMT2-9 and EtcGMT11 now map to +N values (sorted first); 14 new members added for previously-dropped -N values; gen SHA256 CE8A13EDEA... - GeneratedEnumMemberTests.cs: replaced tests that verified the incorrect pre-fix assignment (EtcGMT4 -> "-4") with tests that lock the correct post-fix mapping (EtcGMT4 -> "+4", EtcGMT42 -> "-4", EtcGMT62 -> "-6") - CHANGELOG.md, release_notes.md: corrected to name Plumsail as the one affected client, document the breaking-change set, true baseline d5cb672, and cache provenance; removed incorrect "zero collisions" claim Fixes: #181 Co-authored-by: Dobby --- CHANGELOG.md | 8 ++ release_notes.md | 8 ++ .../Generated/PlumsailExtensions.cs | 62 ++++++++-- .../GeneratedEnumMemberTests.cs | 117 ++++++++++++++++++ 4 files changed, 188 insertions(+), 7 deletions(-) create mode 100644 tests/Azure.Connectors.Sdk.Tests/GeneratedEnumMemberTests.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index fe68af1..6824113 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +- **Extensible enum member normalization collision now handled correctly** — the generator had two related defects. *(1) Normalization collision*: when two distinct swagger enum wire values normalize to the same C# identifier (for example, `Etc/GMT+4` and `Etc/GMT-4` both → `EtcGMT4` after stripping sign characters), the second Swagger-order claimant was silently dropped and the identifier was assigned to whichever value appeared first, irrespective of alphabetic order. *(2) Reserved name collision*: when a swagger value normalized to a mandatory struct member name (`Equals`, `GetHashCode`, `ToString`), the generator emitted a property with that name, which shadowed the required override method and produced CS0102 duplicate-definition compile errors. The hardened two-phase assignment (AzureUX-BPM commits d5cb672..07b2718, PR 16971205) pre-scans natural names in phase 1, then in phase 2 assigns in deterministic sorted order so the alphabetically-first wire value keeps the unsuffixed name (`Etc/GMT+4` → `EtcGMT4`) and each subsequent claimant receives a numeric suffix (`Etc/GMT-4` → `EtcGMT42`); reserved names are instead suffixed with `Value`. An empirical scan of all 100 checked-in connector clients against the frozen 2026-08-28 ARM swagger snapshot (cache manifest SHA256 `ED9C3FB8911D0F28C8D5038CE33ABEE38F7265D186249C8C66CC5C4B7B7CF2C8`) found one connector with active normalization collisions in the current swagger: Plumsail (Timezone enum). Plumsail is regenerated; the remaining 99 clients are unchanged. ([#181](https://github.com/Azure/Connectors-NET-SDK/issues/181)) + + The eleven connectors named in the original issue as affected by the reserved-name variant of this bug (Blackbaudaltruconsti, Blackbaudcrmconstitu, Dataflows, Documentscorepackapi, Dynamicssmbsaas, Etsy, Iaconnectmsoffice, Meisterplan, Powerassist, Tabscannerreceiptocr, Workpoint365) are no longer present in the current ARM connector catalog and their swagger is not in the frozen cache; Etsy is present in the catalog but its current swagger carries no reserved-name collision. No reserved-name collision was found in any of the 97 currently-generated connectors. + ### Breaking Changes +- **Plumsail Timezone enum: seven members now map to positive-offset wire values** — the pre-fix generator assigned the unsuffixed name (`EtcGMT2`…`EtcGMT9`, `EtcGMT11`) to whichever swagger value appeared first, which happened to be the `-N` (negative-offset) value for most entries. The fix assigns based on sorted wire value, so `+N` (lower ASCII, sorts first) now owns the clean identifier. Callers using `EtcGMT2`, `EtcGMT3`, `EtcGMT4`, `EtcGMT7`, `EtcGMT8`, `EtcGMT9`, or `EtcGMT11` should verify they are using the intended timezone direction and rename usages if necessary. The new suffixed members (`EtcGMT22`, `EtcGMT32`, `EtcGMT42`, `EtcGMT72`, `EtcGMT82`, `EtcGMT92`, `EtcGMT112`) now expose the previously silently-dropped negative-offset wire values. Additionally, `EtcGMT6`, `EtcGMT5`, `EtcGMT10`, `EtcGMT1`, `EtcGMT0`, and `Gmt0` acquire new discriminated siblings (`EtcGMT62`, `EtcGMT52`, `EtcGMT102`, `EtcGMT15`, `EtcGMT02`/`EtcGMT03`, `Gmt02`/`Gmt03`) for values that were previously dropped. ([#181](https://github.com/Azure/Connectors-NET-SDK/issues/181)) + - **Google Tasks and PDF.co operation name typos corrected** — `CraeteTaskAsync` is now `CreateTaskAsync`, and `PDFSerarchTextAsync` is now `PDFSearchTextAsync`. PDF.co callers must also rename `PDFSerarchTextInput` and the corresponding model-factory method to `PDFSearchTextInput`. Connector routes and wire payload names are unchanged.