diff --git a/.circleci/test-deploy.yml b/.circleci/test-deploy.yml index ba85f8ca..89d623aa 100644 --- a/.circleci/test-deploy.yml +++ b/.circleci/test-deploy.yml @@ -79,6 +79,7 @@ jobs: at: . - codecov/upload: flags: backend + verbose: true - codecov/upload: fail_on_error: true files: coverage/coverage-final.json diff --git a/package-lock.json b/package-lock.json index aad3adb5..aa033184 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "codecov-circleci-orb", - "version": "6.0.0", + "version": "6.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "codecov-circleci-orb", - "version": "6.0.0", + "version": "6.1.0", "license": "MIT", "devDependencies": { "@types/mocha": "^9.1.0", diff --git a/package.json b/package.json index 311f415d..5f771747 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "codecov-circleci-orb", - "version": "6.0.0", + "version": "6.1.0", "description": "Codecov CircleCI Orb", "main": "index.js", "devDependencies": { diff --git a/src/commands/upload.yml b/src/commands/upload.yml index 3930bd7c..054be6f6 100644 --- a/src/commands/upload.yml +++ b/src/commands/upload.yml @@ -29,6 +29,10 @@ parameters: description: The URL of the build where this is running type: string default: "" + cleanup: + description: If true, download the CLI into a temporary directory and clean it up after the run. Off by default to preserve legacy behavior of downloading into the current working directory. + type: boolean + default: false code: description: The code of the report if using local upload. If unsure, leave default. Read more here https://docs.codecov.com/docs/the-codecov-cli#how-to-use-local-upload type: string @@ -185,6 +189,7 @@ steps: CODECOV_BRANCH: << parameters.branch >> CODECOV_BUILD: << parameters.build >> CODECOV_BUILD_URL: << parameters.build_url >> + CODECOV_CLEANUP: << parameters.cleanup >> CODECOV_CLI_TYPE: codecov-cli CODECOV_CODE: << parameters.code >> CODECOV_DIR: << parameters.dir >> diff --git a/src/dist/download.sh b/src/dist/download.sh index c24fda25..b2cf616a 100755 --- a/src/dist/download.sh +++ b/src/dist/download.sh @@ -55,7 +55,7 @@ then else exit_if_error "Could not find binary file $CODECOV_BINARY" fi -elif [ "$CODECOV_USE_PYPI" == "true" ]; +elif [ "$CODECOV_USE_PYPI" == "true" ] || [ "$CODECOV_USE_PYPI" == "1" ]; then if ! pip install "${CODECOV_CLI_TYPE}$([ "$CODECOV_VERSION" == "latest" ] && echo "" || echo "==$CODECOV_VERSION")"; then exit_if_error "Could not install via pypi." @@ -69,6 +69,15 @@ then CODECOV_COMMAND="${CODECOV_CLI_TYPE}" fi else + CODECOV_DOWNLOAD_DIR="." + if [ "$CODECOV_CLEANUP" == "true" ]; then + CODECOV_DOWNLOAD_DIR=$(mktemp -d) + cleanup_downloads() { + rm -rf "$CODECOV_DOWNLOAD_DIR" + } + trap cleanup_downloads EXIT + fi + if [ -n "$CODECOV_OS" ]; then say "$g==>$x Overridden OS: $b${CODECOV_OS}$x" @@ -86,7 +95,7 @@ else CODECOV_FILENAME="${CODECOV_CLI_TYPE%-cli}" [[ $CODECOV_OS == "windows" ]] && CODECOV_FILENAME+=".exe" - CODECOV_COMMAND="./$CODECOV_FILENAME" + CODECOV_COMMAND="$CODECOV_DOWNLOAD_DIR/$CODECOV_FILENAME" [[ $CODECOV_OS == "macos" ]] && \ ! command -v gpg 2>&1 >/dev/null && \ HOMEBREW_NO_AUTO_UPDATE=1 brew install gpg @@ -94,7 +103,7 @@ else CODECOV_URL="$CODECOV_URL/${CODECOV_VERSION}" CODECOV_URL="$CODECOV_URL/${CODECOV_OS}/${CODECOV_FILENAME}" say "$g ->$x Downloading $b${CODECOV_URL}$x" - curl -O $retry "$CODECOV_URL" + curl -o "$CODECOV_COMMAND" $retry "$CODECOV_URL" say "$g==>$x Finishing downloading $b${CODECOV_OS}:${CODECOV_VERSION}$x" v_url="https://cli.codecov.io/api/${CODECOV_OS}/${CODECOV_VERSION}" diff --git a/src/dist/set_codecov_envs.sh b/src/dist/set_codecov_envs.sh index e73b9bf5..18960762 100755 --- a/src/dist/set_codecov_envs.sh +++ b/src/dist/set_codecov_envs.sh @@ -4,19 +4,17 @@ touch ./codecov_envs chmod u+x ./codecov_envs echo "#!/usr/bin/env bash" > ./codecov_envs -export CODECOV_BINARY_LOCATION= -export CODECOV_CLI_URL= +export CODECOV_CLEANUP= +export CODECOV_CLI_TYPE= export CODECOV_COMMAND= -export CODECOV_DOWNLOAD_ONLY= +export CODECOV_DOWNLOAD_DIR= +export CODECOV_FAIL_ON_ERROR= export CODECOV_FILENAME= -export CODECOV_GCOV_ARGS= -export CODECOV_GCOV_EXECUTABLE= -export CODECOV_GCOV_IGNORE= -export CODECOV_GCOV_INCLUDE= -export CODECOV_PUBLIC_PGP_KEY= -export CODECOV_SWIFT_PROJECT= +export CODECOV_OS= +export CODECOV_RUN_CMD= +export CODECOV_URL= +export CODECOV_VERSION= export CODECOV_WRAPPER_VERSION= -export CODECOV_YML_PATH= env | grep -i "CODECOV_" | grep -iv "CODECOV_TOKEN" | sed -e 's/^/export /' > ./codecov_envs cat ./codecov_envs diff --git a/src/dist/set_defaults.sh b/src/dist/set_defaults.sh index 91346a3f..58bb8f2a 100755 --- a/src/dist/set_defaults.sh +++ b/src/dist/set_defaults.sh @@ -46,11 +46,12 @@ r="\033[0;31m" # errors x="\033[0m" retry="--retry 5 --retry-delay 2" -CODECOV_WRAPPER_VERSION="0.2.9" +CODECOV_WRAPPER_VERSION="0.3.1" CODECOV_VERSION="${CODECOV_VERSION:-latest}" CODECOV_FAIL_ON_ERROR="${CODECOV_FAIL_ON_ERROR:-false}" CODECOV_RUN_CMD="${CODECOV_RUN_CMD:-upload-coverage}" CODECOV_CLI_TYPE=${CODECOV_CLI_TYPE:-"codecov-cli"} +CODECOV_CLEANUP="${CODECOV_CLEANUP:-false}" say " _____ _ / ____| | | diff --git a/src/dist/validate.sh b/src/dist/validate.sh index e47ad978..e908f25b 100755 --- a/src/dist/validate.sh +++ b/src/dist/validate.sh @@ -46,17 +46,30 @@ r="\033[0;31m" # errors x="\033[0m" retry="--retry 5 --retry-delay 2" -if [ "$CODECOV_SKIP_VALIDATION" == "true" ] || [ -n "$CODECOV_BINARY" ] || [ "$CODECOV_USE_PYPI" == "true" ]; +if [ "$CODECOV_SKIP_VALIDATION" == "true" ] || [ "$CODECOV_SKIP_VALIDATION" == "1" ] || [ -n "$CODECOV_BINARY" ] || [ "$CODECOV_USE_PYPI" == "true" ] || [ "$CODECOV_USE_PYPI" == "1" ]; then say "$r==>$x Bypassing validation..." - if [ "$CODECOV_SKIP_VALIDATION" == "true" ]; + if [ "$CODECOV_SKIP_VALIDATION" == "true" ] || [ "$CODECOV_SKIP_VALIDATION" == "1" ]; then chmod +x "$CODECOV_COMMAND" fi else - echo "$(curl -s https://keybase.io/codecovsecops/pgp_keys.asc)" | \ - gpg --no-default-keyring --import - # One-time step + gpg_key_url="https://keybase.io/codecovsecops/pgp_keys.asc" + gpg_import_ok=false + for gpg_attempt in 1 2 3; do + if curl -sf $retry "$gpg_key_url" | gpg --no-default-keyring --import; then + gpg_import_ok=true + break + fi + if [ "$gpg_attempt" -lt 3 ]; then + say "$r ->$x GPG key import attempt $gpg_attempt failed, retrying..." + sleep 2 + fi + done + if [ "$gpg_import_ok" != "true" ]; then + exit_if_error "Could not import GPG verification key after 3 attempts. Please contact Codecov if problem continues" + fi + say "$g==>$x Verifying GPG signature integrity" sha_url="https://cli.codecov.io" sha_url="${sha_url}/${CODECOV_VERSION}/${CODECOV_OS}" @@ -65,16 +78,16 @@ else say "$g ->$x Downloading $b${sha_url}.sig$x" say " " - curl -Os $retry --connect-timeout 2 "$sha_url" - curl -Os $retry --connect-timeout 2 "${sha_url}.sig" + curl -o "$CODECOV_DOWNLOAD_DIR/${CODECOV_FILENAME}.SHA256SUM" -s $retry --connect-timeout 2 "$sha_url" + curl -o "$CODECOV_DOWNLOAD_DIR/${CODECOV_FILENAME}.SHA256SUM.sig" -s $retry --connect-timeout 2 "${sha_url}.sig" - if ! gpg --verify "${CODECOV_FILENAME}.SHA256SUM.sig" "${CODECOV_FILENAME}.SHA256SUM"; + if ! gpg --verify "$CODECOV_DOWNLOAD_DIR/${CODECOV_FILENAME}.SHA256SUM.sig" "$CODECOV_DOWNLOAD_DIR/${CODECOV_FILENAME}.SHA256SUM"; then exit_if_error "Could not verify signature. Please contact Codecov if problem continues" fi - if ! (shasum -a 256 -c "${CODECOV_FILENAME}.SHA256SUM" 2>/dev/null || \ - sha256sum -c "${CODECOV_FILENAME}.SHA256SUM"); + if ! (cd "$CODECOV_DOWNLOAD_DIR" && (shasum -a 256 -c "${CODECOV_FILENAME}.SHA256SUM" 2>/dev/null || \ + sha256sum -c "${CODECOV_FILENAME}.SHA256SUM")); then exit_if_error "Could not verify SHASUM. Please contact Codecov if problem continues" fi @@ -85,12 +98,17 @@ fi if [ -n "$CODECOV_BINARY_LOCATION" ]; then - mkdir -p "$CODECOV_BINARY_LOCATION" && mv "$CODECOV_FILENAME" $_ + mkdir -p "$CODECOV_BINARY_LOCATION" && mv "$CODECOV_COMMAND" "$CODECOV_BINARY_LOCATION/$CODECOV_FILENAME" + CODECOV_COMMAND="$CODECOV_BINARY_LOCATION/$CODECOV_FILENAME" say "$g==>$x ${CODECOV_CLI_TYPE} binary moved to ${CODECOV_BINARY_LOCATION}" fi if [ "$CODECOV_DOWNLOAD_ONLY" = "true" ]; then + if [ "$CODECOV_CLEANUP" == "true" ] && [ -z "$CODECOV_BINARY_LOCATION" ]; then + cp "$CODECOV_COMMAND" "./$CODECOV_FILENAME" + CODECOV_COMMAND="./$CODECOV_FILENAME" + fi say "$g==>$x ${CODECOV_CLI_TYPE} download only called. Exiting..." exit fi diff --git a/src/package.py b/src/package.py index e4c82d44..966f2542 100644 --- a/src/package.py +++ b/src/package.py @@ -7,10 +7,51 @@ FOOTER='env | grep -io "CODECOV_.*=" | tr "=" " " | while read -r val; do echo "export $val=$(eval echo \\\"\$$val\\\")"; done > ./codecov_envs\n' CLEANUP="rm ./codecov_envs\n" +# Wrapper scripts that run as separate orb steps; assignments here must be pre-exported +# so the FOOTER `env | grep CODECOV_` picks them up on the next step. +STEP_SCRIPTS = ('set_defaults.sh', 'download.sh', 'validate.sh') + + def package(): funcs = _get_funcs() _copy_all_files(funcs) _combine_set_args_and_run(funcs) + _write_set_codecov_envs() + + +def _assigned_codecov_suffixes(): + suffixes = set() + for script in STEP_SCRIPTS: + path = os.path.join('src', 'scripts', 'scripts', script) + with open(path, 'r') as f: + text = f.read() + for var in re.findall(r'^\s*(CODECOV_[A-Z0-9_]+)=', text, re.MULTILINE): + suffixes.add(var.removeprefix('CODECOV_')) + return sorted(suffixes) + + +def _write_set_codecov_envs(): + suffixes = _assigned_codecov_suffixes() + lines = [ + '#!/usr/bin/env bash', + '', + 'touch ./codecov_envs', + 'chmod u+x ./codecov_envs', + 'echo "#!/usr/bin/env bash" > ./codecov_envs', + '', + ] + for suffix in suffixes: + lines.append(f'export CODECOV_{suffix}=') + lines.extend([ + '', + 'env | grep -i "CODECOV_" | grep -iv "CODECOV_TOKEN" | sed -e \'s/^/export /\' > ./codecov_envs', + 'cat ./codecov_envs', + '', + ]) + path = os.path.join('src', 'dist', 'set_codecov_envs.sh') + with open(path, 'w') as f: + f.write('\n'.join(lines)) + os.chmod(path, 0o711) def _get_funcs(): with open('src/scripts/scripts/set_funcs.sh', 'r') as f: diff --git a/src/scripts b/src/scripts index bad8df56..1905ad95 160000 --- a/src/scripts +++ b/src/scripts @@ -1 +1 @@ -Subproject commit bad8df56cd845fa9c6115a924bbd3215e1926ec8 +Subproject commit 1905ad958ede83873a45ebdd24319ebfc959396c