Compare commits

..

1 Commits

Author SHA1 Message Date
Tom Hu
9dee4adabc fix: download CLI to temp dir and retry GPG key import
Fixes two regressions in the wrapper script:

1. Dirty git state (#1851, #1804): The binary, SHA256SUM, and
   SHA256SUM.sig files were downloaded into the working directory
   (repo root) and never cleaned up. Now downloads to a mktemp -d
   directory with an EXIT trap that removes it automatically.

2. GPG import failures (#1876): The key import used
   `echo "$(curl ...)" | gpg --import` which strips trailing newlines
   from the PGP key, had no retries, and no error checking. Now pipes
   curl directly to gpg with a 3-attempt retry loop and explicit
   failure reporting.

Made-with: Cursor
2026-02-26 06:41:35 +09:00
7 changed files with 42 additions and 59 deletions

View File

@@ -0,0 +1,14 @@
name: Enforce License Compliance
on:
pull_request:
branches: [main]
jobs:
enforce-license-compliance:
runs-on: ubuntu-latest
steps:
- name: 'Enforce License Compliance'
uses: getsentry/action-enforce-license-compliance@57ba820387a1a9315a46115ee276b2968da51f3d # main
with:
fossa_api_key: ${{ secrets.FOSSA_API_KEY }}

View File

@@ -1,7 +1,7 @@
deploy: deploy:
$(eval VERSION := $(shell cat src/version)) $(eval VERSION := $(shell cat src/version))
git tag -d v7 git tag -d v5
git push origin :v7 git push origin :v5
git tag v7 git tag v5
git tag v$(VERSION) -s -m "" git tag v$(VERSION) -s -m ""
git push origin --tags git push origin --tags

View File

@@ -6,14 +6,6 @@
### Easily upload coverage reports to Codecov from GitHub Actions ### Easily upload coverage reports to Codecov from GitHub Actions
## v7 Release
`v7` of the Codecov GitHub Action bumps the [Codecov Wrapper](https://github.com/codecov/wrapper) submodule, which now fetches the Codecov Uploader PGP verification key from the `codecovsecops` Keybase account.
## v6 Release
`v6` of the Codecov GitHub Action support node24
## v5 Release ## v5 Release
`v5` of the Codecov GitHub Action will use the [Codecov Wrapper](https://github.com/codecov/wrapper) to encapsulate the [CLI](https://github.com/codecov/codecov-cli). This will help ensure that the Action gets updates quicker. `v5` of the Codecov GitHub Action will use the [Codecov Wrapper](https://github.com/codecov/wrapper) to encapsulate the [CLI](https://github.com/codecov/codecov-cli). This will help ensure that the Action gets updates quicker.
@@ -137,7 +129,6 @@ Codecov's Action supports inputs from the user. These inputs, along with their d
| :--- | :--- | :---: | | :--- | :--- | :---: |
| `base_sha` | 'The base SHA to select. This is only used in the "pr-base-picking" run command' | Optional | `base_sha` | 'The base SHA to select. This is only used in the "pr-base-picking" run command' | Optional
| `binary` | The file location of a pre-downloaded version of the CLI. If specified, integrity checking will be bypassed. | Optional | `binary` | The file location of a pre-downloaded version of the CLI. If specified, integrity checking will be bypassed. | Optional
| `cleanup` | If true, download the CLI into a temporary directory and clean it up after the run. Off by default. | Optional
| `codecov_yml_path` | The location of the codecov.yml file. This is currently ONLY used for automated test selection (https://docs.codecov.com/docs/getting-started-with-ats). Note that for all other cases, the Codecov yaml will need to be located as described here: https://docs.codecov.com/docs/codecov-yaml#can-i-name-the-file-codecovyml | Optional | `codecov_yml_path` | The location of the codecov.yml file. This is currently ONLY used for automated test selection (https://docs.codecov.com/docs/getting-started-with-ats). Note that for all other cases, the Codecov yaml will need to be located as described here: https://docs.codecov.com/docs/codecov-yaml#can-i-name-the-file-codecovyml | Optional
| `commit_parent` | SHA (with 40 chars) of what should be the parent of this commit. | Optional | `commit_parent` | SHA (with 40 chars) of what should be the parent of this commit. | Optional
| `directory` | Folder to search for coverage files. Default to the current working directory | Optional | `directory` | Folder to search for coverage files. Default to the current working directory | Optional

View File

@@ -10,10 +10,6 @@ inputs:
binary: binary:
description: 'The file location of a pre-downloaded version of the CLI. If specified, integrity checking will be bypassed.' description: 'The file location of a pre-downloaded version of the CLI. If specified, integrity checking will be bypassed.'
required: false required: false
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.'
required: false
default: 'false'
codecov_yml_path: codecov_yml_path:
description: 'The location of the codecov.yml file. This is crrently ONLY used for automated test selection (https://docs.codecov.com/docs/getting-started-with-ats). Note that for all other cases, the Codecov yaml will need to be located as described here: https://docs.codecov.com/docs/codecov-yaml#can-i-name-the-file-codecovyml' description: 'The location of the codecov.yml file. This is crrently ONLY used for automated test selection (https://docs.codecov.com/docs/getting-started-with-ats). Note that for all other cases, the Codecov yaml will need to be located as described here: https://docs.codecov.com/docs/codecov-yaml#can-i-name-the-file-codecovyml'
required: false required: false
@@ -181,8 +177,6 @@ runs:
steps: steps:
- name: Check system dependencies - name: Check system dependencies
shell: sh shell: sh
env:
INPUT_SKIP_VALIDATION: ${{ inputs.skip_validation }}
run: | run: |
missing_deps="" missing_deps=""
@@ -194,7 +188,7 @@ runs:
done done
# Check for gpg only if validation is not being skipped # Check for gpg only if validation is not being skipped
if [ "$INPUT_SKIP_VALIDATION" != "true" ]; then if [ "${{ inputs.skip_validation }}" != "true" ]; then
if ! command -v gpg >/dev/null 2>&1; then if ! command -v gpg >/dev/null 2>&1; then
missing_deps="$missing_deps gpg" missing_deps="$missing_deps gpg"
fi fi
@@ -236,7 +230,7 @@ runs:
GITHUB_REPOSITORY: ${{ github.repository }} GITHUB_REPOSITORY: ${{ github.repository }}
- name: Get OIDC token - name: Get OIDC token
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
id: oidc id: oidc
with: with:
script: | script: |
@@ -251,27 +245,24 @@ runs:
- name: Get and set token - name: Get and set token
shell: bash shell: bash
run: | run: |
if [ "$INPUT_USE_OIDC" == 'true' ] && [ "$CC_FORK" != 'true' ]; if [ "${{ inputs.use_oidc }}" == 'true' ] && [ "$CC_FORK" != 'true' ];
then then
echo "CC_TOKEN=$CC_OIDC_TOKEN" >> "$GITHUB_ENV" echo "CC_TOKEN=$CC_OIDC_TOKEN" >> "$GITHUB_ENV"
elif [ -n "$INPUT_CODECOV_TOKEN" ]; elif [ -n "${{ env.CODECOV_TOKEN }}" ];
then then
echo -e "\033[0;32m==>\033[0m Token set from env" echo -e "\033[0;32m==>\033[0m Token set from env"
echo "CC_TOKEN=$INPUT_CODECOV_TOKEN" >> "$GITHUB_ENV" echo "CC_TOKEN=${{ env.CODECOV_TOKEN }}" >> "$GITHUB_ENV"
else else
if [ -n "$INPUT_TOKEN" ]; if [ -n "${{ inputs.token }}" ];
then then
echo -e "\033[0;32m==>\033[0m Token set from input" echo -e "\033[0;32m==>\033[0m Token set from input"
CC_TOKEN=$(echo "$INPUT_TOKEN" | tr -d '\n') CC_TOKEN=$(echo "${{ inputs.token }}" | tr -d '\n')
echo "CC_TOKEN=$CC_TOKEN" >> "$GITHUB_ENV" echo "CC_TOKEN=$CC_TOKEN" >> "$GITHUB_ENV"
fi fi
fi fi
env: env:
CC_OIDC_TOKEN: ${{ steps.oidc.outputs.result }} CC_OIDC_TOKEN: ${{ steps.oidc.outputs.result }}
CC_OIDC_AUDIENCE: ${{ inputs.url || 'https://codecov.io' }} CC_OIDC_AUDIENCE: ${{ inputs.url || 'https://codecov.io' }}
INPUT_USE_OIDC: ${{ inputs.use_oidc }}
INPUT_TOKEN: ${{ inputs.token }}
INPUT_CODECOV_TOKEN: ${{ env.CODECOV_TOKEN }}
- name: Override branch for forks - name: Override branch for forks
shell: bash shell: bash
@@ -321,7 +312,6 @@ runs:
CC_BINARY: ${{ inputs.binary }} CC_BINARY: ${{ inputs.binary }}
CC_BUILD: ${{ inputs.override_build }} CC_BUILD: ${{ inputs.override_build }}
CC_BUILD_URL: ${{ inputs.override_build_url }} CC_BUILD_URL: ${{ inputs.override_build_url }}
CC_CLEANUP: ${{ inputs.cleanup }}
CC_CODE: ${{ inputs.report_code }} CC_CODE: ${{ inputs.report_code }}
CC_DIR: ${{ inputs.directory }} CC_DIR: ${{ inputs.directory }}
CC_DISABLE_FILE_FIXES: ${{ inputs.disable_file_fixes }} CC_DISABLE_FILE_FIXES: ${{ inputs.disable_file_fixes }}

44
dist/codecov.sh vendored
View File

@@ -37,12 +37,11 @@ g="\033[0;32m" # info/debug
r="\033[0;31m" # errors r="\033[0;31m" # errors
x="\033[0m" x="\033[0m"
retry="--retry 5 --retry-delay 2" retry="--retry 5 --retry-delay 2"
CC_WRAPPER_VERSION="0.3.1" CC_WRAPPER_VERSION="0.2.7"
CC_VERSION="${CC_VERSION:-latest}" CC_VERSION="${CC_VERSION:-latest}"
CC_FAIL_ON_ERROR="${CC_FAIL_ON_ERROR:-false}" CC_FAIL_ON_ERROR="${CC_FAIL_ON_ERROR:-false}"
CC_RUN_CMD="${CC_RUN_CMD:-upload-coverage}" CC_RUN_CMD="${CC_RUN_CMD:-upload-coverage}"
CC_CLI_TYPE=${CC_CLI_TYPE:-"codecov-cli"} CC_CLI_TYPE=${CC_CLI_TYPE:-"codecov-cli"}
CC_CLEANUP="${CC_CLEANUP:-false}"
say " _____ _ say " _____ _
/ ____| | | / ____| | |
| | ___ __| | ___ ___ _____ __ | | ___ __| | ___ ___ _____ __
@@ -64,28 +63,19 @@ then
else else
exit_if_error "Could not find binary file $CC_BINARY" exit_if_error "Could not find binary file $CC_BINARY"
fi fi
elif [ "$CC_USE_PYPI" == "true" ] || [ "$CC_USE_PYPI" == "1" ]; elif [ "$CC_USE_PYPI" == "true" ];
then then
if ! pip install "${CC_CLI_TYPE}$([ "$CC_VERSION" == "latest" ] && echo "" || echo "==$CC_VERSION")"; then if ! pip install "${CC_CLI_TYPE}$([ "$CC_VERSION" == "latest" ] && echo "" || echo "==$CC_VERSION")"; then
exit_if_error "Could not install via pypi." exit_if_error "Could not install via pypi."
exit exit
fi fi
if [[ "$CC_CLI_TYPE" == "codecov-cli" ]]; then CC_COMMAND="${CC_CLI_TYPE}"
CC_COMMAND="codecovcli"
elif [[ "$CC_CLI_TYPE" == "sentry-prevent-cli" ]]; then
CC_COMMAND="sentry-prevent-cli"
else
CC_COMMAND="${CC_CLI_TYPE}"
fi
else else
CC_DOWNLOAD_DIR="." CC_DOWNLOAD_DIR=$(mktemp -d)
if [ "$CC_CLEANUP" == "true" ]; then cleanup_downloads() {
CC_DOWNLOAD_DIR=$(mktemp -d) rm -rf "$CC_DOWNLOAD_DIR"
cleanup_downloads() { }
rm -rf "$CC_DOWNLOAD_DIR" trap cleanup_downloads EXIT
}
trap cleanup_downloads EXIT
fi
if [ -n "$CC_OS" ]; if [ -n "$CC_OS" ];
then then
say "$g==>$x Overridden OS: $b${CC_OS}$x" say "$g==>$x Overridden OS: $b${CC_OS}$x"
@@ -110,32 +100,30 @@ else
CC_URL="$CC_URL/${CC_VERSION}" CC_URL="$CC_URL/${CC_VERSION}"
CC_URL="$CC_URL/${CC_OS}/${CC_FILENAME}" CC_URL="$CC_URL/${CC_OS}/${CC_FILENAME}"
say "$g ->$x Downloading $b${CC_URL}$x" say "$g ->$x Downloading $b${CC_URL}$x"
curl -o "$CC_COMMAND" $retry "$CC_URL" curl -o "$CC_DOWNLOAD_DIR/$CC_FILENAME" $retry "$CC_URL"
say "$g==>$x Finishing downloading $b${CC_OS}:${CC_VERSION}$x" say "$g==>$x Finishing downloading $b${CC_OS}:${CC_VERSION}$x"
v_url="https://cli.codecov.io/api/${CC_OS}/${CC_VERSION}" v_url="https://cli.codecov.io/api/${CC_OS}/${CC_VERSION}"
v=$(curl $retry --retry-all-errors -s "$v_url" -H "Accept:application/json" | tr \{ '\n' | tr , '\n' | tr \} '\n' | grep "\"version\"" | awk -F'"' '{print $4}' | tail -1) v=$(curl $retry --retry-all-errors -s "$v_url" -H "Accept:application/json" | tr \{ '\n' | tr , '\n' | tr \} '\n' | grep "\"version\"" | awk -F'"' '{print $4}' | tail -1)
say " Version: $b$v$x" say " Version: $b$v$x"
say " " say " "
fi fi
if [ "$CC_SKIP_VALIDATION" == "true" ] || [ "$CC_SKIP_VALIDATION" == "1" ] || [ -n "$CC_BINARY" ] || [ "$CC_USE_PYPI" == "true" ] || [ "$CC_USE_PYPI" == "1" ]; if [ "$CC_SKIP_VALIDATION" == "true" ] || [ -n "$CC_BINARY" ] || [ "$CC_USE_PYPI" == "true" ];
then then
say "$r==>$x Bypassing validation..." say "$r==>$x Bypassing validation..."
if [ "$CC_SKIP_VALIDATION" == "true" ] || [ "$CC_SKIP_VALIDATION" == "1" ]; if [ "$CC_SKIP_VALIDATION" == "true" ];
then then
chmod +x "$CC_COMMAND" chmod +x "$CC_COMMAND"
fi fi
else else
gpg_key_url="https://keybase.io/codecovsecops/pgp_keys.asc" gpg_key_url="https://keybase.io/codecovsecurity/pgp_keys.asc"
gpg_import_ok=false gpg_import_ok=false
for gpg_attempt in 1 2 3; do for gpg_attempt in 1 2 3; do
if curl -sf $retry "$gpg_key_url" | gpg --no-default-keyring --import; then if curl -sf $retry "$gpg_key_url" | gpg --no-default-keyring --import 2>/dev/null; then
gpg_import_ok=true gpg_import_ok=true
break break
fi fi
if [ "$gpg_attempt" -lt 3 ]; then say "$r ->$x GPG key import attempt $gpg_attempt failed, retrying..."
say "$r ->$x GPG key import attempt $gpg_attempt failed, retrying..." sleep 2
sleep 2
fi
done done
if [ "$gpg_import_ok" != "true" ]; then if [ "$gpg_import_ok" != "true" ]; then
exit_if_error "Could not import GPG verification key after 3 attempts. Please contact Codecov if problem continues" exit_if_error "Could not import GPG verification key after 3 attempts. Please contact Codecov if problem continues"
@@ -170,7 +158,7 @@ then
fi fi
if [ "$CC_DOWNLOAD_ONLY" = "true" ]; if [ "$CC_DOWNLOAD_ONLY" = "true" ];
then then
if [ "$CC_CLEANUP" == "true" ] && [ -z "$CC_BINARY_LOCATION" ]; then if [ -n "$CC_DOWNLOAD_DIR" ] && [ -z "$CC_BINARY_LOCATION" ]; then
cp "$CC_COMMAND" "./$CC_FILENAME" cp "$CC_COMMAND" "./$CC_FILENAME"
CC_COMMAND="./$CC_FILENAME" CC_COMMAND="./$CC_FILENAME"
fi fi

View File

@@ -1 +1 @@
7.1.1 5.5.2