diff --git a/.circleci/config.yml b/.circleci/config.yml index 58465fd2d66d..4508ed2b7593 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -252,17 +252,50 @@ jobs: yarn test:ci --selectProjects ReactNative elif [ "<< parameters.react-version >>" == "19.3" ]; then yarn test:ci --maxWorkers=4 --selectProjects ReactDOM --testPathPatterns 'packages/react/src/__tests__/concurrent-.*\.web\.tsx' 'packages/react/src/hooks/__tests__/useCacheState.web.tsx' + elif [ "<< parameters.react-version >>" == "latest" ]; then + # Coverage floors and projects live in the test:coverage script + yarn run test:coverage --ci --maxWorkers=4 --coverageReporters=lcovonly --coverageReporters=text-summary else - curl -fsSO --connect-timeout 10 --max-time 60 https://uploader.codecov.io/latest/linux/codecov && chmod +x codecov || echo "Codecov uploader download failed; skipping coverage upload"; - yarn run test:coverage --ci --maxWorkers=4 --selectProjects ReactDOM Node --coverageReporters=text-lcov > ./lcov.info; - if [ -x ./codecov ]; then - if [ "$CODECOV_TOKEN" != "" ]; then - ./codecov -t ${CODECOV_TOKEN} < ./lcov.info || true; - else - ./codecov < ./lcov.info || true; - fi - fi + echo "Unknown react-version << parameters.react-version >>" + exit 1 fi + - when: + condition: + equal: [latest, << parameters.react-version >>] + steps: + - run: + name: Upload coverage to Codecov + # Upload even when the coverage floors fail, so Codecov shows what dropped + when: always + command: | + # Pinned CLI, checked against Codecov's signing key fingerprint + # before it ever sees CODECOV_TOKEN. + # https://docs.codecov.com/docs/codecov-uploader#integrity-checking-the-uploader + # renovate: datasource=github-releases depName=codecov/codecov-cli + CLI=https://cli.codecov.io/v11.3.1/linux/codecov + KEY_FINGERPRINT=27034E7FDB850E0BBC2C62FF806BB28AED779869 + if [ ! -f coverage/lcov.info ]; then + echo "No coverage report; skipping upload" + exit 0 + fi + DIR="$(mktemp -d)" + export GNUPGHOME="$DIR" + # gpg status goes to a file, not a pipe: CircleCI's pipefail would + # flip the check if an early-exiting grep SIGPIPEd gpg. + if curl -fsS --retry 3 --output-dir "$DIR" -O "$CLI" -O "$CLI.SHA256SUM" -O "$CLI.SHA256SUM.sig" \ + -o key.asc https://keybase.io/codecovsecops/pgp_keys.asc \ + && gpg --batch --import "$DIR/key.asc" \ + && gpg --batch --status-file "$DIR/status" --verify "$DIR/codecov.SHA256SUM.sig" "$DIR/codecov.SHA256SUM" \ + && grep -q "VALIDSIG .*$KEY_FINGERPRINT" "$DIR/status" \ + && (cd "$DIR" && sha256sum -c codecov.SHA256SUM); then + chmod +x "$DIR/codecov" + # Fork PRs have no token; Codecov accepts tokenless uploads from them + "$DIR/codecov" upload-coverage ${CODECOV_TOKEN:+-t "$CODECOV_TOKEN"} --git-service github \ + --file coverage/lcov.info --disable-search --plugin noop \ + || echo "Codecov upload failed" + else + echo "Codecov CLI download or signature check failed; skipping upload" + fi node_matrix: parameters: diff --git a/.github/renovate.json b/.github/renovate.json index 83ab66d08a91..3d8bfb3530f9 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -177,5 +177,15 @@ "groupName": "node", "groupSlug": "node" } + ], + "customManagers": [ + { + "description": "Codecov CLI pinned in CircleCI's coverage upload step", + "customType": "regex", + "managerFilePatterns": ["/^\\.circleci/config\\.yml$/"], + "matchStrings": [ + "# renovate: datasource=(?\\S+) depName=(?\\S+)\\s+CLI=https://cli\\.codecov\\.io/(?v[^/]+)/" + ] + } ] } diff --git a/package.json b/package.json index 1eeff5aa957e..24d9c25df12a 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "build:skills": "yarn workspace rdc-website build:skills", "test": "NODE_ENV=test run jest", "test:ci": "ANANSI_JEST_TYPECHECK=false yarn test --ci", - "test:coverage": "ANANSI_JEST_TYPECHECK=false yarn test --coverage", + "test:coverage": "ANANSI_JEST_TYPECHECK=false yarn test --coverage --selectProjects ReactDOM Node --coverageThreshold='{\"global\":{\"statements\":98,\"branches\":96,\"functions\":90,\"lines\":98}}'", "prepare": "yarn build:copy:ambient && tsc --build --builders 1", "prepack": "yarn prepare", "prepublishOnly": "yarn workspaces foreach -Wpti --no-private run build:legacy-types", diff --git a/packages/normalizr/README.md b/packages/normalizr/README.md index 968464c1238d..54f3f9f9b787 100644 --- a/packages/normalizr/README.md +++ b/packages/normalizr/README.md @@ -1,10 +1,10 @@ # Normalizr Client -[![CircleCI](https://circleci.com/gh/reactive/data-client/tree/master.svg?style=shield)](https://circleci.com/gh/data-clientdata-clients) -[![Coverage Status](https://img.shields.io/codecov/c/gh/reactive/data-client/master.svg?style=flat-square)](https://app.codecov.io/gh/data-clientdata-clients?branch=master) +[![CircleCI](https://circleci.com/gh/reactive/data-client/tree/master.svg?style=shield)](https://circleci.com/gh/reactive/data-client) +[![Coverage Status](https://img.shields.io/codecov/c/gh/reactive/data-client/master.svg?style=flat-square)](https://app.codecov.io/gh/reactive/data-client?branch=master) [![npm downloads](https://img.shields.io/npm/dt/@data-client/normalizr.svg?style=flat-square)](https://www.npmjs.com/package/@data-client/normalizr) [![bundle size](https://img.shields.io/bundlephobia/minzip/@data-client/normalizr?style=flat-square)](https://bundlephobia.com/result?p=@data-client/normalizr) -[![npm version](https://img.shields.io/npm/v/@data-client/normalizr.svg?style=flat-square)](https://www.npmjs.com/package/data-clients/normalizr) [![npm downloads](https://img.shields.io/npm/dm/@data-client/normalizr.svg?style=flat-square)](https://www.npmjs.com/packagdata-clientoks/normalizr) +[![npm version](https://img.shields.io/npm/v/@data-client/normalizr.svg?style=flat-square)](https://www.npmjs.com/package/@data-client/normalizr) [![npm downloads](https://img.shields.io/npm/dm/@data-client/normalizr.svg?style=flat-square)](https://www.npmjs.com/package/@data-client/normalizr) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com) ## Install