Skip to content

Commit

Permalink
Setup OSS Review Toolkit SBoM generation
Browse files Browse the repository at this point in the history
  • Loading branch information
maennchen committed Feb 5, 2025
1 parent 28b0ef2 commit cd35a32
Show file tree
Hide file tree
Showing 9 changed files with 557 additions and 28 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,27 @@ jobs:
shellcheck -e SC2039,2086 bin/elixir && echo "bin/elixir is POSIX compliant"
shellcheck bin/elixirc && echo "bin/elixirc is POSIX compliant"
shellcheck bin/iex && echo "bin/iex is POSIX compliant"
license_compliance:
name: Check Licence Compliance

runs-on: ubuntu-24.04

steps:
- name: Use HTTPS instead of SSH for Git cloning
id: git-config
shell: bash
run: git config --global url.https://github.com/.insteadOf ssh://[email protected]/

- name: Checkout project
id: checkout
uses: actions/checkout@v4

- name: "Run OSS Review Toolkit"
id: ort
uses: ./.github/workflows/ort
with:
upload-reports: true
fail-on-violation: true
report-formats: "WebApp"
version: "${{ github.sha }}"
103 changes: 103 additions & 0 deletions .github/workflows/ort/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
name: "Run OSS Review Toolkit"
description: "Runs OSS Review Toolkit & generates SBoMs"
inputs:
build-artifacts:
description: |
Build Artifact paths to include into SBoM.
May contain a glob pattern or list of paths separated by a newline.
required: false
default: ""
report-formats:
description: "ORT Report Formats"
required: true
fail-on-violation:
description: "Whether to fail on violation."
required: false
default: false
upload-reports:
description: "Whether to upload all reports"
required: false
default: false
version:
desctiption: "Elixir Version (Tag / SHA)"
required: true

outputs:
results-path:
description: "See oss-review-toolkit/ort-ci-github-action action"
value: "${{ steps.ort.outputs.results-path }}"
results-notice-path:
description: "Path to resulting NOTICE file"
value: "${{ steps.ort.outputs.results-path }}/NOTICE_DEFAULT"
results-sbom-cyclonedx-xml-path:
description: "See oss-review-toolkit/ort-ci-github-action action"
value: "${{ steps.ort.outputs.results-sbom-cyclonedx-xml-path }}"
results-sbom-cyclonedx-json-path:
description: "See oss-review-toolkit/ort-ci-github-action action"
value: "${{ steps.ort.outputs.results-sbom-cyclonedx-json-path }}"
results-sbom-spdx-yml-path:
description: "See oss-review-toolkit/ort-ci-github-action action"
value: "${{ steps.ort.outputs.results-sbom-spdx-yml-path }}"
results-sbom-spdx-json-path:
description: "See oss-review-toolkit/ort-ci-github-action action"
value: "${{ steps.ort.outputs.results-sbom-spdx-json-path }}"

runs:
using: "composite"
steps:
- name: Fetch Default ORT Config
id: fetch-default-ort-config
uses: actions/checkout@v4
with:
repository: oss-review-toolkit/ort-config
ref: "main"
path: ".ort-config"

- name: Setup ORT Config
id: setup-ort-config
shell: bash
run: |
mkdir -p "/$HOME/.ort/"
# Move Fetched Default Config into Place
mv .ort-config "/$HOME/.ort/config"
# Append Global ORT Config
cat .ort/config/config.yml >> "$HOME/.ort/config/config.yml"
# Override Default Evaluator Rules
cp .ort/config/evaluator.rules.kts "$HOME/.ort/config/evaluator.rules.kts"
# TODO: Add binary artifacts to ORT to have them included in the SBoM
# Depends on some further work in ORT to correctly detect and name mix
# applications.

- name: "Cache ScanCode"
uses: actions/cache@v4
with:
path: "~/.cache/scancode-tk"
key: ${{ runner.os }}-scancode

