Skip to content

Commit

Permalink
feat(workflows): add reusable github workflow for SBOM diffing
Browse files Browse the repository at this point in the history
  • Loading branch information
ThorbenLindhauer committed Sep 29, 2023
1 parent 3a28741 commit 726d855
Show file tree
Hide file tree
Showing 7 changed files with 219 additions and 0 deletions.
79 changes: 79 additions & 0 deletions .github/workflows/java-dependency-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
name: Compare the dependencies of a pull request to a Maven multi-module project with the base branch. Check according to our Stop & Go list.

on:
workflow_call:
inputs:
ref:
description: 'The reference of the github commit of the reusable workflow. Must match the specified branch/tag/commit where the workflow is called. Workaround to https://github.com/actions/runner/issues/2417. Should never be untrusted content.'
default: 'main'
type: string
secrets:
VAULT_ADDR:
required: true
VAULT_ROLE_ID:
required: true
VAULT_SECRET_ID:
required: true

jobs:
java-dependency-check:
runs-on: ubuntu-latest
name: Java Dependency Check
# todo: filter by label if diff should be performed
steps:
- name: Import Secrets
id: secrets
uses: hashicorp/vault-action@v2.4.3
with:
url: ${{ secrets.VAULT_ADDR }}
method: approle
roleId: ${{ secrets.VAULT_ROLE_ID }}
secretId: ${{ secrets.VAULT_SECRET_ID }}
secrets: |
secret/data/github.com/organizations/camunda NEXUS_USR;
secret/data/github.com/organizations/camunda NEXUS_PSW;
- uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'
- name: Checkout repository
uses: actions/checkout@v3
with:
path: repo-to-check
ref: ${{ github.event.pull_request.head.sha }}
- name: Checkout reusable workflow dir
uses: actions/checkout@v3
with:
repository: camunda/automation-platform-github-actions
token: ${{ secrets.GITHUB_TOKEN }}
path: automation-platform-github-actions
ref: ${{ inputs.ref }} # github.job_workflow_sha seems to be the documented parameter to resolve this, but doesn't work in practice
- name: Generate SBOMs
id: generate-sboms
run: bash ${{ github.workspace }}/automation-platform-github-actions/java-dependency-check/generate-sboms.sh ${{ github.workspace }}/automation-platform-github-actions/java-dependency-check/maven-settings.xml
working-directory: ${{ github.workspace }}/repo-to-check
- name: Diff SBOMs
id: diff-sboms
uses: ./automation-platform-github-actions/java-dependency-check
with:
base-sbom: ${{ github.workspace }}/repo-to-check/target/diff/base.json
head-sbom: ${{ github.workspace }}/repo-to-check/target/diff/head.json
primary-party-group-matcher: "^org\\.camunda"
license-list: ${{ github.workspace }}/automation-platform-github-actions/java-dependency-check/licenses.json
github-comment-template: ${{ github.workspace }}/automation-platform-github-actions/java-dependency-check/diff.hbs
partials: |
componentDetails:${{ github.workspace }}/automation-platform-github-actions/java-dependency-check/component-details.hbs
componentDiff:${{ github.workspace }}/automation-platform-github-actions/java-dependency-check/component-diff.hbs
componentTree:${{ github.workspace }}/automation-platform-github-actions/java-dependency-check/component-tree.hbs
componentVersion:${{ github.workspace }}/automation-platform-github-actions/java-dependency-check/component-version.hbs
output-path: ${{ github.workspace }}/dependency-diff.html
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Upload full diff as workflow artifact
uses: actions/upload-artifact@v3
with:
name: artifacts.zip
path: |
${{ github.workspace }}/dependency-diff.html
${{ github.workspace }}/repo-to-check/target/diff/base.json
${{ github.workspace }}/repo-to-check/target/diff/head.json
retention-days: 30
1 change: 1 addition & 0 deletions common/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ exports.formatJiraLinks = require('./src/format-jira-links.js');
exports.generateReleaseNotes = require('./src/generate-release-notes.js');
exports.synchronizeLabelColors = require('./src/synchronize-label-colors.js');
exports.copyIssue = require('./src/copy-issue.js');
exports.diffSBOMs = require('./src/diff-sboms.js');
62 changes: 62 additions & 0 deletions common/src/diff-sboms.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
const core = require('@actions/core');
const github = require('@actions/github');
const diffSBOMs = require('./sbom-diff/differ.js');
const formatTemplate = require('./sbom-diff/format-handlebars-template.js');
const fs = require('fs');

