Skip to content

[ci] Add signing to the internal pipeline#12158

Open
jonathanpeppers wants to merge 14 commits into
mainfrom
jonathanpeppers-internal-pipeline-signing
Open

[ci] Add signing to the internal pipeline#12158
jonathanpeppers wants to merge 14 commits into
mainfrom
jonathanpeppers-internal-pipeline-signing

Conversation

@jonathanpeppers

Copy link
Copy Markdown
Member

Summary

Adds an in-repo Arcade signing flow to azure-pipelines-internal.yaml without using Xamarin.yaml-templates, which is inaccessible from dnceng-internal and is being phased out.

The new Prepare .NET Release stage:

  • downloads and normalizes the unsigned Windows, macOS, and Linux packages
  • applies the existing SignList.xml certificate mappings through Arcade
  • signs the original NuGet packages and generated workload MSIs
  • packages the signed MSIs into NuGets
  • generates Visual Studio component and pack insertion artifacts after MSI signing
  • signs the generated MSI NuGets and verifies the final outputs
  • always publishes signing binlogs for diagnostics

Real signing is limited to non-PR release/* builds. Other manually queued builds use test signing. PR and scheduled builds skip the stage.

DevDiv comparison

Compared the successful internal outputs from build 3024411 with DevDiv build 14688220:

  • all 63 NuGet packages validate with the same VS Bld Lab test-signing certificate
  • the 18 base package IDs match exactly
  • the 45 generated MSI NuGet package IDs match exactly
  • all 45 embedded MSIs validate with the same test-signing certificate
  • package payload layouts match, aside from expected generated metadata names and content-derived MSI filenames
  • the same three VS insertion archives are produced with matching entry counts

The artifact organization intentionally differs. DevDiv separates Linux and macOS/Windows signed packages, converted package artifacts, and VS blobs into multiple drops. The internal pipeline publishes these retained outputs together in nuget-signed. Nothing currently consumes those internal artifact names, and this change does not publish to Darc/Maestro.

Validation

The Prepare .NET Release stage, including package validation and MicroBuildCodesignVerify, succeeded in internal build 3024411.

jonathanpeppers and others added 13 commits July 15, 2026 11:26
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 866271dd-9544-4263-912e-5cfe20e73dbc
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 866271dd-9544-4263-912e-5cfe20e73dbc
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 866271dd-9544-4263-912e-5cfe20e73dbc
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 866271dd-9544-4263-912e-5cfe20e73dbc
Use the exact tracked .NET SDK for the Arcade toolset and publish a distinct binary log for each signing invocation, including failed jobs.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 866271dd-9544-4263-912e-5cfe20e73dbc
Use eng/install-dotnet.ps1 so the signing job gets the exact Microsoft.NET.Sdk version from eng/Versions.props, including internal preview builds from ci.dot.net. Create the diagnostics directory before SDK installation so failed setup is still archivable.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 866271dd-9544-4263-912e-5cfe20e73dbc
Generate the signing build ID as YYYYMMDD.Revision so Arcade version calculations receive numeric date components instead of the branch-based Azure build number.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 866271dd-9544-4263-912e-5cfe20e73dbc
Restore the pipeline's standard .NET SDK selection now that the binlog identified the malformed OfficialBuildId as the root cause. Keep signing binlog publication for diagnostics.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 866271dd-9544-4263-912e-5cfe20e73dbc
Preserve wildcard rules as literal MSBuild items and convert legacy macOS package paths to Arcade's filename-based signing mappings.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 866271dd-9544-4263-912e-5cfe20e73dbc
Prevent WiX source paths from being resolved relative to their own intermediate directory, which duplicated obj/Release and hid generated eula and icon files.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 866271dd-9544-4263-912e-5cfe20e73dbc
Generated MSI package projects inherit PackageOutputPath from the parent
Workloads project. Override it alongside OutputPath so packaged MSIs are
available to signing validation and publication.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 866271dd-9544-4263-912e-5cfe20e73dbc
Persist the generated MSI and Swix project metadata so Arcade's
AfterSigning phase can package the signed MSI payloads and create insertion
artifacts. Run a final signing pass for the resulting MSI NuGet packages.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 866271dd-9544-4263-912e-5cfe20e73dbc
The workload project item list is not shared with Arcade Sign.proj. Add the
raw MSI outputs directly to Signing.props during the workload build pass so
insertion manifests contain signed installers.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 866271dd-9544-4263-912e-5cfe20e73dbc
Copilot AI review requested due to automatic review settings July 17, 2026 13:28

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an in-repo Arcade-based signing flow to the internal Azure DevOps pipeline, introducing a new Prepare .NET Release stage that signs prebuilt NuGet packages and workload MSIs and then produces Visual Studio workload insertion artifacts—without depending on Xamarin.yaml-templates.

Changes:

  • Adds an Arcade “adapter” build project (Workloads.proj) to generate/sign workload MSIs and persist outputs for later insertion-artifact generation.
  • Introduces supporting Arcade signing hooks (eng/Signing.props, eng/AfterSigning.targets) plus a vsman project used to generate VS manifests after MSI signing.
  • Extends azure-pipelines-internal.yaml with a new “Prepare .NET Release” stage that downloads unsigned artifacts, runs Arcade signing, verifies signatures, and publishes signed outputs and binlogs.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
build-tools/automation/dnceng/arcade/Workloads.proj New MSBuild project to drive workload MSI generation + Arcade signing and persist outputs for later steps.
build-tools/automation/dnceng/arcade/vsman/Workload.vsmanproj New vsman project for generating VS workload insertion manifests/zips after MSI signing.
build-tools/automation/dnceng/arcade/vsman/global.json Pins .NET SDK selection for the vsman restore/build context.
build-tools/automation/dnceng/arcade/eng/Signing.props Arcade signing configuration wiring SignList.xml mappings to ItemsToSign/FileSignInfo.
build-tools/automation/dnceng/arcade/eng/AfterSigning.targets Post-signing hook to generate VS insertion artifacts by invoking Workloads.proj.
build-tools/automation/azure-pipelines-internal.yaml Adds Prepare .NET Release stage to sign NuGets/MSIs, generate insertion artifacts, verify, and publish outputs/logs.

Comment thread build-tools/automation/dnceng/arcade/Workloads.proj
Comment thread build-tools/automation/dnceng/arcade/Workloads.proj
Comment thread build-tools/automation/dnceng/arcade/vsman/Workload.vsmanproj
Comment thread build-tools/automation/dnceng/arcade/vsman/Workload.vsmanproj Outdated
Resolve legacy SignList wildcards against the actual package contents because
Arcade matches explicit signing rules by filename. Preserve Skip precedence
and fail normalization if certificate assignments conflict.

Use the reserved MSBuildProjectName property for VSMan intermediate output.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 866271dd-9544-4263-912e-5cfe20e73dbc
@jonathanpeppers

Copy link
Copy Markdown
Member Author

/review

@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Android PR Reviewer completed successfully!

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Android PR Review — ⚠️ Minor Comments

Reviewed the in-repo Arcade signing flow for the dnceng/internal pipeline: azure-pipelines-internal.yaml, the dnceng/arcade adapter (Workloads.proj, Signing.props, AfterSigning.targets, vsman/Workload.vsmanproj, global.json).

Overall this is a clean, well-organized change. The staged approach (normalize → sign NuGets → build+sign MSIs → sign MSI NuGets → validate → verify) is sensible, unsigned-input assertions fail fast with clear messages, and signing binlogs publish under condition: always() for diagnostics. I confirmed android/global.json has no tools node, so regenerating the isolated adapter's global.json doesn't silently drop sdk/msbuild-sdks — that logic is fine.

Findings (2 inline)

  • ⚠️ SecurityMicroBuildCodesignVerify doesn't cover the base signed NuGet packages in the Shipping root; no NuGet-signature verification runs on them. Worth confirming this is intentional.
  • 💡 Patterns — The $properties = @(...) MSBuild-arg array is duplicated across all three signing steps and will drift; consider hoisting to a variable/template.

Notes

  • CI: no pipeline checks were reported yet at review time (status pending) — merge only once the dnceng internal validation is green.
  • Validation evidence in the PR description (internal build 3024411, DevDiv parity comparison) is solid and appreciated.

Nothing here is merge-blocking on its own; the security question is the one worth a reply before merge.

Generated by Android PR Reviewer for #12158 · 137.6 AIC · ⌖ 18.7 AIC · ⊞ 6.8K
Comment /review to run again

Comment thread build-tools/automation/azure-pipelines-internal.yaml
Comment thread build-tools/automation/azure-pipelines-internal.yaml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants