Skip to content

ci(release): add SBOM evidence and attestations for published packages- #1 - #1865

Open
turbobobbytraykov wants to merge 9 commits into
IgniteUI:masterfrom
turbobobbytraykov:btraykov/sbom-generation
Open

turbobobbytraykov wants to merge 9 commits into
IgniteUI:masterfrom
turbobobbytraykov:btraykov/sbom-generation

Conversation

@turbobobbytraykov

@turbobobbytraykov turbobobbytraykov commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Description

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.

Related Issue

N/A

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; packages are back at 15.8.2). 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.

🤖 Generated with Claude Code

turbobobbytraykov and others added 6 commits October 26, 2026 17:09
…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>
Copilot AI balanced review requested due to automatic review settings October 27, 2026 18:04

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.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

@turbobobbytraykov

Copy link
Copy Markdown
Contributor Author

@kdinev , do you need the accompanying README.MD file like the one we have for the full product (https://static.infragistics.com/marketing/Website/compliance/sbom/Angular/README.md) ?

If we don't need that README for the igniteui-cli package family/group, I'll remove all of the files necessary for generating it.

@coveralls

coveralls commented Oct 27, 2026 •

Copy link
Copy Markdown

Coverage Status

coverage: 94.582%. remained the same — turbobobbytraykov:btraykov/sbom-generation into IgniteUI:master

@kdinev

kdinev commented Oct 28, 2026

Copy link
Copy Markdown
Member

@kdinev , do you need the accompanying README.MD file like the one we have for the full product (https://static.infragistics.com/marketing/Website/compliance/sbom/Angular/README.md) ?

If we don't need that README for the igniteui-cli package family/group, I'll remove all of the files necessary for generating it.

Yes, please, we need the README. Don't remove it from generation.

kdinev
kdinev previously approved these changes Oct 28, 2026
…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>
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.

4 participants