Skip to content
Merged
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
11 changes: 3 additions & 8 deletions .github/workflows/sbom-builder.yml
Original file line number Diff line number Diff line change
Expand Up @@ -259,13 +259,10 @@ jobs:
steps.config.outputs.component_id != '' && !inputs.dry_run
&& (steps.config.outputs.source_type == 'docker'
|| steps.config.outputs.source_type == 'chainguard')
&& steps.config.outputs.product_id != ''
run: |
source scripts/lib/common.sh
source scripts/lib/sbomify-api.sh
if sbomify_digest_exists \
"${{ steps.config.outputs.product_id }}" \
"${{ steps.config.outputs.version }}" \
"${{ steps.config.outputs.component_id }}" \
"${{ steps.digest.outputs.image_digest }}"; then
echo "Digest already exists, skipping upload"
Expand Down Expand Up @@ -319,18 +316,16 @@ jobs:
UPLOAD: true
PRODUCT_RELEASE: ${{ steps.config.outputs.product_release }}

- name: Cleanup old release artifacts
- name: Cleanup old SBOMs
if: >-
steps.config.outputs.product_id != '' && !inputs.dry_run
steps.config.outputs.component_id != '' && !inputs.dry_run
&& steps.upload-decision.outputs.should_upload == 'true'
&& (steps.config.outputs.source_type == 'docker'
|| steps.config.outputs.source_type == 'chainguard')
run: |
source scripts/lib/common.sh
source scripts/lib/sbomify-api.sh
sbomify_cleanup_old_artifacts \
"${{ steps.config.outputs.product_id }}" \
"${{ steps.config.outputs.version }}" \
sbomify_cleanup_old_sboms \
"${{ steps.config.outputs.component_id }}" \
"${{ steps.digest.outputs.image_digest }}"
env:
Expand Down
60 changes: 20 additions & 40 deletions scripts/lib/sbomify-api.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,53 +10,33 @@ set -euo pipefail

SBOMIFY_API="${SBOMIFY_API_URL:-https://app.sbomify.com}"

# Check if a release artifact already has this digest version
# Usage: sbomify_digest_exists <product_id> <tag_version> <component_id> <digest>
# Check if a component already has an SBOM with this digest as version
# Usage: sbomify_digest_exists <component_id> <digest>
# Returns: 0 if exists, 1 if not
sbomify_digest_exists() {
local product_id="$1" tag_version="$2" component_id="$3" digest="$4"
local component_id="$1" digest="$2"

# Find the release
local releases release_id
releases=$(curl -fsSL -H "Authorization: Bearer ${SBOMIFY_TOKEN}" \
"${SBOMIFY_API}/api/v1/releases?product_id=${product_id}&version=${tag_version}")
release_id=$(echo "$releases" | jq -r --arg v "$tag_version" \
'.items[] | select(.version == $v) | .id' | head -1)

[[ -z "$release_id" ]] && return 1 # No release → digest doesn't exist

# Check artifacts for matching digest
local artifacts
artifacts=$(curl -fsSL -H "Authorization: Bearer ${SBOMIFY_TOKEN}" \
"${SBOMIFY_API}/api/v1/releases/${release_id}/artifacts?mode=existing")
echo "$artifacts" | jq -e --arg cid "$component_id" --arg d "$digest" \
'.items[] | select(.component_id == $cid and .sbom_version == $d)' > /dev/null 2>&1
local sboms
sboms=$(curl -fsSL -H "Authorization: Bearer ${SBOMIFY_TOKEN}" \
"${SBOMIFY_API}/api/v1/components/${component_id}/sboms")
echo "$sboms" | jq -e --arg d "$digest" \
'.items[] | select(.sbom.version == $d)' > /dev/null 2>&1
}

# Remove old artifacts for a component from a release (keep only current digest)
# Usage: sbomify_cleanup_old_artifacts <product_id> <tag_version> <component_id> <current_digest>
sbomify_cleanup_old_artifacts() {
local product_id="$1" tag_version="$2" component_id="$3" current_digest="$4"

# Find the release
local releases release_id
releases=$(curl -fsSL -H "Authorization: Bearer ${SBOMIFY_TOKEN}" \
"${SBOMIFY_API}/api/v1/releases?product_id=${product_id}&version=${tag_version}")
release_id=$(echo "$releases" | jq -r --arg v "$tag_version" \
'.items[] | select(.version == $v) | .id' | head -1)

[[ -z "$release_id" ]] && return 0 # No release → nothing to clean
# Remove old SBOMs for a component (keep only current digest)
# Usage: sbomify_cleanup_old_sboms <component_id> <current_digest>
sbomify_cleanup_old_sboms() {
local component_id="$1" current_digest="$2"

# Find old artifacts for this component with different digest
local old_ids
old_ids=$(curl -fsSL -H "Authorization: Bearer ${SBOMIFY_TOKEN}" \
"${SBOMIFY_API}/api/v1/releases/${release_id}/artifacts?mode=existing" | \
jq -r --arg cid "$component_id" --arg d "$current_digest" \
'.items[] | select(.component_id == $cid and .sbom_version != $d) | .id')
local sboms old_ids
sboms=$(curl -fsSL -H "Authorization: Bearer ${SBOMIFY_TOKEN}" \
"${SBOMIFY_API}/api/v1/components/${component_id}/sboms")
old_ids=$(echo "$sboms" | jq -r --arg d "$current_digest" \
'.items[] | select(.sbom.version != $d) | .sbom.id')

for artifact_id in $old_ids; do
log_info "Removing old artifact ${artifact_id} from release ${release_id}"
for sbom_id in $old_ids; do
log_info "Removing old SBOM ${sbom_id} from component ${component_id}"
curl -fsSL -X DELETE -H "Authorization: Bearer ${SBOMIFY_TOKEN}" \
"${SBOMIFY_API}/api/v1/releases/${release_id}/artifacts/${artifact_id}"
"${SBOMIFY_API}/api/v1/sboms/sbom/${sbom_id}" || true
done
}