- name: Run OSS Review Toolkit
id: ort
# TODO: Use released version once the following issue has been released:
# * https://github.com/oss-review-toolkit/ort-ci-github-action/issues/37
# * https://github.com/oss-review-toolkit/ort-ci-github-action/pull/41
# * https://github.com/oss-review-toolkit/ort-ci-github-action/pull/43
uses: maennchen/ort-ci-github-action@action-output
with:
image: ghcr.io/oss-review-toolkit/ort-minimal:latest
run: >
labels,
cache-dependencies,
cache-scan-results,
analyzer,
scanner,
advisor,
evaluator,
reporter,
${{ inputs.upload-reports == 'true' && 'upload-results' || '' }}
fail-on: "${{ inputs.fail-on-violation == 'true' && 'violations,issues' || '' }}"
report-formats: "${{ inputs.report-formats }}"
ort-cli-report-args: '-O CycloneDX=output.file.formats=json,xml -O SpdxDocument=outputFileFormats=JSON,YAML'
sw-version: "${{ inputs.version }}"
115 changes: 87 additions & 28 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ jobs:
git push origin $ref_name --force
build:
name: "Build Elixir"

strategy:
fail-fast: true
matrix:
Expand All @@ -64,7 +66,9 @@ jobs:
- otp: 27
otp_version: "27.0"
build_docs: build_docs

runs-on: ubuntu-22.04

steps:
- uses: actions/checkout@v4
with:
Expand All @@ -77,19 +81,6 @@ jobs:
otp: ${{ matrix.otp }}
build_docs: ${{ matrix.build_docs }}

- name: "Attest docs provenance"
uses: actions/attest-build-provenance@v2
id: attest-docs-provenance
if: matrix.build_docs
with:
subject-path: "Docs.zip"

- name: "Copy docs provenance"
if: matrix.build_docs
run: cp "$ATTESTATION" Docs.zip.sigstore
env:
ATTESTATION: "${{ steps.attest-docs-provenance.outputs.bundle-path }}"

- name: Create Docs Hashes
if: matrix.build_docs
run: |
Expand Down Expand Up @@ -150,18 +141,6 @@ jobs:
timestamp-rfc3161: http://timestamp.acs.microsoft.com
timestamp-digest: SHA256

- name: "Attest release provenance"
id: attest-provenance
uses: actions/attest-build-provenance@v2
with:
subject-path: ${{ env.RELEASE_FILE }}

- name: "Copy release .zip provenance"
shell: bash
run: cp "$ATTESTATION" "${RELEASE_FILE}.sigstore"
env:
ATTESTATION: "${{ steps.attest-provenance.outputs.bundle-path }}"

- name: Create Release Hashes
if: matrix.flavor == 'windows'
shell: pwsh
Expand All @@ -185,14 +164,93 @@ jobs:
name: sign-${{ matrix.flavor }}-elixir-otp-${{ matrix.otp }}
path: ${{ env.RELEASE_FILE }}*

sbom:
name: Generate SBoM

needs: [build, sign]

runs-on: ubuntu-24.04

steps:
- name: Use HTTPS instead of SSH for Git cloning
id: git-config
shell: bash
run: git config --global url.https://github.com/.insteadOf ssh://[email protected]/

- name: Checkout project
id: checkout
uses: actions/checkout@v4

- name: "Download Build Artifacts"
id: download-build-artifacts
uses: actions/download-artifact@v4
with:
pattern: "{sign-*-elixir-otp-*,Docs}"
merge-multiple: true
path: /tmp/build-artifacts/

- name: "Run OSS Review Toolkit"
id: ort
uses: ./.github/workflows/ort
with:
build-artifacts: "/tmp/build-artifacts/*"
report-formats: "CycloneDx,SpdxDocument"
version: "${{ github.ref_type == 'tag' && github.ref_name || github.sha }}"

