Adding command line support to run this action from other CI

This commit is contained in:
Peter Murray
2022-09-26 14:53:51 +00:00
committed by GitHub
parent b386689c6e
commit 39157b5e1a
13 changed files with 6148 additions and 113 deletions
+1
View File
@@ -3,3 +3,4 @@ lib
node_modules
target
runtime
+27
View File
@@ -37,6 +37,33 @@ Upon success it will generate a snapshot captured from Maven POM like;
Currently the action is limited to single module Maven projects, with a future update that will add support for multi-module based projects.
## Command Line Usage
There are experimental command line clients, Linux only for now that will provide the same functionality as the GitHub Action but can be embedded into your existing CI tooling and invoked from the commandline to upload a dpendency snapshot.
You can obtain the executables from the [cli](./cli) directory of the repository for now.
### Parameters
Run the command line tool with the `--help` option to display all the possible configuration options;
```
Usage: maven-dependency-submission [options]
Options:
-V, --version output the version number
-t, --token <token> GitHub access token
-r --repository <repository> GitHub repository, owner/repo_name format
-b --branch-ref <ref> GitHub repository branch reference
-s --sha <commitSha> GitHub repository commit SHA
-d --directory <maven-project-directory> the directory containing the Maven POM file (default: ".")
--github-api-url <url> GitHub API URL (default: "https://api.github.com")
-j --job-name <jobName> Optional name for the activity creating and submitting the graph (default: "maven-dependency-submission-cli")
-i --run-id <jobName> Optional Run ID number for the activity that is providing the graph
-h, --help display help for command
```
## Development
To develop on this project, a Codespace has been provided that will provide all the necessary tools and installation of a JDK and Maven for the test suite to pass. Just open a Codespace and you can start to develop in the quickest possible timeframe.
Binary file not shown.
+1812 -74
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
File diff suppressed because one or more lines are too long
+4071 -7
View File
File diff suppressed because it is too large Load Diff
+5 -1
View File
@@ -5,6 +5,8 @@
"main": "index.js",
"scripts": {
"build": "npm ci && tsc && npm exec -- @vercel/ncc build --source-map lib/index.js",
"pre-build-exe": "npm run build && npm exec -- @vercel/ncc build lib/executable/cli.js -o runtime",
"build-exe-linux-x64": "npm run pre-build-exe && nexe -i runtime/index.js -t linux-x64-14.15.3 -o cli/maven-dependency-submission-linux-x64",
"test": "jest"
},
"repository": {
@@ -20,7 +22,8 @@
"homepage": "https://github.com/advanced-security/maven-dependency-tree-action#readme",
"dependencies": {
"@actions/core": "^1.9.1",
"@github/dependency-submission-toolkit": "^1.2.2",
"@github/dependency-submission-toolkit": "^1.2.3",
"commander": "^9.4.0",
"packageurl-js": "^0.0.7"
},
"devDependencies": {
@@ -29,6 +32,7 @@
"@vercel/ncc": "^0.34.0",
"chai": "^4.3.6",
"jest": "^28.1.3",
"nexe": "^4.0.0-rc.1",
"ts-jest": "^28.0.7",
"ts-node": "^10.8.2",
"typescript": "^4.7.4"
+8 -7
View File
@@ -71,9 +71,10 @@ export class MavenDependencyGraph {
return this.cache.countPackages();
}
createManifest(): Manifest {
const manifest = new Manifest(this.getProjectName());
createManifest(filePath?: string): Manifest {
// The project name is not shown in the UI when you utilize a file path currently, but the file path is required to link up to the repository file
// which is more beneficial at this point.
const manifest = new Manifest(this.getProjectName(), filePath);
const packageUrlToArtifact = this.packageUrlToArtifact;
this.directDependencies.forEach(depPackage => {
@@ -107,7 +108,7 @@ export class MavenDependencyGraph {
let rootPackageNumericId = 0;
const dependencyIdMap = dependencyMap(graph.dependencies);
const idToPackageCachePackage : Map<string, Package> = new Map<string, Package>();
const idToPackageCachePackage: Map<string, Package> = new Map<string, Package>();
// Create the packages for all known artifacts
graph.artifacts.forEach((artifact: DepgraphArtifact) => {
@@ -144,7 +145,7 @@ export class MavenDependencyGraph {
});
}
});
this.directDependencies = getDirectDependencies(rootPackageNumericId, graph.dependencies).map(id => {return idToPackageCachePackage[id]});
this.directDependencies = getDirectDependencies(rootPackageNumericId, graph.dependencies).map(id => { return idToPackageCachePackage[id] });
}
}
@@ -154,10 +155,10 @@ export function parseDependencyJson(file: string): Depgraph {
try {
const depGraph: Depgraph = JSON.parse(data.toString('utf-8'));
return depGraph;
} catch(err: any) {
} catch (err: any) {
throw new Error(`Failed to parse JSON payload: ${err.message}`);
}
} catch(err: any) {
} catch (err: any) {
throw new Error(`Failed to load file ${file}: ${err}`);
}
}
+66
View File
@@ -0,0 +1,66 @@
import { Snapshot, submitSnapshot } from '@github/dependency-submission-toolkit';
import { generateSnapshot } from '../snapshot-generator';
import pkg from '../../package.json';
const { program } = require('commander');
program.name('maven-dependency-submission');
program.version(pkg.version);
program.requiredOption('-t, --token <token>', 'GitHub access token');
program.requiredOption('-r --repository <repository>', 'GitHub repository, owner/repo_name format');
program.requiredOption('-b --branch-ref <ref>', 'GitHub repository branch reference');
program.requiredOption('-s --sha <commitSha>', 'GitHub repository commit SHA');
program.option('-d --directory <maven-project-directory>', 'the directory containing the Maven POM file', '.');
program.option('--github-api-url <url>', 'GitHub API URL', 'https://api.github.com');
program.option('-j --job-name <jobName>', 'Optional name for the activity creating and submitting the graph', 'maven-dependency-submission-cli');
program.option('-i --run-id <jobName>', 'Optional Run ID number for the activity that is providing the graph');
program.parse(process.argv);
async function execute() {
const opts = program.opts();
// Inject some required environment variables like the Actions INPUTs and special environment variables
process.env['INPUT_TOKEN'] = opts.token;
process.env['GITHUB_REPOSITORY'] = opts.repository;
let snapshot: Snapshot | undefined;
try {
// Build a fake GitHub Actions context so that values for the submission APIs can be retrieved
const context = {
sha: opts.sha,
ref: opts.branchRef,
};
const job = {
correlator: opts.jobName,
id: `${opts.runId || Date.now()}`
};
snapshot = await generateSnapshot(opts.directory, context, job);
} catch (err: any) {
console.error(`Failed to generate a dependency snapshot, check logs for more details, ${err}`);
console.log(err.stack);
console.error(err.message);
program.help({ error: true });
process.exit(1);
}
if (snapshot) {
console.log(`Submitting Snapshot...`);
try {
await submitSnapshot(snapshot);
console.log(`completed.`)
} catch (err: any) {
console.error(`Failed to submit the dependency snapshot, check logs for more details, ${err}`);
console.log(err.stack);
console.error(err.message);
program.help({ error: true });
process.exit(1);
}
}
}
execute();
+5 -6
View File
@@ -3,19 +3,18 @@ import * as core from '@actions/core';
import * as path from 'path';
import {Snapshot} from '@github/dependency-submission-toolkit';
import { Snapshot } from '@github/dependency-submission-toolkit';
import { MavenDependencyGraph, parseDependencyJson } from './depgraph';
const version = require('../package.json')['version'];
export async function generateSnapshot(directory: string) {
export async function generateSnapshot(directory: string, context?: any, job?: any) {
const depgraph = await generateDependencyGraph(directory);
try {
const mavenDependencies = new MavenDependencyGraph(depgraph);
const manifest = mavenDependencies.createManifest();
const snapshot = new Snapshot(getDetector());
const manifest = mavenDependencies.createManifest(path.join(directory, 'pom.xml'));
const snapshot = new Snapshot(getDetector(), context, job);
snapshot.addManifest(manifest);
return snapshot;
@@ -61,7 +60,7 @@ export async function generateDependencyGraph(directory: string) {
core.info(executionOutput);
core.info(errors);
core.endGroup();
} catch(err: any) {
} catch (err: any) {
core.error(err);
throw new Error(`A problem was encountered generating dependency files, please check execution logs for details; ${err.message}`);
}
@@ -0,0 +1,21 @@
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>com.github.octodemo:bs-parent:>${revision}${changelist}${sha1}</parent>
<artifactId>bs-parent</artifactId>
<version</version>
<packaging>pom</packaging>
<modules>
<module>bs-library</module>
<module>bs-application</module>
</modules>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</dependency>
</dependencies>
</project>
+113
View File
@@ -0,0 +1,113 @@
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.octodemo</groupId>
<artifactId>bs-parent</artifactId>
<version>${revision}${changelist}${sha1}</version>
<packaging>pom</packaging>
<description>A Java example project to demonstrate a Java development stack with Maven, GitHub Actions, GitHub Package Registry and Azure.</description>
<modules>
<module>bs-library</module>
<module>bs-application</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>11</java.version>
<!--
Dependency Versions
-->
<jetty.version>10.0.0</jetty.version>
<log4j.version>2.17.2</log4j.version>
<!--
Properties used to create a CD style version number for the Maven build
-->
<revision>1.0.0</revision>
<changelist></changelist>
<sha1>-SNAPSHOT</sha1>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-bom</artifactId>
<version>${jetty.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.1.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<!-- To enable debug compilation use the maven.compiler.debug user property -->
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<plugin>
<groupId>com.github.ekryd.echo-maven-plugin</groupId>
<artifactId>echo-maven-plugin</artifactId>
<version>1.3.2</version>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.6</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
+18 -17
View File
@@ -1,19 +1,20 @@
{
"compilerOptions": {
"target": "es6",
"module": "CommonJS",
"outDir": "./lib",
"rootDir": "./src",
"strict": true,
"sourceMap": true,
"noImplicitAny": false,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node"
},
"exclude": [
"node_modules",
"**/*.test.ts"
]
"compilerOptions": {
"target": "es6",
"module": "CommonJS",
"outDir": "./lib",
"sourceRoot": "./src",
"strict": true,
"sourceMap": true,
"noImplicitAny": false,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"resolveJsonModule": true
},
"exclude": [
"node_modules",
"**/*.test.ts"
]
}