Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 99 additions & 0 deletions .github/actions/update-sbom/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
name: Generate SBOM
description: Generates CycloneDX SBOM using CycloneDX PHP Composer plugin
inputs:
output-file:
description: "Output filename for the SBOM"
required: false
default: "sbom.json"
outputs:
HAS_CHANGES:
description: "Whether the SBOM has meaningful changes compared to the existing version"
value: ${{ steps.check_changes.outputs.HAS_CHANGES }}
runs:
using: composite
steps:
- name: Allow CycloneDX plugin
shell: bash
run: composer config allow-plugins.cyclonedx/cyclonedx-php-composer true

- name: Install CycloneDX plugin
shell: bash
run: composer require --dev cyclonedx/cyclonedx-php-composer

- name: Generate SBOM
id: generate-sbom
shell: bash
run: |
echo "Generating SBOM for 'php' project..."
composer CycloneDX:make-sbom --output-file=sbom-new.json --output-format=json --spec-version=1.5

- name: Validate SBOM presence
shell: bash
run: |
if [ ! -f "sbom-new.json" ]; then
echo "Error: SBOM file not found"
exit 1
fi
echo "SBOM file generated: sbom-new.json"

- name: Download CycloneDX CLI
shell: bash
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
shell: bash
run: /tmp/cyclonedx validate --input-file sbom-new.json --fail-on-errors

- name: Check for SBOM changes
id: check_changes
if: steps.generate-sbom.outcome == 'success'
shell: bash
env:
SBOM_FILE: ${{ inputs.output-file }}
run: |
JQ_NORMALIZER='del(.serialNumber) | del(.metadata.timestamp) | walk(if type == "object" and .timestamp then .timestamp = "TIMESTAMP_NORMALIZED" else . end)'

if [ -f "$SBOM_FILE" ]; then
echo "Comparing new SBOM with existing $SBOM_FILE..."

# First try cyclonedx diff for component-level comparison
DIFF_OUTPUT=$(/tmp/cyclonedx diff "$SBOM_FILE" sbom-new.json --component-versions 2>/dev/null || true)

if echo "$DIFF_OUTPUT" | grep -q "^None$"; then
echo "No component changes detected via cyclonedx diff"

# Double-check with jq normalization (excludes metadata like timestamps)
if diff -q \
<(cat "$SBOM_FILE" | jq -r "$JQ_NORMALIZER") \
<(cat sbom-new.json | jq -r "$JQ_NORMALIZER") > /dev/null 2>&1; then
echo "HAS_CHANGES=false" >> $GITHUB_OUTPUT
echo "No meaningful changes detected in SBOM"
rm sbom-new.json
else
echo "HAS_CHANGES=true" >> $GITHUB_OUTPUT
echo "Changes detected in SBOM (non-component changes)"
mv sbom-new.json "$SBOM_FILE"
fi
else
echo "Component changes detected:"
echo "$DIFF_OUTPUT"
echo "HAS_CHANGES=true" >> $GITHUB_OUTPUT
mv sbom-new.json "$SBOM_FILE"
fi
else
echo "No existing $SBOM_FILE found, creating initial version"
echo "HAS_CHANGES=true" >> $GITHUB_OUTPUT
mv sbom-new.json "$SBOM_FILE"
fi
continue-on-error: true

- name: Final SBOM validation
shell: bash
run: |
if [ ! -f "${{ inputs.output-file }}" ]; then
echo "Error: Final SBOM file not found at ${{ inputs.output-file }}"
exit 1
fi
echo "SBOM file validated: ${{ inputs.output-file }}"
88 changes: 81 additions & 7 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ on:
type: "string"

env:
PHP_VERSION: "8.2"
DRIVER_VERSION: "mongodb/mongo-php-driver@${{ inputs.version }}"
SBOM_FILE: "sbom.json"
default-release-message: |
The PHP team is happy to announce that version {0} of the MongoDB PHP library is now available.

Expand Down Expand Up @@ -48,12 +51,6 @@ jobs:
- name: "Create release output"
run: echo '🎬 Release process for version ${{ inputs.version }} started by @${{ github.triggering_actor }}' >> $GITHUB_STEP_SUMMARY

