在CI/CD流程中执行许可证扫描
Pivotal(现为VMware)开发的许可证检查用开源软件有一个名为License Finder的工具。据说GitLab的许可证检查功能(仅限ULTIMATE版本可用)也已经集成了License Finder,我想这个工具可能可以用来检查产品的许可证,所以在GitLab的CI/CD流水线中集成了它。
另外,我所调查的是v7.0.1时的版本,如果版本不同可能存在内容不一致的可能性,请您知悉。
“License Finder” 是什么?
根据官方页面的解释,License Finder与包管理器合作,检测依赖关系并检测包的许可证,将这些许可证与用户定义的许可证列表进行比较,并提供实用的例外报告。
这一特点不仅仅停留在检测上,还能与用户定义的许可证列表进行比较,我认为这是其主要特点之一。
以下是支持的语言和软件包管理器。
另外,虽然属于实验性质,但也对以下进行了适配。
-
- Erlang (rebar, Erlang.mk)
-
- Objective-C, Swift (Carthage, CocoaPods ※0.39以下, Swift Package Manager(SPM))
-
- Elixir (mix)
-
- Golang (gvt, glide,dep, trash, govendor)
-
- JavaScript (yarn)
-
- C++/C (conan)
-
- Scala (sbt)
-
- Rust (cargo)
-
- PHP (composer)
-
- Python (Conda, pipenv)
- Flutter (flutter pub)
请在手上确认操作正确
安装
必须满足以下前提条件:需要安装Ruby2.4.0或以上版本。
有多种安装方法可供选择,但考虑到将其集成到CI/CD流水线中,我们选择在Linux上使用gem命令进行安装。
sudo apt install ruby-rubygems -y
sudo gem install license_finder
扫描和检查
我要对paketo-buildpacks中的样例maven进行执行,其中包含了许多不同语言的示例。
首先,下载源代码,然后将其移动到maven项目下。
git clone https://github.com/paketo-buildpacks/samples.git /tmp/paketo-sample
cd /tmp/paketo-sample/java/maven
执行后大约30秒会输出结果。
$ license_finder
LicenseFinder::Maven: is active
Dependencies that need approval:
HdrHistogram, 2.1.12, "Public Domain, per Creative Commons CC0, Simplified BSD"
LatencyUtils, 2.0.3, "Public Domain, per Creative Commons CC0"
accessors-smart, 2.4.8, "Apache 2.0"
android-json, 0.0.20131108.vaadin1, "Apache 2.0"
apiguardian-api, 1.1.2, "Apache 2.0"
asm, 9.1, "New BSD"
assertj-core, 3.22.0, "Apache 2.0"
byte-buddy, 1.12.11, "Apache 2.0"
byte-buddy-agent, 1.12.11, "Apache 2.0"
hamcrest, 2.2, "BSD License 3"
jackson-annotations, 2.13.3, "Apache 2.0"
jackson-core, 2.13.3, "Apache 2.0"
jackson-databind, 2.13.3, "Apache 2.0"
jackson-datatype-jdk8, 2.13.3, "Apache 2.0"
jackson-datatype-jsr310, 2.13.3, "Apache 2.0"
jackson-module-parameter-names, 2.13.3, "Apache 2.0"
jakarta.activation-api, 1.2.2, "EDL 1.0"
jakarta.annotation-api, 1.3.5, "EPL 2.0, GPL2 w/ CPE"
jakarta.xml.bind-api, 2.3.3, "Eclipse Distribution License - v 1.0"
json-path, 2.7.0, "Apache 2.0"
json-smart, 2.4.8, "Apache 2.0"
jsonassert, 1.5.0, "Apache 2.0"
jul-to-slf4j, 1.7.36, MIT
junit-jupiter, 5.8.2, "Eclipse Public License v2.0"
junit-jupiter-api, 5.8.2, "Eclipse Public License v2.0"
junit-jupiter-engine, 5.8.2, "Eclipse Public License v2.0"
junit-jupiter-params, 5.8.2, "Eclipse Public License v2.0"
junit-platform-commons, 1.8.2, "Eclipse Public License v2.0"
junit-platform-engine, 1.8.2, "Eclipse Public License v2.0"
log4j-api, 2.17.2, "Apache 2.0"
log4j-to-slf4j, 2.17.2, "Apache 2.0"
logback-classic, 1.2.11, "Eclipse Public License 1.0, GNU Lesser General Public License"
logback-core, 1.2.11, "Eclipse Public License 1.0, GNU Lesser General Public License"
micrometer-core, 1.9.1, "Apache 2.0"
mockito-core, 4.5.1, MIT
mockito-junit-jupiter, 4.5.1, MIT
netty-buffer, 4.1.78.Final, "Apache 2.0"
netty-codec, 4.1.78.Final, "Apache 2.0"
netty-codec-dns, 4.1.78.Final, "Apache 2.0"
netty-codec-http, 4.1.78.Final, "Apache 2.0"
netty-codec-http2, 4.1.78.Final, "Apache 2.0"
netty-codec-socks, 4.1.78.Final, "Apache 2.0"
netty-common, 4.1.78.Final, "Apache 2.0"
netty-handler, 4.1.78.Final, "Apache 2.0"
netty-handler-proxy, 4.1.78.Final, "Apache 2.0"
netty-resolver, 4.1.78.Final, "Apache 2.0"
netty-resolver-dns, 4.1.78.Final, "Apache 2.0"
netty-resolver-dns-classes-macos, 4.1.78.Final, "Apache 2.0"
netty-resolver-dns-native-macos, 4.1.78.Final, "Apache 2.0"
netty-transport, 4.1.78.Final, "Apache 2.0"
netty-transport-classes-epoll, 4.1.78.Final, "Apache 2.0"
netty-transport-native-epoll, 4.1.78.Final, "Apache 2.0"
netty-transport-native-unix-common, 4.1.78.Final, "Apache 2.0"
objenesis, 3.2, "Apache 2.0"
opentest4j, 1.2.0, "Apache 2.0"
reactive-streams, 1.0.4, MIT-0
reactor-core, 3.4.19, "Apache 2.0"
reactor-netty-core, 1.0.20, "Apache 2.0"
reactor-netty-http, 1.0.20, "Apache 2.0"
reactor-test, 3.4.19, "Apache 2.0"
slf4j-api, 1.7.36, MIT
snakeyaml, 1.30, "Apache 2.0"
spring-aop, 5.3.21, "Apache 2.0"
spring-beans, 5.3.21, "Apache 2.0"
spring-boot, 2.7.1, "Apache 2.0"
spring-boot-actuator, 2.7.1, "Apache 2.0"
spring-boot-actuator-autoconfigure, 2.7.1, "Apache 2.0"
spring-boot-autoconfigure, 2.7.1, "Apache 2.0"
spring-boot-starter, 2.7.1, "Apache 2.0"
spring-boot-starter-actuator, 2.7.1, "Apache 2.0"
spring-boot-starter-json, 2.7.1, "Apache 2.0"
spring-boot-starter-logging, 2.7.1, "Apache 2.0"
spring-boot-starter-reactor-netty, 2.7.1, "Apache 2.0"
spring-boot-starter-test, 2.7.1, "Apache 2.0"
spring-boot-starter-webflux, 2.7.1, "Apache 2.0"
spring-boot-test, 2.7.1, "Apache 2.0"
spring-boot-test-autoconfigure, 2.7.1, "Apache 2.0"
spring-context, 5.3.21, "Apache 2.0"
spring-core, 5.3.21, "Apache 2.0"
spring-expression, 5.3.21, "Apache 2.0"
spring-jcl, 5.3.21, "Apache 2.0"
spring-test, 5.3.21, "Apache 2.0"
spring-web, 5.3.21, "Apache 2.0"
spring-webflux, 5.3.21, "Apache 2.0"
xmlunit-core, 2.9.0, "Apache 2.0"
既然如此,就试试GoModules的示例吧。
$ cd ../../go/mod/
$ license_finder action_items
LicenseFinder::GoModules: is active
Dependencies that need approval:
github.com/gorilla/mux, v1.8.0, "New BSD"
需要注意的是,“需要批准的依赖项”,而license_finder只会输出未经批准的许可证。
让我们看看批准后会发生什么。
$ license_finder approvals add github.com/gorilla/mux
The github.com/gorilla/mux dependency has been approved!
$ license_finder
LicenseFinder::GoModules: is active
All dependencies are approved for use
如此,将不再显示。
将其集成到CI/CD流水线中。
提供了公式镜像,但有一些特殊之处。
查看镜像的Dockerfile可以看到CMD用法有点不同。
CMD cd /scan && /bin/bash -l
在这里,bash -l命令用于加载.bash_profile文件,如果不执行此命令,则无法进行扫描。如果要在管道中执行,请加载.profile文件以设置环境变量等。下面是我用于进行操作验证的.gitlab-ci.yml文件内容。
license-scan:
image: licensefinder/license_finder
stage: build
rules:
- if: '$CI_PIPELINE_SOURCE == "push"'
script:
- |
. ~/.profile
/LicenseFinder/bin/license_finder | tee license_list.txt || true
artifacts:
paths:
- license_list.txt
expire_in: 1 days
如果您想在管道中保护部署的话,可以将管道中的“|| true”去掉,并在未批准的许可证存在时停止。
在进行Gradle扫描时需要注意的问题
根据官方网站的描述,需要添加license-gradle-plugin的配置,但是即使按照license-gradle-plugin的README进行配置,仍会出现以下错误。
FAILURE: Build failed with an exception.
* What went wrong:
Some problems were found with the configuration of task ':downloadLicenses' (type 'DownloadLicenses').
- In plugin 'com.github.hierynomus.license-report' type 'nl.javadude.gradle.plugins.license.DownloadLicenses' property 'html' has redundant getters: 'getHtml()' and 'isHtml()'.
通过在build.gradle中进行以下设置,可以避免这种情况。(引用来源:stackoverflow)
plugins {
id "com.github.hierynomus.license-report" version"0.16.1"
}
/**
* You will have to specify for which configuration dependencies should be resolved.
* Note check in Gradle documentation about configuration types that can be resolved.
* https://docs.gradle.org/current/userguide/declaring_dependencies.html#sec:resolvable-consumable-configs
*
* Following are resolvable by default:
* - compileClasspath
* - runtimeClasspath
*/
downloadLicenses {
includeProjectDependencies = true
dependencyConfiguration = 'runtimeClasspath'
// or
// dependencyConfiguration = 'compileClasspath'
}