From bd248650767ac48deff9a08acbd5ff2c8d69c9f7 Mon Sep 17 00:00:00 2001 From: Andy Feller Date: Fri, 30 May 2025 12:46:51 -0400 Subject: [PATCH] Adopt license compliance scripts into workflows, docs This commit introduces the use of `go-licenses` within CI/CD and manual processes for generating / updating the license information used by GitHub CLI including the code required by license to be redistributed. During GitHub CLI pull requests, the `lint` workflow will notify users if this information is not updated. --- .github/licenses.tmpl | 13 ++++++++++ .github/workflows/lint.yml | 13 ++++++++++ docs/license-compliance.md | 52 ++++++++++++++++++++++++++++++++++++++ script/licenses | 23 +++++++++++++++++ script/licenses-check | 21 +++++++++++++++ 5 files changed, 122 insertions(+) create mode 100644 .github/licenses.tmpl create mode 100644 docs/license-compliance.md create mode 100755 script/licenses create mode 100755 script/licenses-check diff --git a/.github/licenses.tmpl b/.github/licenses.tmpl new file mode 100644 index 000000000..f9e800d3d --- /dev/null +++ b/.github/licenses.tmpl @@ -0,0 +1,13 @@ +# GitHub CLI dependencies + +The following open source dependencies are used to build the [cli/cli][] GitHub CLI. + +## Go Packages + +Some packages may only be included on certain architectures or operating systems. + +{{ range . }} +- [{{.Name}}](https://pkg.go.dev/{{.Name}}) ([{{.LicenseName}}]({{.LicenseURL}})) +{{- end }} + +[cli/cli]: https://github.com/cli/cli diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index f1ae1e522..2d8a79ab5 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -5,11 +5,15 @@ on: - "**.go" - go.mod - go.sum + - ".github/licenses.tmpl" + - "script/licenses*" pull_request: paths: - "**.go" - go.mod - go.sum + - ".github/licenses.tmpl" + - "script/licenses*" permissions: contents: read @@ -56,3 +60,12 @@ jobs: bin/golangci-lint run --out-format=colored-line-number --timeout=3m || STATUS=$? exit $STATUS + + # actions/setup-go does not setup the installed toolchain to be preferred over the system install, + # which causes go-licenses to raise "Package ... does not have module info" errors. + # for more information, https://github.com/google/go-licenses/issues/244#issuecomment-1885098633 + - name: Check licenses + run: | + export GOROOT=$(go env GOROOT) + export PATH=${GOROOT}/bin:$PATH + ./script/licenses-check diff --git a/docs/license-compliance.md b/docs/license-compliance.md new file mode 100644 index 000000000..238ab9aa0 --- /dev/null +++ b/docs/license-compliance.md @@ -0,0 +1,52 @@ +# License Compliance + +GitHub CLI complies with the software licenses of its dependencies. This document explains how license compliance is maintained. + +## Overview + +When a dependency is added or updated, the license information needs to be updated. We use the [`google/go-licenses`](https://github.com/google/go-licenses) tool to: + +1. Generate markdown documentation listing all Go dependencies and their licenses +2. Copy license files for dependencies that require redistribution + +## License Files + +The following files contain license information: + +- `third-party-licenses.darwin.md` - License information for macOS dependencies +- `third-party-licenses.linux.md` - License information for Linux dependencies +- `third-party-licenses.windows.md` - License information for Windows dependencies +- `third-party/` - Directory containing source code and license files that require redistribution + +## Updating License Information + +When dependencies change, you need to update the license information: + +1. Update license information for all platforms: + + ```shell + script/licenses + ``` + +2. Commit the changes: + + ```shell + git add third-party-licenses.*.md third-party/ + git commit -m "Update third-party license information" + ``` + +## Checking License Compliance + +The CI workflow checks if license information is up to date. To check locally: + +```sh +script/licenses-check +``` + +If the check fails, follow the instructions to update the license information. + +## How It Works + +- `script/licenses` - Script to generate license information for all platforms or a specific platform +- `script/licenses-check` - Script to check if license information is up to date +- `.github/workflows/lint.yml` - CI workflow that includes license compliance checking diff --git a/script/licenses b/script/licenses new file mode 100755 index 000000000..d1e85fe0d --- /dev/null +++ b/script/licenses @@ -0,0 +1,23 @@ +#!/bin/bash + +go install github.com/google/go-licenses@latest + +rm -rf third-party +mkdir -p third-party +export TEMPDIR="$(mktemp -d)" + +trap "rm -fr ${TEMPDIR}" EXIT + +for goos in linux darwin windows ; do + # Note: we ignore warnings because we want the command to succeed, however the output should be checked + # for any new warnings, and potentially we may need to add license information. + # + # Normally these warnings are packages containing non go code, which may or may not require explicit attribution, + # depending on the license. + echo "Generating licenses for ${goos}..." + GOOS="${goos}" go-licenses save ./... --save_path="${TEMPDIR}/${goos}" --force || echo "Ignore warnings" + GOOS="${goos}" go-licenses report ./... --template .github/licenses.tmpl --ignore github.com/cli/cli > third-party-licenses.${goos}.md || echo "Ignore warnings" + cp -fR "${TEMPDIR}/${goos}"/* third-party/ +done + +echo "Licenses generated for all platforms." diff --git a/script/licenses-check b/script/licenses-check new file mode 100755 index 000000000..c19c9efb0 --- /dev/null +++ b/script/licenses-check @@ -0,0 +1,21 @@ +#!/bin/bash + +go install github.com/google/go-licenses@latest + +for goos in linux darwin windows ; do + # Note: we ignore warnings because we want the command to succeed, however the output should be checked + # for any new warnings, and potentially we may need to add license information. + # + # Normally these warnings are packages containing non go code, which may or may not require explicit attribution, + # depending on the license. + echo "Checking licenses for ${goos}..." + GOOS="${goos}" go-licenses report ./... --template .github/licenses.tmpl --ignore github.com/cli/cli > third-party-licenses.${goos}.copy.md || echo "Ignore warnings" + if ! diff -s third-party-licenses.${goos}.copy.md third-party-licenses.${goos}.md; then + echo "::error title=License check failed::Please update the license files by running \`script/licenses\` and committing the output." + rm -f third-party-licenses.${goos}.copy.md + exit 1 + fi + rm -f third-party-licenses.${goos}.copy.md +done + +echo "License check passed for all platforms."