From ebb15090f06e0ead22d02ff1ccdc674f5f68cfbc Mon Sep 17 00:00:00 2001 From: Mikhail Preyskurantov <5574159+mpreyskurantov@users.noreply.github.com> Date: Mon, 25 May 2026 21:19:39 +0300 Subject: [PATCH 01/16] cyclonedx cli validate sbom --- .github/workflows/build_all.yml | 30 ++++++++++++++++++++++- .github/workflows/packages_publishing.yml | 28 ++++++++++++++++++++- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build_all.yml b/.github/workflows/build_all.yml index 32a5bf059e82..95df6143537b 100644 --- a/.github/workflows/build_all.yml +++ b/.github/workflows/build_all.yml @@ -17,6 +17,7 @@ on: env: NX_CLOUD_ACCESS_TOKEN: ${{ github.ref_name == github.event.repository.default_branch && secrets.NX_CLOUD_ACCESS_TOKEN || '' }} NX_SKIP_NX_CACHE: ${{ contains(github.event.pull_request.labels.*.name, 'skip-cache') && 'true' || 'false' }} + CYCLONEDX_CLI_VERSION: 0.32.0 jobs: build: @@ -70,7 +71,34 @@ jobs: pnpm set //npm.pkg.github.com/:_authToken="$NODE_AUTH_TOKEN"; pnpm nx build sbom; - - name: Upload SBOM artifacts + - name: Install CycloneDX CLI + if: ${{ github.event_name == 'push' || github.event.inputs.SBOM == 'true' }} + shell: bash + run: | + tool_dir="$RUNNER_TEMP/cyclonedx-cli" + mkdir -p "$tool_dir" + curl -fsSL "https://github.com/CycloneDX/cyclonedx-cli/releases/download/v${{ env.CYCLONEDX_CLI_VERSION }}/cyclonedx-linux-x64" -o "$tool_dir/cyclonedx" + chmod +x "$tool_dir/cyclonedx" + echo "$tool_dir" >> "$GITHUB_PATH" + + - name: Validate SBOMs + if: ${{ github.event_name == 'push' || github.event.inputs.SBOM == 'true' }} + shell: bash + run: | + shopt -s nullglob + sbom_files=(packages/sbom/dist/*.sbom.json) + + if [ ${#sbom_files[@]} -eq 0 ]; then + echo "No SBOM files found in packages/sbom/dist" + exit 1 + fi + + for file in "${sbom_files[@]}"; do + echo "Validating $file" + cyclonedx validate --input-file "$file" --input-format json --fail-on-errors + done + + - name: Upload SBOMs if: ${{ github.event_name == 'push' || github.event.inputs.SBOM == 'true' }} uses: actions/upload-artifact@v7 with: diff --git a/.github/workflows/packages_publishing.yml b/.github/workflows/packages_publishing.yml index 06b2ba623c51..3d58095fc690 100644 --- a/.github/workflows/packages_publishing.yml +++ b/.github/workflows/packages_publishing.yml @@ -20,6 +20,7 @@ env: NX_SKIP_NX_CACHE: true FILTER: ${{ github.event_name == 'workflow_dispatch' && inputs.filter || '' }} SET_TIMESTAMP_VERSION: ${{ inputs.tag == 'daily' }} + CYCLONEDX_CLI_VERSION: 0.32.0 jobs: build: @@ -81,10 +82,35 @@ jobs: pnpm set "//npm.pkg.github.com/:_authToken" "$env:NODE_AUTH_TOKEN" pnpm nx build sbom; + - name: Install CycloneDX CLI + shell: bash + run: | + tool_dir="$RUNNER_TEMP/cyclonedx-cli" + mkdir -p "$tool_dir" + curl -fsSL "https://github.com/CycloneDX/cyclonedx-cli/releases/download/v${{ env.CYCLONEDX_CLI_VERSION }}/cyclonedx-win-x64.exe" -o "$tool_dir/cyclonedx.exe" + chmod +x "$tool_dir/cyclonedx.exe" || true + echo "$tool_dir" >> "$GITHUB_PATH" + + - name: Validate SBOMs + shell: bash + run: | + shopt -s nullglob + sbom_files=(packages/sbom/dist/*.sbom.json) + + if [ ${#sbom_files[@]} -eq 0 ]; then + echo "No SBOM files found in packages/sbom/dist" + exit 1 + fi + + for file in "${sbom_files[@]}"; do + echo "Validating $file" + cyclonedx validate --input-file "$file" --input-format json --fail-on-errors + done + - name: Build artifacts package run: pnpm run make-artifacts-package - - name: Upload SBOM artifact + - name: Upload SBOMs uses: actions/upload-artifact@v7 with: name: sbom From 5411141c1d5146e9e28dd1865275686d52226d81 Mon Sep 17 00:00:00 2001 From: Mikhail Preyskurantov <5574159+mpreyskurantov@users.noreply.github.com> Date: Wed, 3 Jun 2026 19:04:15 +0300 Subject: [PATCH 02/16] sha256sum / checksum --- .github/workflows/build_all.yml | 2 ++ .github/workflows/packages_publishing.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/build_all.yml b/.github/workflows/build_all.yml index 95df6143537b..be285e8473b4 100644 --- a/.github/workflows/build_all.yml +++ b/.github/workflows/build_all.yml @@ -18,6 +18,7 @@ env: NX_CLOUD_ACCESS_TOKEN: ${{ github.ref_name == github.event.repository.default_branch && secrets.NX_CLOUD_ACCESS_TOKEN || '' }} NX_SKIP_NX_CACHE: ${{ contains(github.event.pull_request.labels.*.name, 'skip-cache') && 'true' || 'false' }} CYCLONEDX_CLI_VERSION: 0.32.0 + CYCLONEDX_CLI_LINUX_X64_SHA256: 454879e6a4a405c8a13bff49b8982adcb0596f3019b26b0811c66e4d7f0783e1 jobs: build: @@ -78,6 +79,7 @@ jobs: tool_dir="$RUNNER_TEMP/cyclonedx-cli" mkdir -p "$tool_dir" curl -fsSL "https://github.com/CycloneDX/cyclonedx-cli/releases/download/v${{ env.CYCLONEDX_CLI_VERSION }}/cyclonedx-linux-x64" -o "$tool_dir/cyclonedx" + echo "${{ env.CYCLONEDX_CLI_LINUX_X64_SHA256 }} $tool_dir/cyclonedx" | sha256sum -c - chmod +x "$tool_dir/cyclonedx" echo "$tool_dir" >> "$GITHUB_PATH" diff --git a/.github/workflows/packages_publishing.yml b/.github/workflows/packages_publishing.yml index 3d58095fc690..a5c84421659a 100644 --- a/.github/workflows/packages_publishing.yml +++ b/.github/workflows/packages_publishing.yml @@ -21,6 +21,7 @@ env: FILTER: ${{ github.event_name == 'workflow_dispatch' && inputs.filter || '' }} SET_TIMESTAMP_VERSION: ${{ inputs.tag == 'daily' }} CYCLONEDX_CLI_VERSION: 0.32.0 + CYCLONEDX_CLI_WIN_X64_SHA256: b1c00dbb40e628ec8c1252771871341ac4d4aaf032f832d83bd22cb2b1d258ae jobs: build: @@ -88,6 +89,7 @@ jobs: tool_dir="$RUNNER_TEMP/cyclonedx-cli" mkdir -p "$tool_dir" curl -fsSL "https://github.com/CycloneDX/cyclonedx-cli/releases/download/v${{ env.CYCLONEDX_CLI_VERSION }}/cyclonedx-win-x64.exe" -o "$tool_dir/cyclonedx.exe" + echo "${{ env.CYCLONEDX_CLI_WIN_X64_SHA256 }} $tool_dir/cyclonedx.exe" | sha256sum -c - chmod +x "$tool_dir/cyclonedx.exe" || true echo "$tool_dir" >> "$GITHUB_PATH" From 73369e3846c558eaff11f4c0c68c14fa3040f1d3 Mon Sep 17 00:00:00 2001 From: Mikhail Preyskurantov <5574159+mpreyskurantov@users.noreply.github.com> Date: Fri, 5 Jun 2026 14:43:26 +0300 Subject: [PATCH 03/16] CYCLONEDX_CLI: WIN -> LINUX (after #33854) --- .github/workflows/packages_publishing.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/packages_publishing.yml b/.github/workflows/packages_publishing.yml index 70f72396b140..ba609e05bb67 100644 --- a/.github/workflows/packages_publishing.yml +++ b/.github/workflows/packages_publishing.yml @@ -21,7 +21,7 @@ env: FILTER: ${{ github.event_name == 'workflow_dispatch' && inputs.filter || '' }} SET_TIMESTAMP_VERSION: ${{ inputs.tag == 'daily' }} CYCLONEDX_CLI_VERSION: 0.32.0 - CYCLONEDX_CLI_WIN_X64_SHA256: b1c00dbb40e628ec8c1252771871341ac4d4aaf032f832d83bd22cb2b1d258ae + CYCLONEDX_CLI_LINUX_X64_SHA256: 454879e6a4a405c8a13bff49b8982adcb0596f3019b26b0811c66e4d7f0783e1 jobs: build: @@ -66,8 +66,8 @@ jobs: run: | tool_dir="$RUNNER_TEMP/cyclonedx-cli" mkdir -p "$tool_dir" - curl -fsSL "https://github.com/CycloneDX/cyclonedx-cli/releases/download/v${{ env.CYCLONEDX_CLI_VERSION }}/cyclonedx-win-x64.exe" -o "$tool_dir/cyclonedx.exe" - echo "${{ env.CYCLONEDX_CLI_WIN_X64_SHA256 }} $tool_dir/cyclonedx.exe" | sha256sum -c - + curl -fsSL "https://github.com/CycloneDX/cyclonedx-cli/releases/download/v${{ env.CYCLONEDX_CLI_VERSION }}/cyclonedx-linux-x64" -o "$tool_dir/cyclonedx" + echo "${{ env.CYCLONEDX_CLI_LINUX_X64_SHA256 }} $tool_dir/cyclonedx" | sha256sum -c - chmod +x "$tool_dir/cyclonedx.exe" || true echo "$tool_dir" >> "$GITHUB_PATH" From 76ef292018766b672641cad270b7afb3bb140164 Mon Sep 17 00:00:00 2001 From: Mikhail Preyskurantov <5574159+mpreyskurantov@users.noreply.github.com> Date: Fri, 5 Jun 2026 15:07:03 +0300 Subject: [PATCH 04/16] CYCLONEDX_CLI: WIN -> LINUX, v2, exe || true (after #33854) Signed-off-by: Mikhail Preyskurantov <5574159+mpreyskurantov@users.noreply.github.com> --- .github/workflows/packages_publishing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/packages_publishing.yml b/.github/workflows/packages_publishing.yml index ba609e05bb67..21d0185d4ee2 100644 --- a/.github/workflows/packages_publishing.yml +++ b/.github/workflows/packages_publishing.yml @@ -68,7 +68,7 @@ jobs: mkdir -p "$tool_dir" curl -fsSL "https://github.com/CycloneDX/cyclonedx-cli/releases/download/v${{ env.CYCLONEDX_CLI_VERSION }}/cyclonedx-linux-x64" -o "$tool_dir/cyclonedx" echo "${{ env.CYCLONEDX_CLI_LINUX_X64_SHA256 }} $tool_dir/cyclonedx" | sha256sum -c - - chmod +x "$tool_dir/cyclonedx.exe" || true + chmod +x "$tool_dir/cyclonedx" echo "$tool_dir" >> "$GITHUB_PATH" - name: Validate SBOMs From aaffe18392a1c69fc54137cd6d13b02a3ac56124 Mon Sep 17 00:00:00 2001 From: Mikhail Preyskurantov <5574159+mpreyskurantov@users.noreply.github.com> Date: Fri, 5 Jun 2026 18:46:03 +0300 Subject: [PATCH 05/16] SBOM package(s) flow (like for NPM package(s)) --- .github/workflows/packages_publishing.yml | 66 +++++++++++++++++++++-- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/.github/workflows/packages_publishing.yml b/.github/workflows/packages_publishing.yml index 21d0185d4ee2..64d4aa02dd32 100644 --- a/.github/workflows/packages_publishing.yml +++ b/.github/workflows/packages_publishing.yml @@ -93,14 +93,14 @@ jobs: - name: Upload SBOMs uses: actions/upload-artifact@v7 with: - name: sbom + name: sbom-packages path: packages/sbom/dist retention-days: 7 - name: Upload packages uses: actions/upload-artifact@v7 with: - name: packages + name: npm-packages path: artifacts/npm/*.tgz retention-days: 2 @@ -122,10 +122,17 @@ jobs: - name: Get sources uses: actions/checkout@v6 - - name: Download artifacts + - name: Download packages uses: actions/download-artifact@v8 with: - name: packages + name: npm-packages + path: npm-packages + + - name: Download SBOMs + uses: actions/download-artifact@v8 + with: + name: sbom-packages + path: sbom-packages - name: Use Node.js uses: actions/setup-node@v6 @@ -145,13 +152,49 @@ jobs: PACKAGE: ${{ matrix.package }} run: | SCOPE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]'); - PACKAGE_DIR=$(pnpm --silent run change-package-scope --tgz $PACKAGE.tgz --scope $SCOPE) + PACKAGE_DIR=$(pnpm --silent run change-package-scope --tgz npm-packages/$PACKAGE.tgz --scope $SCOPE) echo "packageDir=$PACKAGE_DIR" >> "$GITHUB_OUTPUT"; cd $PACKAGE_DIR; pnpm pkg get name | tr -d '"' | sed -r 's/(.*)/name=\1/' >> "$GITHUB_OUTPUT"; pnpm pkg get version | tr -d '"' | sed -r 's/(.*)/version=\1/' >> "$GITHUB_OUTPUT"; pnpm pkg get version | tr -d '"' | sed -r 's/([0-9]+\.[0-9]+).*/majorVersion=\1/' >> "$GITHUB_OUTPUT"; + - name: Build SBOM package + id: scopedSbomPackage + env: + PACKAGE_NAME: ${{ steps.scopedPackage.outputs.name }} + PACKAGE_VERSION: ${{ steps.scopedPackage.outputs.version }} + run: | + UNSCOPED_PACKAGE_NAME=$(echo "$PACKAGE_NAME" | sed -r 's#^@[^/]+/##'); + SBOM_FILE="sbom-packages/$UNSCOPED_PACKAGE_NAME.sbom.json"; + + # if [ ! -f "$SBOM_FILE" ]; then + # echo "No SBOM found for $UNSCOPED_PACKAGE_NAME" + # echo "hasSbom=false" >> "$GITHUB_OUTPUT"; + # exit 0; + # fi + + SCOPE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]'); + SBOM_PACKAGE_NAME="$UNSCOPED_PACKAGE_NAME-sbom"; + SBOM_PACKAGE_DIR="sbom-package/$SBOM_PACKAGE_NAME"; + SBOM_TGZ_DIR="sbom-package-tgz"; + PACKAGE_LICENSE=$(node -p "require('./package.json').license"); + PACKAGE_AUTHOR=$(node -p "require('./package.json').author"); + + mkdir -p "$SBOM_PACKAGE_DIR" "$SBOM_TGZ_DIR"; + cp "$SBOM_FILE" "$SBOM_PACKAGE_DIR/"; + cd "$SBOM_PACKAGE_DIR"; + node -e "const fs = require('fs'); const [name, version, license, author] = process.argv.slice(1); fs.writeFileSync('package.json', JSON.stringify({ name, version, license, author }, null, 2));" "$SBOM_PACKAGE_NAME" "$PACKAGE_VERSION" "$PACKAGE_LICENSE" "$PACKAGE_AUTHOR"; + npm pack --pack-destination "../../$SBOM_TGZ_DIR"; + cd ../..; + + SCOPED_SBOM_PACKAGE_DIR=$(pnpm --silent run change-package-scope --tgz "$SBOM_TGZ_DIR/$SBOM_PACKAGE_NAME-$PACKAGE_VERSION.tgz" --scope "$SCOPE"); + echo "packageDir=$SCOPED_SBOM_PACKAGE_DIR" >> "$GITHUB_OUTPUT"; + cd "$SCOPED_SBOM_PACKAGE_DIR"; + pnpm pkg get name | tr -d '"' | sed -r 's/(.*)/name=\1/' >> "$GITHUB_OUTPUT"; + pnpm pkg get version | tr -d '"' | sed -r 's/(.*)/version=\1/' >> "$GITHUB_OUTPUT"; + pnpm pkg get version | tr -d '"' | sed -r 's/([0-9]+\.[0-9]+).*/majorVersion=\1/' >> "$GITHUB_OUTPUT"; + # --ignore-scripts is required for publishing devextreme-angular which fails with error: # 'Trying to publish a package that has been compiled by Ivy in full compilation mode.' # Should be removed. @@ -167,6 +210,19 @@ jobs: pnpm publish --no-git-checks --quiet --ignore-scripts --tag $PACKAGE_VERSION_MAJOR-${{ inputs.tag }} --registry https://npm.pkg.github.com; pnpm dist-tag add $PACKAGE_NAME@$PACKAGE_VERSION latest --registry=https://npm.pkg.github.com; + # --ignore-scripts - like above, should be removed, check if could be removed everywhere + - name: Publish SBOM to npm.pkg.github.com + working-directory: ${{ steps.scopedSbomPackage.outputs.packageDir }} + env: + NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PACKAGE_NAME: ${{ steps.scopedSbomPackage.outputs.name }} + PACKAGE_VERSION: ${{ steps.scopedSbomPackage.outputs.version }} + PACKAGE_VERSION_MAJOR: ${{ steps.scopedSbomPackage.outputs.majorVersion }} + run: | + pnpm set //npm.pkg.github.com/:_authToken="$NODE_AUTH_TOKEN"; + pnpm publish --no-git-checks --quiet --ignore-scripts --tag $PACKAGE_VERSION_MAJOR-${{ inputs.tag }} --registry https://npm.pkg.github.com; + pnpm dist-tag add $PACKAGE_NAME@$PACKAGE_VERSION latest --registry=https://npm.pkg.github.com; + notify: runs-on: devextreme-shr2 name: Send notifications From 0da90d64ff6db956a8857ebbc41fc1976453f6fe Mon Sep 17 00:00:00 2001 From: Mikhail Preyskurantov <5574159+mpreyskurantov@users.noreply.github.com> Date: Fri, 5 Jun 2026 19:01:09 +0300 Subject: [PATCH 06/16] SBOM package(s) optimized flow only (no NPM package(s)) --- .github/workflows/packages_publishing.yml | 98 ++++------------------- 1 file changed, 14 insertions(+), 84 deletions(-) diff --git a/.github/workflows/packages_publishing.yml b/.github/workflows/packages_publishing.yml index 64d4aa02dd32..4db59ba9faf1 100644 --- a/.github/workflows/packages_publishing.yml +++ b/.github/workflows/packages_publishing.yml @@ -20,8 +20,6 @@ env: NX_SKIP_NX_CACHE: true FILTER: ${{ github.event_name == 'workflow_dispatch' && inputs.filter || '' }} SET_TIMESTAMP_VERSION: ${{ inputs.tag == 'daily' }} - CYCLONEDX_CLI_VERSION: 0.32.0 - CYCLONEDX_CLI_LINUX_X64_SHA256: 454879e6a4a405c8a13bff49b8982adcb0596f3019b26b0811c66e4d7f0783e1 jobs: build: @@ -29,6 +27,7 @@ jobs: runs-on: ubuntu-latest outputs: packages: ${{ steps.filter.outputs.packages }} + version: ${{ steps.packageVersion.outputs.version }} steps: - name: Get sources uses: actions/checkout@v6 @@ -49,47 +48,20 @@ jobs: if: ${{ env.SET_TIMESTAMP_VERSION == 'true' }} run: pnpm run all:set-timestamp-version - - name: Build npm packages - env: - BUILD_INTERNAL_PACKAGE: true - run: pnpm run all:build + - name: Get package version + id: packageVersion + run: | + PACKAGE_VERSION=$(node -p "require('./package.json').version") + echo "version=$PACKAGE_VERSION" >> "$GITHUB_OUTPUT" - name: Build SBOMs + continue-on-error: true env: NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | pnpm set //npm.pkg.github.com/:_authToken="$NODE_AUTH_TOKEN"; pnpm nx build sbom; - - name: Install CycloneDX CLI - shell: bash - run: | - tool_dir="$RUNNER_TEMP/cyclonedx-cli" - mkdir -p "$tool_dir" - curl -fsSL "https://github.com/CycloneDX/cyclonedx-cli/releases/download/v${{ env.CYCLONEDX_CLI_VERSION }}/cyclonedx-linux-x64" -o "$tool_dir/cyclonedx" - echo "${{ env.CYCLONEDX_CLI_LINUX_X64_SHA256 }} $tool_dir/cyclonedx" | sha256sum -c - - chmod +x "$tool_dir/cyclonedx" - echo "$tool_dir" >> "$GITHUB_PATH" - - - name: Validate SBOMs - shell: bash - run: | - shopt -s nullglob - sbom_files=(packages/sbom/dist/*.sbom.json) - - if [ ${#sbom_files[@]} -eq 0 ]; then - echo "No SBOM files found in packages/sbom/dist" - exit 1 - fi - - for file in "${sbom_files[@]}"; do - echo "Validating $file" - cyclonedx validate --input-file "$file" --input-format json --fail-on-errors - done - - - name: Build artifacts package - run: pnpm run make-artifacts-package - - name: Upload SBOMs uses: actions/upload-artifact@v7 with: @@ -97,18 +69,11 @@ jobs: path: packages/sbom/dist retention-days: 7 - - name: Upload packages - uses: actions/upload-artifact@v7 - with: - name: npm-packages - path: artifacts/npm/*.tgz - retention-days: 2 - - name: Filter packages id: filter - working-directory: artifacts/npm + working-directory: packages/sbom/dist shell: bash - run: ls *.tgz | grep -E -i "$FILTER" | sed -r 's/^(.*).tgz$/"\1"/g' | paste -sd "," - | sed -r 's/(.*)/packages=[\1]/' >> "$GITHUB_OUTPUT" + run: ls *.sbom.json | grep -E -i "$FILTER" | sed -r 's/^(.*).sbom.json$/"\1"/g' | paste -sd "," - | sed -r 's/(.*)/packages=[\1]/' >> "$GITHUB_OUTPUT" publish: name: Publish package @@ -122,12 +87,6 @@ jobs: - name: Get sources uses: actions/checkout@v6 - - name: Download packages - uses: actions/download-artifact@v8 - with: - name: npm-packages - path: npm-packages - - name: Download SBOMs uses: actions/download-artifact@v8 with: @@ -146,36 +105,22 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile - - name: Change package scope - id: scopedPackage - env: - PACKAGE: ${{ matrix.package }} - run: | - SCOPE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]'); - PACKAGE_DIR=$(pnpm --silent run change-package-scope --tgz npm-packages/$PACKAGE.tgz --scope $SCOPE) - echo "packageDir=$PACKAGE_DIR" >> "$GITHUB_OUTPUT"; - cd $PACKAGE_DIR; - pnpm pkg get name | tr -d '"' | sed -r 's/(.*)/name=\1/' >> "$GITHUB_OUTPUT"; - pnpm pkg get version | tr -d '"' | sed -r 's/(.*)/version=\1/' >> "$GITHUB_OUTPUT"; - pnpm pkg get version | tr -d '"' | sed -r 's/([0-9]+\.[0-9]+).*/majorVersion=\1/' >> "$GITHUB_OUTPUT"; - - name: Build SBOM package id: scopedSbomPackage env: - PACKAGE_NAME: ${{ steps.scopedPackage.outputs.name }} - PACKAGE_VERSION: ${{ steps.scopedPackage.outputs.version }} + PACKAGE: ${{ matrix.package }} + PACKAGE_VERSION: ${{ needs.build.outputs.version }} run: | - UNSCOPED_PACKAGE_NAME=$(echo "$PACKAGE_NAME" | sed -r 's#^@[^/]+/##'); - SBOM_FILE="sbom-packages/$UNSCOPED_PACKAGE_NAME.sbom.json"; + SBOM_FILE="sbom-packages/$PACKAGE.sbom.json"; # if [ ! -f "$SBOM_FILE" ]; then - # echo "No SBOM found for $UNSCOPED_PACKAGE_NAME" + # echo "No SBOM found for $PACKAGE" # echo "hasSbom=false" >> "$GITHUB_OUTPUT"; # exit 0; # fi SCOPE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]'); - SBOM_PACKAGE_NAME="$UNSCOPED_PACKAGE_NAME-sbom"; + SBOM_PACKAGE_NAME="$PACKAGE-sbom"; SBOM_PACKAGE_DIR="sbom-package/$SBOM_PACKAGE_NAME"; SBOM_TGZ_DIR="sbom-package-tgz"; PACKAGE_LICENSE=$(node -p "require('./package.json').license"); @@ -195,21 +140,6 @@ jobs: pnpm pkg get version | tr -d '"' | sed -r 's/(.*)/version=\1/' >> "$GITHUB_OUTPUT"; pnpm pkg get version | tr -d '"' | sed -r 's/([0-9]+\.[0-9]+).*/majorVersion=\1/' >> "$GITHUB_OUTPUT"; - # --ignore-scripts is required for publishing devextreme-angular which fails with error: - # 'Trying to publish a package that has been compiled by Ivy in full compilation mode.' - # Should be removed. - - name: Publish to npm.pkg.github.com - working-directory: ${{ steps.scopedPackage.outputs.packageDir }} - env: - NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - PACKAGE_NAME: ${{ steps.scopedPackage.outputs.name }} - PACKAGE_VERSION: ${{ steps.scopedPackage.outputs.version }} - PACKAGE_VERSION_MAJOR: ${{ steps.scopedPackage.outputs.majorVersion }} - run: | - pnpm set //npm.pkg.github.com/:_authToken="$NODE_AUTH_TOKEN"; - pnpm publish --no-git-checks --quiet --ignore-scripts --tag $PACKAGE_VERSION_MAJOR-${{ inputs.tag }} --registry https://npm.pkg.github.com; - pnpm dist-tag add $PACKAGE_NAME@$PACKAGE_VERSION latest --registry=https://npm.pkg.github.com; - # --ignore-scripts - like above, should be removed, check if could be removed everywhere - name: Publish SBOM to npm.pkg.github.com working-directory: ${{ steps.scopedSbomPackage.outputs.packageDir }} From 7614d0594c8cc239d0d05820ab76ebc700e128bd Mon Sep 17 00:00:00 2001 From: Mikhail Preyskurantov <5574159+mpreyskurantov@users.noreply.github.com> Date: Mon, 8 Jun 2026 17:41:43 +0300 Subject: [PATCH 07/16] revert "continue-on-error: true" --- .github/workflows/packages_publishing.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/packages_publishing.yml b/.github/workflows/packages_publishing.yml index 4db59ba9faf1..5d5d470c3eeb 100644 --- a/.github/workflows/packages_publishing.yml +++ b/.github/workflows/packages_publishing.yml @@ -55,7 +55,6 @@ jobs: echo "version=$PACKAGE_VERSION" >> "$GITHUB_OUTPUT" - name: Build SBOMs - continue-on-error: true env: NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | From 6cf243acb3ac9a1ff0fbb9a20af795a84b4d9816 Mon Sep 17 00:00:00 2001 From: Mikhail Preyskurantov <5574159+mpreyskurantov@users.noreply.github.com> Date: Mon, 8 Jun 2026 17:48:18 +0300 Subject: [PATCH 08/16] Revert "SBOM package(s) optimized flow only (no NPM package(s))" This reverts commit 0da90d64ff6db956a8857ebbc41fc1976453f6fe. --- .github/workflows/packages_publishing.yml | 97 ++++++++++++++++++++--- 1 file changed, 84 insertions(+), 13 deletions(-) diff --git a/.github/workflows/packages_publishing.yml b/.github/workflows/packages_publishing.yml index 5d5d470c3eeb..64d4aa02dd32 100644 --- a/.github/workflows/packages_publishing.yml +++ b/.github/workflows/packages_publishing.yml @@ -20,6 +20,8 @@ env: NX_SKIP_NX_CACHE: true FILTER: ${{ github.event_name == 'workflow_dispatch' && inputs.filter || '' }} SET_TIMESTAMP_VERSION: ${{ inputs.tag == 'daily' }} + CYCLONEDX_CLI_VERSION: 0.32.0 + CYCLONEDX_CLI_LINUX_X64_SHA256: 454879e6a4a405c8a13bff49b8982adcb0596f3019b26b0811c66e4d7f0783e1 jobs: build: @@ -27,7 +29,6 @@ jobs: runs-on: ubuntu-latest outputs: packages: ${{ steps.filter.outputs.packages }} - version: ${{ steps.packageVersion.outputs.version }} steps: - name: Get sources uses: actions/checkout@v6 @@ -48,11 +49,10 @@ jobs: if: ${{ env.SET_TIMESTAMP_VERSION == 'true' }} run: pnpm run all:set-timestamp-version - - name: Get package version - id: packageVersion - run: | - PACKAGE_VERSION=$(node -p "require('./package.json').version") - echo "version=$PACKAGE_VERSION" >> "$GITHUB_OUTPUT" + - name: Build npm packages + env: + BUILD_INTERNAL_PACKAGE: true + run: pnpm run all:build - name: Build SBOMs env: @@ -61,6 +61,35 @@ jobs: pnpm set //npm.pkg.github.com/:_authToken="$NODE_AUTH_TOKEN"; pnpm nx build sbom; + - name: Install CycloneDX CLI + shell: bash + run: | + tool_dir="$RUNNER_TEMP/cyclonedx-cli" + mkdir -p "$tool_dir" + curl -fsSL "https://github.com/CycloneDX/cyclonedx-cli/releases/download/v${{ env.CYCLONEDX_CLI_VERSION }}/cyclonedx-linux-x64" -o "$tool_dir/cyclonedx" + echo "${{ env.CYCLONEDX_CLI_LINUX_X64_SHA256 }} $tool_dir/cyclonedx" | sha256sum -c - + chmod +x "$tool_dir/cyclonedx" + echo "$tool_dir" >> "$GITHUB_PATH" + + - name: Validate SBOMs + shell: bash + run: | + shopt -s nullglob + sbom_files=(packages/sbom/dist/*.sbom.json) + + if [ ${#sbom_files[@]} -eq 0 ]; then + echo "No SBOM files found in packages/sbom/dist" + exit 1 + fi + + for file in "${sbom_files[@]}"; do + echo "Validating $file" + cyclonedx validate --input-file "$file" --input-format json --fail-on-errors + done + + - name: Build artifacts package + run: pnpm run make-artifacts-package + - name: Upload SBOMs uses: actions/upload-artifact@v7 with: @@ -68,11 +97,18 @@ jobs: path: packages/sbom/dist retention-days: 7 + - name: Upload packages + uses: actions/upload-artifact@v7 + with: + name: npm-packages + path: artifacts/npm/*.tgz + retention-days: 2 + - name: Filter packages id: filter - working-directory: packages/sbom/dist + working-directory: artifacts/npm shell: bash - run: ls *.sbom.json | grep -E -i "$FILTER" | sed -r 's/^(.*).sbom.json$/"\1"/g' | paste -sd "," - | sed -r 's/(.*)/packages=[\1]/' >> "$GITHUB_OUTPUT" + run: ls *.tgz | grep -E -i "$FILTER" | sed -r 's/^(.*).tgz$/"\1"/g' | paste -sd "," - | sed -r 's/(.*)/packages=[\1]/' >> "$GITHUB_OUTPUT" publish: name: Publish package @@ -86,6 +122,12 @@ jobs: - name: Get sources uses: actions/checkout@v6 + - name: Download packages + uses: actions/download-artifact@v8 + with: + name: npm-packages + path: npm-packages + - name: Download SBOMs uses: actions/download-artifact@v8 with: @@ -104,22 +146,36 @@ jobs: - name: Install dependencies run: pnpm install --frozen-lockfile + - name: Change package scope + id: scopedPackage + env: + PACKAGE: ${{ matrix.package }} + run: | + SCOPE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]'); + PACKAGE_DIR=$(pnpm --silent run change-package-scope --tgz npm-packages/$PACKAGE.tgz --scope $SCOPE) + echo "packageDir=$PACKAGE_DIR" >> "$GITHUB_OUTPUT"; + cd $PACKAGE_DIR; + pnpm pkg get name | tr -d '"' | sed -r 's/(.*)/name=\1/' >> "$GITHUB_OUTPUT"; + pnpm pkg get version | tr -d '"' | sed -r 's/(.*)/version=\1/' >> "$GITHUB_OUTPUT"; + pnpm pkg get version | tr -d '"' | sed -r 's/([0-9]+\.[0-9]+).*/majorVersion=\1/' >> "$GITHUB_OUTPUT"; + - name: Build SBOM package id: scopedSbomPackage env: - PACKAGE: ${{ matrix.package }} - PACKAGE_VERSION: ${{ needs.build.outputs.version }} + PACKAGE_NAME: ${{ steps.scopedPackage.outputs.name }} + PACKAGE_VERSION: ${{ steps.scopedPackage.outputs.version }} run: | - SBOM_FILE="sbom-packages/$PACKAGE.sbom.json"; + UNSCOPED_PACKAGE_NAME=$(echo "$PACKAGE_NAME" | sed -r 's#^@[^/]+/##'); + SBOM_FILE="sbom-packages/$UNSCOPED_PACKAGE_NAME.sbom.json"; # if [ ! -f "$SBOM_FILE" ]; then - # echo "No SBOM found for $PACKAGE" + # echo "No SBOM found for $UNSCOPED_PACKAGE_NAME" # echo "hasSbom=false" >> "$GITHUB_OUTPUT"; # exit 0; # fi SCOPE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]'); - SBOM_PACKAGE_NAME="$PACKAGE-sbom"; + SBOM_PACKAGE_NAME="$UNSCOPED_PACKAGE_NAME-sbom"; SBOM_PACKAGE_DIR="sbom-package/$SBOM_PACKAGE_NAME"; SBOM_TGZ_DIR="sbom-package-tgz"; PACKAGE_LICENSE=$(node -p "require('./package.json').license"); @@ -139,6 +195,21 @@ jobs: pnpm pkg get version | tr -d '"' | sed -r 's/(.*)/version=\1/' >> "$GITHUB_OUTPUT"; pnpm pkg get version | tr -d '"' | sed -r 's/([0-9]+\.[0-9]+).*/majorVersion=\1/' >> "$GITHUB_OUTPUT"; + # --ignore-scripts is required for publishing devextreme-angular which fails with error: + # 'Trying to publish a package that has been compiled by Ivy in full compilation mode.' + # Should be removed. + - name: Publish to npm.pkg.github.com + working-directory: ${{ steps.scopedPackage.outputs.packageDir }} + env: + NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PACKAGE_NAME: ${{ steps.scopedPackage.outputs.name }} + PACKAGE_VERSION: ${{ steps.scopedPackage.outputs.version }} + PACKAGE_VERSION_MAJOR: ${{ steps.scopedPackage.outputs.majorVersion }} + run: | + pnpm set //npm.pkg.github.com/:_authToken="$NODE_AUTH_TOKEN"; + pnpm publish --no-git-checks --quiet --ignore-scripts --tag $PACKAGE_VERSION_MAJOR-${{ inputs.tag }} --registry https://npm.pkg.github.com; + pnpm dist-tag add $PACKAGE_NAME@$PACKAGE_VERSION latest --registry=https://npm.pkg.github.com; + # --ignore-scripts - like above, should be removed, check if could be removed everywhere - name: Publish SBOM to npm.pkg.github.com working-directory: ${{ steps.scopedSbomPackage.outputs.packageDir }} From eb2326fa7c68faf7a5df32fec491e168f9dff06e Mon Sep 17 00:00:00 2001 From: Mikhail Preyskurantov <5574159+mpreyskurantov@users.noreply.github.com> Date: Mon, 8 Jun 2026 17:53:02 +0300 Subject: [PATCH 09/16] *.sbom.json -> *.cdx.json --- .github/workflows/packages_publishing.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/packages_publishing.yml b/.github/workflows/packages_publishing.yml index 64d4aa02dd32..d375f9ccd3f3 100644 --- a/.github/workflows/packages_publishing.yml +++ b/.github/workflows/packages_publishing.yml @@ -75,7 +75,7 @@ jobs: shell: bash run: | shopt -s nullglob - sbom_files=(packages/sbom/dist/*.sbom.json) + sbom_files=(packages/sbom/dist/*.cdx.json) if [ ${#sbom_files[@]} -eq 0 ]; then echo "No SBOM files found in packages/sbom/dist" @@ -166,7 +166,7 @@ jobs: PACKAGE_VERSION: ${{ steps.scopedPackage.outputs.version }} run: | UNSCOPED_PACKAGE_NAME=$(echo "$PACKAGE_NAME" | sed -r 's#^@[^/]+/##'); - SBOM_FILE="sbom-packages/$UNSCOPED_PACKAGE_NAME.sbom.json"; + SBOM_FILE="sbom-packages/$UNSCOPED_PACKAGE_NAME.cdx.json"; # if [ ! -f "$SBOM_FILE" ]; then # echo "No SBOM found for $UNSCOPED_PACKAGE_NAME" From 525e50b1da01905995b98ad94440f846d569077c Mon Sep 17 00:00:00 2001 From: Mikhail Preyskurantov <5574159+mpreyskurantov@users.noreply.github.com> Date: Mon, 8 Jun 2026 18:33:03 +0300 Subject: [PATCH 10/16] dx-make-sbom with hashes --- .github/workflows/packages_publishing.yml | 25 ++++++++++++++++++++++- packages/sbom/project.json | 13 ++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/.github/workflows/packages_publishing.yml b/.github/workflows/packages_publishing.yml index d375f9ccd3f3..28a7009fe47c 100644 --- a/.github/workflows/packages_publishing.yml +++ b/.github/workflows/packages_publishing.yml @@ -20,6 +20,7 @@ env: NX_SKIP_NX_CACHE: true FILTER: ${{ github.event_name == 'workflow_dispatch' && inputs.filter || '' }} SET_TIMESTAMP_VERSION: ${{ inputs.tag == 'daily' }} + SBOM_PACKAGE_NAMES: devextreme,devextreme-angular,devextreme-react,devextreme-vue,devextreme-themebuilder CYCLONEDX_CLI_VERSION: 0.32.0 CYCLONEDX_CLI_LINUX_X64_SHA256: 454879e6a4a405c8a13bff49b8982adcb0596f3019b26b0811c66e4d7f0783e1 @@ -54,12 +55,34 @@ jobs: BUILD_INTERNAL_PACKAGE: true run: pnpm run all:build + - name: Prepare SBOM package inputs + shell: bash + run: | + package_version=$(node -p "require('./package.json').version") + IFS=',' read -ra package_names <<< "$SBOM_PACKAGE_NAMES" + sbom_packages=() + + for package_name in "${package_names[@]}"; do + tgz_path="artifacts/npm/$package_name-$package_version.tgz" + + if [ ! -f "$tgz_path" ]; then + echo "Expected package tarball not found: $tgz_path" + exit 1 + fi + + sbom_packages+=("$package_name(../../$tgz_path)") + done + + sbom_packages_value=$(IFS=,; echo "${sbom_packages[*]}") + echo "SBOM_PACKAGES=$sbom_packages_value" >> "$GITHUB_ENV" + echo "$sbom_packages_value" + - name: Build SBOMs env: NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | pnpm set //npm.pkg.github.com/:_authToken="$NODE_AUTH_TOKEN"; - pnpm nx build sbom; + pnpm nx built-hashes sbom; - name: Install CycloneDX CLI shell: bash diff --git a/packages/sbom/project.json b/packages/sbom/project.json index 4d9389597869..462ac2170b7e 100644 --- a/packages/sbom/project.json +++ b/packages/sbom/project.json @@ -22,6 +22,19 @@ ] } }, + "built-hashes": { + "executor": "nx:run-commands", + "dependsOn": ["install-dependencies"], + "options": { + "cwd": "{projectRoot}", + "parallel": false, + "commands": [ + "rm -rf dist/", + "pnpm dx-make-sbom ../../ dist/ \"$SBOM_PACKAGES\"", + "cp dist/devextreme.cdx.json dist/devextreme-dist.cdx.json" + ] + } + }, "make": { "executor": "nx:run-commands", "dependsOn": ["install-dependencies"], From 3ed1bf06f06610ec70226951c7e252c2e6a80b9f Mon Sep 17 00:00:00 2001 From: Mikhail Preyskurantov <5574159+mpreyskurantov@users.noreply.github.com> Date: Mon, 8 Jun 2026 19:02:12 +0300 Subject: [PATCH 11/16] hasSbom for tgz --- .github/workflows/packages_publishing.yml | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/.github/workflows/packages_publishing.yml b/.github/workflows/packages_publishing.yml index 28a7009fe47c..6b5f0f7a175c 100644 --- a/.github/workflows/packages_publishing.yml +++ b/.github/workflows/packages_publishing.yml @@ -191,11 +191,17 @@ jobs: UNSCOPED_PACKAGE_NAME=$(echo "$PACKAGE_NAME" | sed -r 's#^@[^/]+/##'); SBOM_FILE="sbom-packages/$UNSCOPED_PACKAGE_NAME.cdx.json"; - # if [ ! -f "$SBOM_FILE" ]; then - # echo "No SBOM found for $UNSCOPED_PACKAGE_NAME" - # echo "hasSbom=false" >> "$GITHUB_OUTPUT"; - # exit 0; - # fi + if [[ ",$SBOM_PACKAGE_NAMES," != *",$UNSCOPED_PACKAGE_NAME,"* ]]; then + echo "SBOM publishing is not configured for $UNSCOPED_PACKAGE_NAME" + echo "hasSbom=false" >> "$GITHUB_OUTPUT"; + exit 0; + fi + + if [ ! -f "$SBOM_FILE" ]; then + echo "No SBOM found for $UNSCOPED_PACKAGE_NAME" + echo "hasSbom=false" >> "$GITHUB_OUTPUT"; + exit 0; + fi SCOPE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]'); SBOM_PACKAGE_NAME="$UNSCOPED_PACKAGE_NAME-sbom"; @@ -212,6 +218,7 @@ jobs: cd ../..; SCOPED_SBOM_PACKAGE_DIR=$(pnpm --silent run change-package-scope --tgz "$SBOM_TGZ_DIR/$SBOM_PACKAGE_NAME-$PACKAGE_VERSION.tgz" --scope "$SCOPE"); + echo "hasSbom=true" >> "$GITHUB_OUTPUT"; echo "packageDir=$SCOPED_SBOM_PACKAGE_DIR" >> "$GITHUB_OUTPUT"; cd "$SCOPED_SBOM_PACKAGE_DIR"; pnpm pkg get name | tr -d '"' | sed -r 's/(.*)/name=\1/' >> "$GITHUB_OUTPUT"; @@ -235,6 +242,7 @@ jobs: # --ignore-scripts - like above, should be removed, check if could be removed everywhere - name: Publish SBOM to npm.pkg.github.com + if: ${{ steps.scopedSbomPackage.outputs.hasSbom == 'true' }} working-directory: ${{ steps.scopedSbomPackage.outputs.packageDir }} env: NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 5519d6c943187a9ea23daaed1adf35c3c163cf8b Mon Sep 17 00:00:00 2001 From: Mikhail Preyskurantov <5574159+mpreyskurantov@users.noreply.github.com> Date: Tue, 9 Jun 2026 16:07:44 +0300 Subject: [PATCH 12/16] build-hashed --- .github/workflows/packages_publishing.yml | 2 +- packages/sbom/project.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/packages_publishing.yml b/.github/workflows/packages_publishing.yml index 6b5f0f7a175c..c0d71b59eac6 100644 --- a/.github/workflows/packages_publishing.yml +++ b/.github/workflows/packages_publishing.yml @@ -82,7 +82,7 @@ jobs: NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | pnpm set //npm.pkg.github.com/:_authToken="$NODE_AUTH_TOKEN"; - pnpm nx built-hashes sbom; + pnpm nx build-hashed sbom; - name: Install CycloneDX CLI shell: bash diff --git a/packages/sbom/project.json b/packages/sbom/project.json index 462ac2170b7e..470ae9c74375 100644 --- a/packages/sbom/project.json +++ b/packages/sbom/project.json @@ -22,7 +22,7 @@ ] } }, - "built-hashes": { + "build-hashed": { "executor": "nx:run-commands", "dependsOn": ["install-dependencies"], "options": { From f036febd4b477d2dde7b44a209acd5cb7aa13aba Mon Sep 17 00:00:00 2001 From: Mikhail Preyskurantov <5574159+mpreyskurantov@users.noreply.github.com> Date: Wed, 10 Jun 2026 22:12:41 +0300 Subject: [PATCH 13/16] validate via action --- .github/workflows/packages_publishing.yml | 30 ++++++++++------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/.github/workflows/packages_publishing.yml b/.github/workflows/packages_publishing.yml index c0d71b59eac6..5773adf16b8b 100644 --- a/.github/workflows/packages_publishing.yml +++ b/.github/workflows/packages_publishing.yml @@ -21,8 +21,6 @@ env: FILTER: ${{ github.event_name == 'workflow_dispatch' && inputs.filter || '' }} SET_TIMESTAMP_VERSION: ${{ inputs.tag == 'daily' }} SBOM_PACKAGE_NAMES: devextreme,devextreme-angular,devextreme-react,devextreme-vue,devextreme-themebuilder - CYCLONEDX_CLI_VERSION: 0.32.0 - CYCLONEDX_CLI_LINUX_X64_SHA256: 454879e6a4a405c8a13bff49b8982adcb0596f3019b26b0811c66e4d7f0783e1 jobs: build: @@ -84,17 +82,8 @@ jobs: pnpm set //npm.pkg.github.com/:_authToken="$NODE_AUTH_TOKEN"; pnpm nx build-hashed sbom; - - name: Install CycloneDX CLI - shell: bash - run: | - tool_dir="$RUNNER_TEMP/cyclonedx-cli" - mkdir -p "$tool_dir" - curl -fsSL "https://github.com/CycloneDX/cyclonedx-cli/releases/download/v${{ env.CYCLONEDX_CLI_VERSION }}/cyclonedx-linux-x64" -o "$tool_dir/cyclonedx" - echo "${{ env.CYCLONEDX_CLI_LINUX_X64_SHA256 }} $tool_dir/cyclonedx" | sha256sum -c - - chmod +x "$tool_dir/cyclonedx" - echo "$tool_dir" >> "$GITHUB_PATH" - - - name: Validate SBOMs + - name: Collect SBOM files + id: sbomFiles shell: bash run: | shopt -s nullglob @@ -105,10 +94,17 @@ jobs: exit 1 fi - for file in "${sbom_files[@]}"; do - echo "Validating $file" - cyclonedx validate --input-file "$file" --input-format json --fail-on-errors - done + { + echo "files<> "$GITHUB_OUTPUT" + + - name: Validate SBOMs + uses: mpreyskurantov/github-actions/validate-sbom@sbom-val-dev + with: + input-format: json + input-files: ${{ steps.sbomFiles.outputs.files }} - name: Build artifacts package run: pnpm run make-artifacts-package From 8f9a65fc2f992c2831c7ce1b77f2eac50e807854 Mon Sep 17 00:00:00 2001 From: Mikhail Preyskurantov <5574159+mpreyskurantov@users.noreply.github.com> Date: Wed, 17 Jun 2026 18:14:14 +0300 Subject: [PATCH 14/16] DevExpress/github-actions/validate-sbom + commit hash --- .github/workflows/packages_publishing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/packages_publishing.yml b/.github/workflows/packages_publishing.yml index 5773adf16b8b..1b2b78985a50 100644 --- a/.github/workflows/packages_publishing.yml +++ b/.github/workflows/packages_publishing.yml @@ -101,7 +101,7 @@ jobs: } >> "$GITHUB_OUTPUT" - name: Validate SBOMs - uses: mpreyskurantov/github-actions/validate-sbom@sbom-val-dev + uses: DevExpress/github-actions/validate-sbom@5034a6d5e0fd18fc2826ed20a5140f9c83b8994f with: input-format: json input-files: ${{ steps.sbomFiles.outputs.files }} From 6bb3327da65483aad095dd3e0cdf54a249f8304d Mon Sep 17 00:00:00 2001 From: Mikhail Preyskurantov <5574159+mpreyskurantov@users.noreply.github.com> Date: Sun, 21 Jun 2026 01:13:11 +0300 Subject: [PATCH 15/16] publish scoped sboms instantly (without changing scope) --- .github/workflows/packages_publishing.yml | 32 ++++++++++++++--------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/.github/workflows/packages_publishing.yml b/.github/workflows/packages_publishing.yml index 1b2b78985a50..6c87112b7824 100644 --- a/.github/workflows/packages_publishing.yml +++ b/.github/workflows/packages_publishing.yml @@ -53,6 +53,8 @@ jobs: BUILD_INTERNAL_PACKAGE: true run: pnpm run all:build + # Builds the dx-make-sbom package argument list from known package names and the tgz files produced in artifacts/npm. + # Produces SBOM_PACKAGES for the packages/sbom build-hashed target. - name: Prepare SBOM package inputs shell: bash run: | @@ -75,6 +77,8 @@ jobs: echo "SBOM_PACKAGES=$sbom_packages_value" >> "$GITHUB_ENV" echo "$sbom_packages_value" + # Generates CycloneDX SBOM JSON files for the selected packages using the just-built tgz files. + # Produces packages/sbom/dist/*.cdx.json. - name: Build SBOMs env: NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -82,6 +86,8 @@ jobs: pnpm set //npm.pkg.github.com/:_authToken="$NODE_AUTH_TOKEN"; pnpm nx build-hashed sbom; + # Collects concrete SBOM file paths for validation because the shared action expects explicit file names. + # Produces the sbomFiles.outputs.files multiline output. - name: Collect SBOM files id: sbomFiles shell: bash @@ -100,6 +106,8 @@ jobs: echo "EOF" } >> "$GITHUB_OUTPUT" + # Validates every generated CycloneDX SBOM file with the shared validation action. + # Produces no artifact; fails the workflow if any SBOM is invalid. - name: Validate SBOMs uses: DevExpress/github-actions/validate-sbom@5034a6d5e0fd18fc2826ed20a5140f9c83b8994f with: @@ -109,6 +117,8 @@ jobs: - name: Build artifacts package run: pnpm run make-artifacts-package + # Saves generated SBOM files for the publish job. + # Produces the sbom-packages workflow artifact. - name: Upload SBOMs uses: actions/upload-artifact@v7 with: @@ -147,6 +157,8 @@ jobs: name: npm-packages path: npm-packages + # Restores generated SBOM files from the build job. + # Produces the local sbom-packages directory for matrix publishing. - name: Download SBOMs uses: actions/download-artifact@v8 with: @@ -178,6 +190,8 @@ jobs: pnpm pkg get version | tr -d '"' | sed -r 's/(.*)/version=\1/' >> "$GITHUB_OUTPUT"; pnpm pkg get version | tr -d '"' | sed -r 's/([0-9]+\.[0-9]+).*/majorVersion=\1/' >> "$GITHUB_OUTPUT"; + # Wraps the matching SBOM JSON file into a minimal scoped npm package when the matrix package has an SBOM. + # Produces scopedSbomPackage outputs used by the publish step. - name: Build SBOM package id: scopedSbomPackage env: @@ -200,23 +214,15 @@ jobs: fi SCOPE=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]'); - SBOM_PACKAGE_NAME="$UNSCOPED_PACKAGE_NAME-sbom"; + SBOM_PACKAGE_NAME="@$SCOPE/$UNSCOPED_PACKAGE_NAME-sbom"; SBOM_PACKAGE_DIR="sbom-package/$SBOM_PACKAGE_NAME"; - SBOM_TGZ_DIR="sbom-package-tgz"; - PACKAGE_LICENSE=$(node -p "require('./package.json').license"); - PACKAGE_AUTHOR=$(node -p "require('./package.json').author"); - mkdir -p "$SBOM_PACKAGE_DIR" "$SBOM_TGZ_DIR"; + mkdir -p "$SBOM_PACKAGE_DIR"; cp "$SBOM_FILE" "$SBOM_PACKAGE_DIR/"; cd "$SBOM_PACKAGE_DIR"; - node -e "const fs = require('fs'); const [name, version, license, author] = process.argv.slice(1); fs.writeFileSync('package.json', JSON.stringify({ name, version, license, author }, null, 2));" "$SBOM_PACKAGE_NAME" "$PACKAGE_VERSION" "$PACKAGE_LICENSE" "$PACKAGE_AUTHOR"; - npm pack --pack-destination "../../$SBOM_TGZ_DIR"; - cd ../..; - - SCOPED_SBOM_PACKAGE_DIR=$(pnpm --silent run change-package-scope --tgz "$SBOM_TGZ_DIR/$SBOM_PACKAGE_NAME-$PACKAGE_VERSION.tgz" --scope "$SCOPE"); + node -e "const fs = require('fs'); const [name, version] = process.argv.slice(1); fs.writeFileSync('package.json', JSON.stringify({ name, version }, null, 2));" "$SBOM_PACKAGE_NAME" "$PACKAGE_VERSION"; echo "hasSbom=true" >> "$GITHUB_OUTPUT"; - echo "packageDir=$SCOPED_SBOM_PACKAGE_DIR" >> "$GITHUB_OUTPUT"; - cd "$SCOPED_SBOM_PACKAGE_DIR"; + echo "packageDir=$PWD" >> "$GITHUB_OUTPUT"; pnpm pkg get name | tr -d '"' | sed -r 's/(.*)/name=\1/' >> "$GITHUB_OUTPUT"; pnpm pkg get version | tr -d '"' | sed -r 's/(.*)/version=\1/' >> "$GITHUB_OUTPUT"; pnpm pkg get version | tr -d '"' | sed -r 's/([0-9]+\.[0-9]+).*/majorVersion=\1/' >> "$GITHUB_OUTPUT"; @@ -237,6 +243,8 @@ jobs: pnpm dist-tag add $PACKAGE_NAME@$PACKAGE_VERSION latest --registry=https://npm.pkg.github.com; # --ignore-scripts - like above, should be removed, check if could be removed everywhere + # Publishes the generated scoped SBOM npm package to GitHub Packages. + # Produces @/-sbom in the npm.pkg.github.com feed. - name: Publish SBOM to npm.pkg.github.com if: ${{ steps.scopedSbomPackage.outputs.hasSbom == 'true' }} working-directory: ${{ steps.scopedSbomPackage.outputs.packageDir }} From 221223812bd51eb87aeeb68990681846abd683cd Mon Sep 17 00:00:00 2001 From: Mikhail Preyskurantov <5574159+mpreyskurantov@users.noreply.github.com> Date: Sun, 21 Jun 2026 21:18:15 +0300 Subject: [PATCH 16/16] packages/sbom/pnpm-lock.yaml: the lockfile contains entries that the active policies reject --- packages/sbom/pnpm-lock.yaml | 170 +++++++++++++++++++---------------- 1 file changed, 93 insertions(+), 77 deletions(-) diff --git a/packages/sbom/pnpm-lock.yaml b/packages/sbom/pnpm-lock.yaml index c7bb6af659c9..6df372c35dd0 100644 --- a/packages/sbom/pnpm-lock.yaml +++ b/packages/sbom/pnpm-lock.yaml @@ -31,24 +31,24 @@ packages: resolution: {integrity: sha512-mTaD3YA1pJeEom8oyKjQ7wmfR+kDBZss15+aBIZ83gYkWFlgT9rWSM1cMsAcBJLTR9vcHIQ/bCo/JZewXkHN5Q==} engines: {node: '>=20'} - '@babel/code-frame@7.29.0': - resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + '@babel/code-frame@7.29.7': + resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} engines: {node: '>=6.9.0'} - '@babel/generator@7.29.1': - resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + '@babel/generator@7.29.7': + resolution: {integrity: sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==} engines: {node: '>=6.9.0'} - '@babel/helper-globals@7.28.0': - resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + '@babel/helper-globals@7.29.7': + resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@7.27.1': - resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + '@babel/helper-string-parser@7.29.7': + resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.28.5': - resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} engines: {node: '>=6.9.0'} '@babel/parser@7.29.3': @@ -56,16 +56,21 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - '@babel/template@7.28.6': - resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + '@babel/parser@7.29.7': + resolution: {integrity: sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/template@7.29.7': + resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==} engines: {node: '>=6.9.0'} '@babel/traverse@7.29.0': resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} engines: {node: '>=6.9.0'} - '@babel/types@7.29.0': - resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + '@babel/types@7.29.7': + resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==} engines: {node: '>=6.9.0'} '@bufbuild/protobuf@2.12.0': @@ -259,8 +264,8 @@ packages: resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} engines: {node: '>=14.16'} - cacheable-request@13.0.18: - resolution: {integrity: sha512-rFWadDRKJs3s2eYdXlGggnBZKG7MTblkFBB0YllFds+UYnfogDp2wcR6JN97FhRkHTvq59n2vhNoHNZn29dh/Q==} + cacheable-request@13.0.19: + resolution: {integrity: sha512-SVXGH037+Mo1aIMO5B2UcleR43FGjFdN+M8JObSyEoQ2Mn4CODRWx28gN5jiTF0n5ItsgtIZfyargMNs8GX4kg==} engines: {node: '>=18'} call-bind-apply-helpers@1.0.2: @@ -309,6 +314,10 @@ packages: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} + content-type@2.0.0: + resolution: {integrity: sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==} + engines: {node: '>=18'} + css-select@5.2.2: resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} @@ -395,8 +404,8 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + es-object-atoms@1.1.2: + resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} engines: {node: '>= 0.4'} escalade@3.2.0: @@ -427,8 +436,8 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-east-asian-width@1.5.0: - resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} + get-east-asian-width@1.6.0: + resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} engines: {node: '>=18'} get-intrinsic@1.3.0: @@ -459,8 +468,8 @@ packages: resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} engines: {node: '>= 0.4'} - hasown@2.0.3: - resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} engines: {node: '>= 0.4'} hermes-estree@0.36.1: @@ -469,8 +478,8 @@ packages: hermes-parser@0.36.1: resolution: {integrity: sha512-GApNk4zLHi2UWoWZZkx7LNCOSzLSc5lB55pZ/PhK7ycFeg7u5LcF88p/WbpIi1XUDtE0MpHE3uRR3u3KB7TjSQ==} - hosted-git-info@9.0.2: - resolution: {integrity: sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==} + hosted-git-info@9.0.3: + resolution: {integrity: sha512-Hc+ghLoSt6QaYZUv0WBiIvmMDZuZZ7oaDvdH8MbfOO4lOsxdXLEvuC6ePoGs9H1X9oCLyq6+NVN0MKqD+ydxyg==} engines: {node: ^20.17.0 || >=22.9.0} htmlparser2@10.1.0: @@ -545,8 +554,8 @@ packages: resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - lru-cache@11.3.5: - resolution: {integrity: sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==} + lru-cache@11.5.1: + resolution: {integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==} engines: {node: 20 || >=22} math-intrinsics@1.1.0: @@ -739,8 +748,8 @@ packages: resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} engines: {node: '>= 0.4'} - side-channel@1.1.0: - resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + side-channel@1.1.1: + resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} engines: {node: '>= 0.4'} signal-exit@4.1.0: @@ -792,17 +801,17 @@ packages: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} - type-is@2.0.1: - resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} - engines: {node: '>= 0.6'} + type-is@2.1.0: + resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} + engines: {node: '>= 18'} typescript@6.0.3: resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} engines: {node: '>=14.17'} hasBin: true - undici@7.25.0: - resolution: {integrity: sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==} + undici@7.28.0: + resolution: {integrity: sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==} engines: {node: '>=20.18.1'} unpipe@1.0.0: @@ -903,52 +912,56 @@ snapshots: '@bufbuild/protobuf': 2.12.0 optional: true - '@babel/code-frame@7.29.0': + '@babel/code-frame@7.29.7': dependencies: - '@babel/helper-validator-identifier': 7.28.5 + '@babel/helper-validator-identifier': 7.29.7 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/generator@7.29.1': + '@babel/generator@7.29.7': dependencies: - '@babel/parser': 7.29.3 - '@babel/types': 7.29.0 + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 - '@babel/helper-globals@7.28.0': {} + '@babel/helper-globals@7.29.7': {} - '@babel/helper-string-parser@7.27.1': {} + '@babel/helper-string-parser@7.29.7': {} - '@babel/helper-validator-identifier@7.28.5': {} + '@babel/helper-validator-identifier@7.29.7': {} '@babel/parser@7.29.3': dependencies: - '@babel/types': 7.29.0 + '@babel/types': 7.29.7 - '@babel/template@7.28.6': + '@babel/parser@7.29.7': dependencies: - '@babel/code-frame': 7.29.0 - '@babel/parser': 7.29.3 - '@babel/types': 7.29.0 + '@babel/types': 7.29.7 + + '@babel/template@7.29.7': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/parser': 7.29.7 + '@babel/types': 7.29.7 '@babel/traverse@7.29.0': dependencies: - '@babel/code-frame': 7.29.0 - '@babel/generator': 7.29.1 - '@babel/helper-globals': 7.28.0 + '@babel/code-frame': 7.29.7 + '@babel/generator': 7.29.7 + '@babel/helper-globals': 7.29.7 '@babel/parser': 7.29.3 - '@babel/template': 7.28.6 - '@babel/types': 7.29.0 + '@babel/template': 7.29.7 + '@babel/types': 7.29.7 debug: 4.4.3 transitivePeerDependencies: - supports-color - '@babel/types@7.29.0': + '@babel/types@7.29.7': dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.28.5 + '@babel/helper-string-parser': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 '@bufbuild/protobuf@2.12.0': optional: true @@ -1098,7 +1111,7 @@ snapshots: '@gar/promise-retry': 1.0.3 '@npmcli/promise-spawn': 9.0.1 ini: 6.0.0 - lru-cache: 11.3.5 + lru-cache: 11.5.1 npm-pick-manifest: 11.0.3 proc-log: 6.1.0 semver: 7.8.1 @@ -1117,7 +1130,7 @@ snapshots: dependencies: '@npmcli/git': 7.0.2 glob: 13.0.6 - hosted-git-info: 9.0.2 + hosted-git-info: 9.0.3 json-parse-even-better-errors: 5.0.0 proc-log: 6.1.0 semver: 7.8.1 @@ -1168,7 +1181,7 @@ snapshots: on-finished: 2.4.1 qs: 6.15.2 raw-body: 3.0.2 - type-is: 2.0.1 + type-is: 2.1.0 transitivePeerDependencies: - supports-color optional: true @@ -1186,7 +1199,7 @@ snapshots: cacheable-lookup@7.0.0: {} - cacheable-request@13.0.18: + cacheable-request@13.0.19: dependencies: '@types/http-cache-semantics': 4.2.0 get-stream: 9.0.1 @@ -1228,7 +1241,7 @@ snapshots: parse5: 7.3.0 parse5-htmlparser2-tree-adapter: 7.1.0 parse5-parser-stream: 7.1.2 - undici: 7.25.0 + undici: 7.28.0 whatwg-mimetype: 4.0.0 chownr@3.0.0: {} @@ -1274,6 +1287,9 @@ snapshots: content-type@1.0.5: optional: true + content-type@2.0.0: + optional: true + css-select@5.2.2: dependencies: boolbase: 1.0.0 @@ -1352,7 +1368,7 @@ snapshots: es-errors@1.3.0: optional: true - es-object-atoms@1.1.1: + es-object-atoms@1.1.2: dependencies: es-errors: 1.3.0 optional: true @@ -1386,26 +1402,26 @@ snapshots: get-caller-file@2.0.5: {} - get-east-asian-width@1.5.0: {} + get-east-asian-width@1.6.0: {} get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 es-define-property: 1.0.1 es-errors: 1.3.0 - es-object-atoms: 1.1.1 + es-object-atoms: 1.1.2 function-bind: 1.1.2 get-proto: 1.0.1 gopd: 1.2.0 has-symbols: 1.1.0 - hasown: 2.0.3 + hasown: 2.0.4 math-intrinsics: 1.1.0 optional: true get-proto@1.0.1: dependencies: dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 + es-object-atoms: 1.1.2 optional: true get-stream@9.0.1: @@ -1427,7 +1443,7 @@ snapshots: '@sindresorhus/is': 7.2.0 byte-counter: 0.1.0 cacheable-lookup: 7.0.0 - cacheable-request: 13.0.18 + cacheable-request: 13.0.19 decompress-response: 10.0.0 form-data-encoder: 4.1.0 http2-wrapper: 2.2.1 @@ -1440,7 +1456,7 @@ snapshots: has-symbols@1.1.0: optional: true - hasown@2.0.3: + hasown@2.0.4: dependencies: function-bind: 1.1.2 optional: true @@ -1453,9 +1469,9 @@ snapshots: hermes-estree: 0.36.1 optional: true - hosted-git-info@9.0.2: + hosted-git-info@9.0.3: dependencies: - lru-cache: 11.3.5 + lru-cache: 11.5.1 htmlparser2@10.1.0: dependencies: @@ -1520,7 +1536,7 @@ snapshots: lowercase-keys@3.0.0: {} - lru-cache@11.3.5: {} + lru-cache@11.5.1: {} math-intrinsics@1.1.0: optional: true @@ -1570,7 +1586,7 @@ snapshots: npm-package-arg@13.0.2: dependencies: - hosted-git-info: 9.0.2 + hosted-git-info: 9.0.3 proc-log: 6.1.0 semver: 7.8.1 validate-npm-package-name: 7.0.2 @@ -1630,7 +1646,7 @@ snapshots: path-scurry@2.0.2: dependencies: - lru-cache: 11.3.5 + lru-cache: 11.5.1 minipass: 7.1.3 picocolors@1.1.1: {} @@ -1646,7 +1662,7 @@ snapshots: qs@6.15.2: dependencies: - side-channel: 1.1.0 + side-channel: 1.1.1 optional: true quick-lru@5.1.1: {} @@ -1709,7 +1725,7 @@ snapshots: side-channel-map: 1.0.1 optional: true - side-channel@1.1.0: + side-channel@1.1.1: dependencies: es-errors: 1.3.0 object-inspect: 1.13.4 @@ -1742,7 +1758,7 @@ snapshots: string-width@7.2.0: dependencies: emoji-regex: 10.6.0 - get-east-asian-width: 1.5.0 + get-east-asian-width: 1.6.0 strip-ansi: 7.2.0 strip-ansi@7.2.0: @@ -1764,9 +1780,9 @@ snapshots: type-fest@4.41.0: {} - type-is@2.0.1: + type-is@2.1.0: dependencies: - content-type: 1.0.5 + content-type: 2.0.0 media-typer: 1.1.0 mime-types: 3.0.2 optional: true @@ -1774,7 +1790,7 @@ snapshots: typescript@6.0.3: optional: true - undici@7.25.0: {} + undici@7.28.0: {} unpipe@1.0.0: optional: true