func PushSBOM()

in pkg/oci.go [28:111]


func PushSBOM(sbomDoc *v2_3.Document, sbomDescriptor *v1.Descriptor, sbomBytes []byte, reference string, spdx_annotations map[string]string, pushSummary bool, attachArtifacts map[string][]string, dest oras.Target) (*v1.Descriptor, error) {
	mem := memory.New()
	ctx := context.Background()

	// Create a Reader for the bytes
	sbomReader := bytes.NewReader(sbomBytes)

	// Add descriptor to a memory store
	err := mem.Push(ctx, *sbomDescriptor, sbomReader)
	if err != nil {
		return nil, fmt.Errorf("error pushing SBOM into memory store: %w", err)
	}

	layers := []v1.Descriptor{*sbomDescriptor}

	// Add annotations to the manifest
	annotations := make(map[string]string)
	for k, v := range spdx_annotations {
		annotations[k] = v
	}

	// add the summary blob as a layer if pushSummary is set
	if pushSummary {
		sbomSummary, err := GetSBOMSummary(sbomDoc)
		if err != nil {
			return nil, fmt.Errorf("error getting SBOM summary: %w", err)
		}
		// Marshal the summary into a string
		summaryBytes, err := json.Marshal(sbomSummary)
		if err != nil {
			return nil, fmt.Errorf("error marshaling summary into bytes: %w", err)
		}
		summaryDescriptor, err := oras.PushBytes(ctx, mem, "application/json", summaryBytes)
		if err != nil {
			return nil, fmt.Errorf("error pushing summary into memory store: %w", err)
		}
		layers = append(layers, summaryDescriptor)
	}

	// Pack the files and tag the packed manifest
	artifactType := MEDIATYPE_SPDX
	manifestDescriptor, err := oras.PackManifest(ctx, mem, oras.PackManifestVersion1_1, artifactType, oras.PackManifestOptions{
		Layers:              layers,
		ManifestAnnotations: annotations,
	})
	if err != nil {
		return nil, fmt.Errorf("error packing manifest: %w", err)
	}

	// Use the latest tag if no tag is specified
	tag := "latest"
	ref, err := registry.ParseReference(reference)
	if err != nil {
		return nil, fmt.Errorf("error parsing reference: %w", err)
	}

	if ref.Reference != "" {
		tag = ref.Reference
	}

	if err = mem.Tag(ctx, manifestDescriptor, tag); err != nil {
		return nil, err
	}

	if len(attachArtifacts) > 0 {
		for artifactType, paths := range attachArtifacts {
			for _, path := range paths {
				// load the artifact from the path
				artifactDesc, artifactBytes, err := LoadArtifactFromFile(path, artifactType)
				if err != nil {
					return nil, fmt.Errorf("error loading artifact: %v", err)
				}
				err = AttachArtifact(ctx, &manifestDescriptor, artifactDesc, artifactType, artifactBytes, mem)
				if err != nil {
					return nil, fmt.Errorf("error attaching artifact: %v", err)
				}
			}
		}
	}

	// Copy from the memory store to the remote repository
	manifest, err := oras.ExtendedCopy(ctx, mem, tag, dest, tag, oras.DefaultExtendedCopyOptions)
	return &manifest, err
}