- name: Attest Distribution Assets with SBoM
id: attest-sbom
uses: actions/attest-sbom@v2
with:
subject-path: |
/tmp/build-artifacts/{elixir-otp-*.*,Docs.zip}
${{ steps.ort.outputs.results-sbom-cyclonedx-xml-path }}
${{ steps.ort.outputs.results-sbom-cyclonedx-json-path }}
${{ steps.ort.outputs.results-sbom-spdx-yml-path }}
${{ steps.ort.outputs.results-sbom-spdx-json-path }}
sbom-path: "${{ steps.ort.outputs.results-sbom-spdx-json-path }}"

- name: "Copy SBoM provenance"
id: sbom-provenance
shell: bash
run: |
mkdir attestations
for FILE in /tmp/build-artifacts/{elixir-otp-*.*,Docs.zip}; do
cp "$ATTESTATION" "attestations/$(basename "$FILE").sigstore"
done
cp "$ATTESTATION" "attestations/$(basename "${{ steps.ort.outputs.results-sbom-cyclonedx-xml-path }}").sigstore"
cp "$ATTESTATION" "attestations/$(basename "${{ steps.ort.outputs.results-sbom-cyclonedx-json-path }}").sigstore"
cp "$ATTESTATION" "attestations/$(basename "${{ steps.ort.outputs.results-sbom-spdx-yml-path }}").sigstore"
cp "$ATTESTATION" "attestations/$(basename "${{ steps.ort.outputs.results-sbom-spdx-json-path }}").sigstore"
env:
ATTESTATION: "${{ steps.attest-sbom.outputs.bundle-path }}"

- name: "Assemble Release SBoM Artifacts"
uses: actions/upload-artifact@v4
with:
name: "SBoM"
path: |
${{ steps.ort.outputs.results-sbom-cyclonedx-xml-path }}
${{ steps.ort.outputs.results-sbom-cyclonedx-json-path }}
${{ steps.ort.outputs.results-sbom-spdx-yml-path }}
${{ steps.ort.outputs.results-sbom-spdx-json-path }}
- name: "Assemble Distribution Attestations"
uses: actions/upload-artifact@v4
with:
name: "Attestations"
path: "attestations/*.sigstore"

upload-release:
needs: [create_draft_release, build, sign]
needs: [create_draft_release, build, sign, sbom]
runs-on: ubuntu-22.04

steps:
- uses: actions/download-artifact@v4
with:
pattern: "{sign-*-elixir-otp-*,Docs}"
pattern: "{sign-*-elixir-otp-*,Docs,SBoM,Attestations}"
merge-multiple: true

- name: Upload Pre-built
Expand All @@ -218,7 +276,8 @@ jobs:
elixir-otp-*.exe.sigstore \
Docs.zip \
Docs.zip.sha{1,256}sum \
Docs.zip.sigstore
Docs.zip.sigstore \
bom.*
upload-builds-hex-pm:
needs: [build, sign]
Expand Down
20 changes: 20 additions & 0 deletions .ort.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
curations:
license_findings:
- path: "lib/elixir/pages/images/logo.png"
reason: "INCORRECT"
comment: "Apply Trademark Policy to Elixir Logo"
detected_license: "NONE"
concluded_license: "LicenseRef-elixir-trademark-policy"

- path: "lib/elixir/pages/references/library-guidelines.md"
reason: "INCORRECT"
comment: |
The guide mentions multiple licenses for users to choose from.
It however is not licensed itself by the mentioned licenses.
concluded_license: "Apache-2.0"

- path: "**/*"
reason: "INCORRECT"
comment: "Apply default license to all unknown files"
detected_license: "NONE"
concluded_license: "Apache-2.0"
9 changes: 9 additions & 0 deletions .ort/config/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
ort:
scanner:
skipConcluded: false
includeFilesWithoutFindings: true

analyzer:
allowDynamicVersions: true
enabledPackageManagers: [Unmanaged]
skipExcluded: true
Loading

0 comments on commit cd35a32

Please sign in to comment.