Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add DT companion Plugin v1.0.0 #1

Merged
merged 18 commits into from
Jul 3, 2023
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
25 changes: 25 additions & 0 deletions .github/workflows/pre-merge.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Pre Merge Checks

on:
push:
branches:
- main
pull_request:
branches:
- '*'

jobs:
gradle:
runs-on: ubuntu-latest
env:
GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PUBLISH_KEY }}
GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PUBLISH_SECRET }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cache
uses: gradle/gradle-build-action@v2
- name: Validate
run: ./gradlew check validatePlugins --continue
- name: Integration Test
run: ./gradlew integrationTest --info
24 changes: 24 additions & 0 deletions .github/workflows/publish-plugin.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Publish to Gradle Plugin Portal

on:
push:
tags:
- '*'

jobs:
gradle:
runs-on: ubuntu-latest
env:
GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PUBLISH_KEY }}
GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PUBLISH_SECRET }}
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Cache
uses: gradle/gradle-build-action@v2
- name: Validate
run: ./gradlew check validatePlugins --continue
- name: Integration Test
run: ./gradlew integrationTest
- name: Publish
run: ./gradlew publishPlugins
44 changes: 44 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/

### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/

.idea/

### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

### VS Code ###
.vscode/

### Mac OS ###
.DS_Store
110 changes: 110 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Gradle Dependency Track Companion w Plugin

