ci(publish): split release workflow into build, sign, pack, sbom generation and publish jobs - #38
Conversation
There was a problem hiding this comment.
Pull request overview
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
This PR restructures the NuGet release pipeline into chained, least-privilege jobs, adds artifact integrity checks between jobs, and integrates SBOM generation + attestation into the same workflow while pinning strong-name identity verification.
Changes:
- Split
publish.ymlinto build/sign/pack/sbom/publish/release-attach jobs with minimal permissions and checksum-verified artifact handoffs. - Added pinned strong-name public key and verification script to detect key substitution.
- Moved SBOM generation from the standalone
sbom.ymlintopublish.yml, including provenance + SBOM attestations.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
eng/IG.publickey.hex |
Adds the pinned strong-name public key blob used for validation. |
.github/workflows/sbom.yml |
Removes standalone SBOM workflow (superseded by publish.yml). |
.github/workflows/publish.yml |
Replaces single-job release with chained least-privilege jobs + checksum validation + SBOM/attestation and release asset upload. |
.github/scripts/verify-strong-name.ps1 |
Verifies assembly strong-name identity against the pinned public key/token. |
.github/scripts/artifact-checksums.ps1 |
Writes/verifies per-handoff SHA-256 manifests to detect tampering/drift. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
.github/workflows/publish.yml:465
- The least-privilege summary says only
sign-assemblies,pack, andsbomreceiveid-token: write, butpublishalso receives it here. This permission is expected for NuGet trusted publishing, so update the description to include the publish job rather than documenting a stricter permission boundary than the workflow implements.
permissions:
contents: read
id-token: write
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
.github/workflows/publish.yml:479
- The publish job never checks out or reads repository contents, and the pinned NuGet login action only needs OIDC. Granting
contents: readunnecessarily gives every step in the credential-bearing publish job a readable repository token, contrary to the least-privilege boundary introduced here; retain onlyid-token: write.
contents: read
|
Hi, @PureWeen! I think I was able to follow your recommendations from the other PRs I stacked below this one: Can you please reveiw this one? A successful release with all of the changes from this branch: https://github.com/IgniteUI/IgniteUI.Blazor.GridLite/releases/tag/0.9.2-alpha.2 |
* Strong-name signing for the assemblies * ci(publish): split release workflow into build, sign, pack, sbom generation and publish jobs (#38)
Summary
Restructures the NuGet release workflow (
publish.yml) into isolated, least-privilege jobs, pins the expected strong-name and Authenticode signer identities, and adds signed-package digest continuity, SBOM generation, attestations, and release evidence to the same pipeline that publishes the package.What changed
publishjob into six chained jobs:build→sign-assemblies→pack→sbom→publish→attach-to-release.sign-assembliesandpackreceive Azure OIDC/Key Vault access,sbomcan create attestations,publishreceives only OIDC for NuGet trusted publishing, and onlyattach-to-releasecan write release assets.eng/IG.publickey.hex: the approved Infragistics strong-name public key, pinned in the repo and checked independently of the signing key used at build time.eng/IG.authenticode-certificates.sha256: an allowlist containing the SHA-256 fingerprint of each approved Authenticode signing certificate..github/scripts/verify-strong-name.ps1: verifies each packaged assembly withsn.exeand compares its full public key/token with the repository pin, so a different internally valid key is rejected;sn.exeresolution now supports an explicit path, checksPATH, and falls back to the newest installed Windows SDK.--no-build --no-restore, signs and verifies the.nupkg, records its SHA-256 digest, and exposes that digest to downstream jobs.sbom-tool4.1.5 manifest so release signing restores do not discover the SBOM tool.sbomjob restores npm dependency metadata without lifecycle scripts, generates SPDX 2.2 and 3.0 documents over the signed package plus the NuGet and npm dependency graphs, verifies both outputs and the package reference, and bounds external license lookup to 180 seconds.actions/attestdoes not currently accept it as an SBOM predicate.publishperforms no checkout or build, verifies the package digest against both thepackandsbomjobs, revalidates its NuGet signature, and publishes through NuGet trusted publishing.attach-to-releaseuploads the signed package, its checksum, both SPDX documents, and both attestation bundles as release assets.release: createdtorelease: published.Why
The previous single-job workflow combined build, Key Vault signing, packaging, and NuGet publishing responsibilities, and neither the strong-name key nor the Authenticode signer identity was pinned against substitution. The new job boundaries narrow each credential's exposure, make key or signer substitution a hard failure, and prove that the exact signed and attested package is the one sent to NuGet.org and attached to the GitHub release.
Testing
net8.0/net9.0/net10.0) with a disposable strong-name key — build succeeds, only pre-existing nullable warnings.--no-build --no-restore) and confirmed the.nupkgcontains all three assemblies, the generated JS bundle, and all 8 theme CSS files.verify-strong-name.ps1rejects assemblies signed with a substituted (disposable) key, and independently re-derived the pinned public key's token.verify-strong-name.ps1against the release DLLs using both automatic Windows 10 SDK resolution and an explicit-SnPath; an invalid explicit path is rejected.32997751378exercised the build, assembly signing, package signing, and digest handoffs; its actualnupkg-signedartifact was then used to validate the corrected SBOM commands locally.IgniteUI.Blazor.GridLite.0.9.2-alpha.1.nupkg; SPDX 2.2 reported 98 packages and 2 files.actions/attestcommit SHA against the upstreamv4.2.2tag.actions/attestinput contract supports explicitsubject-name/subject-digestbinding, and both attestations use the digest reverified immediately before attestation.npm ci --ignore-scriptswithout lifecycle execution or a change to the signed package digest, then regenerated SPDX 2.2 from the real signed artifact: 98 packages and 2 files were detected, including the.nupkg,esbuild, andvite.git diff --checkclean; all 26 action references in the workflow confirmed pinned to commit SHAs.