Volunteer Management: separate-identity OS build + AppSource→OS migration script#50
Volunteer Management: separate-identity OS build + AppSource→OS migration script#50lukasdominms wants to merge 4 commits into
Conversation
…edicated key (token 703f25cc8a15a472), remap assembly/type/step GUIDs, solution uniquename->volunteermanagementos
VolunteerManagement/Deployment/Migrate-VolunteerManagementToOpenSource.ps1 (parameterized strip-references / delete-appsource-solution / verify stages, generic az-cli auth, SupportsShouldProcess) plus README. Both solutions are Microsoft-published; named by goal (migrate to open-source) and distinguished by origin (AppSource vs OS build) rather than ambiguous 'official'.
|
I noticed one metadata consistency issue from the solution rename: <data name="15062:LocalizedName,VolunteerManagement" xml:space="preserve">
<value>Volunteer Management</value>
<comment> 'VolunteerManagement' : LocalizedName for Solution</comment>
</data>Since the solution unique name/display name changed to |
| </LocalizedNames> | ||
| <Descriptions /> | ||
| <Version>1.0.3.10172</Version> | ||
| <Version>1.2.4.0</Version> |
There was a problem hiding this comment.
This version (1.2.4.0) does not appear to comply with our OneNonprofit versioning guide: https://dev.azure.com/oneCELA/OneNonprofit/_wiki/wikis/OneNonprofit.wiki/1925/Versioning. Can we update this to follow the required version format before merging?
There was a problem hiding this comment.
Good catch — 1.2.4.0 used stage 4, which isn't valid per the guide (stage is 0–3). Updated to 1.1.3.0: minor bump for the OS variant, stage 3 (GA), build 0, and higher than the AppSource package (1.0.3.10172) for version continuity. Happy to adjust major/minor if a different lineage is preferred.
There was a problem hiding this comment.
Pull request overview
This PR enables the open-source Volunteer Management solution to install side-by-side with the AppSource managed solution by separating solution/assembly identity, and adds a PowerShell migration tool to strip blocking PCF references and delete the AppSource solution during migration.
Changes:
- Renames the plugin assembly identity to PluginsOS (new strong-name key) and updates solution metadata to reference the OS identity.
- Remaps plugin type / SDK step IDs and updates solution root components accordingly.
- Adds a productized migration script and README under
VolunteerManagement/Deployment/.
Reviewed changes
Copilot reviewed 30 out of 31 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| VolunteerManagement/VolunteerManagementResources/Plugins/Plugins.csproj | Renames the plugin assembly to PluginsOS and switches signing key to PluginsOS.snk. |
| VolunteerManagement/VolunteerManagement/Solution/Other/Solution.xml | Changes solution unique name/display name/version and updates root components to OS plugin assembly + remapped step IDs. |
| VolunteerManagement/VolunteerManagement/Solution/PluginAssemblies/PluginsOS-50D34BB8-E4AA-4DF8-84EA-9D70B19DC72D/PluginsOS.dll.data.xml | Adds OS plugin assembly registration metadata (new assembly/token + plugin type IDs). |
| VolunteerManagement/VolunteerManagement/Solution/PluginAssemblies/Plugins-5D562315-37A4-EB11-B1AC-000D3A1FC0E7/Plugins.dll.data.xml | Removes legacy plugin assembly registration metadata for the AppSource identity. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{f47addb7-4a4e-4a86-8056-4e4bcbb37f19}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{e64ae12c-30cd-44eb-97e0-b57d576ab55b}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{dc676866-dead-48da-9b43-52059af2ab83}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{be4980b9-ce95-45a3-8cc7-37aa9d8eeb67}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{9b5438cb-cf96-43df-ad7f-fe771e84e3d3}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{86e747bf-c118-47b2-8dd4-cfb70d016bf7}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{867d43b7-af76-4888-bfe2-fed50d694fdf}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{85b90a27-8b53-40aa-a130-f2d0d5b91c9e}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{8271517a-25f9-4cf2-a006-20e7248dc767}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{81f97b73-9836-4d95-91b6-6e6736f581b1}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{7fec674a-f06a-4fef-89c0-9a7f814e5e86}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{7a061612-6940-4b13-8706-3d0fb99e2c30}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{78d39fed-f4da-46fe-86f3-82ef5193777a}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{719cbec5-f3dd-4b86-80ac-3080893f7bd2}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{671dd33c-2ae1-434c-8652-40a96ea4a6d2}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{6664dd0c-4ca7-4045-bc59-7614a4af751e}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{659e5220-eae9-430a-b1a0-75f423107a4a}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{5751b036-57ec-4d93-b297-2004a77c8ae7}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{442d349d-61bc-4265-a52e-cf2222d69ef0}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{39ef623b-a978-4e2a-a5cf-9df6268c4cce}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{2c7c7185-3d66-41d3-89fb-c8c635046dae}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{2a00b8be-03e1-46db-a352-b49f1c379753}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{252d5074-6f45-4861-a269-ee1ea14ac398}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{055e9f02-c8e4-4834-86e5-d5912bd34619}.xml | Updates step ID and retargets step to PluginsOS / new plugin type ID. |
| VolunteerManagement/Deployment/Migrate-VolunteerManagementToOpenSource.ps1 | Adds the staged migration script (strip references / delete AppSource / verify). |
| VolunteerManagement/Deployment/README.md | Adds migration flow documentation and usage guidance for the new script. |
Comments suppressed due to low confidence (4)
VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{f47addb7-4a4e-4a86-8056-4e4bcbb37f19}.xml:2
- Typo in the SDK step display name: "Opportuntiy" → "Opportunity". Since this line is being rewritten in this PR anyway, it’s a good opportunity to correct the spelling for readability in the Dataverse registration UI.
VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{e64ae12c-30cd-44eb-97e0-b57d576ab55b}.xml:2 - Typo in the SDK step display name: "Opportuntiy" → "Opportunity". Keeping these display names clean helps when troubleshooting step registrations in the plugin registration UI.
VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{7a061612-6940-4b13-8706-3d0fb99e2c30}.xml:2 - Typo in the SDK step display name: "Opportuntiy" → "Opportunity".
VolunteerManagement/VolunteerManagement/Solution/SdkMessageProcessingSteps/{055e9f02-c8e4-4834-86e5-d5912bd34619}.xml:2 - Typo in the SDK step display name: "Opportuntiy" → "Opportunity".
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| function Invoke-StripReferences { | ||
| Write-Host '=== Stripping AppSource PCF references from system forms ===' -ForegroundColor Cyan | ||
| $forms = (Invoke-RestMethod -Uri "$base/systemforms?`$select=formid,name,objecttypecode,formxml" -Headers $headers).value |
There was a problem hiding this comment.
Fixed — added a Get-AllPages helper that follows @odata.nextLink, so the system forms query now reads every page.
| Write-Host "Patched forms: $patchedForms" | ||
|
|
||
| Write-Host '=== Stripping AppSource PCF references from saved queries (views) ===' -ForegroundColor Cyan | ||
| $views = (Invoke-RestMethod -Uri "$base/savedqueries?`$select=savedqueryid,name,returnedtypecode,layoutxml" -Headers $headers).value |
There was a problem hiding this comment.
Fixed — the saved queries query now pages through @odata.nextLink via the same Get-AllPages helper.
| ```powershell | ||
| pac solution import --path .\VolunteerManagement\bin\Release\VolunteerManagement_managed.zip | ||
| ``` | ||
|
|
||
| (Build it first with `dotnet build VolunteerManagement\VolunteerManagement.cdsproj -c Release`.) |
There was a problem hiding this comment.
Fixed — paths are now repo-root-relative and I added a note that all commands run from the repository root.
- Solution version 1.2.4.0 -> 1.1.3.0 (versioning guide: stage must be 0-3 GA=3; higher than AppSource 1.0.3.10172) - Migration script: page through @odata.nextLink for systemforms and savedqueries (Get-AllPages helper) so large environments don't miss references - README: repo-root-relative paths and explicit working-directory note
Summary
Enables the open-source (OS) Volunteer Management build to be deployed side-by-side with the AppSource managed solution under a separate identity, and adds a productized script to migrate an environment from the AppSource solution to the OS build.
Both solutions are published by Microsoft; they are distinguished by origin — the AppSource managed solution (installed from the marketplace) vs. the OS build (compiled from this repository).
Why
The OS build previously shared its identity (solution unique name, plugin assembly strong-name) with the AppSource solution, so the two could not coexist. To support a controlled migration, the OS build now ships under its own identity. This lets it install alongside the AppSource solution, after which the AppSource solution can be removed.
Removing the AppSource solution is blocked by a hard dependency: the forms and views it contributes reference its PCF controls in the active (merged) layer. That
Form → ControlPublished dependency lives in the active layer independent of solution ownership, so it prevents deletion. Re-assigning component ownership to the OS solution does not clear it (verified empirically). The dependency must be removed by rewriting the active form/view layers.Changes
Plugins→PluginsOS, with a dedicated stable signing key (PluginsOS.snk, token703f25cc8a15a472) and a new assembly GUID.VolunteerManagement→volunteermanagementos(display name "Volunteer Management (OS)").1.2.4.0.VolunteerManagement/Deployment/Migrate-VolunteerManagementToOpenSource.ps1— parameterized, opt-in stages:-StripReferences— rewrites forms + saved queries to substitute the default control for the AppSource PCF controls, thenPublishAllXml(clears the blocking dependency).-DeleteAppSourceSolution— deletes the AppSource managed solution by unique name.-Verify— reports plugin assemblies, PCF control ownership, and SDK step registration.az account get-access-tokenby default;-AccessToken/-AzCommandoverrides). Destructive stages support-WhatIf/-Confirm(ConfirmImpact = High).README.mddocumenting the full side-by-side migration flow.How to use
dotnet build VolunteerManagement/VolunteerManagement/VolunteerManagement.cdsproj -c Releasepac solution import --path .../VolunteerManagement_managed.zip.\Migrate-VolunteerManagementToOpenSource.ps1 -EnvironmentUrl <url> -StripReferences.\Migrate-VolunteerManagementToOpenSource.ps1 -EnvironmentUrl <url> -DeleteAppSourceSolution.\Migrate-VolunteerManagementToOpenSource.ps1 -EnvironmentUrl <url> -VerifyTesting
Notes