This Gradle plugin is designed to ease the process of working with [Dependency Track](https://dependencytrack.org/), a Continuous SBOM Analysis Platform. With this plugin, you can automate the upload process of SBOM files, generate Vex files for component or vulnerability suppression, and more.

## Features

The plugin offers several tasks:

- `generateVex`: Generates VEX file.
- `getOutdatedDependencies`: Gets outdated dependencies.
- `getSuppressedVuln`: Gets suppressed vulnerabilities.
- `runDepTrackWorkflow`: Runs `uploadSbom`, `generateVex` and `uploadVex` tasks for CI/CD.
- `uploadSbom`: Uploads SBOM file.
- `uploadVex`: Uploads VEX file.

### Task Configuration

Each task requires certain inputs which are to be specified in your `build.gradle.kts`. The configuration for each task is as follows:

#### uploadSbom

- `url`: Dependency Track API URL
- `apiKey`: Dependency Track API KEY
- `inputFile`: *Optional* - Default: build/reports/bom.json
- `uploadSbom`: [Dependency Track BOM Upload Api Reference](https://yoursky.blue/documentation-api/dependencytrack.html#tag/bom/operation/UploadBom)

#### generateVex

- `vexComponent`: *Optional* - For suppressing vulnerabilities in one component
- `vexVulnerability`: *Optional* - For suppressing vulnerabilities in all components
- `inputFile`: *Optional* - Default: build/reports/bom.json
- `outputFile`: *Optional* - Default: build/reports/vex.json

#### uploadVex

- `url`: Dependency Track API URL
- `apiKey`: Dependency Track API KEY
- `outputFile`: *Optional* (Default "build/reports/vex.json")
- `uploadVex`: [Dependency Track VEX Upload API Reference](https://yoursky.blue/documentation-api/dependencytrack.html#tag/vex/operation/uploadVex)

#### runDepTrackWorkflow

- This task requires configuration for `uploadSbom`, `generateVex`, and `uploadVex`.
- Runs `uploadSbom`, `generateVex` and `uploadVex` tasks for CI/CD.

#### getOutdatedDependencies

- `url`: Dependency Track API URL
- `apiKey`: Dependency Track API KEY
- `getOutdatedDependencies`: [Dependency Track Project Lookup API Reference](https://yoursky.blue/documentation-api/dependencytrack.html#tag/project/operation/getProjectByNameAndVersion)

#### getSuppressedVuln

- `url`: Dependency Track API URL
- `apiKey`: Dependency Track API KEY
- `getSuppressedVuln`: [Dependency Track Project Lookup API Reference](https://yoursky.blue/documentation-api/dependencytrack.html#tag/project/operation/getProjectByNameAndVersion)

## Example Configuration

Here's how you can configure all tasks:

```kotlin
import com.liftric.dtcp.extensions.*
import org.cyclonedx.model.vulnerability.Vulnerability

val version: String by project
val name: String by project
dependencyTrackCompanion {
url.set("https://api.dtrack.example.com")
apiKey.set(System.getenv("DT_API_KEY"))
uploadSBOM {
autoCreate.set(true)
projectName.set(name)
projectVersion.set(version)
parentName.set(name)
}
uploadVex {
projectName.set(name)
projectVersion.set(version)
}
getOutdatedDependencies {
projectName.set(name)
projectVersion.set(version)
}
getSuppressedVuln {
projectName.set(name)
projectVersion.set(version)
}
Khartris marked this conversation as resolved.
Show resolved Hide resolved
vexComponent {
purl.set("pkg:maven/org.eclipse.jetty/jetty-http@9.4.49.v20220914?type=jar")
vulnerability {
id.set("CVE-2023-26048")
source.set("NVD")
analysis.set(Vulnerability.Analysis.State.FALSE_POSITIVE)
}
}
vexVulnerability {
id.set("CVE-2020-8908")
source.set("NVD")
analysis.set(Vulnerability.Analysis.State.RESOLVED)
detail.set("This is resolved")
}
}
```

## License

This Gradle Dependency Track Plugin is released under MIT License.

This project is not a derivative of [Dependency Track](https://dependencytrack.org/), but a tool that interacts with it. Please note that Dependency Track is released under the [Apache 2.0 license](https://www.apache.org/licenses/LICENSE-2.0). Refer to their respective licenses for more information.
99 changes: 99 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
@Suppress("DSL_SCOPE_VIOLATION") // IntelliJ incorrectly marks libs as not callable
plugins {
`maven-publish`
alias(libs.plugins.kotlinJvm)
alias(libs.plugins.kotlinSerialization)
alias(libs.plugins.dockerCompose)
alias(libs.plugins.gradlePluginPublish)
}

repositories {
mavenCentral()
gradlePluginPortal()
}

dockerCompose {
// Docker Compose v1 is needed for this Plugin to work
useComposeFiles.set(listOf("docker-compose.yml"))
waitForTcpPorts.set(true)
captureContainersOutput.set(true)
stopContainers.set(true)
removeContainers.set(true)
buildBeforeUp.set(true)
}

val integrationTest = sourceSets.create("integrationTest")
tasks {
val test by existing
withType<Test> {
useJUnitPlatform()
testLogging {
events("passed", "skipped", "failed")
}
systemProperty("org.gradle.testkit.dir", gradle.gradleUserHomeDir)
}

val integrationTestTask = register<Test>("integrationTest") {
description = "Runs the integration tests"
group = "verification"
testClassesDirs = integrationTest.output.classesDirs
classpath = integrationTest.runtimeClasspath
mustRunAfter(test)
useJUnitPlatform()
}
dockerCompose.isRequiredBy(integrationTestTask)

val propertiesTask = register<WriteProperties>("writePluginProperties") {
outputFile = file("src/main/resources/plugin.properties")
property("vendor", project.property("pluginVendor").toString())
property("name", project.property("pluginName").toString())
property("version", project.property("pluginVersion").toString())
}
}

tasks.named("build") {
dependsOn("writePluginProperties")
}


gradlePlugin {
testSourceSets(integrationTest)
plugins {
create("dependency-track-companion-plugin") {
id = "${project.property("pluginGroup")}.${project.property("pluginName")}"
implementationClass = "${project.property("pluginGroup")}.dtcp.DepTrackCompanionPlugin"
displayName = project.property("pluginName").toString()
version = project.property("pluginVersion").toString()
group = project.property("pluginGroup").toString()
}
}
}
pluginBundle {
website = "https://github.com/Liftric/dependency-track-companion-plugin"
vcsUrl = "https://github.com/Liftric/dependency-track-companion-plugin"
description = "Common tasks for Dependency Track interaction, like SBOM upload or VEX Generation"
tags = listOf("dependency", "track", "sbom", "vex", "upload", "generate")
}


dependencies {
implementation(platform(libs.kotlinBom))
implementation(libs.kotlinStdlibJdk8)
implementation(libs.cyclonedxCoreJava)
implementation(libs.ktorClientCio)
implementation(libs.ktorClientCore)
implementation(libs.ktorClientJson)
implementation(libs.ktorClientSerialization)
implementation(libs.ktorClientContentNegotiation)
implementation(libs.ktorSerializationKotlinxJson)
implementation(libs.kotlinReflect)

testImplementation(libs.junitJupiter)

"integrationTestImplementation"(gradleTestKit())
"integrationTestImplementation"(libs.cyclonedxCoreJava)
"integrationTestImplementation"(libs.junitJupiter)
"integrationTestImplementation"(libs.ktorClientCio)
"integrationTestImplementation"(libs.ktorClientContentNegotiation)
"integrationTestImplementation"(libs.ktorSerializationKotlinxJson)
}
41 changes: 41 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
version: '3.7'

#####################################################
# This Docker Compose file contains two services
# Dependency-Track API Server
# Dependency-Track FrontEnd
#####################################################

volumes:
dependency-track:

services:
dtrack-apiserver:
image: dependencytrack/apiserver

environment:
- ALPINE_ENFORCE_AUTHENTICATION=false
- ALPINE_ENFORCE_AUTHORIZATION=true
deploy:
resources:
limits:
memory: 12288m
reservations:
memory: 8192m
restart_policy:
condition: on-failure
ports:
- '8081:8080'
volumes:
- 'dependency-track:/data'
restart: unless-stopped

dtrack-frontend:
image: dependencytrack/frontend
depends_on:
- dtrack-apiserver
environment:
- API_BASE_URL=http://localhost:8081
ports:
- "8080:8080"
restart: unless-stopped
5 changes: 5 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
kotlin.code.style=official
pluginGroup=com.liftric
pluginVersion=1.0.0
pluginName=dependency-track-companion-plugin
pluginVendor=Liftric
Binary file added gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
5 changes: 5 additions & 0 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading