diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 98ede851..4c461b94 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -142,10 +142,12 @@ jobs: AC_PASSWORD: ${{ secrets.ENG_CI_APPLE_ID_PASS }} - uses: anchore/sbom-action@v0 + continue-on-error: true with: artifact-name: sbom.spdx.json - uses: 8398a7/action-slack@v3 + continue-on-error: true with: status: ${{ job.status }} fields: repo,workflow,action,eventName diff --git a/install.sh b/install.sh index 6c47882e..63f8ee4c 100755 --- a/install.sh +++ b/install.sh @@ -6,6 +6,11 @@ PROJECT_NAME="grype" OWNER=anchore REPO="${PROJECT_NAME}" GITHUB_DOWNLOAD_PREFIX=https://github.com/${OWNER}/${REPO}/releases/download +INSTALL_SH_BASE_URL=https://raw.githubusercontent.com/${OWNER}/${PROJECT_NAME} +PROGRAM_ARGS=$@ + +# do not change the name of this parameter (this must always be backwards compatible) +DOWNLOAD_TAG_INSTALL_SCRIPT=${DOWNLOAD_TAG_INSTALL_SCRIPT:-true} # # usage [script-name] @@ -607,7 +612,10 @@ install_asset() ( main() ( # parse arguments + # note: never change default install directory (this must always be backwards compatible) install_dir=${install_dir:-./bin} + + # note: never change the program flags or arguments (this must always be backwards compatible) while getopts "b:dh?x" arg; do case "$arg" in b) install_dir="$OPTARG" ;; @@ -644,20 +652,30 @@ main() ( return 1 fi - version=$(tag_to_version "${tag}") - - download_dir=$(mktemp -d) - trap 'rm -rf -- "$download_dir"' EXIT - # run the application + version=$(tag_to_version "${tag}") os=$(uname_os) arch=$(uname_arch) format=$(get_format_name "${os}" "${arch}" "tar.gz") binary=$(get_binary_name "${os}" "${arch}" "${PROJECT_NAME}") download_url="${GITHUB_DOWNLOAD_PREFIX}/${tag}" + # we always use the install.sh script that is associated with the tagged release. Why? the latest install.sh is not + # guaranteed to be able to install every version of the application. We use the DOWNLOAD_TAG_INSTALL_SCRIPT env var + # to indicate if we should continue processing with the existing script or to download the script from the given tag. + if [ "${DOWNLOAD_TAG_INSTALL_SCRIPT}" = "true" ]; then + export DOWNLOAD_TAG_INSTALL_SCRIPT=false + log_info "fetching release script for tag='${tag}'" + http_copy "${INSTALL_SH_BASE_URL}/${tag}/install.sh" "" | sh -s -- ${PROGRAM_ARGS} + exit $? + fi + log_info "using release tag='${tag}' version='${version}' os='${os}' arch='${arch}'" + + download_dir=$(mktemp -d) + trap 'rm -rf -- "$download_dir"' EXIT + log_debug "downloading files into ${download_dir}" download_and_install_asset "${download_url}" "${download_dir}" "${install_dir}" "${PROJECT_NAME}" "${os}" "${arch}" "${version}" "${format}" "${binary}" diff --git a/test/install/Makefile b/test/install/Makefile index 25a71b2c..30e002e5 100644 --- a/test/install/Makefile +++ b/test/install/Makefile @@ -13,6 +13,9 @@ UNIT=make unit-local # the line if there are breaking changes made that don't align with the latest release (but will be OK with the next # release) ACCEPTANCE_CMD=sh -c '../../install.sh -b /usr/local/bin && grype version' +# we also want to test against a previous release to ensure that install.sh defers execution to a former install.sh +PREVIOUS_RELEASE=v0.24.0 +ACCEPTANCE_PREVIOUS_RELEASE_CMD=sh -c "../../install.sh -b /usr/local/bin $(PREVIOUS_RELEASE) && grype version" # CI cache busting values; change these if you want CI to not use previous stored cache INSTALL_TEST_CACHE_BUSTER=894d8ca @@ -28,23 +31,37 @@ test: unit acceptance ci-test-mac: unit-local acceptance-local # note: do not add acceptance-local to this list +.PHONY: acceptance acceptance: acceptance-ubuntu-20.04 acceptance-alpine-3.6 acceptance-busybox-1.35 +.PHONY: unit unit: unit-ubuntu-20.04 +.PHONY: unit-local unit-local: $(call title,unit tests) @for f in $(shell ls *_test.sh); do echo "Running unit test suite '$${f}'"; bash $${f} || exit 1; done -acceptance-local: - $(acceptance) +.PHONY: acceptance-local +acceptance-local: acceptance-current-release-local acceptance-previous-release-local +.PHONY: acceptance-current-release-local +acceptance-current-release-local: + $(ACCEPTANCE_CMD) + +.PHONY: acceptance-previous-release-local +acceptance-previous-release-local: + $(ACCEPTANCE_PREVIOUS_RELEASE_CMD) + grype version | grep $(shell echo $(PREVIOUS_RELEASE)| tr -d "v") + +.PHONY: save save: ubuntu-20.04 alpine-3.6 busybox-1.35 @mkdir cache || true docker image save -o cache/ubuntu-env.tar $(UBUNTU_IMAGE) docker image save -o cache/alpine-env.tar $(ALPINE_IMAGE) docker image save -o cache/busybox-env.tar $(BUSYBOX_IMAGE) +.PHONY: load load: docker image load -i cache/ubuntu-env.tar docker image load -i cache/alpine-env.tar @@ -52,16 +69,19 @@ load: ## UBUNTU ####################################################### +.PHONY: acceptance-ubuntu-20.04 acceptance-ubuntu-20.04: ubuntu-20.04 $(call title,ubuntu:20.04 - acceptance) $(DOCKER_RUN) $(UBUNTU_IMAGE) \ $(ACCEPTANCE_CMD) +.PHONY: unit-ubuntu-20.04 unit-ubuntu-20.04: ubuntu-20.04 $(call title,ubuntu:20.04 - unit) $(DOCKER_RUN) $(UBUNTU_IMAGE) \ $(UNIT) +.PHONY: ubuntu-20.04 ubuntu-20.04: $(call title,ubuntu:20.04 - build environment) docker build -t $(UBUNTU_IMAGE) -f $(ENVS)/Dockerfile-ubuntu-20.04 . @@ -70,11 +90,13 @@ ubuntu-20.04: # note: unit tests cannot be run with sh (alpine dosn't have bash by default) +.PHONY: acceptance-alpine-3.6 acceptance-alpine-3.6: alpine-3.6 $(call title,alpine:3.6 - acceptance) $(DOCKER_RUN) $(ALPINE_IMAGE) \ $(ACCEPTANCE_CMD) +.PHONY: alpine-3.6 alpine-3.6: $(call title,alpine:3.6 - build environment) docker build -t $(ALPINE_IMAGE) -f $(ENVS)/Dockerfile-alpine-3.6 . @@ -85,12 +107,14 @@ alpine-3.6: # note: busybox by default will not have cacerts, so you will get TLS warnings (we want to test under these conditions) +.PHONY: acceptance-busybox-1.35 acceptance-busybox-1.35: busybox-1.35 $(call title,busybox-1.35 - acceptance) $(DOCKER_RUN) $(BUSYBOX_IMAGE) \ $(ACCEPTANCE_CMD) @echo "\n*** test note: you should see grype spit out a 'x509: certificate signed by unknown authority' error --this is expected ***" +.PHONY: busybox-1.35 busybox-1.35: $(call title,busybox-1.35 - build environment) docker pull $(BUSYBOX_IMAGE)