A full-featured license tool to check and fix license headers and resolve dependencies' licenses.
You can use License-Eye in GitHub Actions or in your local machine.
First of all, add a .licenserc.yaml in the root of your project, for Apache Software Foundation projects, the following configuration should be enough.
Note: The full configurations can be found in the configuration section.
header:
license:
spdx-id: Apache-2.0
copyright-owner: Apache Software Foundation
paths-ignore:
- 'dist'
- 'licenses'
- '**/*.md'
- 'LICENSE'
- 'NOTICE'
comment: on-failure
# If you don't want to check dependencies' license compatibility, remove the following part
dependency:
files:
- pom.xml # If this is a maven project.
- Cargo.toml # If this is a rust project.
- package.json # If this is a npm project.
- go.mod # If this is a Go project.
- Gemfile.lock # If this is a Ruby project (Bundler). Ensure Gemfile.lock is committed.
To check license headers in GitHub Actions, add a step in your GitHub workflow.
- name: Check License Header
uses: apache/skywalking-eyes/header@main # always prefer to use a revision instead of `main`.
# with:
# log: debug # optional: set the log level. The default value is `info`.
# config: .licenserc.yaml # optional: set the config file. The default value is `.licenserc.yaml`.
# token: # optional: the token that license eye uses when it needs to comment on the pull request. Set to empty ("") to disable commenting on pull request. The default value is ${{ github.token }}
# mode: # optional: Which mode License-Eye should be run in. Choices are `check` or `fix`. The default value is `check`.
By default the action runs License-Eye in check mode, which will raise an error
if any of the processed files are missing license headers. If mode is set to
fix, the action will instead apply the license header to any processed file
that is missing a license header. The fixed files can then be pushed back to the
pull request using another GitHub action. For example:
- name: Fix License Header
uses: apache/skywalking-eyes/header@main
with:
mode: fix
- name: Apply Changes
uses: EndBug/add-and-commit@v4
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
author_name: License Bot
author_email: license_bot@github.com
message: 'Automatic application of license header'
Warning: The exit code of fix mode is always 0 and can not be used to block CI status. Consider running the action in check mode if you would like CI to fail when a file is missing a license header.
Note: In 0.3.0 and earlier versions, GitHub Actions
apache/skywalking-eyesonly works for header check/fix, since 0.4.0, we have a dedicate GitHub Actionsapache/skywalking-eyes/headerfor header check/fix and a GitHub Actionsapache/skywalking-eyes/dependencyfor dependency resolve/check. Nowapache/skywalking-eyesis equivalent toapache/skywalking-eyes/headerin order not to break existing usages ofapache/skywalking-eyes.
To check dependencies license in GitHub Actions, add a step in your GitHub workflow.
- name: Check Dependencies' License
uses: apache/skywalking-eyes/dependency@main # always prefer to use a revision instead of `main`.
# with:
# log: debug # optional: set the log level. The default value is `info`.
# config: .licenserc.yaml # optional: set the config file. The default value is `.licenserc.yaml`.
# mode: # optional: Which mode License-Eye should be run in. Choices are `check` or `resolve`. The default value is `check`.
# flags: # optional: Extra flags appended to the command, for example, `--summary=path/to/template.tmpl`
Ruby projects (Bundler)
License-Eye can resolve Ruby dependencies and their licenses directly from Gemfile.lock.
Rules applied: - If a .gemspec file exists in the same directory as Gemfile.lock, the project is treated as a library and development dependencies are ignored. Runtime dependencies (and their transitives) are included. - If no .gemspec is present, the project is treated as an app and all dependencies from Gemfile.lock are considered (both runtime and development).
Requirements: - Commit Gemfile.lock to version control so License-Eye can read the locked dependency graph. - For libraries, ensure the .gemspec is present in the same directory as Gemfile.lock.
Minimal config snippet:
dependency:
files:
- Gemfile.lock
GitHub Actions example:
name: Apache SkyWalking Eyes
permissions:
contents: read
on:
push:
branches:
- 'main'
- '*-stable'
tags:
- '!*' # Do not execute on tags
pull_request:
branches:
- '*'
# Allow manually triggering the workflow.
workflow_dispatch:
# Cancels all previous workflow runs for the same branch that have not yet completed.
concurrency:
# The concurrency group contains the workflow name and the branch name.
group: "${{ github.workflow }}-${{ github.ref }}"
cancel-in-progress: true
jobs:
license-check:
if: "!contains(github.event.commits[0].message, '[ci skip]') && !contains(github.event.commits[0].message, '[skip ci]')"
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Check Dependencies' License
uses: apache/skywalking-eyes/dependency@main
with:
config: .licenserc.yaml
# Ruby packages declared as dependencies in gemspecs or Gemfiles are
# typically consumed as binaries; enable weak-compatibility
# so permissive and weak-copyleft combinations are treated as compatible.
flags: --weak-compatible
Note: License-Eye may query the RubyGems API to determine licenses when they are not specified in your configuration. Ensure the workflow has network access.
The following flags are available for all commands:
| Flag name | Short name | Description |
|---|---|---|
--verbosity |
-v |
Set log level (debug, info, warn, error, fatal, panic). Default: info |
--config |
-c |
Path to the configuration file. Default: .licenserc.yaml |
Examples:
license-eye --verbosity debug --config .licenserc.yaml header check
license-eye -v warn -c path/to/.licenserc.yaml dep resolve
For Bash, users can execute the following command,
docker run -it --rm -v $(pwd):/github/workspace apache/skywalking-eyes header check
docker run -it --rm -v $(pwd):/github/workspace apache/skywalking-eyes header fix
For PowerShell 7, users can execute the following command,
docker run -it --rm -v ${pwd}:/github/workspace apache/skywalking-eyes header check
docker run -it --rm -v ${pwd}:/github/workspace apache/skywalking-eyes header fix
To check dependencies' licenses in Docker, you'll need the appropriate language runtime and package managers in your environment. The base Docker image only includes the license-eye binary. To check dependencies, you can build a custom Docker image with your required language tools:
FROM apache/skywalking-eyes:latest
# Install the tools you need
See the examples directory for more detailed examples and Dockerfiles for different languages.
For users and developers who want to help to test the latest codes on main branch, we publish a Docker image to the GitHub
Container Registry for every commit in main branch, tagged with the commit sha. If it's the latest commit in main
branch, it's also tagged with latest.
Note: these Docker images are not official Apache releases. For official releases, please refer to the download page for executable binary and the Docker hub for Docker images.
docker run -it --rm -v $(pwd):/github/workspace ghcr.io/apache/skywalking-eyes/license-eye header check
docker run -it --rm -v $(pwd):/github/workspace ghcr.io/apache/skywalking-eyes/license-eye header fix
git clone https://github.com/apache/skywalking-eyes
cd skywalking-eyes
make build
Notes: The make build command will generate a bin directory in the current project directory. Choose the appropriate binary file according to your operating system.
If you have the Go SDK installed, you can also use the go install command to install the latest code.
go install github.com/apache/skywalking-eyes/cmd/license-eye@latest
If you don’t have it installed, you can install it by running the following command in terminal:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Then install license-eye using the following command:
brew install license-eye
license-eye -c test/testdata/.licenserc_for_test_check.yaml header check
Header Check Result
INFO Loading configuration from file: test/testdata/.licenserc_for_test_check.yaml
INFO Totally checked 30 files, valid: 12, invalid: 12, ignored: 6, fixed: 0
ERROR the following files don't have a valid license header:
test/testdata/include_test/without_license/testcase.go
test/testdata/include_test/without_license/testcase.graphql
test/testdata/include_test/without_license/testcase.ini
test/testdata/include_test/without_license/testcase.java
test/testdata/include_test/without_license/testcase.md
test/testdata/include_test/without_license/testcase.php
test/testdata/include_test/without_license/testcase.py
test/testdata/include_test/without_license/testcase.sh
test/testdata/include_test/without_license/testcase.yaml
test/testdata/include_test/without_license/testcase.yml
test/testdata/test-spdx-asf.yaml
test/testdata/test-spdx.yaml
exit status 1
license-eye -c test/testdata/.licenserc_for_test_fix.yaml header fix
Header Fix Result
INFO Loading configuration from file: test/testdata/.licenserc_for_test_fix.yaml
INFO Totally checked 20 files, valid: 10, invalid: 10, ignored: 0, fixed: 10
This command assists human audits of the dependencies licenses. It's exit code is always 0.
It supports three flags, in addition to the global ones:
| Flag name | Short name | Description |
|---|---|---|
--output |
-o |
Save the dependencies' LICENSE files to a specified directory so that you can put them in distribution package if needed. |
--summary |
-s |
Based on the template, aggregate all dependency information and generate a LICENSE file. |
--license |
-l |
The output path to the LICENSE file to be generated. The default summary format will be used if summary template file is not specified |
license-eye -c test/testdata/.licenserc_for_test_check.yaml dep resolve -o ./dependencies/licenses -s LICENSE.tpl
Dependency Resolve Result
``` INFO Loading configuration from file: .licenserc.yaml WARNING Failed to resolve the license of github.com/acomagu/bufpipe@v1.0.3: cannot find license file Dependency | License | Version ------------------------------------ | -------------------- | ---------------------------------------- github.com/Masterminds/goutils | Apache-2.0 | v1.1.1 github.com/Masterminds/semver/v3 | MIT | v3.1.1 github.com/Masterminds/sprig/v3 | MIT | v3.2.2 github.com/Microsoft/go-winio | MIT | v0.5.2 github.com/ProtonMail/go-crypto | BSD-3-Clause | v0.0.0-20220824120805-4b6e5c587895 github.com/bmatcuk/doublestar/v2 | MIT | v2.0.4 github.com/cloudflare/circl | BSD-3-Clause | v1.2.0 github.com/davecgh/go-spew | ISC | v1.1.1 github.com/emirpasic/gods | BSD-2-Clause and ISC | v1.18.1 github.com/go-git/gcfg | BSD-3-Clause | v1.5.0 github.com/go-git/go-billy/v5 | Apache-2.0 | v5.3.1 github.com/go-git/go-git/v5 | Apache-2.0 | v5.4.2 github.com/golang/protobuf | BSD-3-Clause |
$ claude mcp add skywalking-eyes \
-- python -m otcore.mcp_server <graph>