Skip to content

fix: handle malformed email address headers #2843

fix: handle malformed email address headers

fix: handle malformed email address headers #2843

Workflow file for this run

name: Image SBOM
on:
push:
branches: [ master ]
tags:
- 'v*'
pull_request:
branches: [ master ]
workflow_dispatch:
permissions:
contents: write
env:
IMAGE_LOCAL_REF: openmed-image-sbom:${{ github.sha }}
IMAGE_SBOM_FILE: image-sbom.cdx.json
IMAGE_SBOM_DIGEST_FILE: image-sbom.cdx.json.sha256
jobs:
image-sbom:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v4
- name: Build service image for SBOM
uses: docker/build-push-action@v7
with:
context: .
file: Dockerfile
load: true
tags: ${{ env.IMAGE_LOCAL_REF }}
labels: |
org.opencontainers.image.source=https://github.com/${{ github.repository }}
org.opencontainers.image.revision=${{ github.sha }}
org.opencontainers.image.title=OpenMed service image
- name: Generate CycloneDX image SBOM
uses: anchore/sbom-action@v0
with:
image: ${{ env.IMAGE_LOCAL_REF }}
format: cyclonedx-json
output-file: ${{ env.IMAGE_SBOM_FILE }}
- name: Validate image SBOM
run: |
python - <<'PY'
import json
import sys
from pathlib import Path
path = Path("image-sbom.cdx.json")
if not path.exists():
raise SystemExit("image SBOM was not generated")
if path.stat().st_size == 0:
raise SystemExit("image SBOM is empty")
try:
bom = json.loads(path.read_text(encoding="utf-8"))
except json.JSONDecodeError as exc:
raise SystemExit(f"image SBOM is malformed JSON: {exc}") from exc
if bom.get("bomFormat") != "CycloneDX":
raise SystemExit("image SBOM is not a CycloneDX document")
if not bom.get("specVersion"):
raise SystemExit("image SBOM is missing specVersion")
components = bom.get("components")
if not isinstance(components, list) or not components:
raise SystemExit("image SBOM does not list any components")
purls = [
component.get("purl", "")
for component in components
if isinstance(component, dict)
]
has_os_component = any(
purl.startswith(("pkg:deb/", "pkg:apk/", "pkg:rpm/"))
for purl in purls
) or any(
component.get("type") == "operating-system"
for component in components
if isinstance(component, dict)
)
has_python_component = any(
purl.startswith("pkg:pypi/")
for purl in purls
)
if not has_os_component:
raise SystemExit("image SBOM does not include OS package components")
if not has_python_component:
raise SystemExit("image SBOM does not include Python package components")
print(
"validated image SBOM: "
f"{len(components)} components, CycloneDX {bom.get('specVersion')}"
)
PY
- name: Compute image SBOM digest
id: sbom_digest
run: |
sha256sum "$IMAGE_SBOM_FILE" > "$IMAGE_SBOM_DIGEST_FILE"
digest="sha256:$(cut -d' ' -f1 "$IMAGE_SBOM_DIGEST_FILE")"
echo "digest=$digest" >> "$GITHUB_OUTPUT"
echo "$digest"
- name: Upload image SBOM artifact
uses: actions/upload-artifact@v7
with:
name: image-sbom
path: |
${{ env.IMAGE_SBOM_FILE }}
${{ env.IMAGE_SBOM_DIGEST_FILE }}
if-no-files-found: error
- name: Attach image SBOM to tagged GitHub release
if: github.event_name == 'push' && github.ref_type == 'tag'
env:
GH_TOKEN: ${{ github.token }}
run: |
gh release upload "$GITHUB_REF_NAME" \
"$IMAGE_SBOM_FILE" "$IMAGE_SBOM_DIGEST_FILE" \
--clobber \
|| gh release create "$GITHUB_REF_NAME" \
"$IMAGE_SBOM_FILE" "$IMAGE_SBOM_DIGEST_FILE" \
--title "$GITHUB_REF_NAME" --generate-notes