From fa852ace7fc5c5311d9cd8fdbf9b2827f5905f16 Mon Sep 17 00:00:00 2001 From: MatteoPologruto Date: Wed, 15 Mar 2023 13:51:26 +0100 Subject: [PATCH] Add CI workflow to check for unapproved Go dependency licenses A task and GitHub Actions workflow are provided here for checking the license types of Go project dependencies. On every push and pull request that affects relevant files, the CI workflow will check: - If the dependency licenses cache is up to date - If any of the project's dependencies have an unapproved license type. Approval can be based on: - Universally allowed license type - Individual dependency --- .../workflows/check-go-dependencies-task.yml | 152 ++++++++++++++++++ .licensed.yml | 12 ++ README.md | 1 + Taskfile.yml | 32 ++++ 4 files changed, 197 insertions(+) create mode 100644 .github/workflows/check-go-dependencies-task.yml create mode 100644 .licensed.yml diff --git a/.github/workflows/check-go-dependencies-task.yml b/.github/workflows/check-go-dependencies-task.yml new file mode 100644 index 0000000..7a155e6 --- /dev/null +++ b/.github/workflows/check-go-dependencies-task.yml @@ -0,0 +1,152 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/check-go-dependencies-task.md +name: Check Go Dependencies + +env: + # See: https://github.com/actions/setup-go/tree/main#supported-version-syntax + GO_VERSION: "1.19" + +# See: https://docs.github.com/actions/using-workflows/events-that-trigger-workflows +on: + create: + push: + paths: + - ".github/workflows/check-go-dependencies-task.ya?ml" + - ".licenses/**" + - ".licensed.json" + - ".licensed.ya?ml" + - "Taskfile.ya?ml" + - "**/.gitmodules" + - "**/go.mod" + - "**/go.sum" + pull_request: + paths: + - ".github/workflows/check-go-dependencies-task.ya?ml" + - ".licenses/**" + - ".licensed.json" + - ".licensed.ya?ml" + - "Taskfile.ya?ml" + - "**/.gitmodules" + - "**/go.mod" + - "**/go.sum" + schedule: + # Run periodically to catch breakage caused by external changes. + - cron: "0 8 * * WED" + workflow_dispatch: + repository_dispatch: + +jobs: + run-determination: + runs-on: ubuntu-latest + outputs: + result: ${{ steps.determination.outputs.result }} + steps: + - name: Determine if the rest of the workflow should run + id: determination + run: | + RELEASE_BRANCH_REGEX="refs/heads/[0-9]+.[0-9]+.x" + # The `create` event trigger doesn't support `branches` filters, so it's necessary to use Bash instead. + if [[ + "${{ github.event_name }}" != "create" || + "${{ github.ref }}" =~ $RELEASE_BRANCH_REGEX + ]]; then + # Run the other jobs. + RESULT="true" + else + # There is no need to run the other jobs. + RESULT="false" + fi + + echo "result=$RESULT" >> $GITHUB_OUTPUT + + check-cache: + needs: run-determination + if: needs.run-determination.outputs.result == 'true' + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + submodules: recursive + + # This is required to allow jonabc/setup-licensed to install licensed via Ruby gem. + - name: Install Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ruby # Install latest version + + - name: Install licensed + uses: jonabc/setup-licensed@v1 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Install Go + uses: actions/setup-go@v4 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Install Task + uses: arduino/setup-task@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Update dependencies license metadata cache + run: task --silent general:cache-dep-licenses + + - name: Check for outdated cache + id: diff + run: | + git add . + if ! git diff --cached --color --exit-code; then + echo + echo "::error::Dependency license metadata out of sync. See: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/check-go-dependencies-task.md#metadata-cache" + exit 1 + fi + + # Some might find it convenient to have CI generate the cache rather than setting up for it locally + - name: Upload cache to workflow artifact + if: failure() && steps.diff.outcome == 'failure' + uses: actions/upload-artifact@v3 + with: + if-no-files-found: error + name: dep-licenses-cache + path: .licenses/ + + check-deps: + needs: run-determination + if: needs.run-determination.outputs.result == 'true' + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + submodules: recursive + + # This is required to allow jonabc/setup-licensed to install licensed via Ruby gem. + - name: Install Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ruby # Install latest version + + - name: Install licensed + uses: jonabc/setup-licensed@v1 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Install Go + uses: actions/setup-go@v4 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Install Task + uses: arduino/setup-task@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Check for dependencies with unapproved licenses + run: task --silent general:check-dep-licenses diff --git a/.licensed.yml b/.licensed.yml new file mode 100644 index 0000000..673a4ec --- /dev/null +++ b/.licensed.yml @@ -0,0 +1,12 @@ +# See: https://github.com/github/licensed/blob/master/docs/configuration.md +sources: + go: true + +# This list is incomplete. It must be updated when new dependencies are needed for the project +allowed: + - bsd-3-clause + - bsd-3-clause-clear + - bsd-2-clause # Subsumed by `bsd-2-clause-views` + - bsd-2-clause-netbsd # Deprecated ID for `bsd-2-clause` + - bsd-2-clause-views # This is the version linked from https://www.gnu.org/licenses/license-list.html#FreeBSD + - bsd-2-clause-freebsd # Deprecated ID for `bsd-2-clause-views` diff --git a/README.md b/README.md index dc4b94f..67f197c 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ [![Codecov](https://codecov.io/gh/arduino/go-win32-utils/branch/main/graph/badge.svg)](https://codecov.io/gh/arduino/go-win32-utils) [![Check Go status](https://github.com/arduino/go-win32-utils/actions/workflows/check-go-task.yml/badge.svg)](https://github.com/arduino/go-win32-utils/actions/workflows/check-go-task.yml) [![Check License status](https://github.com/arduino/go-win32-utils/actions/workflows/check-license.yml/badge.svg)](https://github.com/arduino/go-win32-utils/actions/workflows/check-license.yml) +[![Check Go Dependencies status](https://github.com/arduino/go-win32-utils/actions/workflows/check-go-dependencies-task.yml/badge.svg)](https://github.com/arduino/go-win32-utils/actions/workflows/check-go-dependencies-task.yml) This library contains some useful calls to win32 API that are not available on the standard golang library. diff --git a/Taskfile.yml b/Taskfile.yml index 336ce9f..30582db 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -160,3 +160,35 @@ tasks: dir: "{{.DEFAULT_GO_MODULE_PATH}}" cmds: - go build -v {{.LDFLAGS}} + + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-dependencies-task/Taskfile.yml + general:cache-dep-licenses: + desc: Cache dependency license metadata + deps: + - task: general:prepare-deps + cmds: + - | + if ! which licensed &>/dev/null; then + if [[ {{OS}} == "windows" ]]; then + echo "Licensed does not have Windows support." + echo "Please use Linux/macOS or download the dependencies cache from the GitHub Actions workflow artifact." + else + echo "licensed not found or not in PATH." + echo "Please install: https://github.com/github/licensed#as-an-executable" + fi + exit 1 + fi + - licensed cache + + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-dependencies-task/Taskfile.yml + general:check-dep-licenses: + desc: Check for unapproved dependency licenses + deps: + - task: general:cache-dep-licenses + cmds: + - licensed status + + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-go-dependencies-task/Taskfile.yml + general:prepare-deps: + desc: Prepare project dependencies for license check + # No preparation is needed for Go module-based projects.