diff options
author | Alex Goodman <wagoodman@users.noreply.github.com> | 2023-07-06 22:01:46 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-06 22:01:46 -0400 |
commit | d5e8a9296882f113e3990daca5e6b16109f512b8 (patch) | |
tree | 9182ab95acf9bdd102dd2d44a80424268f2df4b7 | |
parent | 42925c1b058a3187ec1bbd63b3557517e1fe04da (diff) |
Rework CI validation workflow and makefile (#460)
* rework CI validation workflow and makefile
* enable push
* fix job names
* fix license check
* fix snapshot builds
* fix acceptance tests
* fix linting
* disable pull request event
* rework windows runner caching
* disable release pipeline and add issue templates
73 files changed, 998 insertions, 510 deletions
diff --git a/.bouncer.yaml b/.bouncer.yaml new file mode 100644 index 0000000..9ee3121 --- /dev/null +++ b/.bouncer.yaml @@ -0,0 +1,12 @@ +permit: + - BSD.* + - MIT.* + - Apache.* + - MPL.* + - ISC + - WTFPL + +ignore-packages: + # crypto/internal/boring is released under the openSSL license as a part of the Golang Standard Library + - crypto/internal/boring + diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 35375e8..0000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,59 +0,0 @@ -version: 2.1 - -jobs: - run-static-analyses: - parameters: - version: - type: string - working_directory: /home/circleci/app - docker: - - image: cimg/go:<< parameters.version >> - environment: - GO111MODULE: "on" - steps: - - checkout - - restore_cache: - keys: - - golang-<< parameters.version >>-{{ checksum "go.sum" }} - - run: make ci-install-go-tools - - save_cache: - key: golang-<< parameters.version >>-{{ checksum "go.sum" }} - paths: - - "/go/pkg/mod" - - run: - name: run static analysis - command: make ci-static-analysis - - run-tests: - parameters: - version: - type: string - working_directory: /home/circleci/app - docker: - - image: cimg/go:<< parameters.version >> - environment: - GO111MODULE: "on" - steps: - - checkout - - restore_cache: - keys: - - golang-<< parameters.version >>-{{ checksum "go.sum" }} - - run: make ci-install-go-tools - - save_cache: - key: golang-<< parameters.version >>-{{ checksum "go.sum" }} - paths: - - "/go/pkg/mod" - - run: - name: run unit tests - command: make ci-unit-test - - -workflows: - commit: - jobs: - - run-static-analyses: - version: "1.19" - - run-tests: - version: "1.19" - - run-tests: - version: "1.19" diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 0cfb4a1..51d9b59 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,2 +1 @@ github: ['wagoodman'] -custom: ['https://www.paypal.me/wagoodman'] diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..6879ffd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,20 @@ +--- +name: Bug report +about: Something isn't working as expected +title: '' +labels: bug +assignees: '' + +--- + +**What happened**: + +**What you expected to happen**: + +**How to reproduce it (as minimally and precisely as possible)**: + +**Anything else we need to know?**: + +**Environment**: +- OS version +- Docker version (if applicable) diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..437f1aa --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,15 @@ +--- +name: Feature request +about: Got an idea for a new feature? Let us know! +title: '' +labels: enhancement +assignees: '' + +--- + +**What would you like to be added**: + +**Why is this needed**: + +**Additional context**: +<!-- Add any other context or screenshots about the feature request here. --> diff --git a/.github/actions/bootstrap/action.yaml b/.github/actions/bootstrap/action.yaml new file mode 100644 index 0000000..df71a17 --- /dev/null +++ b/.github/actions/bootstrap/action.yaml @@ -0,0 +1,76 @@ +name: "Bootstrap" +description: "Bootstrap all tools and dependencies" +inputs: + go-version: + description: "Go version to install" + required: true + default: "1.20.x" + use-go-cache: + description: "Restore go cache" + required: true + default: "true" + cache-key-prefix: + description: "Prefix all cache keys with this value" + required: true + default: "efa04b89c1b1" + build-cache-key-prefix: + description: "Prefix build cache key with this value" + required: true + default: "f8b6d31dea" + bootstrap-apt-packages: + description: "Space delimited list of tools to install via apt" + default: "" + +runs: + using: "composite" + steps: + - uses: actions/setup-go@v3 + with: + go-version: ${{ inputs.go-version }} + + - name: Restore tool cache + id: tool-cache + uses: actions/cache@v3 + with: + path: ${{ github.workspace }}/.tmp + key: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-tool-${{ hashFiles('Makefile') }} + + # note: we need to keep restoring the go mod cache before bootstrapping tools since `go install` is used in + # some installations of project tools. + - name: Restore go module cache + id: go-mod-cache + if: inputs.use-go-cache == 'true' + uses: actions/cache@v3 + with: + path: | + ~/go/pkg/mod + key: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-go-${{ inputs.go-version }}-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ inputs.cache-key-prefix }}-${{ runner.os }}-go-${{ inputs.go-version }}- + + - name: (cache-miss) Bootstrap project tools + shell: bash + if: steps.tool-cache.outputs.cache-hit != 'true' + run: make bootstrap-tools + + - name: Restore go build cache + id: go-cache + if: inputs.use-go-cache == 'true' + uses: actions/cache@v3 + with: + path: | + ~/.cache/go-build + key: ${{ inputs.cache-key-prefix }}-${{ inputs.build-cache-key-prefix }}-${{ runner.os }}-go-${{ inputs.go-version }}-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ inputs.cache-key-prefix }}-${{ inputs.build-cache-key-prefix }}-${{ runner.os }}-go-${{ inputs.go-version }}- + + - name: (cache-miss) Bootstrap go dependencies + shell: bash + if: steps.go-mod-cache.outputs.cache-hit != 'true' && inputs.use-go-cache == 'true' + run: make bootstrap-go + + - name: Install apt packages + if: inputs.bootstrap-apt-packages != '' + shell: bash + run: | + DEBIAN_FRONTEND=noninteractive sudo apt update && sudo -E apt install -y ${{ inputs.bootstrap-apt-packages }} diff --git a/.github/scripts/ci-check.sh b/.github/scripts/ci-check.sh new file mode 100755 index 0000000..0ab83a3 --- /dev/null +++ b/.github/scripts/ci-check.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +red=$(tput setaf 1) +bold=$(tput bold) +normal=$(tput sgr0) + +# assert we are running in CI (or die!) +if [[ -z "$CI" ]]; then + echo "${bold}${red}This step should ONLY be run in CI. Exiting...${normal}" + exit 1 +fi diff --git a/.github/scripts/coverage.py b/.github/scripts/coverage.py new file mode 100755 index 0000000..db14135 --- /dev/null +++ b/.github/scripts/coverage.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python3 +import subprocess +import sys +import shlex + + +class bcolors: + HEADER = '\033[95m' + OKBLUE = '\033[94m' + OKCYAN = '\033[96m' + OKGREEN = '\033[92m' + WARNING = '\033[93m' + FAIL = '\033[91m' + ENDC = '\033[0m' + BOLD = '\033[1m' + UNDERLINE = '\033[4m' + + +if len(sys.argv) < 3: + print("Usage: coverage.py [threshold] [go-coverage-report]") + sys.exit(1) + + +threshold = float(sys.argv[1]) +report = sys.argv[2] + + +args = shlex.split(f"go tool cover -func {report}") +p = subprocess.run(args, capture_output=True, text=True) + +percent_coverage = float(p.stdout.splitlines()[-1].split()[-1].replace("%", "")) +print(f"{bcolors.BOLD}Coverage: {percent_coverage}%{bcolors.ENDC}") + +if percent_coverage < threshold: + print(f"{bcolors.BOLD}{bcolors.FAIL}Coverage below threshold of {threshold}%{bcolors.ENDC}") + sys.exit(1) diff --git a/.github/scripts/go-mod-tidy-check.sh b/.github/scripts/go-mod-tidy-check.sh new file mode 100755 index 0000000..41bc639 --- /dev/null +++ b/.github/scripts/go-mod-tidy-check.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +set -eu + +ORIGINAL_STATE_DIR=$(mktemp -d "TEMP-original-state-XXXXXXXXX") +TIDY_STATE_DIR=$(mktemp -d "TEMP-tidy-state-XXXXXXXXX") + +trap "cp -v ${ORIGINAL_STATE_DIR}/* ./ && rm -fR ${ORIGINAL_STATE_DIR} ${TIDY_STATE_DIR}" EXIT + +echo "Capturing original state of files..." +cp -v go.mod go.sum "${ORIGINAL_STATE_DIR}" + +echo "Capturing state of go.mod and go.sum after running go mod tidy..." +go mod tidy +cp -v go.mod go.sum "${TIDY_STATE_DIR}" +echo "" + +set +e + +# Detect difference between the git HEAD state and the go mod tidy state +DIFF_MOD=$(diff -u "${ORIGINAL_STATE_DIR}/go.mod" "${TIDY_STATE_DIR}/go.mod") +DIFF_SUM=$(diff -u "${ORIGINAL_STATE_DIR}/go.sum" "${TIDY_STATE_DIR}/go.sum") + +if [[ -n "${DIFF_MOD}" || -n "${DIFF_SUM}" ]]; then + echo "go.mod diff:" + echo "${DIFF_MOD}" + echo "go.sum diff:" + echo "${DIFF_SUM}" + echo "" + printf "FAILED! go.mod and/or go.sum are NOT tidy; please run 'go mod tidy'.\n\n" + exit 1 +fi diff --git a/.github/scripts/trigger-release.sh b/.github/scripts/trigger-release.sh new file mode 100755 index 0000000..c1a5432 --- /dev/null +++ b/.github/scripts/trigger-release.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env bash +set -eu + +bold=$(tput bold) +normal=$(tput sgr0) + +if ! [ -x "$(command -v gh)" ]; then + echo "The GitHub CLI could not be found. To continue follow the instructions at https://github.com/cli/cli#installation" + exit 1 +fi + +gh auth status + +# we need all of the git state to determine the next version. Since tagging is done by +# the release pipeline it is possible to not have all of the tags from previous releases. +git fetch --tags + +# populates the CHANGELOG.md and VERSION files +echo "${bold}Generating changelog...${normal}" +make changelog 2> /dev/null + +NEXT_VERSION=$(cat VERSION) + +if [[ "$NEXT_VERSION" == "" || "${NEXT_VERSION}" == "(Unreleased)" ]]; then + echo "Could not determine the next version to release. Exiting..." + exit 1 +fi + +while true; do + read -p "${bold}Do you want to trigger a release for version '${NEXT_VERSION}'?${normal} [y/n] " yn + case $yn in + [Yy]* ) echo; break;; + [Nn]* ) echo; echo "Cancelling release..."; exit;; + * ) echo "Please answer yes or no.";; + esac +done + +echo "${bold}Kicking off release for ${NEXT_VERSION}${normal}..." +echo +gh workflow run release.yaml -f version=${NEXT_VERSION} + +echo +echo "${bold}Waiting for release to start...${normal}" +sleep 10 + +set +e + +echo "${bold}Head to the release workflow to monitor the release:${normal} $(gh run list --workflow=release.yaml --limit=1 --json url --jq '.[].url')" +id=$(gh run list --workflow=release.yaml --limit=1 --json databaseId --jq '.[].databaseId') +gh run watch $id --exit-status || (echo ; echo "${bold}Logs of failed step:${normal}" && GH_PAGER="" gh run view $id --log-failed) diff --git a/.github/workflows/pipeline.yml b/.github/workflows/pipeline.yml deleted file mode 100644 index 7778ef9..0000000 --- a/.github/workflows/pipeline.yml +++ /dev/null @@ -1,180 +0,0 @@ -name: 'app-pipeline' -on: - push: - pull_request: - types: [ opened, reopened ] -env: - DOCKER_CLI_VERSION: "19.03.1" -jobs: - unit-test: - strategy: - matrix: - go-version: [1.19.x] - # todo: support windows - platform: [ubuntu-latest, macos-latest] - # platform: [ubuntu-latest, macos-latest, windows-latest] - runs-on: ${{ matrix.platform }} - steps: - - - uses: actions/setup-go@v1 - with: - go-version: ${{ matrix.go-version }} - - - uses: actions/checkout@v1 - - - name: Cache go dependencies - id: unit-cache-go-dependencies - uses: actions/cache@v1 - with: - path: ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ matrix.go-version }}-${{ hashFiles('**/go.sum') }} - restore-keys: ${{ runner.os }}-go-${{ matrix.go-version }}- - - - name: Install go dependencies - if: steps.unit-cache-go-dependencies.outputs.cache-hit != 'true' - run: go get ./... - - - name: Test - run: make ci-unit-test - - build-artifacts: - runs-on: ubuntu-latest - steps: - - uses: actions/setup-go@v1 - with: - go-version: '1.19.x' - - - uses: actions/checkout@v |