在CI/CD流程中执行许可证扫描

Pivotal(现为VMware)开发的许可证检查用开源软件有一个名为License Finder的工具。据说GitLab的许可证检查功能(仅限ULTIMATE版本可用)也已经集成了License Finder,我想这个工具可能可以用来检查产品的许可证,所以在GitLab的CI/CD流水线中集成了它。

另外,我所调查的是v7.0.1时的版本,如果版本不同可能存在内容不一致的可能性,请您知悉。

“License Finder” 是什么?

根据官方页面的解释,License Finder与包管理器合作,检测依赖关系并检测包的许可证,将这些许可证与用户定义的许可证列表进行比较,并提供实用的例外报告。

这一特点不仅仅停留在检测上,还能与用户定义的许可证列表进行比较,我认为这是其主要特点之一。

以下是支持的语言和软件包管理器。

Project TypePackage ManagerRuby GemsbundlerPython 2.7 Eggspip2Python 3.5 Eggspip3Node.jsnpmBowerbowerNuget (without license discovery)nugetGodepGodepGo workspaceGo langGo modulesGo langJavamavenJavagradle

另外,虽然属于实验性质,但也对以下进行了适配。

    • 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
1660704287273.png

如果您想在管道中保护部署的话,可以将管道中的“|| 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'
}
广告
将在 10 秒后关闭
bannerAds