const readFile = function(path) {
return fs.readFileSync(path, 'utf8')
}

const writeFile = function(path, content) {
fs.writeFileSync(path, content); // default encoding is utf8
}

module.exports = async function () {
const baseSbomPath = core.getInput('base-sbom');
const headSbomPath = core.getInput('head-sbom');
const primaryPartyGroupMatcher = core.getInput('primary-party-group-matcher');
const licenseListPath = core.getInput('license-list');
const commentTemplatePath = core.getInput('github-comment-template');
const partialPathsString = core.getInput('partials');
const repoToken = core.getInput('repo-token');
const outputPath = core.getInput('output-path');

const octokit = github.getOctokit(repoToken);
const repo = github.context.payload.repository;
const prNumber = github.context.payload.number;

const baseSbom = readFile(baseSbomPath);
const headSbom = readFile(headSbomPath);

const licenseList = readFile(licenseListPath);

const commentTemplate = readFile(commentTemplatePath);

const partials = partialPathsString.split(/[\r\n]+/).reduce(
(result, input) => {
[ partialId, partialPath ] = input.split(':');
result[partialId.trim()] = readFile(partialPath.trim());
return result;
},
{}
);

const rootComponentDiff = await diffSBOMs(baseSbom, headSbom, primaryPartyGroupMatcher, licenseList);

const diff = await formatTemplate(rootComponentDiff, commentTemplate, partials);

core.info(`Dependency diff:`);
core.info(diff.fullDiff);

octokit.rest.issues.createComment({
owner: repo.owner.login,
repo: repo.name,
issue_number: prNumber,
body: diff.githubComment
});

writeFile(outputPath, diff.fullDiff);


}
30 changes: 30 additions & 0 deletions java-dependency-check/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: 'Diff SBOMs'
description: 'Diffs two SBOM files and publishes a comment in a github pull request with the result'
inputs:
base-sbom:
description: 'The path to the base SBOM file'
required: true
head-sbom:
description: 'The path to the SBOM file to compare to the base SBOM'
required: true
primary-party-group-matcher:
description: 'A Javascript regex that is matched against artifact group IDs to determine primary dependencies (i.e. not third-party)'
required: true
license-list:
description: 'The path to a file that contains the go/caution/stop license lists'
required: true
github-comment-template:
description: 'The path to a handlebars template for the resulting github comment'
required: true
partials:
description: 'A multi-line string, each line of the format <name>:<path> pointing to a handlebars partial file used by the main template'
required: false
repo-token:
description: 'Github access token'
required: true
output-path:
description: 'Path to a file that the full diff output will be written to (in HTML)'
required: true
runs:
using: 'node16'
main: 'index.js'
31 changes: 31 additions & 0 deletions java-dependency-check/generate-sboms.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/bin/bash
# Parameters
# $1: path to Maven settings file to be used

set -e
# let script stop when one of the commands fails (e.g. one of the Maven builds)

git fetch

if [[ $(git diff origin/$GITHUB_BASE_REF HEAD --name-only | grep pom.xml$ | wc -c) -ne 0 ]]; then

echo "POM changes detected. Diffing SBOMs"

mkdir -p target/diff

mvn -s "$1" --no-transfer-progress org.cyclonedx:cyclonedx-maven-plugin:2.7.9:makeAggregateBom

echo "SBOM generated for github ref HEAD"

cp target/bom.json target/diff/head.json

git checkout -f origin/$GITHUB_BASE_REF
mvn -s "$1" --no-transfer-progress org.cyclonedx:cyclonedx-maven-plugin:2.7.9:makeAggregateBom

echo "SBOM generated for github ref $GITHUB_BASE_REF"

cp target/bom.json target/diff/base.json

else
echo "No POM changes. Not diffing SBOMs"
fi
3 changes: 3 additions & 0 deletions java-dependency-check/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const common = require('../common/dist/index.js');

common.diffSBOMs();
13 changes: 13 additions & 0 deletions java-dependency-check/maven-settings.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">

<servers>
<server>
<id>camunda-nexus</id>
<username>${env.NEXUS_USR}</username>
<password>${env.NEXUS_PSW}</password>
</server>
</servers>
</settings>

0 comments on commit 726d855

Please sign in to comment.