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
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ else()
set(ONE_VERSION "${PROJECT_VERSION}+${PROJECT_GIT_SHA}")
endif()
message(STATUS "One version: ${ONE_VERSION}")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/VERSION" "${ONE_VERSION}")

if(ONE_INDEX OR ONE_SERVER)
add_subdirectory(src/shared)
Expand Down
9 changes: 6 additions & 3 deletions enterprise/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ COPY test/unit /source/test/unit
COPY test/js /source/test/js

RUN cd /source && npm ci
RUN mkdir -p /usr/share/sourcemeta/one \
&& cd /source && npm sbom --sbom-format spdx --sbom-type library --omit dev \
> /usr/share/sourcemeta/one/npm-packages.spdx.json

ARG SOURCEMETA_ONE_BUILD_TYPE=Release
ARG SOURCEMETA_ONE_PARALLEL=2
Expand Down Expand Up @@ -74,6 +71,12 @@ RUN cmake --build /build --config ${SOURCEMETA_ONE_BUILD_TYPE} \
RUN ctest --test-dir /build --build-config ${SOURCEMETA_ONE_BUILD_TYPE} \
--output-on-failure --parallel

RUN mkdir -p /usr/share/sourcemeta/one \
&& cd /source && npm sbom --sbom-format spdx --sbom-type library --omit dev \
> /usr/share/sourcemeta/one/npm-packages.spdx.json \
&& node /source/enterprise/scripts/sbom-vendorpull.js /build/VERSION \
> /usr/share/sourcemeta/one/vendor-packages.spdx.json

FROM debian:trixie-slim

RUN apt-get --yes update && apt-get install --yes --no-install-recommends \
Expand Down
103 changes: 103 additions & 0 deletions enterprise/scripts/sbom-vendorpull.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#!/usr/bin/env node

// Generates an SPDX 2.3 JSON Software Bill of Materials (SBOM) for the
// vendored C++ and frontend dependencies managed through DEPENDENCIES files

import { readFileSync, readdirSync, existsSync } from "node:fs";
import { join, resolve, dirname } from "node:path";
import { fileURLToPath } from "node:url";

const LICENSES = {
"core": "AGPL-3.0-or-later OR LicenseRef-Commercial",
"blaze": "AGPL-3.0-or-later OR LicenseRef-Commercial",
"hydra": "AGPL-3.0-or-later OR LicenseRef-Commercial",
"codegen": "AGPL-3.0-or-later OR LicenseRef-Commercial",
"jsonbinpack": "AGPL-3.0-or-later OR LicenseRef-Commercial",
"jsonschema": "AGPL-3.0-only",
"uwebsockets": "Apache-2.0",
"bootstrap": "MIT",
"bootstrap-icons": "MIT",
"pcre2": "BSD-3-Clause",
"zlib": "Zlib",
"curl": "curl",
"nghttp2": "MIT",
"cpr": "MIT",
"c-ares": "MIT",
"libpsl": "MIT",
"openssl": "Apache-2.0"
};

const versionFile = process.argv[2];
if (!versionFile) {
process.stderr.write(`Usage: ${process.argv[1]} <version-file>\n`);
process.exit(1);
}

const version = readFileSync(versionFile, "utf-8").trim();
const root = resolve(dirname(fileURLToPath(import.meta.url)), "../..");

const vendorDirectory = join(root, "vendor");
const files = [
join(root, "DEPENDENCIES"),
...existsSync(vendorDirectory)
? readdirSync(vendorDirectory, { withFileTypes: true })
.filter((entry) => entry.isDirectory())
.map((entry) => join(vendorDirectory, entry.name, "DEPENDENCIES"))
: []
].filter(existsSync).sort();

const seenUrls = new Set();
const packages = [{
name: "sourcemeta-one-enterprise",
SPDXID: "SPDXRef-RootPackage",
versionInfo: version,
downloadLocation: "https://github.com/sourcemeta/one",
filesAnalyzed: false,
licenseConcluded: "NOASSERTION",
licenseDeclared: "NOASSERTION"
}];
const relationships = [{
spdxElementId: "SPDXRef-DOCUMENT",
relationshipType: "DESCRIBES",
relatedSpdxElement: "SPDXRef-RootPackage"
}];

let index = 0;
for (const file of files) {
for (const line of readFileSync(file, "utf-8").split("\n")) {
if (!line.trim()) continue;
const [name, url, entryVersion] = line.split(/\s+/);
const license = LICENSES[name];
if (!license || seenUrls.has(url)) continue;
seenUrls.add(url);
index += 1;
const spdxid = `SPDXRef-Vendor-${index}`;
packages.push({
name, SPDXID: spdxid,
versionInfo: entryVersion,
downloadLocation: url,
filesAnalyzed: false,
licenseConcluded: license,
licenseDeclared: license
});
relationships.push({
spdxElementId: "SPDXRef-RootPackage",
relationshipType: "DEPENDS_ON",
relatedSpdxElement: spdxid
});
}
}

process.stdout.write(JSON.stringify({
spdxVersion: "SPDX-2.3",
dataLicense: "CC0-1.0",
SPDXID: "SPDXRef-DOCUMENT",
name: "sourcemeta-one-enterprise",
documentNamespace: `https://one.sourcemeta.com/sbom/${version}`,
creationInfo: {
created: new Date().toISOString(),
creators: [ "Tool: enterprise/scripts/sbom-vendorpull.js" ]
},
packages,
relationships
}, null, 2) + "\n");