diff --git a/.binny.yaml b/.binny.yaml new file mode 100644 index 00000000..abe08533 --- /dev/null +++ b/.binny.yaml @@ -0,0 +1,104 @@ +tools: + # we want to use a pinned version of binny to manage the toolchain (so binny manages itself!) + - name: binny + version: + want: v0.7.0 + method: github-release + with: + repo: anchore/binny + + # used to produce SBOMs during release + - name: syft + version: + want: latest + method: github-release + with: + repo: anchore/syft + + # used to sign mac binaries at release + - name: quill + version: + want: v0.4.1 + method: github-release + with: + repo: anchore/quill + + # used for linting + - name: golangci-lint + version: + want: v1.57.2 + method: github-release + with: + repo: golangci/golangci-lint + + # used for showing the changelog at release + - name: glow + version: + want: v1.5.1 + method: github-release + with: + repo: charmbracelet/glow + + # used for signing the checksums file at release + - name: cosign + version: + want: v2.2.4 + method: github-release + with: + repo: sigstore/cosign + + # used in integration tests to verify JSON schemas + - name: yajsv + version: + want: v1.4.1 + method: github-release + with: + repo: neilpa/yajsv + + # used to release all artifacts + - name: goreleaser + version: + want: v1.25.1 + method: github-release + with: + repo: goreleaser/goreleaser + + # used for organizing imports during static analysis + - name: gosimports + version: + want: v0.3.8 + method: github-release + with: + repo: rinchsan/gosimports + + # used at release to generate the changelog + - name: chronicle + version: + want: v0.8.0 + method: github-release + with: + repo: anchore/chronicle + + # used during static analysis for license compliance + - name: bouncer + version: + want: v0.4.0 + method: github-release + with: + repo: wagoodman/go-bouncer + + # used for running all local and CI tasks + - name: task + version: + want: v3.36.0 + method: github-release + with: + repo: go-task/task + + # used for triggering a release + - name: gh + version: + want: v2.48.0 + method: github-release + with: + repo: cli/cli diff --git a/.github/actions/bootstrap/action.yaml b/.github/actions/bootstrap/action.yaml index a0d11095..bffc07de 100644 --- a/.github/actions/bootstrap/action.yaml +++ b/.github/actions/bootstrap/action.yaml @@ -9,14 +9,18 @@ inputs: description: "Python version to install" required: true default: "3.10" + go-dependencies: + description: "Download go dependencies" + required: true + default: "true" cache-key-prefix: description: "Prefix all cache keys with this value" required: true - default: "831180ac26" - build-cache-key-prefix: - description: "Prefix build cache key with this value" + default: "1ac8281053" + compute-fingerprints: + description: "Compute test fixture fingerprints" required: true - default: "f8b6d31dea" + default: "true" bootstrap-apt-packages: description: "Space delimited list of tools to install via apt" default: "libxml2-utils" @@ -26,6 +30,7 @@ runs: steps: # note: go mod and build is automatically cached on default with v4+ - uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe #v4.1.0 + if: inputs.go-version != '' with: go-version: ${{ inputs.go-version }} @@ -33,30 +38,21 @@ runs: with: python-version: ${{ inputs.python-version }} - - name: Restore python cache - id: python-venv-cache - uses: actions/cache@69d9d449aced6a2ede0bc19182fadc3a0a42d2b0 # v3.2.6 - with: - path: | - test/quality/venv - test/quality/vulnerability-match-labels/venv - key: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-python-${{ inputs.python-version }}-${{ hashFiles('**/test/quality/**/requirements.txt') }} - - name: Restore tool cache id: tool-cache - uses: actions/cache@v3 + uses: actions/cache@704facf57e6136b1bc63b828d79edcd491f0ee84 #v3.3.2 with: - path: ${{ github.workspace }}/.tmp - key: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-tool-${{ hashFiles('Makefile') }} + path: ${{ github.workspace }}/.tool + key: ${{ inputs.cache-key-prefix }}-${{ runner.os }}-tool-${{ hashFiles('.binny.yaml') }} - - name: (cache-miss) Bootstrap project tools + - name: Install project tools shell: bash - if: steps.tool-cache.outputs.cache-hit != 'true' - run: make bootstrap-tools + run: make tools - - name: Bootstrap go dependencies + - name: Install go dependencies + if: inputs.go-dependencies == 'true' shell: bash - run: make bootstrap-go + run: make ci-bootstrap-go - name: Install apt packages if: inputs.bootstrap-apt-packages != '' @@ -65,5 +61,6 @@ runs: DEBIAN_FRONTEND=noninteractive sudo apt update && sudo -E apt install -y ${{ inputs.bootstrap-apt-packages }} - name: Create all cache fingerprints + if: inputs.compute-fingerprints == 'true' shell: bash run: make fingerprints diff --git a/.github/scripts/go-mod-tidy-check.sh b/.github/scripts/go-mod-tidy-check.sh index 41bc6391..28f22fcd 100755 --- a/.github/scripts/go-mod-tidy-check.sh +++ b/.github/scripts/go-mod-tidy-check.sh @@ -4,19 +4,18 @@ 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 +trap "cp -p ${ORIGINAL_STATE_DIR}/* ./ && git update-index -q --refresh && rm -fR ${ORIGINAL_STATE_DIR} ${TIDY_STATE_DIR}" EXIT -echo "Capturing original state of files..." -cp -v go.mod go.sum "${ORIGINAL_STATE_DIR}" +# capturing original state of files... +cp go.mod go.sum "${ORIGINAL_STATE_DIR}" -echo "Capturing state of go.mod and go.sum after running go mod tidy..." +# 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 "" +cp go.mod go.sum "${TIDY_STATE_DIR}" set +e -# Detect difference between the git HEAD state and the go mod tidy state +# 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") diff --git a/.github/scripts/syft-released-version-check.sh b/.github/scripts/syft-released-version-check.sh deleted file mode 100755 index 73b7cf6f..00000000 --- a/.github/scripts/syft-released-version-check.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env sh - -SYFT_LINE=$(cat go.mod | grep github.com/anchore/syft) - -if [ "$(echo $SYFT_LINE | grep -o '-' | wc -l)" -gt "1" ]; then - echo "syft version is not a released version! $SYFT_LINE" - exit 1 -else - echo 'syft version is a released version!' -fi \ No newline at end of file diff --git a/.github/scripts/update-version-file.sh b/.github/scripts/update-version-file.sh index 9c3b56d0..8481f254 100755 --- a/.github/scripts/update-version-file.sh +++ b/.github/scripts/update-version-file.sh @@ -2,8 +2,8 @@ set -ue BIN="grype" -DISTDIR=$1 -VERSION=$2 +VERSION_FILE="VERSION" +VERSION=$1 # the source of truth as to whether we want to notify users of an update is if the release just created is NOT # flagged as a pre-release on github @@ -12,10 +12,9 @@ if [[ "$(curl -SsL https://api.github.com/repos/anchore/${BIN}/releases/tags/${V exit 0 fi -echo "creating and publishing version file" +echo "creating and publishing version file (${VERSION})" # create a version file for version-update checks -VERSION_FILE="${DISTDIR}/VERSION" echo "${VERSION}" | tee "${VERSION_FILE}" # upload the version file that supports the application version update check diff --git a/.github/workflows/release-version-file.yaml b/.github/workflows/release-version-file.yaml new file mode 100644 index 00000000..20cdb7de --- /dev/null +++ b/.github/workflows/release-version-file.yaml @@ -0,0 +1,32 @@ +name: "Release" + +on: + + workflow_dispatch: + inputs: + version: + description: release version to update the version file with (prefixed with v) + required: true + + workflow_call: + inputs: + version: + type: string + description: release version to update the version file with (prefixed with v) + required: true + +jobs: + + release: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b #v4.1.4 + + - name: Update version file + run: make ci-release-version-file + env: + RELEASE_VERSION: ${{ github.event.inputs.version }} + # for updating the VERSION file in S3... + AWS_ACCESS_KEY_ID: ${{ secrets.TOOLBOX_AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.TOOLBOX_AWS_SECRET_ACCESS_KEY }} + diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 04b482ac..05f25225 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -90,6 +90,10 @@ jobs: echo "CLI Test (Linux) Status: ${{ steps.cli-linux.outputs.conclusion }}" false + # only release core assets within the "release" job. Any other assets not already under the purview of the + # goreleaser configuration should be added as separate jobs to allow for debugging separately from the release workflow + # as well as not accidentally be re-run as a step multiple times (as could be done within the release workflow) as + # not all actions are guaranteed to be idempotent. release: needs: [quality-gate] runs-on: ubuntu-20.04 @@ -121,9 +125,6 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Cosign install - uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 #v3.5.0 - - name: Tag release run: | git config user.name "anchoreci" @@ -146,10 +147,6 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # for updating brew formula in anchore/homebrew-syft GITHUB_BREW_TOKEN: ${{ secrets.ANCHOREOPS_GITHUB_OSS_WRITE_TOKEN }} - # for updating the VERSION file in S3... - AWS_ACCESS_KEY_ID: ${{ secrets.TOOLBOX_AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.TOOLBOX_AWS_SECRET_ACCESS_KEY }} - - uses: anchore/sbom-action@7ccf588e3cf3cc2611714c2eeae48550fbc17552 # v0.15.11 continue-on-error: true @@ -165,3 +162,10 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SLACK_TOOLBOX_WEBHOOK_URL }} if: ${{ success() }} + + release-version-file: + needs: [release] + uses: ./.github/workflows/release-version-file.yaml + with: + version: ${{ github.event.inputs.version }} + secrets: inherit diff --git a/.github/workflows/update-bootstrap-tools.yml b/.github/workflows/update-bootstrap-tools.yml index 5ccf41a6..c42c65f9 100644 --- a/.github/workflows/update-bootstrap-tools.yml +++ b/.github/workflows/update-bootstrap-tools.yml @@ -1,14 +1,10 @@ -name: PR for latest versions of bootstrap tools +name: PR for latest versions of tools on: schedule: - cron: "0 8 * * *" # 3 AM EST workflow_dispatch: -env: - GO_VERSION: "1.21.x" - GO_STABLE_VERSION: true - permissions: contents: read @@ -17,66 +13,54 @@ jobs: runs-on: ubuntu-latest if: github.repository == 'anchore/grype' # only run for main repo steps: - - uses: actions/checkout@44c2b7a8a4ea60a981eaca3cf939b5f4305c123b # v4.1.5 + - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b #v4.1.4 - - uses: actions/setup-go@cdcb36043654635271a94b9a6d1392de5bb323a7 # v5.0.1 + - name: Bootstrap environment + uses: ./.github/actions/bootstrap with: - go-version: ${{ env.GO_VERSION }} - stable: ${{ env.GO_STABLE_VERSION }} + bootstrap-apt-packages: "" + compute-fingerprints: "false" + go-dependencies: false - - run: | - GOLANGCILINT_LATEST_VERSION=$(go list -m -json github.com/golangci/golangci-lint@latest 2>/dev/null | jq -r '.Version') - BOUNCER_LATEST_VERSION=$(go list -m -json github.com/wagoodman/go-bouncer@latest 2>/dev/null | jq -r '.Version') - CHRONICLE_LATEST_VERSION=$(go list -m -json github.com/anchore/chronicle@latest 2>/dev/null | jq -r '.Version') - GORELEASER_LATEST_VERSION=$(go list -m -json github.com/goreleaser/goreleaser@latest 2>/dev/null | jq -r '.Version') - GOSIMPORTS_LATEST_VERSION=$(go list -m -json github.com/rinchsan/gosimports@latest 2>/dev/null | jq -r '.Version') - YAJSV_LATEST_VERSION=$(go list -m -json github.com/neilpa/yajsv@latest 2>/dev/null | jq -r '.Version') - QUILL_LATEST_VERSION=$(go list -m -json github.com/anchore/quill@latest 2>/dev/null | jq -r '.Version') - GLOW_LATEST_VERSION=$(go list -m -json github.com/charmbracelet/glow@latest 2>/dev/null | jq -r '.Version') - - # update version variables in the Makefile - sed -r -i -e 's/^(GOLANGCILINT_VERSION := ).*/\1'${GOLANGCILINT_LATEST_VERSION}'/' Makefile - sed -r -i -e 's/^(BOUNCER_VERSION := ).*/\1'${BOUNCER_LATEST_VERSION}'/' Makefile - sed -r -i -e 's/^(CHRONICLE_VERSION := ).*/\1'${CHRONICLE_LATEST_VERSION}'/' Makefile - sed -r -i -e 's/^(GORELEASER_VERSION := ).*/\1'${GORELEASER_LATEST_VERSION}'/' Makefile - sed -r -i -e 's/^(GOSIMPORTS_VERSION := ).*/\1'${GOSIMPORTS_LATEST_VERSION}'/' Makefile - sed -r -i -e 's/^(YAJSV_VERSION := ).*/\1'${YAJSV_LATEST_VERSION}'/' Makefile - sed -r -i -e 's/^(QUILL_VERSION := ).*/\1'${QUILL_LATEST_VERSION}'/' Makefile - sed -r -i -e 's/^(GLOW_VERSION := ).*/\1'${GLOW_LATEST_VERSION}'/' Makefile - - # export the versions for use with create-pull-request - echo "GOLANGCILINT=$GOLANGCILINT_LATEST_VERSION" >> $GITHUB_OUTPUT - echo "BOUNCER=$BOUNCER_LATEST_VERSION" >> $GITHUB_OUTPUT - echo "CHRONICLE=$CHRONICLE_LATEST_VERSION" >> $GITHUB_OUTPUT - echo "GORELEASER=$GORELEASER_LATEST_VERSION" >> $GITHUB_OUTPUT - echo "GOSIMPORTS=$GOSIMPORTS_LATEST_VERSION" >> $GITHUB_OUTPUT - echo "YAJSV=$YAJSV_LATEST_VERSION" >> $GITHUB_OUTPUT - echo "QUILL=$QUILL_LATEST_VERSION" >> $GITHUB_OUTPUT - echo "GLOW=$GLOW_LATEST_VERSION" >> $GITHUB_OUTPUT + - name: "Update tool versions" id: latest-versions + run: | + make update-tools + make list-tools + + export NO_COLOR=1 + delimiter="$(openssl rand -hex 8)" + + { + echo "status<<${delimiter}" + make list-tool-updates + echo "${delimiter}" + } >> $GITHUB_OUTPUT + + { + echo "### Tool version status" + echo "\`\`\`" + make list-tool-updates + echo "\`\`\`" + } >> $GITHUB_STEP_SUMMARY - - uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # v2.1.0 + - uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a #v2.1.0 id: generate-token with: app_id: ${{ secrets.TOKEN_APP_ID }} private_key: ${{ secrets.TOKEN_APP_PRIVATE_KEY }} - - uses: peter-evans/create-pull-request@6d6857d36972b65feb161a90e484f2984215f83e # v6.0.5 + - uses: peter-evans/create-pull-request@6d6857d36972b65feb161a90e484f2984215f83e #v6.0.5 with: signoff: true delete-branch: true - branch: auto/latest-bootstrap-tools + branch: auto/latest-tools labels: dependencies - commit-message: 'chore(deps): update bootstrap tools to latest versions' - title: 'chore(deps): update bootstrap tools to latest versions' + commit-message: 'chore(deps): update tools to latest versions' + title: 'chore(deps): update tools to latest versions' body: | - - [golangci-lint ${{ steps.latest-versions.outputs.GOLANGCILINT }}](https://github.com/golangci/golangci-lint/releases/tag/${{ steps.latest-versions.outputs.GOLANGCILINT }}) - - [bouncer ${{ steps.latest-versions.outputs.BOUNCER }}](https://github.com/wagoodman/go-bouncer/releases/tag/${{ steps.latest-versions.outputs.BOUNCER }}) - - [chronicle ${{ steps.latest-versions.outputs.CHRONICLE }}](https://github.com/anchore/chronicle/releases/tag/${{ steps.latest-versions.outputs.CHRONICLE }}) - - [goreleaser ${{ steps.latest-versions.outputs.GORELEASER }}](https://github.com/goreleaser/goreleaser/releases/tag/${{ steps.latest-versions.outputs.GORELEASER }}) - - [gosimports ${{ steps.latest-versions.outputs.GOSIMPORTS }}](https://github.com/rinchsan/gosimports/releases/tag/${{ steps.latest-versions.outputs.GOSIMPORTS }}) - - [yajsv ${{ steps.latest-versions.outputs.YAJSV }}](https://github.com/neilpa/yajsv/releases/tag/${{ steps.latest-versions.outputs.YAJSV }}) - - [quill ${{ steps.latest-versions.outputs.QUILL }}](https://github.com/anchore/quill/releases/tag/${{ steps.latest-versions.outputs.QUILL }}) - - [glow ${{ steps.latest-versions.outputs.GLOW }}](https://github.com/charmbracelet/glow/releases/tag/${{ steps.latest-versions.outputs.GLOW }}) - This is an auto-generated pull request to update all of the bootstrap tools to the latest versions. + ``` + ${{ steps.latest-versions.outputs.status }} + ``` + This is an auto-generated pull request to update all of the tools to the latest versions. token: ${{ steps.generate-token.outputs.token }} diff --git a/.github/workflows/validations.yaml b/.github/workflows/validations.yaml index b58f15d6..2cb06b9e 100644 --- a/.github/workflows/validations.yaml +++ b/.github/workflows/validations.yaml @@ -102,9 +102,6 @@ jobs: - name: Bootstrap environment uses: ./.github/actions/bootstrap - - name: Validate grype output against the CycloneDX schema - run: make validate-cyclonedx-schema - - name: Restore integration test cache uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 #v4.0.2 with: diff --git a/.gitignore b/.gitignore index 08749faa..af1ef36b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,34 +1,72 @@ -/.tool-versions -/go.work -/go.work.sum +# local development tailoring +go.work +go.work.sum +.tool-versions + +# app configuration /.grype.yaml +# tool and bin directories +.tmp/ +bin/ +/bin +/.bin +/build +/dist +/snapshot +/.tool +/.task + +# changelog generation CHANGELOG.md -/VERSION -/snapshot/ -/dist/ -*.profile -.server +VERSION + +# IDE configuration +.vscode/ +.idea/ +.server/ +.history/ + +# test related *.fingerprint +/test/results +coverage.txt +*.log +.server + +# grype-db related /metadata.json /listing.json -.vscode/ *.db *.db-journal !**/test-fixtures/**/*.db -*.tar -*tar.gz -.idea/ -*.iml -*.log + +# probable archives .images -.tmp/ -*.tmp -coverage.txt +*.tar +*.jar +*.war +*.ear +*.jpi +*.hpi +*.zip +*.iml + +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test # OS files .DS_Store +*.profile + # Binaries for programs and plugins *.exe *.exe~ diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 42efc0fd..8c24865f 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -41,7 +41,7 @@ builds: ldflags: *build-ldflags hooks: post: - - cmd: .tmp/quill sign-and-notarize "{{ .Path }}" --dry-run={{ .IsSnapshot }} --ad-hoc={{ .IsSnapshot }} -vv + - cmd: .tool/quill sign-and-notarize "{{ .Path }}" --dry-run={{ .IsSnapshot }} --ad-hoc={{ .IsSnapshot }} -vv env: - QUILL_LOG_FILE=/tmp/quill-{{ .Target }}.log @@ -249,7 +249,7 @@ docker_manifests: signs: - - cmd: cosign + - cmd: .tool/cosign signature: "${artifact}.sig" certificate: "${artifact}.pem" args: diff --git a/Makefile b/Makefile index 8f05072d..a048366a 100644 --- a/Makefile +++ b/Makefile @@ -1,360 +1,43 @@ -BIN := grype -TEMP_DIR := ./.tmp - -# Command templates ################################# -LINT_CMD := $(TEMP_DIR)/golangci-lint run --tests=false -GOIMPORTS_CMD := $(TEMP_DIR)/gosimports -local github.com/anchore -RELEASE_CMD := $(TEMP_DIR)/goreleaser release --clean -SNAPSHOT_CMD := $(RELEASE_CMD) --skip-publish --skip-sign --snapshot -CHRONICLE_CMD = $(TEMP_DIR)/chronicle -GLOW_CMD = $(TEMP_DIR)/glow - -# Tool versions ################################# -GOLANGCILINT_VERSION := v1.58.1 -GOSIMPORTS_VERSION := v0.3.8 -BOUNCER_VERSION := v0.4.0 -CHRONICLE_VERSION := v0.8.0 -GORELEASER_VERSION := v1.25.1 -YAJSV_VERSION := v1.4.1 -QUILL_VERSION := v0.4.1 -GLOW_VERSION := v1.5.1 -SKOPEO_VERSION := v1.12.0 - -# Formatting variables ############################ -BOLD := $(shell tput -T linux bold) -PURPLE := $(shell tput -T linux setaf 5) -GREEN := $(shell tput -T linux setaf 2) -CYAN := $(shell tput -T linux setaf 6) -RED := $(shell tput -T linux setaf 1) -RESET := $(shell tput -T linux sgr0) -TITLE := $(BOLD)$(PURPLE) -SUCCESS := $(BOLD)$(GREEN) - -# Test variables ################################# -# the quality gate lower threshold for unit test total % coverage (by function statements) -COVERAGE_THRESHOLD := 47 -RESULTS_DIR := $(TEMP_DIR)/results -COVER_REPORT := $(RESULTS_DIR)/cover.report -COVER_TOTAL := $(RESULTS_DIR)/cover.total -LICENSES_REPORT := $(RESULTS_DIR)/licenses.json - -## Build variables ################################# -VERSION := $(shell git describe --dirty --always --tags) -DIST_DIR := ./dist -SNAPSHOT_DIR := ./snapshot -CHANGELOG := CHANGELOG.md -OS := $(shell uname | tr '[:upper:]' '[:lower:]') -SNAPSHOT_BIN := $(realpath $(shell pwd)/$(SNAPSHOT_DIR)/$(OS)-build_$(OS)_amd64_v1/$(BIN)) - -ifndef TEMP_DIR - $(error TEMP_DIR is not set) -endif - -ifndef RESULTS_DIR - $(error RESULTS_DIR is not set) -endif - -ifndef DIST_DIR - $(error DIST_DIR is not set) -endif - -ifndef SNAPSHOT_DIR - $(error SNAPSHOT_DIR is not set) -endif - -ifndef VERSION - $(error VERSION is not set) -endif - -define title - @printf '$(TITLE)$(1)$(RESET)\n' -endef - -define safe_rm_rf - bash -c 'test -z "$(1)" && false || rm -rf $(1)' -endef - -define safe_rm_rf_children - bash -c 'test -z "$(1)" && false || rm -rf $(1)/*' -endef - -.DEFAULT_GOAL:=help - -.PHONY: all -all: static-analysis test ## Run all checks (linting, license check, unit, integration, and linux acceptance tests tests) - @printf '$(SUCCESS)All checks pass!$(RESET)\n' - -.PHONY: static-analysis -static-analysis: check-go-mod-tidy lint check-licenses validate-grype-db-schema - -.PHONY: test -test: unit integration validate-cyclonedx-schema validate-grype-db-schema cli ## Run all tests (unit, integration, linux acceptance, and CLI tests) - -.PHONY: validate-cyclonedx-schema -validate-cyclonedx-schema: - cd schema/cyclonedx && make - -.PHONY: validate-grype-db-schema -validate-grype-db-schema: - # ensure the codebase is only referencing a single grype-db schema version, multiple is not allowed - python test/validate-grype-db-schema.py +TOOL_DIR = .tool +BINNY = $(TOOL_DIR)/binny +TASK = $(TOOL_DIR)/task +.DEFAULT_GOAL := make-default ## Bootstrapping targets ################################# -.PHONY: bootstrap -bootstrap: $(TEMP_DIR) bootstrap-go bootstrap-tools ## Download and install all tooling dependencies (+ prep tooling in the ./tmp dir) - $(call title,Bootstrapping dependencies) +# note: we need to assume that binny and task have not already been installed +$(BINNY): + @mkdir -p $(TOOL_DIR) + @curl -sSfL https://raw.githubusercontent.com/anchore/binny/main/install.sh | sh -s -- -b $(TOOL_DIR) -.PHONY: bootstrap-tools -bootstrap-tools: $(TEMP_DIR) - curl -sSfL https://raw.githubusercontent.com/anchore/quill/main/install.sh | sh -s -- -b $(TEMP_DIR)/ $(QUILL_VERSION) - GO111MODULE=off GOBIN=$(realpath $(TEMP_DIR)) go get -u golang.org/x/perf/cmd/benchstat || GOBIN=$(realpath $(TEMP_DIR)) go get -u golang.org/x/perf/cmd/benchstat - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(TEMP_DIR)/ $(GOLANGCILINT_VERSION) - curl -sSfL https://raw.githubusercontent.com/wagoodman/go-bouncer/master/bouncer.sh | sh -s -- -b $(TEMP_DIR)/ $(BOUNCER_VERSION) - curl -sSfL https://raw.githubusercontent.com/anchore/chronicle/main/install.sh | sh -s -- -b $(TEMP_DIR)/ $(CHRONICLE_VERSION) - .github/scripts/goreleaser-install.sh -d -b $(TEMP_DIR)/ $(GORELEASER_VERSION) - # the only difference between goimports and gosimports is that gosimports removes extra whitespace between import blocks (see https://github.com/golang/go/issues/20818) - GOBIN="$(realpath $(TEMP_DIR))" go install github.com/rinchsan/gosimports/cmd/gosimports@$(GOSIMPORTS_VERSION) - GOBIN="$(realpath $(TEMP_DIR))" go install github.com/neilpa/yajsv@$(YAJSV_VERSION) - GOBIN="$(realpath $(TEMP_DIR))" go install github.com/charmbracelet/glow@$(GLOW_VERSION) - GOBIN="$(realpath $(TEMP_DIR))" CGO_ENABLED=0 GO_DYN_FLAGS="" go install -tags "containers_image_openpgp" github.com/containers/skopeo/cmd/skopeo@$(SKOPEO_VERSION) +# note: we need to assume that binny and task have not already been installed +.PHONY: task +$(TASK) task: $(BINNY) + @$(BINNY) install task -q -.PHONY: bootstrap-go -bootstrap-go: +.PHONY: ci-bootstrap-go +ci-bootstrap-go: go mod download -$(TEMP_DIR): - mkdir -p $(TEMP_DIR) +# this is a bootstrapping catch-all, where if the target doesn't exist, we'll ensure the tools are installed and then try again +%: + make $(TASK) + $(TASK) $@ +## Shim targets ################################# -## Static analysis targets ################################# +.PHONY: make-default +make-default: $(TASK) + @# run the default task in the taskfile + @$(TASK) -.PHONY: lint -lint: ## Run gofmt + golangci lint checks - $(call title,Running linters) - # ensure there are no go fmt differences - @printf "files with gofmt issues: [$(shell gofmt -l -s .)]\n" - @test -z "$(shell gofmt -l -s .)" +# for those of us that can't seem to kick the habit of typing `make ...` lets wrap the superior `task` tool +TASKS := $(shell bash -c "test -f $(TASK) && $(TASK) -l | grep '^\* ' | cut -d' ' -f2 | tr -d ':' | tr '\n' ' '" ) $(shell bash -c "test -f $(TASK) && $(TASK) -l | grep 'aliases:' | cut -d ':' -f 3 | tr '\n' ' ' | tr -d ','") - # run all golangci-lint rules - $(LINT_CMD) - @[ -z "$(shell $(GOIMPORTS_CMD) -d .)" ] || (echo "goimports needs to be fixed" && false) +.PHONY: $(TASKS) +$(TASKS): $(TASK) + @$(TASK) $@ - # go tooling does not play well with certain filename characters, ensure the common cases don't result in future "go get" failures - $(eval MALFORMED_FILENAMES := $(shell find . | grep -e ':' | grep -v -e "test/quality/.yardstick" -e "test/quality/vulnerability-match-labels")) - @bash -c "[[ '$(MALFORMED_FILENAMES)' == '' ]] || (printf '\nfound unsupported filename characters:\n$(MALFORMED_FILENAMES)\n\n' && false)" - -.PHONY: format -format: ## Auto-format all source code - $(call title,Running formatters) - gofmt -w -s . - $(GOIMPORTS_CMD) -w . - go mod tidy - -.PHONY: lint-fix -lint-fix: format ## Auto-format all source code + run golangci lint fixers - $(call title,Running lint fixers) - $(LINT_CMD) --fix - -.PHONY: check-licenses -check-licenses: ## Ensure transitive dependencies are compliant with the current license policy - $(call title,Checking for license compliance) - $(TEMP_DIR)/bouncer check ./... - -check-go-mod-tidy: - @ .github/scripts/go-mod-tidy-check.sh && echo "go.mod and go.sum are tidy!" - -## Testing targets ################################# - -.PHONY: unit -unit: $(TEMP_DIR) ## Run unit tests (with coverage) - $(call title,Running unit tests) - go test -race -coverprofile $(TEMP_DIR)/unit-coverage-details.txt $(shell go list ./... | grep -v anchore/grype/test) - @.github/scripts/coverage.py $(COVERAGE_THRESHOLD) $(TEMP_DIR)/unit-coverage-details.txt - -.PHONY: integration -integration: ## Run integration tests - $(call title,Running integration tests) - go test -v ./test/integration - go run cmd/grype/main.go alpine:latest - -.PHONY: quality -quality: ## Run quality tests - $(call title,Running quality tests) - cd test/quality && make - -.PHONY: cli -cli: $(SNAPSHOT_DIR) ## Run CLI tests - chmod 755 "$(SNAPSHOT_BIN)" - $(SNAPSHOT_BIN) version - SYFT_BINARY_LOCATION='$(SNAPSHOT_BIN)' \ - go test -count=1 -timeout=15m -v ./test/cli - -## Test-fixture-related targets ################################# - -# note: this is used by CI to determine if various test fixture cache should be restored or recreated -# TODO (cphillips) check for all fixtures and individual makefile -fingerprints: - $(call title,Creating all test cache input fingerprints) - - # for IMAGE integration test fixtures - cd test/integration/test-fixtures && \ - make cache.fingerprint - - # for INSTALL integration test fixtures - cd test/install && \ - make cache.fingerprint - - # for CLI test fixtures - cd test/cli/test-fixtures && \ - make cache.fingerprint - -.PHONY: show-test-image-cache -show-test-image-cache: ## Show all docker and image tar cache - $(call title,Docker daemon cache) - @docker images --format '{{.ID}} {{.Repository}}:{{.Tag}}' | grep stereoscope-fixture- | sort - - $(call title,Tar cache) - @find . -type f -wholename "**/test-fixtures/cache/stereoscope-fixture-*.tar" | sort - -.PHONY: show-test-snapshots -show-test-snapshots: ## Show all test snapshots - $(call title,Test snapshots) - @find . -type f -wholename "**/test-fixtures/snapshot/*" | sort - -## install.sh testing targets ################################# - -install-test: $(SNAPSHOT_DIR) - cd test/install && \ - make - -install-test-cache-save: $(SNAPSHOT_DIR) - cd test/install && \ - make save - -install-test-cache-load: $(SNAPSHOT_DIR) - cd test/install && \ - make load - -install-test-ci-mac: $(SNAPSHOT_DIR) - cd test/install && \ - make ci-test-mac - -.PHONY: compare-test-deb-package-install -compare-test-deb-package-install: $(TEMP_DIR) $(SNAPSHOT_DIR) - $(call title,Running compare test: DEB install) - $(COMPARE_DIR)/deb.sh \ - $(SNAPSHOT_DIR) \ - $(COMPARE_DIR) \ - $(COMPARE_TEST_IMAGE) \ - $(TEMP_DIR) - -.PHONY: compare-test-rpm-package-install -compare-test-rpm-package-install: $(TEMP_DIR) $(SNAPSHOT_DIR) - $(call title,Running compare test: RPM install) - $(COMPARE_DIR)/rpm.sh \ - $(SNAPSHOT_DIR) \ - $(COMPARE_DIR) \ - $(COMPARE_TEST_IMAGE) \ - $(TEMP_DIR) - -## Code and data generation targets ################################# - -.PHONY: generate -generate: ## Generate any code or data required by the project - cd grype/internal && go generate . - -## Build-related targets ################################# - -.PHONY: build -build: $(SNAPSHOT_DIR) - -$(SNAPSHOT_DIR): ## Build snapshot release binaries and packages - $(call title,Building snapshot artifacts) - - # create a config with the dist dir overridden - echo "dist: $(SNAPSHOT_DIR)" > $(TEMP_DIR)/goreleaser.yaml - cat .goreleaser.yaml >> $(TEMP_DIR)/goreleaser.yaml - - # build release snapshots - $(SNAPSHOT_CMD) --config $(TEMP_DIR)/goreleaser.yaml - -.PHONY: changelog -changelog: clean-changelog ## Generate and show the changelog for the current unreleased version - $(CHRONICLE_CMD) -vv -n --version-file VERSION > $(CHANGELOG) - @$(GLOW_CMD) $(CHANGELOG) - -$(CHANGELOG): - $(CHRONICLE_CMD) -vvv > $(CHANGELOG) - -.PHONY: release -release: - @.github/scripts/trigger-release.sh - -.PHONY: ci-release -ci-release: ci-check clean-dist $(CHANGELOG) - $(call title,Publishing release artifacts) - - # create a config with the dist dir overridden - echo "dist: $(DIST_DIR)" > $(TEMP_DIR)/goreleaser.yaml - cat .goreleaser.yaml >> $(TEMP_DIR)/goreleaser.yaml - - bash -c "\ - $(RELEASE_CMD) \ - --config $(TEMP_DIR)/goreleaser.yaml \ - --release-notes <(cat $(CHANGELOG)) \ - || (cat /tmp/quill-*.log && false)" - - # upload the version file that supports the application version update check (excluding pre-releases) - .github/scripts/update-version-file.sh "$(DIST_DIR)" "$(VERSION)" - -.PHONY: ci-check -ci-check: - @.github/scripts/ci-check.sh - -## Cleanup targets ################################# - -.PHONY: clean -clean: clean-dist clean-snapshot ## Remove previous builds, result reports, and test cache - $(call safe_rm_rf_children,$(TEMP_DIR)) - -.PHONY: clean-snapshot -clean-snapshot: - $(call safe_rm_rf,$(SNAPSHOT_DIR)) - rm -f $(TEMP_DIR)/goreleaser.yaml - -.PHONY: clean-dist -clean-dist: clean-changelog - $(call safe_rm_rf,$(DIST_DIR)) - rm -f $(TEMP_DIR)/goreleaser.yaml - -.PHONY: clean-changelog -clean-changelog: - rm -f $(CHANGELOG) VERSION - -clean-test-image-cache: clean-test-image-tar-cache clean-test-image-docker-cache ## Clean test image cache - -## Halp! ################################# - -.PHONY: help -help: ## Display this help - @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "$(BOLD)$(CYAN)%-25s$(RESET)%s\n", $$1, $$2}' - - -.PHONY: validate-grype-test-config -validate-grype-test-config: - # ensure the update URL is not overridden (not pointing to staging) - @bash -c '\ - grep -q "update-url" test/grype-test-config.yaml; \ - if [ $$? -eq 0 ]; then \ - echo "Found \"update-url\" in CLI testing config. Cannot release if previous CLI testing did not use production (default) values"; \ - fi' - -.PHONY: validate-syft-release-version -validate-syft-release-version: - @./.github/scripts/syft-released-version-check.sh - -.PHONY: clean-test-cache -clean-test-cache: ## Delete all test cache (built docker image tars) - find . -type f -wholename "**/test-fixtures/cache/*.tar" -delete +help: $(TASK) + @$(TASK) -l diff --git a/README.md b/README.md index 6930d76a..8d39ec6b 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/anchore/grype.svg)](https://github.com/anchore/grype) [![License: Apache-2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/anchore/grype/blob/main/LICENSE) [![Slack Invite](https://img.shields.io/badge/Slack-Join-blue?logo=slack)](https://anchore.com/slack) -[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/anchore/grype/badge)](https://api.securityscorecards.dev/projects/github.com/anchore/grype) +[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/anchore/grype/badge)](https://scorecard.dev/viewer/?uri=github.com/anchore/grype) [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/6708/badge)](https://www.bestpractices.dev/projects/6708) A vulnerability scanner for container images and filesystems. Easily [install the binary](#installation) to try it out. Works with [Syft](https://github.com/anchore/syft), the powerful SBOM (software bill of materials) tool for container images and filesystems. diff --git a/Taskfile.yaml b/Taskfile.yaml new file mode 100644 index 00000000..781eb8cb --- /dev/null +++ b/Taskfile.yaml @@ -0,0 +1,425 @@ + +version: "3" +vars: + OWNER: anchore + PROJECT: grype + + # static file dirs + TOOL_DIR: .tool + TMP_DIR: .tmp + + # used for changelog generation + CHANGELOG: CHANGELOG.md + NEXT_VERSION: VERSION + + # used for snapshot builds + OS: + sh: uname -s | tr '[:upper:]' '[:lower:]' + ARCH: + sh: | + [ "$(uname -m)" = "x86_64" ] && echo "amd64_v1" || echo $(uname -m) + PROJECT_ROOT: + sh: echo $PWD + # note: the snapshot dir must be a relative path starting with ./ + SNAPSHOT_DIR: ./snapshot + SNAPSHOT_BIN: "{{ .PROJECT_ROOT }}/{{ .SNAPSHOT_DIR }}/{{ .OS }}-build_{{ .OS }}_{{ .ARCH }}/{{ .PROJECT }}" + SNAPSHOT_CMD: "{{ .TOOL_DIR }}/goreleaser release --config {{ .TMP_DIR }}/goreleaser.yaml --clean --snapshot --skip=publish --skip=sign" + BUILD_CMD: "{{ .TOOL_DIR }}/goreleaser build --config {{ .TMP_DIR }}/goreleaser.yaml --clean --snapshot --single-target" + RELEASE_CMD: "{{ .TOOL_DIR }}/goreleaser release --clean --release-notes {{ .CHANGELOG }}" + VERSION: + sh: git describe --dirty --always --tags + + # used for install and acceptance testing + COMPARE_DIR: ./test/compare + COMPARE_TEST_IMAGE: centos:8.2.2004 + +env: + SYFT_CHECK_FOR_APP_UPDATE: false + GRYPE_CHECK_FOR_APP_UPDATE: false + +tasks: + + ## High-level tasks ################################# + + default: + desc: Run all validation tasks + aliases: + - pr-validations + - validations + cmds: + - task: static-analysis + - task: test + - task: install-test + + static-analysis: + desc: Run all static analysis tasks + cmds: + - task: check-go-mod-tidy + - task: check-licenses + - task: lint + - task: validate-cyclonedx-schema + - task: validate-grype-db-schema + + test: + desc: Run all levels of test + cmds: + - task: unit + - task: integration + - task: cli + + ## Bootstrap tasks ################################# + + binny: + internal: true + # desc: Get the binny tool + generates: + - "{{ .TOOL_DIR }}/binny" + status: + - "test -f {{ .TOOL_DIR }}/binny" + cmd: "curl -sSfL https://raw.githubusercontent.com/anchore/binny/main/install.sh | sh -s -- -b .tool" + silent: true + + tools: + desc: Install all tools needed for CI and local development + deps: [binny] + aliases: + - bootstrap + generates: + - ".binny.yaml" + - "{{ .TOOL_DIR }}/*" + status: + - "{{ .TOOL_DIR }}/binny check -v" + cmd: "{{ .TOOL_DIR }}/binny install -v" + silent: true + + update-tools: + desc: Update pinned versions of all tools to their latest available versions + deps: [binny] + generates: + - ".binny.yaml" + - "{{ .TOOL_DIR }}/*" + cmd: "{{ .TOOL_DIR }}/binny update -v" + silent: true + + list-tools: + desc: List all tools needed for CI and local development + deps: [binny] + cmd: "{{ .TOOL_DIR }}/binny list" + silent: true + + list-tool-updates: + desc: List all tools that are not up to date relative to the binny config + deps: [binny] + cmd: "{{ .TOOL_DIR }}/binny list --updates" + silent: true + + tmpdir: + silent: true + generates: + - "{{ .TMP_DIR }}" + cmd: "mkdir -p {{ .TMP_DIR }}" + + ## Static analysis tasks ################################# + + format: + desc: Auto-format all source code + deps: [tools] + cmds: + - gofmt -w -s . + - "{{ .TOOL_DIR }}/gosimports -local github.com/anchore -w ." + - go mod tidy + + lint-fix: + desc: Auto-format all source code + run golangci lint fixers + deps: [tools] + cmds: + - task: format + - "{{ .TOOL_DIR }}/golangci-lint run --tests=false --fix" + + lint: + desc: Run gofmt + golangci lint checks + vars: + BAD_FMT_FILES: + sh: gofmt -l -s . + BAD_FILE_NAMES: + sh: "find . | grep -e ':' | grep -v -e 'test/quality/.yardstick' -e 'test/quality/vulnerability-match-labels' || true" + deps: [tools] + cmds: + # ensure there are no go fmt differences + - cmd: 'test -z "{{ .BAD_FMT_FILES }}" || (echo "files with gofmt issues: [{{ .BAD_FMT_FILES }}]"; exit 1)' + silent: true + # ensure there are no files with ":" in it (a known back case in the go ecosystem) + - cmd: 'test -z "{{ .BAD_FILE_NAMES }}" || (echo "files with bad names: [{{ .BAD_FILE_NAMES }}]"; exit 1)' + silent: true + # run linting + - "{{ .TOOL_DIR }}/golangci-lint run --tests=false" + + check-licenses: + # desc: Ensure transitive dependencies are compliant with the current license policy + deps: [tools] + cmd: "{{ .TOOL_DIR }}/bouncer check ./..." + + check-go-mod-tidy: + # desc: Ensure go.mod and go.sum are up to date + cmds: + - cmd: .github/scripts/go-mod-tidy-check.sh && echo "go.mod and go.sum are tidy!" + silent: true + + validate-cyclonedx-schema: + desc: Run integration tests + cmds: + - "cd schema/cyclonedx && make" + + validate-grype-db-schema: + desc: Ensure the codebase is only referencing a single grype-db schema version (multiple is not allowed) + cmds: + - python test/validate-grype-db-schema.py + + + ## Testing tasks ################################# + + unit: + desc: Run unit tests + deps: + - tmpdir + vars: + TEST_PKGS: + sh: "go list ./... | grep -v {{ .OWNER }}/{{ .PROJECT }}/test | grep -v {{ .OWNER }}/{{ .PROJECT }}/internal/test | tr '\n' ' '" + + # unit test coverage threshold (in % coverage) + COVERAGE_THRESHOLD: 47 + cmds: + - "go test -coverprofile {{ .TMP_DIR }}/unit-coverage-details.txt {{ .TEST_PKGS }}" + - cmd: ".github/scripts/coverage.py {{ .COVERAGE_THRESHOLD }} {{ .TMP_DIR }}/unit-coverage-details.txt" + silent: true + + integration: + desc: Run integration tests + cmds: + - "go test -v ./test/integration" + # exercise most of the CLI with the data race detector + - "go run -race cmd/{{ .PROJECT }}/main.go alpine:latest" + + cli: + desc: Run CLI tests + # note: we don't want to regenerate the snapshot unless we have to. In CI it's probable + # that the cache being restored with the correct binary will be rebuilt since the timestamps + # and local checksums will not line up. + deps: [tools, snapshot] + sources: + - "{{ .SNAPSHOT_BIN }}" + - ./test/cli/** + - ./**/*.go + cmds: + - cmd: "echo 'testing binary: {{ .SNAPSHOT_BIN }}'" + silent: true + + - cmd: "test -f {{ .SNAPSHOT_BIN }} || (find {{ .SNAPSHOT_DIR }} && echo '\nno snapshot found' && false)" + silent: true + + - "go test -count=1 -timeout=15m -v ./test/cli" + + quality: + desc: Run quality tests + cmds: + - "cd test/quality && make" + + + ## Test-fixture-related targets ################################# + + fingerprints: + desc: Generate test fixture fingerprints + generates: + - test/integration/test-fixtures/cache.fingerprint + - test/install/cache.fingerprint + - test/cli/test-fixtures/cache.fingerprint + cmds: + # for IMAGE integration test fixtures + - "cd test/integration/test-fixtures && make cache.fingerprint" + # for INSTALL integration test fixtures + - "cd test/install && make cache.fingerprint" + # for CLI test fixtures + - "cd test/cli/test-fixtures && make cache.fingerprint" + + show-test-image-cache: + silent: true + cmds: + - "echo '\nDocker daemon cache:'" + - "docker images --format '{{`{{.ID}}`}} {{`{{.Repository}}`}}:{{`{{.Tag}}`}}' | grep stereoscope-fixture- | sort" + - "echo '\nTar cache:'" + - 'find . -type f -wholename "**/test-fixtures/snapshot/*" | sort' + + + ## install.sh testing targets ################################# + + install-test: + cmds: + - "cd test/install && make" + + install-test-cache-save: + cmds: + - "cd test/install && make save" + + install-test-cache-load: + cmds: + - "cd test/install && make load" + + install-test-ci-mac: + cmds: + - "cd test/install && make ci-test-mac" + + generate-compare-file: + cmd: "go run ./cmd/{{ .PROJECT }} {{ .COMPARE_TEST_IMAGE }} -o json > {{ .COMPARE_DIR }}/test-fixtures/acceptance-{{ .COMPARE_TEST_IMAGE }}.json" + + compare-mac: + deps: [tmpdir] + cmd: | + {{ .COMPARE_DIR }}/mac.sh \ + {{ .SNAPSHOT_DIR }} \ + {{ .COMPARE_DIR }} \ + {{ .COMPARE_TEST_IMAGE }} \ + {{ .TMP_DIR }} + + compare-linux: + cmds: + - task: compare-test-deb-package-install + - task: compare-test-rpm-package-install + + compare-test-deb-package-install: + deps: [tmpdir] + cmd: | + {{ .COMPARE_DIR }}/deb.sh \ + {{ .SNAPSHOT_DIR }} \ + {{ .COMPARE_DIR }} \ + {{ .COMPARE_TEST_IMAGE }} \ + {{ .TMP_DIR }} + + compare-test-rpm-package-install: + deps: [tmpdir] + cmd: | + {{ .COMPARE_DIR }}/rpm.sh \ + {{ .SNAPSHOT_DIR }} \ + {{ .COMPARE_DIR }} \ + {{ .COMPARE_TEST_IMAGE }} \ + {{ .TMP_DIR }} + + + ## Code and data generation targets ################################# + + generate: + desc: Run data generation tasks + cmds: + - "cd grype/internal && go generate" + + + ## Build-related targets ################################# + + build: + desc: Build the project + deps: [tools, tmpdir] + generates: + - "{{ .PROJECT }}" + cmds: + - silent: true + cmd: | + echo "dist: {{ .SNAPSHOT_DIR }}" > {{ .TMP_DIR }}/goreleaser.yaml + cat .goreleaser.yaml >> {{ .TMP_DIR }}/goreleaser.yaml + + - "{{ .BUILD_CMD }}" + + snapshot: + desc: Create a snapshot release + aliases: + - build + deps: [tools, tmpdir] + sources: + - cmd/**/*.go + - "{{ .PROJECT }}/**/*.go" + - internal/**/*.go + method: checksum + generates: + - "{{ .SNAPSHOT_BIN }}" + cmds: + - silent: true + cmd: | + echo "dist: {{ .SNAPSHOT_DIR }}" > {{ .TMP_DIR }}/goreleaser.yaml + cat .goreleaser.yaml >> {{ .TMP_DIR }}/goreleaser.yaml + + - "{{ .SNAPSHOT_CMD }}" + + changelog: + desc: Generate a changelog + deps: [tools] + generates: + - "{{ .CHANGELOG }}" + - "{{ .NEXT_VERSION }}" + cmds: + - "{{ .TOOL_DIR }}/chronicle -vv -n --version-file {{ .NEXT_VERSION }} > {{ .CHANGELOG }}" + - "{{ .TOOL_DIR }}/glow {{ .CHANGELOG }}" + + + ## Release targets ################################# + + release: + desc: Create a release + interactive: true + deps: [tools] + cmds: + - cmd: .github/scripts/trigger-release.sh + silent: true + + + ## CI-only targets ################################# + + ci-check: + # desc: "[CI only] Are you in CI?" + cmds: + - cmd: .github/scripts/ci-check.sh + silent: true + + ci-release: + # desc: "[CI only] Create a release" + deps: [tools] + cmds: + - task: ci-check + - "{{ .TOOL_DIR }}/chronicle -vvv > CHANGELOG.md" + - cmd: "cat CHANGELOG.md" + silent: true + - "{{ .RELEASE_CMD }}" + + ci-release-version-file: + # desc: "[CI only] Update the version file" + deps: [tools] + cmds: + - task: ci-check + - ".github/scripts/update-version-file.sh {{ .RELEASE_VERSION }}" + requires: + vars: + - RELEASE_VERSION + + ci-validate-test-config: + # desc: "[CI only] Ensure the update URL is not overridden (not pointing to staging)" + silent: true + cmd: | + bash -c '\ + grep -q "update-url" test/grype-test-config.yaml; \ + if [ $? -eq 0 ]; then \ + echo "Found \"update-url\" in CLI testing config. Cannot release if previous CLI testing did not use production (default) values"; \ + else + echo "Test configuration valid" + fi' + + + ## Cleanup targets ################################# + + clean-snapshot: + desc: Remove any snapshot builds + cmds: + - "rm -rf {{ .SNAPSHOT_DIR }}" + - "rm -rf {{ .TMP_DIR }}/goreleaser.yaml" + + clean-cache: + desc: Remove all docker cache and local image tar cache + cmds: + - 'find . -type f -wholename "**/test-fixtures/cache/stereoscope-fixture-*.tar" -delete' + - "docker images --format '{{`{{.ID}}`}} {{`{{.Repository}}`}}' | grep stereoscope-fixture- | awk '{print $$1}' | uniq | xargs -r docker rmi --force" diff --git a/schema/cyclonedx/Makefile b/schema/cyclonedx/Makefile index 2c122004..028ea982 100644 --- a/schema/cyclonedx/Makefile +++ b/schema/cyclonedx/Makefile @@ -11,4 +11,4 @@ validate-schema-xml: .PHONY: validate-schema-json validate-schema-json: go run ../../cmd/grype -c ../../test/grype-test-config.yaml ubuntu:latest -v -o cyclonedx-json > bom.json - ../../.tmp/yajsv -s cyclonedx.json bom.json + ../../.tool/yajsv -s cyclonedx.json bom.json