You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ci(release): add SBOM evidence and attestations for published packages - #1878
Adds release supply-chain evidence for every package npm-publish.yml publishes, using the same approach as IgniteUI/igniteui-angular, IgniteUI/igniteui-webcomponents and IgniteUI/igniteui-react: one delivered CycloneDX SBOM per package, plus an overall SBOM README for the release. npm publishing now uses the exact tarballs that were inventoried and attested.
What the release workflow now does
build (read-only, no OIDC): builds as before, then scripts/build-sbom.js packs every publishable lerna package once. The packages are @igniteui/cli-core, @igniteui/angular-templates, @igniteui/angular-schematics, @igniteui/mcp-server and igniteui-cli, read from lerna.json and sorted in dependency order. For each tarball it:
installs it in isolation (--omit=dev --ignore-scripts), with workspace siblings resolved from the tarballs of the same build through npm overrides, because those versions aren't on npm yet;
generates a CycloneDX 1.6 SBOM with @cyclonedx/cyclonedx-npm, re-roots it on the published package and checks the graph for duplicate, unknown or unreachable refs;
validates the SBOM against the official schema, writes .sha256/.sha512 digests and runs npm audit on the delivered closure.
It also writes a best-effort build-environment SBOM of the repository toolchain and one README covering every package in the release.
attest: build provenance for all tarballs. attest-sbom: a matrix job that creates one CycloneDX SBOM attestation per package. Both are skipped in private repos.
publish: now publishes the verified tarballs in dependency order instead of lerna exec npm publish, after verifying their checksums. It runs only after both attestation jobs succeed.
attach-to-release: uploads the tarballs, digests, delivered SBOMs, an SBOM archive (with README and supply-chain notes) and the attestation bundles to the release. It also adds a supply-chain section to the release notes, unless the notes were edited during the build.
mcp-registry: now needs: publish and runs after a successful npm publish (still skipped for prereleases). The workflow_dispatch path is unchanged.
Licenses in each SBOM are the ones the installed packages declare, as in the Angular, Web Components and React releases. No external license lookup is performed and no SPDX documents are produced.
Dependency manifest change: adds @cyclonedx/cyclonedx-npm (^6.0.1) as a root devDependency (package.json / yarn.lock). The generator runs from node_modules, so release-time generation does not fetch it from the network. Also removes the root deploy script, which the workflow no longer uses.
Package manifest change: adds "license": "MIT" to @igniteui/mcp-server's package.json, matching the License section of its README. Without it, that package's SBOM component had no license.
Versions: this branch sets igniteui-cli, @igniteui/cli-core and @igniteui/mcp-server to 15.8.3-alpha.0, and @igniteui/angular-templates and @igniteui/angular-schematics to 22.2.1583-alpha.0, for a full prerelease of this flow.
Related Issue
Duplicate of #1865 (opened from the fork), pushed to this repository.
Type of Change
Bug fix (non-breaking change that fixes an issue)
New feature (non-breaking change that adds functionality)
Breaking change (fix or feature that would cause existing functionality to change)
Documentation update
Refactoring / code cleanup
Build / CI configuration change
Affected Packages
@igniteui/mcp-server (packages/igniteui-mcp): license field only
No other package contents change; the release workflow now inventories all of them.
Checklist
I have tested my changes locally (npm run jasmine: 714 passed, 2 pre-existing pending)
I have built the project successfully (tsc, tsconfig-pack, build:mcp)
I have run the linter (npm run lint: 0 errors; 1 pre-existing warning in packages/core/util/Schematics.ts)
I have added/updated tests as needed: not applicable. SBOM generation is a release supplement, not package functionality, so it has no Jasmine specs; it is validated by the release run below.
My changes do not introduce new warnings or errors
Additional Context
Ran scripts/build-sbom.js end to end locally against the current packages (15.8.2 / 22.2.1582). All five SBOMs and the build-environment SBOM validated against CycloneDX 1.6, and the overall README rendered with every package. Findings:
@igniteui/mcp-server declared no license in its package.json, so its SBOM component had none. Fixed in this PR by declaring MIT, as its README states.
Before the merge from master bumped zod to ^4.6.6, npm audit reported a high-severity advisory in zod, reached through @igniteui/mcp-server (and so also through igniteui-cli). The next release run's supply-chain notes will show whether the bump clears it.
Validated with a dummy release (previous revision; a re-run against this revision is pending). A 0.0.0 GitHub release in this fork ran the workflow with publish disabled and the versions temporarily set to 0.0.0 (both since reverted). All jobs succeeded. Checked:
All 27 expected release assets: per package, the tarball, .sha256, .sha512, SBOM and SBOM attestation bundle, plus the SBOM archive and the provenance bundle. Every digest matches its tarball.
Each SBOM is rooted on the published package (purl, MIT license, tarball hashes), has no unreachable components, and resolves workspace siblings to the tarballs of the same build.
gh attestation verify passes for every tarball with both the provenance and CycloneDX predicate types, bound to the release tag, commit and run. The attested SBOMs match the released ones.
The supply-chain section was added to the release notes without changing the authored text.
…blish
Pack every publishable package once and describe the exact tarballs with
validated CycloneDX 1.6 SBOMs, build provenance and per-package SBOM
attestations, then attach the evidence to the GitHub release. Licenses a
package does not declare are looked up on ClearlyDefined; gaps produce a
warning instead of failing the release.
npm publish (and the MCP Registry job that depends on it) is disabled
until the flow is validated with a dummy GitHub release.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
….json
The README already states MIT; without the field the package's SBOM
component carried no license and every release raised a license-gap warning.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
setup-node v7 no longer exports a dummy NODE_AUTH_TOKEN, and yarn 1 fails on
the ${NODE_AUTH_TOKEN} reference in the .npmrc that registry-url writes. The
build job never publishes, so it does not need the registry configuration.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
TEST ONLY - revert before merging. The release workflow validates that the
MCP server's package.json and server.json match the release tag, so the
dummy 0.0.0 release needs igniteui-cli, @igniteui/cli-core and
@igniteui/mcp-server at 0.0.0 and the internal ~ranges pointing at it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This reverts commit 48562a5.
The dummy 0.0.0 release validated the workflow; the packages return to 15.8.2.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The release flow was validated end to end with a dummy 0.0.0 release:
the publish job runs again after the attestations, and the MCP Registry
job follows a successful npm publish.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mmy release
TEST ONLY - revert before merging. Validates the per-package CycloneDX
SBOM flow with a dummy 0.0.1 GitHub release in this fork:
- the npm publish job is disabled, and the MCP Registry job is skipped
with it, since it runs only after a successful publish;
- igniteui-cli, @igniteui/cli-core and @igniteui/mcp-server (package.json
and server.json) are set to 0.0.1, with the internal ~ranges pointing at
it, because the workflow checks the MCP server version against the
release tag.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ublishing
Reverts 27dbfd9 now that the dummy 0.0.1 release validated the SBOM flow
end to end:
- igniteui-cli, @igniteui/cli-core and @igniteui/mcp-server (package.json
and server.json) are back at 15.8.2, matching IgniteUI/igniteui-cli master,
with the internal ~ranges pointing at it again;
- the npm publish job runs again, and the MCP Registry job with it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Prepares a full prerelease of the SBOM release flow:
- igniteui-cli, @igniteui/cli-core and @igniteui/mcp-server (package.json
and server.json) are set to 15.8.3-alpha.0;
- @igniteui/angular-templates and @igniteui/angular-schematics are set to
22.2.1583-alpha.0, following the scheme in scripts/versionScript.ts;
- the internal ~ranges point at the new versions.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The reason will be displayed to describe this comment to others. Learn more.
🟡 Changes recommended
Release notes mislabel the subject package’s direct dependencies as transitive because the “Direct” flag reflects the synthetic audit workspace rather than the subject package’s runtime dependency declarations.
The reason will be displayed to describe this comment to others. Learn more.
🔵 Needs a closer look
Nested dependencies under the promoted main component are neither normalized nor included in known refs, causing valid dependency trees to fail validation and block releases.
No open issues 🎉
1 previously missed issue
In code that hasn't changed since last review
Normalize descendants when promoting the main component
scripts/build-sbom.ts:365
CycloneDX preserves physical component nesting by default, but promoteMainComponent() does not normalize descendants inside main.components, and assertDeliveredShape() also omits those descendants from its known refs. If the subject contains a nested dependency, its graph ref is normalized while its component ref is not, so validation rejects a valid dependency tree and stops the release. Pass --flatten-components here, or update both helpers to traverse the promoted component's descendants.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds release supply-chain evidence for every package
npm-publish.ymlpublishes, using the same approach as IgniteUI/igniteui-angular, IgniteUI/igniteui-webcomponents and IgniteUI/igniteui-react: one delivered CycloneDX SBOM per package, plus an overall SBOM README for the release. npm publishing now uses the exact tarballs that were inventoried and attested.What the release workflow now does
build (read-only, no OIDC): builds as before, then
scripts/build-sbom.jspacks every publishable lerna package once. The packages are@igniteui/cli-core,@igniteui/angular-templates,@igniteui/angular-schematics,@igniteui/mcp-serverandigniteui-cli, read fromlerna.jsonand sorted in dependency order. For each tarball it:--omit=dev --ignore-scripts), with workspace siblings resolved from the tarballs of the same build through npmoverrides, because those versions aren't on npm yet;@cyclonedx/cyclonedx-npm, re-roots it on the published package and checks the graph for duplicate, unknown or unreachable refs;.sha256/.sha512digests and runsnpm auditon the delivered closure.It also writes a best-effort build-environment SBOM of the repository toolchain and one README covering every package in the release.
attest: build provenance for all tarballs. attest-sbom: a matrix job that creates one CycloneDX SBOM attestation per package. Both are skipped in private repos.
publish: now publishes the verified tarballs in dependency order instead of
lerna exec npm publish, after verifying their checksums. It runs only after both attestation jobs succeed.attach-to-release: uploads the tarballs, digests, delivered SBOMs, an SBOM archive (with README and supply-chain notes) and the attestation bundles to the release. It also adds a supply-chain section to the release notes, unless the notes were edited during the build.
mcp-registry: now
needs: publishand runs after a successful npm publish (still skipped for prereleases). Theworkflow_dispatchpath is unchanged.Licenses in each SBOM are the ones the installed packages declare, as in the Angular, Web Components and React releases. No external license lookup is performed and no SPDX documents are produced.
Related Issue
Duplicate of #1865 (opened from the fork), pushed to this repository.
Type of Change
Affected Packages
@igniteui/mcp-server(packages/igniteui-mcp):licensefield onlyNo other package contents change; the release workflow now inventories all of them.
Checklist
npm run jasmine: 714 passed, 2 pre-existing pending)tsc,tsconfig-pack,build:mcp)npm run lint: 0 errors; 1 pre-existing warning inpackages/core/util/Schematics.ts)Additional Context
Ran
scripts/build-sbom.jsend to end locally against the current packages (15.8.2 / 22.2.1582). All five SBOMs and the build-environment SBOM validated against CycloneDX 1.6, and the overall README rendered with every package. Findings:@igniteui/mcp-serverdeclared nolicensein itspackage.json, so its SBOM component had none. Fixed in this PR by declaring MIT, as its README states.masterbumpedzodto^4.6.6,npm auditreported a high-severity advisory inzod, reached through@igniteui/mcp-server(and so also throughigniteui-cli). The next release run's supply-chain notes will show whether the bump clears it.Validated with a dummy release (previous revision; a re-run against this revision is pending). A
0.0.0GitHub release in this fork ran the workflow withpublishdisabled and the versions temporarily set to 0.0.0 (both since reverted). All jobs succeeded. Checked:.sha256,.sha512, SBOM and SBOM attestation bundle, plus the SBOM archive and the provenance bundle. Every digest matches its tarball.gh attestation verifypasses for every tarball with both the provenance and CycloneDX predicate types, bound to the release tag, commit and run. The attested SBOMs match the released ones.🤖 Generated with Claude Code