- name: "Generate token and checkout repository"
uses: mongodb-labs/drivers-github-tools/secure-checkout@v3
with:
app_id: ${{ vars.APP_ID }}
private_key: ${{ secrets.APP_PRIVATE_KEY }}

Comment on lines -51 to -56
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this removed? The "Create and push new release branch" step pushes a branch in line 91, which requires an appropriate token if I'm not mistaken.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was moved to later stages, but now I moved it up - before sbom gen.

- name: "Store version numbers in env variables"
run: |
echo RELEASE_VERSION=${{ inputs.version }} >> $GITHUB_ENV
Expand Down Expand Up @@ -94,16 +91,93 @@ jobs:
git push origin ${RELEASE_BRANCH}

#
# Preliminary checks done - commence the release process
# Preliminary checks done - setting up the environment
#

- name: "Generate token and checkout repository"
uses: mongodb-labs/drivers-github-tools/secure-checkout@v3
with:
app_id: ${{ vars.APP_ID }}
private_key: ${{ secrets.APP_PRIVATE_KEY }}
submodules: true
fetch-depth: 0

- name: "Set up drivers-github-tools"
uses: mongodb-labs/drivers-github-tools/setup@v3
with:
aws_role_arn: ${{ secrets.AWS_ROLE_ARN }}
aws_region_name: ${{ vars.AWS_REGION_NAME }}
aws_secret_id: ${{ secrets.AWS_SECRET_ID }}

- name: "Setup PHP environment"
id: setup-php
uses: ./.github/actions/setup
with:
php-version: ${{ env.PHP_VERSION }}
driver-version: ${{ env.DRIVER_VERSION }}
working-directory: '.'
continue-on-error: true

#
# Preliminary checks and setup done - generate SBOM before tagging
#

- name: "Generate/Update composer.lock"
id: composer-lock
run: |
echo "Resolving dependencies and generating composer.lock..."
composer update --no-install
echo "composer.lock generated with resolved versions"
continue-on-error: true

- name: "Generate SBOM"
id: generate-sbom
if: steps.composer-lock.outcome == 'success'
uses: ./.github/actions/update-sbom
with:
output-file: ${{ env.SBOM_FILE }}
continue-on-error: true

- name: "Determine branch to merge up to"
if: steps.generate-sbom.outputs.HAS_CHANGES == 'true'
id: get-next-branch
uses: alcaeus/automatic-merge-up-action/get-next-branch@1.0.1
with:
ref: ${{ github.ref_name }}
branchNamePattern: 'v<major>.<minor>'
devBranchNamePattern: 'v<major>.x'
ignoredBranches: ${{ vars.IGNORED_MERGE_UP_BRANCHES }}

- name: "Manually merge up changes"
if: steps.generate-sbom.outputs.HAS_CHANGES == 'true' && steps.get-next-branch.outputs.hasNextBranch == 'true'
run: |
git checkout ${NEXT_BRANCH}
git merge --strategy=ours ${RELEASE_BRANCH}
git push origin ${NEXT_BRANCH}
git checkout ${RELEASE_BRANCH}
env:
NEXT_BRANCH: ${{ steps.get-next-branch.outputs.branchName }}

- name: "Commit SBOM changes"
if: steps.generate-sbom.outputs.HAS_CHANGES == 'true'
run: |
git add ${{ env.SBOM_FILE }}
git commit -m "chore: Update SBOM for release ${{ inputs.version }}"
git push
echo "SBOM updated and committed" >> $GITHUB_STEP_SUMMARY
continue-on-error: true

- name: "Report SBOM status"
run: |
if [[ "${{ steps.generate-sbom.outcome }}" == "success" ]]; then
echo "SBOM generation completed successfully" >> $GITHUB_STEP_SUMMARY
else
echo "SBOM generation skipped or failed - continuing with release" >> $GITHUB_STEP_SUMMARY
fi

#
# Preliminary checks done - commence the release process
#
- name: "Prepare release message"
run: |
cat > release-message <<'EOL'
Expand Down
Loading