diff --git a/src/main.ts b/src/main.ts index 8b1cc49..2155fd5 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,6 +1,5 @@ import * as core from '@actions/core' -import { parseSBOMFromPath, storePredicate } from './sbom' -import { generateSBOMPredicate } from '@actions/attest' +import { parseSBOMFromPath, storePredicate, generateSBOMPredicate } from './sbom' /** * The main function for the action. diff --git a/src/sbom.ts b/src/sbom.ts index 5566841..f7b78cb 100644 --- a/src/sbom.ts +++ b/src/sbom.ts @@ -1,7 +1,11 @@ import fs from 'fs' -import { SBOM } from '@actions/attest' +import { Predicate } from '@actions/attest' import * as path from 'path' -import type { Predicate } from '@actions/attest' + +export type SBOM = { + type: 'spdx' | 'cyclonedx' + object: object +} export async function parseSBOMFromPath(filePath: string): Promise { // Read the file content @@ -59,3 +63,36 @@ export const storePredicate = (predicate: Predicate): string => { fs.writeFileSync(tempFile, JSON.stringify(predicate.params)) return tempFile } + +export const generateSBOMPredicate = (sbom: SBOM): Predicate => { + if (sbom.type === 'spdx') { + return generateSPDXIntoto(sbom.object) + } + if (sbom.type === 'cyclonedx') { + return generateCycloneDXIntoto(sbom.object) + } + throw new Error('Unsupported SBOM format') +} + +// ref: https://github.com/in-toto/attestation/blob/main/spec/predicates/spdx.md +const generateSPDXIntoto = (sbom: object): Predicate => { + const spdxVersion = (sbom as { spdxVersion?: string })?.['spdxVersion'] + if (!spdxVersion) { + throw new Error('Cannot find spdxVersion in the SBOM') + } + + const version = spdxVersion.split('-')[1] + + return { + type: `https://spdx.dev/Document/v${version}`, + params: sbom + } +} + +// ref: https://github.com/in-toto/attestation/blob/main/spec/predicates/cyclonedx.md +const generateCycloneDXIntoto = (sbom: object): Predicate => { + return { + type: 'https://cyclonedx.org/bom', + params: sbom + } +}