-
Notifications
You must be signed in to change notification settings - Fork 31
INTPYTHON-821 Add workflow to update SBOM #451
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| name: Generate SBOM | ||
|
|
||
| # This workflow uses cyclonedx-py and publishes an sbom.json artifact. | ||
| # It runs on manual trigger or when package files change on the target | ||
| # branches, and creates a PR with the updated SBOM. | ||
| # Internal documentation: go/sbom-scope | ||
|
|
||
| on: | ||
| workflow_dispatch: {} | ||
| push: | ||
| branches: ['main', '5.2.x'] | ||
| paths: | ||
| - 'pyproject.toml' | ||
| - 'requirements.txt' | ||
|
Comment on lines
+12
to
+14
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's possible for these files to have changes that don't involve any dependency changes. Is there logic in this job that prevents a PR from being opened in this case? (I guess GitHub may disallow a PR with no changes, or possibly it would be closed immediately; just want to confirm.)
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure myself, but I would say that if it:
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Depending on the answer to #451 (comment), it might be better to simply make this part of the pre-release process.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the file changes at all, it will trigger the action to run and make an sbom PR. you'd just see the dates/metadata of the sbom.json to be changed. In that scenario the team can just close the PR. Our team does require that the master branch have an up-to-date sbom for tracking. I can definitely add the logic if you think it's worth the extra step (actions will still get ran regardless, but we'd just compare the sbom files to see if any components actually got changed)
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it's straightforward, I think it would be valuable to avoid useless PRs, especially if this script has to be applied to many repositories.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And incidentally, we don't have any dependencies in
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. pyproject.toml stores the info for the actual django-mngodb-backend. Changes to meta data will be reflected into sbom (description, versions, etc). With the new check for component diff check, this should solve the false positive change issue if you're modifying something that won't update the sbom.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just to clarify: we do have dependencies in
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @thanhnguyen-mdb FYI, see what pymongo did: mongodb/mongo-python-driver#2647 removing pyproject.toml from the watched paths). If I understand correctly, maybe it would have been better to use the alternative approach you implemented here (although I'm not sure if there's any practical difference). |
||
|
|
||
| permissions: | ||
| contents: write | ||
| pull-requests: write | ||
|
|
||
| jobs: | ||
| sbom: | ||
| name: Generate SBOM and Create PR | ||
| runs-on: ubuntu-latest | ||
| concurrency: | ||
| group: sbom-${{ github.ref }} | ||
| cancel-in-progress: false | ||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v6 | ||
| with: | ||
| persist-credentials: false | ||
| - name: Set up Python | ||
| uses: actions/setup-python@v6 | ||
| with: | ||
| python-version: "3.x" | ||
| - name: Generate SBOM | ||
| run: | | ||
| python -m venv .venv | ||
| source .venv/bin/activate | ||
| pip install . | ||
| pip uninstall -y pip setuptools | ||
| deactivate | ||
| python -m venv .venv-sbom | ||
| source .venv-sbom/bin/activate | ||
| pip install cyclonedx-bom==7.2.1 | ||
thanhnguyen-mdb marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| cyclonedx-py environment --spec-version 1.5 --output-format JSON --output-file sbom-new.json .venv | ||
| # Add PURL for django-mongodb-backend (local package doesn't get PURL automatically) | ||
| jq '(.components[] | select(.name == "django-mongodb-backend" and .purl == null)) |= (. + {purl: ("pkg:pypi/django-mongodb-backend@" + .version)})' sbom-new.json > sbom.tmp.json && mv sbom.tmp.json sbom-new.json | ||
| - name: Download CycloneDX CLI | ||
| run: | | ||
| curl -L -s -o /tmp/cyclonedx "https://github.com/CycloneDX/cyclonedx-cli/releases/download/v0.29.1/cyclonedx-linux-x64" | ||
| chmod +x /tmp/cyclonedx | ||
| - name: Validate SBOM | ||
| run: /tmp/cyclonedx validate --input-file sbom-new.json --fail-on-errors | ||
| - name: Check for changes | ||
| id: check_changes | ||
| run: | | ||
| if [ -f sbom.json ]; then | ||
| echo "Comparing new SBOM with existing sbom.json..." | ||
| # Use cyclonedx diff to check for component changes | ||
| DIFF_OUTPUT=$(/tmp/cyclonedx diff sbom.json sbom-new.json --component-versions) | ||
|
|
||
| # Check if there are meaningful changes (output contains more than just "None") | ||
| if echo "$DIFF_OUTPUT" | grep -q "^None$"; then | ||
| echo "No component changes detected (only metadata differs)" | ||
| echo "Keeping existing sbom.json" | ||
| rm sbom-new.json | ||
| else | ||
| echo "Component changes detected:" | ||
| echo "$DIFF_OUTPUT" | ||
| echo "Updating sbom.json" | ||
| mv sbom-new.json sbom.json | ||
| fi | ||
| else | ||
| echo "No existing sbom.json found, creating initial version" | ||
| mv sbom-new.json sbom.json | ||
| fi | ||
| - name: Cleanup | ||
| if: always() | ||
| run: rm -rf .venv .venv-sbom | ||
| - name: Upload SBOM artifact | ||
| uses: actions/upload-artifact@v6 | ||
| with: | ||
| name: sbom | ||
| path: sbom.json | ||
| if-no-files-found: error | ||
| - name: Create Pull Request | ||
| uses: peter-evans/create-pull-request@84ae59a2cdc2258d6fa0732dd66352dddae2a412 # v7.0.9 | ||
| with: | ||
| token: ${{ secrets.GITHUB_TOKEN }} | ||
| commit-message: 'Update SBOM after dependency changes' | ||
| branch: auto-update-sbom-${{ github.run_id }} | ||
| delete-branch: true | ||
| title: 'Update SBOM' | ||
| body: | | ||
| ## Automated SBOM Update | ||
|
|
||
| This PR was automatically generated because dependency manifest files changed. | ||
|
|
||
| ### Changes | ||
| - Updated `sbom.json` to reflect current dependencies | ||
|
|
||
| ### Verification | ||
| The SBOM was generated using cyclonedx-py with the current Python environment. | ||
|
|
||
| ### Triggered by | ||
| - Commit: ${{ github.sha }} | ||
| - Workflow run: ${{ github.run_id }} | ||
|
|
||
| --- | ||
| _This PR was created automatically by the [SBOM workflow](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})_ | ||
| labels: | | ||
| sbom | ||
| automated | ||
| dependencies | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added the 5.2.x branch here, but I'm not sure if it works correctly. Will the job checkout this branch and send the PR to it?