From 70fcb41c906c0626c2ab142429406cfdb12d563e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 21 Apr 2021 15:07:38 +0000 Subject: [PATCH 01/52] build(deps): update dependency simple-git to v2.38.0 (#9668) Co-authored-by: Renovate Bot --- package.json | 2 +- yarn.lock | 19 ++++++------------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index f4cd1ea6b76f26..254795565d2b48 100644 --- a/package.json +++ b/package.json @@ -178,7 +178,7 @@ "semver-utils": "1.1.4", "shlex": "2.0.2", "shortid": "2.2.16", - "simple-git": "2.37.0", + "simple-git": "2.38.0", "slugify": "1.5.0", "traverse": "0.6.6", "upath": "2.0.1", diff --git a/yarn.lock b/yarn.lock index 9e9558987729df..2e371654502a32 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3325,7 +3325,7 @@ debug@3.1.0: dependencies: ms "2.0.0" -debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: +debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== @@ -3346,13 +3346,6 @@ debug@^3.1.0: dependencies: ms "^2.1.1" -debug@^4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== - dependencies: - ms "2.1.2" - debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" @@ -9235,14 +9228,14 @@ signale@^1.2.1: figures "^2.0.0" pkg-conf "^2.1.0" -simple-git@2.37.0: - version "2.37.0" - resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-2.37.0.tgz#9cf30a1fe6f58453a2ca3e65562428b38ff76f84" - integrity sha512-ZK6qRnP+Xa2v23UEZDNHUfzswsuNCDHOQpWZRkpqNaXn7V5wVBBx3zRJLji3pROJGzrzA7mXwY7preL5EKuAaQ== +simple-git@2.38.0: + version "2.38.0" + resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-2.38.0.tgz#5bc66bec40bce4f8ef950f4966f427799b4dd758" + integrity sha512-CORjrfirWMEGbJAxaXDH/PjZVOeATeG2bkafM9DsLVcFkbF9sXQGIIpEI6FeyXpvUsFK69T/pa4+4FKY9TUJMQ== dependencies: "@kwsites/file-exists" "^1.1.1" "@kwsites/promise-deferred" "^1.1.1" - debug "^4.3.2" + debug "^4.3.1" sisteransi@^1.0.5: version "1.0.5" From d4d24b71f77adbca006ea14213b2e053bd4d44ff Mon Sep 17 00:00:00 2001 From: Michael Kriese Date: Wed, 21 Apr 2021 19:35:20 +0200 Subject: [PATCH 02/52] build: prepare maintenance releases (#9671) --- .github/workflows/build.yml | 1 + .github/workflows/release-npm.yml | 2 +- .releaserc | 14 ++++++++++++-- tools/dispatch-release.mjs | 8 +++++--- tools/release.mjs | 4 ++-- tools/utils.mjs | 5 ++++- 6 files changed, 25 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c7825e1b9754d5..144292f75b8d89 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,6 +4,7 @@ on: push: branches: - master + - v24 workflow_dispatch: diff --git a/.github/workflows/release-npm.yml b/.github/workflows/release-npm.yml index fac7bcb140545e..a26410c73baea6 100644 --- a/.github/workflows/release-npm.yml +++ b/.github/workflows/release-npm.yml @@ -51,6 +51,6 @@ jobs: - name: Publish ${{ github.event.client_payload.version }} run: | echo '//registry.npmjs.org/:_authToken=${NPM_TOKEN}' >> ~/.npmrc - npm publish + npm publish --tag ${{ github.event.client_payload.tag }} env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.releaserc b/.releaserc index 625c7479a8e760..e6ca1a4e3d47cc 100644 --- a/.releaserc +++ b/.releaserc @@ -12,7 +12,7 @@ "@semantic-release/exec", { "verifyConditionsCmd": "run-s verify", - "publishCmd": "run-s \"release -- {@}\" -- --release=${nextRelease.version} --sha=${nextRelease.gitHead}" + "publishCmd": "run-s \"release -- {@}\" -- --release=${nextRelease.version} --sha=${nextRelease.gitHead} --tag=${nextRelease.channel}" } ] ], @@ -82,5 +82,15 @@ } ] }, - "tagFormat": "${version}" + "tagFormat": "${version}", + "branches": [ + { + "name": "v24", + "range": "24.x", + "channel": "v24" + }, + { + "name": "master" + } + ] } diff --git a/tools/dispatch-release.mjs b/tools/dispatch-release.mjs index b1beb8a53648cc..927d6e52b1e254 100644 --- a/tools/dispatch-release.mjs +++ b/tools/dispatch-release.mjs @@ -1,9 +1,10 @@ import got from 'got'; import shell from 'shelljs'; -import { program } from './utils.mjs'; +import { options } from './utils.mjs'; -const version = program.release; -const dry = program.dryRun; +const version = options.release; +const tag = options.tag; +const dry = options.dryRun; shell.echo(`Dispatching version: ${version}`); @@ -27,6 +28,7 @@ shell.echo(`Dispatching version: ${version}`); sha: process.env.GITHUB_SHA, ref: process.env.GITHUB_REF, version, + tag, }, }, } diff --git a/tools/release.mjs b/tools/release.mjs index a475489216cc4c..eb1d20f3ea4294 100644 --- a/tools/release.mjs +++ b/tools/release.mjs @@ -1,7 +1,7 @@ import shell from 'shelljs'; -import { program } from './utils.mjs'; +import { options } from './utils.mjs'; -const version = program.release; +const version = options.release; // const sha = program.sha; // let err = false; diff --git a/tools/utils.mjs b/tools/utils.mjs index 49f1e215ffe156..6840a0236d3616 100644 --- a/tools/utils.mjs +++ b/tools/utils.mjs @@ -5,11 +5,14 @@ const program = new commander.Command(); program .version('0.0.1') .requiredOption('-r, --release ', 'Version to use') - .option('-s, --sha ', 'Sha to use') + .option('-s, --sha ', 'Git sha to use') + .option('-t, --tag ', 'Npm dist-tag to publish to', 'latest') .option('-d, --dry-run'); program.parse(process.argv); +export const options = program.opts(); + export { program }; /** From 1c2add83966593bcd4fbd75b432d212d1eec6cf3 Mon Sep 17 00:00:00 2001 From: Michael Kriese Date: Wed, 21 Apr 2021 20:58:10 +0200 Subject: [PATCH 03/52] build: fix npm release (#9672) --- .github/workflows/release-npm.yml | 3 ++- tools/dispatch-release.mjs | 2 +- tools/utils.mjs | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release-npm.yml b/.github/workflows/release-npm.yml index a26410c73baea6..b7286c4738e7dd 100644 --- a/.github/workflows/release-npm.yml +++ b/.github/workflows/release-npm.yml @@ -51,6 +51,7 @@ jobs: - name: Publish ${{ github.event.client_payload.version }} run: | echo '//registry.npmjs.org/:_authToken=${NPM_TOKEN}' >> ~/.npmrc - npm publish --tag ${{ github.event.client_payload.tag }} + npm publish --tag ${TAG:-latest} env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + TAG: ${{ github.event.client_payload.tag }} diff --git a/tools/dispatch-release.mjs b/tools/dispatch-release.mjs index 927d6e52b1e254..3bdc53a23f53b7 100644 --- a/tools/dispatch-release.mjs +++ b/tools/dispatch-release.mjs @@ -3,7 +3,7 @@ import shell from 'shelljs'; import { options } from './utils.mjs'; const version = options.release; -const tag = options.tag; +const tag = options.tag || 'latest'; const dry = options.dryRun; shell.echo(`Dispatching version: ${version}`); diff --git a/tools/utils.mjs b/tools/utils.mjs index 6840a0236d3616..34e0d88af752c2 100644 --- a/tools/utils.mjs +++ b/tools/utils.mjs @@ -6,7 +6,7 @@ program .version('0.0.1') .requiredOption('-r, --release ', 'Version to use') .option('-s, --sha ', 'Git sha to use') - .option('-t, --tag ', 'Npm dist-tag to publish to', 'latest') + .option('-t, --tag ', 'Npm dist-tag to publish to') .option('-d, --dry-run'); program.parse(process.argv); From c6b34abf9bf0187548c94154669217cf0a78db02 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 22 Apr 2021 00:30:04 +0000 Subject: [PATCH 04/52] build(deps): update dependency azure-devops-node-api to v10.2.2 (#9674) Co-authored-by: Renovate Bot --- package.json | 2 +- yarn.lock | 23 +++++++++++------------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index 254795565d2b48..9d25d303cbd601 100644 --- a/package.json +++ b/package.json @@ -128,7 +128,7 @@ "@sindresorhus/is": "4.0.0", "@yarnpkg/core": "2.4.0", "@yarnpkg/parsers": "2.3.0", - "azure-devops-node-api": "10.2.1", + "azure-devops-node-api": "10.2.2", "bunyan": "1.8.15", "cacache": "15.0.6", "chalk": "4.1.0", diff --git a/yarn.lock b/yarn.lock index 2e371654502a32..b1eaa52f27bbd6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2308,14 +2308,13 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== -azure-devops-node-api@10.2.1: - version "10.2.1" - resolved "https://registry.yarnpkg.com/azure-devops-node-api/-/azure-devops-node-api-10.2.1.tgz#835080164f8c30cec6506c47198b044c053f1f36" - integrity sha512-XuSiUaYpk0tQpd9fD8qfRa5y1IdavupKNVmwxy0w/RhmxG2Wl8uAYnNJchUoWd3Rn9On0mYTCCZSn+UlYdYFSg== +azure-devops-node-api@10.2.2: + version "10.2.2" + resolved "https://registry.yarnpkg.com/azure-devops-node-api/-/azure-devops-node-api-10.2.2.tgz#9f557e622dd07bbaa9bd5e7e84e17c761e2151b2" + integrity sha512-4TVv2X7oNStT0vLaEfExmy3J4/CzfuXolEcQl/BRUmvGySqKStTG2O55/hUQ0kM7UJlZBLgniM0SBq4d/WkKow== dependencies: tunnel "0.0.6" - typed-rest-client "^1.8.0" - underscore "1.8.3" + typed-rest-client "^1.8.4" babel-jest@^26.6.3: version "26.6.3" @@ -10173,14 +10172,14 @@ type-fest@^0.8.0, type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== -typed-rest-client@^1.8.0: - version "1.8.1" - resolved "https://registry.yarnpkg.com/typed-rest-client/-/typed-rest-client-1.8.1.tgz#2ecb18dd360ce2a722ad30d0e076712f1fc3d191" - integrity sha512-7JbJFBZZuu3G64u6ksklN1xtVGfqBKiR5MQoTe5oLTi68OyB6pRuuIQCllfK/BdGjQtZYp62rgUOnEYDz4e9Xg== +typed-rest-client@^1.8.4: + version "1.8.4" + resolved "https://registry.yarnpkg.com/typed-rest-client/-/typed-rest-client-1.8.4.tgz#ba3fb788e5b9322547406392533f12d660a5ced6" + integrity sha512-MyfKKYzk3I6/QQp6e1T50py4qg+c+9BzOEl2rBmQIpStwNUoqQ73An+Tkfy9YuV7O+o2mpVVJpe+fH//POZkbg== dependencies: qs "^6.9.1" tunnel "0.0.6" - underscore "1.8.3" + underscore "^1.12.1" typedarray-to-buffer@^3.1.5: version "3.1.5" @@ -10219,7 +10218,7 @@ umask@^1.1.0, umask@~1.1.0: resolved "https://registry.yarnpkg.com/umask/-/umask-1.1.0.tgz#f29cebf01df517912bb58ff9c4e50fde8e33320d" integrity sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0= -underscore@1.8.3, underscore@^1.12.1: +underscore@^1.12.1: version "1.12.1" resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.12.1.tgz#7bb8cc9b3d397e201cf8553336d262544ead829e" integrity sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw== From 3516c7051e1e1318674ff023285c631b2c82080b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 22 Apr 2021 05:38:28 +0000 Subject: [PATCH 05/52] chore(deps): update dependency @types/eslint to v7.2.10 (#9675) Co-authored-by: Renovate Bot --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 9d25d303cbd601..63478b25c2fee2 100644 --- a/package.json +++ b/package.json @@ -202,7 +202,7 @@ "@types/changelog-filename-regex": "2.0.0", "@types/clean-git-ref": "2.0.0", "@types/conventional-commits-detector": "1.0.0", - "@types/eslint": "7.2.8", + "@types/eslint": "7.2.10", "@types/fs-extra": "9.0.11", "@types/git-url-parse": "9.0.0", "@types/github-url-from-git": "1.5.0", diff --git a/yarn.lock b/yarn.lock index b1eaa52f27bbd6..26c8522ff8ffe4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1388,10 +1388,10 @@ resolved "https://registry.yarnpkg.com/@types/emscripten/-/emscripten-1.39.4.tgz#d61990c0cee72c4e475de737a140b51fe925a2c8" integrity sha512-k3LLVMFrdNA9UCvMDPWMbFrGPNb+GcPyw29ktJTo1RCN7RmxFG5XzPZcPKRlnLuLT/FRm8wp4ohvDwNY7GlROQ== -"@types/eslint@7.2.8": - version "7.2.8" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.2.8.tgz#45cd802380fcc352e5680e1781d43c50916f12ee" - integrity sha512-RTKvBsfz0T8CKOGZMfuluDNyMFHnu5lvNr4hWEsQeHXH6FcmIDIozOyWMh36nLGMwVd5UFNXC2xztA8lln22MQ== +"@types/eslint@7.2.10": + version "7.2.10" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.2.10.tgz#4b7a9368d46c0f8cd5408c23288a59aa2394d917" + integrity sha512-kUEPnMKrqbtpCq/KTaGFFKAcz6Ethm2EjCoKIDaCmfRBWLbFuTcOJfTlorwbnboXBzahqWLgUp1BQeKHiJzPUQ== dependencies: "@types/estree" "*" "@types/json-schema" "*" From dca841b984ba7ef4a4e3dcc182d4f2314c3d9411 Mon Sep 17 00:00:00 2001 From: Michael Kriese Date: Thu, 22 Apr 2021 08:26:02 +0200 Subject: [PATCH 06/52] build: release workflow update (#9677) --- .github/workflows/build.yml | 23 ++++++++++++++++--- .github/workflows/release-npm.yml | 37 +++++++++++++++++++++++++------ 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 144292f75b8d89..7dccfacde6a1bb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,12 +7,19 @@ on: - v24 workflow_dispatch: + inputs: + dryRun: + description: 'Dry-Run' + default: 'true' env: + # Currently no way to detect automatically (#8153) + DEFAULT_BRANCH: master YARN_MODULES_CACHE_KEY: v1 YARN_PACKAGE_CACHE_KEY: v1 YARN_CACHE_FOLDER: .cache/yarn NODE_VERSION: 14 + DRY_RUN: true jobs: test: @@ -98,7 +105,8 @@ jobs: uses: codecov/codecov-action@v1.4.1 if: always() && env.coverage == 'true' - # build after tests to exclude files + # build after tests to exclude build files from tests + # TODO: check if build before test speeds up tests - name: Build run: yarn build @@ -179,6 +187,16 @@ jobs: yarn config set version-git-tag false npm config set scripts-prepend-node-path true + - name: Check dry run + run: | + if [[ "${{github.event_name}}" == "workflow_dispatch" && "${{ github.event.inputs.dryRun }}" != "true" ]]; then + echo "DRY_RUN=false" >> $GITHUB_ENV + elif [[ "${{github.ref}}" == "refs/heads/${{env.DEFAULT_BRANCH}}" ]]; then + echo "DRY_RUN=false" >> $GITHUB_ENV + elif [[ "${{github.ref}}" =~ ^refs/heads/v[0-9]+(\.[0-9]+)?$ ]]; then + echo "DRY_RUN=false" >> $GITHUB_ENV + fi + # full checkout for semantic-release - uses: actions/checkout@v2.3.4 with: @@ -194,10 +212,9 @@ jobs: run: yarn install --frozen-lockfile - name: semantic-release - if: github.ref == 'refs/heads/master' run: | echo '//registry.npmjs.org/:_authToken=${NPM_TOKEN}' >> ~/.npmrc - npx semantic-release --dry-run ${{github.ref != 'refs/heads/master'}} --ci ${{github.ref == 'refs/heads/master'}} + npx semantic-release --dry-run ${{env.DRY_RUN}} env: GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/release-npm.yml b/.github/workflows/release-npm.yml index b7286c4738e7dd..c718fb45dc9d5b 100644 --- a/.github/workflows/release-npm.yml +++ b/.github/workflows/release-npm.yml @@ -1,13 +1,29 @@ name: release-npm + on: repository_dispatch: types: [renovate-release] + workflow_dispatch: + inputs: + sha: + description: 'Git sha to checkout' + required: true + version: + description: 'Version to release' + required: true + tag: + description: 'Npm dist-tag' + default: 'latest' + env: YARN_MODULES_CACHE_KEY: v1 YARN_PACKAGE_CACHE_KEY: v1 YARN_CACHE_FOLDER: .cache/yarn NODE_VERSION: 14 + GIT_SHA: ${{ github.event.client_payload.sha }} + NPM_VERSION: ${{ github.event.client_payload.version }} + NPM_TAG: ${{ github.event.client_payload.tag }} jobs: release-npm: @@ -27,9 +43,17 @@ jobs: yarn config set version-git-tag false npm config set scripts-prepend-node-path true + - name: Prepare env + run: | + if [[ "${{github.event_name}}" == "workflow_dispatch" ]]; then + echo "GIT_SHA=${{ github.event.inputs.sha }}" >> $GITHUB_ENV + echo "NPM_VERSION=${{ github.event.inputs.version }}" >> $GITHUB_ENV + echo "NPM_TAG=${{ github.event.inputs.tag }}" >> $GITHUB_ENV + fi + - uses: actions/checkout@v2.3.4 with: - ref: ${{ github.event.client_payload.sha }} + ref: ${{ env.GIT_SHA }} - name: Cache Yarn packages id: yarn_cache_packages @@ -41,17 +65,16 @@ jobs: - name: Installing dependencies run: yarn install --frozen-lockfile - - name: Build ${{ github.event.client_payload.version }} + - name: Build ${{ env.NPM_VERSION }} run: yarn build - - name: Prepare ${{ github.event.client_payload.version }} + - name: Prepare ${{ env.NPM_VERSION }} run: | - npm --no-git-tag-version version ${{ github.event.client_payload.version }} + npm --no-git-tag-version version ${{ env.NPM_VERSION }} - - name: Publish ${{ github.event.client_payload.version }} + - name: Publish ${{ env.NPM_VERSION }} run: | echo '//registry.npmjs.org/:_authToken=${NPM_TOKEN}' >> ~/.npmrc - npm publish --tag ${TAG:-latest} + npm publish --tag ${NPM_TAG:-latest} env: NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - TAG: ${{ github.event.client_payload.tag }} From 1a1ace919e5ce1d7ec182eddd8f313222cb91407 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Sun, 4 Apr 2021 09:18:56 +0200 Subject: [PATCH 07/52] feat: remove RENOVATE_LEGACY_GIT_AUTHOR_EMAIL (#9389) Removes RENOVATE_LEGACY_GIT_AUTHOR_EMAIL support. Closes #9111 BREAKING CHANGE: RENOVATE_LEGACY_GIT_AUTHOR_EMAIL is no longer supported. Use `ignoredAuthors` in config instead. --- docs/usage/self-hosted-experimental.md | 5 ----- lib/util/git/index.ts | 1 - 2 files changed, 6 deletions(-) diff --git a/docs/usage/self-hosted-experimental.md b/docs/usage/self-hosted-experimental.md index 1151bd65d624ac..2f00716900c3b6 100644 --- a/docs/usage/self-hosted-experimental.md +++ b/docs/usage/self-hosted-experimental.md @@ -27,11 +27,6 @@ If set to any integer, Renovate will use this integer instead of the default npm If set to any value, Renovate will skip its default artifacts filter check in the Maven datasource. Skiping the check will speed things up, but may result in versions being returned which don't properly exist on the server. -## RENOVATE_LEGACY_GIT_AUTHOR_EMAIL - -An additional `gitAuthor` email to ignore. -This variable is deprecated: use `ignoredAuthors` instead. - ## RENOVATE_PAGINATE_ALL If set to any value, Renovate will always paginate requests to GitHub fully, instead of stopping after 10 pages. diff --git a/lib/util/git/index.ts b/lib/util/git/index.ts index 3ced1d68ead6f5..829f18abe8cdcd 100644 --- a/lib/util/git/index.ts +++ b/lib/util/git/index.ts @@ -488,7 +488,6 @@ export async function isBranchModified(branchName: string): Promise { ).trim(); const { gitAuthorEmail } = config; if ( - lastAuthor === process.env.RENOVATE_LEGACY_GIT_AUTHOR_EMAIL || // remove in next major release lastAuthor === gitAuthorEmail || config.ignoredAuthors.some((ignoredAuthor) => lastAuthor === ignoredAuthor) ) { From 57015047b2120c3b8e5b1e8c4d2272820c587d83 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 21 Apr 2021 09:04:07 +0200 Subject: [PATCH 08/52] feat: drop NPM_TOKEN support (#9391) Removes support for NPM_TOKEN. BREAKING CHANGE: Do not use NPM_TOKEN in env to configure npm authentication. Configure hostRules instead. --- docs/usage/private-modules.md | 2 +- lib/config/presets/npm/index.spec.ts | 1 - .../npm/__snapshots__/index.spec.ts.snap | 39 ------------------- lib/datasource/npm/index.spec.ts | 16 -------- lib/datasource/npm/npmrc.spec.ts | 1 - lib/datasource/npm/npmrc.ts | 5 --- lib/manager/npm/post-update/lerna.ts | 1 - lib/manager/npm/post-update/npm.ts | 1 - lib/manager/npm/post-update/pnpm.ts | 1 - lib/manager/npm/post-update/yarn.ts | 1 - 10 files changed, 1 insertion(+), 67 deletions(-) diff --git a/docs/usage/private-modules.md b/docs/usage/private-modules.md index 44d95db472515c..2c8e596f774dc9 100644 --- a/docs/usage/private-modules.md +++ b/docs/usage/private-modules.md @@ -64,7 +64,7 @@ module.exports = { }; ``` -**NOTE:** Do not use `NPM_TOKEN` as an environment variable, it's incompatible with `hostRules` and will be deprecated soon. +**NOTE:** Do not use `NPM_TOKEN` as an environment variable. ### Commit .npmrc file into repository diff --git a/lib/config/presets/npm/index.spec.ts b/lib/config/presets/npm/index.spec.ts index 931ae3d39d6c60..fa5bd9afd76e95 100644 --- a/lib/config/presets/npm/index.spec.ts +++ b/lib/config/presets/npm/index.spec.ts @@ -7,7 +7,6 @@ jest.mock('registry-auth-token'); jest.mock('delay'); describe(getName(__filename), () => { - delete process.env.NPM_TOKEN; beforeEach(() => { jest.resetAllMocks(); setAdminConfig(); diff --git a/lib/datasource/npm/__snapshots__/index.spec.ts.snap b/lib/datasource/npm/__snapshots__/index.spec.ts.snap index 85d618101b79ab..ac9065cc23dea7 100644 --- a/lib/datasource/npm/__snapshots__/index.spec.ts.snap +++ b/lib/datasource/npm/__snapshots__/index.spec.ts.snap @@ -519,45 +519,6 @@ Array [ ] `; -exports[`datasource/npm/index should use NPM_TOKEN if provided 1`] = ` -Object { - "name": "@foobar/core", - "registryUrl": "https://registry.npmjs.org/", - "releases": Array [ - Object { - "releaseTimestamp": "2018-05-06T05:21:53.000Z", - "version": "0.0.1", - }, - Object { - "releaseTimestamp": "2018-05-07T05:21:53.000Z", - "version": "0.0.2", - }, - ], - "sourceDirectory": "src/a", - "sourceUrl": "https://github.com/renovateapp/dummy", - "tags": Object { - "latest": "0.0.1", - }, - "versions": Object {}, -} -`; - -exports[`datasource/npm/index should use NPM_TOKEN if provided 2`] = ` -Array [ - Object { - "headers": Object { - "accept": "application/json", - "accept-encoding": "gzip, deflate, br", - "authorization": "Bearer some-token", - "host": "registry.npmjs.org", - "user-agent": "https://github.com/renovatebot/renovate", - }, - "method": "GET", - "url": "https://registry.npmjs.org/@foobar%2Fcore", - }, -] -`; - exports[`datasource/npm/index should use default registry if missing from npmrc 1`] = ` Object { "name": "foobar", diff --git a/lib/datasource/npm/index.spec.ts b/lib/datasource/npm/index.spec.ts index a4979577cf60cb..1b630c14be2635 100644 --- a/lib/datasource/npm/index.spec.ts +++ b/lib/datasource/npm/index.spec.ts @@ -15,7 +15,6 @@ const registryAuthToken: jest.Mock<_registryAuthToken.NpmCredentials> = _registr let npmResponse: any; describe(getName(__filename), () => { - delete process.env.NPM_TOKEN; beforeEach(() => { jest.resetAllMocks(); httpMock.setup(); @@ -269,21 +268,6 @@ describe(getName(__filename), () => { expect(httpMock.getTrace()).toMatchSnapshot(); }); - it('should use NPM_TOKEN if provided', async () => { - httpMock - .scope('https://registry.npmjs.org', { - reqheaders: { authorization: 'Bearer some-token' }, - }) - .get('/@foobar%2Fcore') - .reply(200, { ...npmResponse, name: '@foobar/core' }); - const oldToken = process.env.NPM_TOKEN; - process.env.NPM_TOKEN = 'some-token'; - const res = await getPkgReleases({ datasource, depName: '@foobar/core' }); - process.env.NPM_TOKEN = oldToken; - expect(res).toMatchSnapshot(); - expect(httpMock.getTrace()).toMatchSnapshot(); - }); - it('should use host rules by hostName if provided', async () => { hostRules.add({ hostType: 'npm', diff --git a/lib/datasource/npm/npmrc.spec.ts b/lib/datasource/npm/npmrc.spec.ts index d340093435907f..186e4969726351 100644 --- a/lib/datasource/npm/npmrc.spec.ts +++ b/lib/datasource/npm/npmrc.spec.ts @@ -9,7 +9,6 @@ const sanitize = mocked(_sanitize); describe(getName(__filename), () => { beforeEach(() => { - delete process.env.NPM_TOKEN; setNpmrc(''); setAdminConfig(); jest.resetAllMocks(); diff --git a/lib/datasource/npm/npmrc.ts b/lib/datasource/npm/npmrc.ts index 7afc4c89b13e52..dae13dfca01852 100644 --- a/lib/datasource/npm/npmrc.ts +++ b/lib/datasource/npm/npmrc.ts @@ -129,11 +129,6 @@ export function resolvePackage(packageName: string): PackageResolution { { token: maskToken(authInfo.token), npmName: packageName }, 'Using auth (via npmrc) for npm lookup' ); - } else if (process.env.NPM_TOKEN && process.env.NPM_TOKEN !== 'undefined') { - logger.warn( - 'Support for NPM_TOKEN in env will be dropped in the next major release' - ); - headers.authorization = `Bearer ${process.env.NPM_TOKEN}`; } return { headers, packageUrl, registryUrl }; } diff --git a/lib/manager/npm/post-update/lerna.ts b/lib/manager/npm/post-update/lerna.ts index 08cfc8be3d4c6c..acba413c40c108 100644 --- a/lib/manager/npm/post-update/lerna.ts +++ b/lib/manager/npm/post-update/lerna.ts @@ -99,7 +99,6 @@ export async function generateLockFiles( if (getAdminConfig().trustLevel === 'high') { execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; - execOptions.extraEnv.NPM_TOKEN = env.NPM_TOKEN; } if (config.dockerMapDotfiles) { const homeDir = diff --git a/lib/manager/npm/post-update/npm.ts b/lib/manager/npm/post-update/npm.ts index d3e43876605615..0025d620fe4c76 100644 --- a/lib/manager/npm/post-update/npm.ts +++ b/lib/manager/npm/post-update/npm.ts @@ -74,7 +74,6 @@ export async function generateLockFile( if (getAdminConfig().trustLevel === 'high') { execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; - execOptions.extraEnv.NPM_TOKEN = env.NPM_TOKEN; } if (config.dockerMapDotfiles) { const homeDir = diff --git a/lib/manager/npm/post-update/pnpm.ts b/lib/manager/npm/post-update/pnpm.ts index 7816267e786744..6541a412870a23 100644 --- a/lib/manager/npm/post-update/pnpm.ts +++ b/lib/manager/npm/post-update/pnpm.ts @@ -53,7 +53,6 @@ export async function generateLockFile( if (getAdminConfig().trustLevel === 'high') { execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; - execOptions.extraEnv.NPM_TOKEN = env.NPM_TOKEN; } if (config.dockerMapDotfiles) { const homeDir = diff --git a/lib/manager/npm/post-update/yarn.ts b/lib/manager/npm/post-update/yarn.ts index e179f717703ead..34aed8c7cdbf68 100644 --- a/lib/manager/npm/post-update/yarn.ts +++ b/lib/manager/npm/post-update/yarn.ts @@ -124,7 +124,6 @@ export async function generateLockFile( if (getAdminConfig().trustLevel === 'high') { execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; - execOptions.extraEnv.NPM_TOKEN = env.NPM_TOKEN; } if (config.dockerMapDotfiles) { const homeDir = From 95ac10998cdc9ec3a65d7e1dcf84002743acf29b Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Sun, 4 Apr 2021 10:58:32 +0200 Subject: [PATCH 09/52] feat: remove logLevel support in config (#9390) Remove support for logLevel in config. Must be configured using LOG_LEVEL instead. Closes #8291 BREAKING CHANGE: Configure LOG_LEVEL in env and not in config or CLI --- docs/usage/self-hosted-configuration.md | 12 ------------ lib/config/definitions.ts | 7 ------- lib/config/index.ts | 11 +---------- lib/config/types.ts | 1 - 4 files changed, 1 insertion(+), 30 deletions(-) diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index b6673d42fc629a..93af532f4906e1 100644 --- a/docs/usage/self-hosted-configuration.md +++ b/docs/usage/self-hosted-configuration.md @@ -233,18 +233,6 @@ If left as default (null), a random short ID will be selected. ## logFileLevel -## logLevel - -We recommend that you run the Renovate bot at the debug level if you can. -Use the environment variable `LOG_LEVEL=debug` to run Renovate at the debug level. - -When you use `LOG_LEVEL=debug`, debug logging starts from the beginning of the app. -If you had configured debug logging in a file config, then the debug logging starts _after_ the file config is parsed. - -Additionally, if you configure `LOG_FORMAT=json` in env then logging will be done in JSON format instead of "pretty" format, which is usually better if you're doing any ingestion or parsing of the logs. - -Warning: Configuring `logLevel` config option or `--log-level` cli option is deprecated and will be removed in a major version. - ## onboarding Set this to `false` only if all three statements are true: diff --git a/lib/config/definitions.ts b/lib/config/definitions.ts index ecc1d455c5f7b1..5bf8d99305ef2b 100644 --- a/lib/config/definitions.ts +++ b/lib/config/definitions.ts @@ -294,13 +294,6 @@ const options: RenovateOptions[] = [ admin: true, }, // Log options - { - name: 'logLevel', - description: 'Logging level. Deprecated, use `LOG_LEVEL` environment.', - stage: 'global', - type: 'string', - allowedValues: ['fatal', 'error', 'warn', 'info', 'debug', 'trace'], - }, { name: 'logFile', description: 'Log file path.', diff --git a/lib/config/index.ts b/lib/config/index.ts index 6fbe43fc3c351c..a005f9bf1ee8ed 100644 --- a/lib/config/index.ts +++ b/lib/config/index.ts @@ -1,4 +1,4 @@ -import { addStream, levels, logger, setContext } from '../logger'; +import { addStream, logger, setContext } from '../logger'; import { get, getLanguageList, getManagerList } from '../manager'; import { ensureDir, getSubDirectory, readFile } from '../util/fs'; import { ensureTrailingSlash } from '../util/url'; @@ -75,15 +75,6 @@ export async function parseConfigs( delete config.privateKeyPath; } - // Deprecated set log level: https://github.com/renovatebot/renovate/issues/8291 - // istanbul ignore if - if (config.logLevel) { - logger.warn( - 'Configuring logLevel in CLI or file is deprecated. Use LOG_LEVEL environment variable instead' - ); - levels('stdout', config.logLevel); - } - if (config.logContext) { // This only has an effect if logContext was defined via file or CLI, otherwise it would already have been detected in env setContext(config.logContext); diff --git a/lib/config/types.ts b/lib/config/types.ts index 21806dd46c7ec6..b2c9ca6b37fb42 100644 --- a/lib/config/types.ts +++ b/lib/config/types.ts @@ -74,7 +74,6 @@ export interface GlobalOnlyConfig { gitPrivateKey?: string; logFile?: string; logFileLevel?: LogLevel; - logLevel?: LogLevel; prCommitsPerRunLimit?: number; privateKeyPath?: string; redisUrl?: string; From 8af905e8f5ddc5f48360a15f6e7226f79c9e57aa Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Thu, 15 Apr 2021 22:15:30 +0200 Subject: [PATCH 10/52] feat: split trustLevel into separate options (#9388) Removes trustLevel and replaces it with 3 other options instead. No longer necessary to set anything additional is configuring `allowedPostUpgradeCommands` BREAKING CHANGE: `trustLevel` is no longer supported and instead broken into `allowCustomCrateRegistries` , `allowScripts` , and `exposeAllEnv`. --- docs/usage/self-hosted-configuration.md | 20 +++++++------- .../__snapshots__/migration.spec.ts.snap | 6 +++-- lib/config/admin.ts | 4 ++- lib/config/definitions.ts | 26 +++++++++++++++---- lib/config/migration.spec.ts | 1 + lib/config/migration.ts | 11 +++++--- lib/config/types.ts | 4 ++- .../crate/__snapshots__/index.spec.ts.snap | 2 +- lib/datasource/crate/index.spec.ts | 12 ++++----- lib/datasource/crate/index.ts | 4 +-- lib/datasource/npm/index.spec.ts | 4 +-- lib/datasource/npm/npmrc.spec.ts | 2 +- lib/datasource/npm/npmrc.ts | 8 +++--- lib/manager/composer/artifacts.spec.ts | 5 ++-- lib/manager/composer/artifacts.ts | 2 +- lib/manager/npm/extract/index.ts | 2 +- lib/manager/npm/post-update/lerna.spec.ts | 2 +- lib/manager/npm/post-update/lerna.ts | 7 ++--- lib/manager/npm/post-update/npm.ts | 2 +- lib/manager/npm/post-update/pnpm.ts | 4 +-- lib/manager/npm/post-update/yarn.ts | 4 +-- lib/manager/pip_requirements/extract.spec.ts | 2 +- lib/manager/pip_requirements/extract.ts | 2 +- lib/util/exec/env.spec.ts | 2 +- lib/util/exec/env.ts | 2 +- lib/util/exec/exec.spec.ts | 2 +- lib/workers/branch/index.spec.ts | 8 +++--- 27 files changed, 88 insertions(+), 62 deletions(-) diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index 93af532f4906e1..7b2bbd01ad6e75 100644 --- a/docs/usage/self-hosted-configuration.md +++ b/docs/usage/self-hosted-configuration.md @@ -9,6 +9,8 @@ The configuration options listed in this document are applicable to self-hosted Please also see [Self-Hosted Experimental Options](./self-hosted-experimental.md). +## allowCustomCrateRegistries + ## allowPostUpgradeCommandTemplating Set to true to allow templating of dependency level post-upgrade commands. @@ -52,6 +54,8 @@ npm ci --ignore-scripts npx ng update @angular/core --from=10.0.0 --to=11.0.0 --migrate-only --allow-dirty --force ``` +## allowScripts + ## allowedPostUpgradeCommands A list of regular expressions that determine which commands in `postUpgradeTasks` are allowed to be executed. @@ -186,6 +190,13 @@ e.g. ## endpoint +## exposeAllEnv + +By default, Renovate will only pass a limited set of environment variables to package managers. +Potentially, there could be leaks of confidential data if a script you don't trust enumerates all values in env, so set this to true only if you trust the repositories which the bot runs against. + +Setting this to true will also allow for variable substitution in `.npmrc` files. + ## force This object is used as a "force override" when you need to make sure certain configuration overrides whatever is configured in the repository. @@ -375,13 +386,4 @@ This is currently applicable to `npm` and `lerna`/`npm` only, and only used in c ## token -## trustLevel - -Setting trustLevel to `"high"` can make sense in many self-hosted cases where the bot operator trusts the content in each repository. - -Setting trustLevel=high means: - -- Child processes are run with full access to `env` -- `.npmrc` files can have environment variable substitution performed - ## username diff --git a/lib/config/__snapshots__/migration.spec.ts.snap b/lib/config/__snapshots__/migration.spec.ts.snap index 48456d788edf78..a9d93e6307f2b3 100644 --- a/lib/config/__snapshots__/migration.spec.ts.snap +++ b/lib/config/__snapshots__/migration.spec.ts.snap @@ -78,6 +78,8 @@ Array [ exports[`config/migration migrateConfig(config, parentConfig) migrates config 1`] = ` Object { "additionalBranchPrefix": "{{parentDir}}-", + "allowCustomCrateRegistries": true, + "allowScripts": true, "autodiscover": true, "automerge": false, "automergeType": "branch", @@ -94,6 +96,7 @@ Object { "dependencyDashboard": true, "dependencyDashboardTitle": "foo", "enabled": true, + "exposeAllEnv": true, "extends": Array [ ":automergeBranch", "config:js-app", @@ -109,8 +112,8 @@ Object { "includeForks": true, "lockFileMaintenance": Object { "automerge": true, + "exposeAllEnv": false, "schedule": "before 5am", - "trustLevel": "low", }, "major": Object { "automerge": false, @@ -243,7 +246,6 @@ Object { "travis": Object { "enabled": true, }, - "trustLevel": "high", } `; diff --git a/lib/config/admin.ts b/lib/config/admin.ts index 6d6fd61fc69edd..feb3701c818dcd 100644 --- a/lib/config/admin.ts +++ b/lib/config/admin.ts @@ -4,15 +4,17 @@ let adminConfig: RepoAdminConfig = {}; // TODO: once admin config work is complete, add a test to make sure this list includes all options with admin=true export const repoAdminOptions = [ + 'allowCustomCrateRegistries', 'allowPostUpgradeCommandTemplating', + 'allowScripts', 'allowedPostUpgradeCommands', 'customEnvVariables', 'dockerChildPrefix', 'dockerImagePrefix', 'dockerUser', 'dryRun', + 'exposeAllEnv', 'privateKey', - 'trustLevel', ]; export function setAdminConfig(config: RenovateConfig = {}): void { diff --git a/lib/config/definitions.ts b/lib/config/definitions.ts index 5bf8d99305ef2b..92b85aadaf02af 100644 --- a/lib/config/definitions.ts +++ b/lib/config/definitions.ts @@ -473,17 +473,33 @@ const options: RenovateOptions[] = [ default: false, }, { - name: 'trustLevel', + name: 'exposeAllEnv', description: - 'Set this to "high" if the bot should trust the repository owners/contents.', + 'Configure this to true to allow passing of all env variables to package managers.', admin: true, - type: 'string', - default: 'low', + type: 'boolean', + default: false, + }, + { + name: 'allowScripts', + description: + 'Configure this to true if repositories are allowed to run install scripts.', + admin: true, + type: 'boolean', + default: false, + }, + { + name: 'allowCustomCrateRegistries', + description: + 'Configure this to true if custom crate registries are allowed.', + admin: true, + type: 'boolean', + default: false, }, { name: 'ignoreScripts', description: - 'Configure this to true if trustLevel is high but you wish to skip running scripts when updating lock files.', + 'Configure this to true if allowScripts=true but you wish to skip running scripts when updating lock files.', type: 'boolean', default: false, }, diff --git a/lib/config/migration.spec.ts b/lib/config/migration.spec.ts index 7bd348c5ea4996..6f19f5c6cacffe 100644 --- a/lib/config/migration.spec.ts +++ b/lib/config/migration.spec.ts @@ -56,6 +56,7 @@ describe(getName(__filename), () => { masterIssueTitle: 'foo', gomodTidy: true, upgradeInRange: true, + trustLevel: 'high', automergeType: 'branch-push', branchName: '{{{branchPrefix}}}{{{managerBranchPrefix}}}{{{branchTopic}}}{{{baseDir}}}', diff --git a/lib/config/migration.ts b/lib/config/migration.ts index 8b4f7ad5b18d5b..32ddd4566b6eaa 100644 --- a/lib/config/migration.ts +++ b/lib/config/migration.ts @@ -191,11 +191,14 @@ export function migrateConfig( migratedConfig.rebaseWhen = 'never'; } } else if (key === 'exposeEnv') { + migratedConfig.exposeAllEnv = val; delete migratedConfig.exposeEnv; - if (val === true) { - migratedConfig.trustLevel = 'high'; - } else if (val === false) { - migratedConfig.trustLevel = 'low'; + } else if (key === 'trustLevel') { + delete migratedConfig.trustLevel; + if (val === 'high') { + migratedConfig.allowCustomCrateRegistries ??= true; + migratedConfig.allowScripts ??= true; + migratedConfig.exposeAllEnv ??= true; } } else if ( key === 'branchName' && diff --git a/lib/config/types.ts b/lib/config/types.ts index b2c9ca6b37fb42..2ef022c21c49b8 100644 --- a/lib/config/types.ts +++ b/lib/config/types.ts @@ -83,15 +83,17 @@ export interface GlobalOnlyConfig { // Config options used within the repository worker, but not user configurable // The below should contain config options where admin=true export interface RepoAdminConfig { + allowCustomCrateRegistries?: boolean; allowPostUpgradeCommandTemplating?: boolean; + allowScripts?: boolean; allowedPostUpgradeCommands?: string[]; customEnvVariables?: Record; dockerChildPrefix?: string; dockerImagePrefix?: string; dockerUser?: string; dryRun?: boolean; + exposeAllEnv?: boolean; privateKey?: string | Buffer; - trustLevel?: 'low' | 'high'; } export interface LegacyAdminConfig { diff --git a/lib/datasource/crate/__snapshots__/index.spec.ts.snap b/lib/datasource/crate/__snapshots__/index.spec.ts.snap index 48572b6e73a18d..6e8b60c6991564 100644 --- a/lib/datasource/crate/__snapshots__/index.spec.ts.snap +++ b/lib/datasource/crate/__snapshots__/index.spec.ts.snap @@ -331,7 +331,7 @@ Array [ ] `; -exports[`datasource/crate/index getReleases refuses to clone if trustLevel is not high 1`] = `null`; +exports[`datasource/crate/index getReleases refuses to clone if allowCustomCrateRegistries is not true 1`] = `null`; exports[`datasource/crate/index getReleases returns null for 404 1`] = ` Array [ diff --git a/lib/datasource/crate/index.spec.ts b/lib/datasource/crate/index.spec.ts index a83b9f6293da56..dd8e79fdefb2cb 100644 --- a/lib/datasource/crate/index.spec.ts +++ b/lib/datasource/crate/index.spec.ts @@ -225,7 +225,7 @@ describe(getName(__filename), () => { expect(res).toBeDefined(); expect(httpMock.getTrace()).toMatchSnapshot(); }); - it('refuses to clone if trustLevel is not high', async () => { + it('refuses to clone if allowCustomCrateRegistries is not true', async () => { const { mockClone } = setupGitMocks(); const url = 'https://dl.cloudsmith.io/basic/myorg/myrepo/cargo/index.git'; @@ -240,7 +240,7 @@ describe(getName(__filename), () => { }); it('clones cloudsmith private registry', async () => { const { mockClone } = setupGitMocks(); - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ allowCustomCrateRegistries: true }); const url = 'https://dl.cloudsmith.io/basic/myorg/myrepo/cargo/index.git'; const res = await getPkgReleases({ datasource, @@ -254,7 +254,7 @@ describe(getName(__filename), () => { }); it('clones other private registry', async () => { const { mockClone } = setupGitMocks(); - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ allowCustomCrateRegistries: true }); const url = 'https://github.com/mcorbin/testregistry'; const res = await getPkgReleases({ datasource, @@ -268,7 +268,7 @@ describe(getName(__filename), () => { }); it('clones once then reuses the cache', async () => { const { mockClone } = setupGitMocks(); - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ allowCustomCrateRegistries: true }); const url = 'https://github.com/mcorbin/othertestregistry'; await getPkgReleases({ datasource, @@ -284,7 +284,7 @@ describe(getName(__filename), () => { }); it('guards against race conditions while cloning', async () => { const { mockClone } = setupGitMocks(250); - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ allowCustomCrateRegistries: true }); const url = 'https://github.com/mcorbin/othertestregistry'; await Promise.all([ @@ -310,7 +310,7 @@ describe(getName(__filename), () => { }); it('returns null when git clone fails', async () => { setupErrorGitMock(); - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ allowCustomCrateRegistries: true }); const url = 'https://github.com/mcorbin/othertestregistry'; const result = await getPkgReleases({ diff --git a/lib/datasource/crate/index.ts b/lib/datasource/crate/index.ts index cce827f726b39f..44d39cb1852829 100644 --- a/lib/datasource/crate/index.ts +++ b/lib/datasource/crate/index.ts @@ -163,9 +163,9 @@ async function fetchRegistryInfo( }; if (flavor !== RegistryFlavor.CratesIo) { - if (getAdminConfig().trustLevel !== 'high') { + if (!getAdminConfig().allowCustomCrateRegistries) { logger.warn( - 'crate datasource: trustLevel=high is required for registries other than crates.io, bailing out' + 'crate datasource: allowCustomCrateRegistries=true is required for registries other than crates.io, bailing out' ); return null; } diff --git a/lib/datasource/npm/index.spec.ts b/lib/datasource/npm/index.spec.ts index 1b630c14be2635..d5091d722de3ad 100644 --- a/lib/datasource/npm/index.spec.ts +++ b/lib/datasource/npm/index.spec.ts @@ -359,7 +359,7 @@ describe(getName(__filename), () => { .reply(200, npmResponse); process.env.REGISTRY = 'https://registry.from-env.com'; process.env.RENOVATE_CACHE_NPM_MINUTES = '15'; - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ exposeAllEnv: true }); // eslint-disable-next-line no-template-curly-in-string const npmrc = 'registry=${REGISTRY}'; const res = await getPkgReleases({ datasource, depName: 'foobar', npmrc }); @@ -368,7 +368,7 @@ describe(getName(__filename), () => { }); it('should throw error if necessary env var is not present', () => { - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ exposeAllEnv: true }); // eslint-disable-next-line no-template-curly-in-string expect(() => setNpmrc('registry=${REGISTRY_MISSING}')).toThrow( Error('env-replace') diff --git a/lib/datasource/npm/npmrc.spec.ts b/lib/datasource/npm/npmrc.spec.ts index 186e4969726351..41fff3d27c3457 100644 --- a/lib/datasource/npm/npmrc.spec.ts +++ b/lib/datasource/npm/npmrc.spec.ts @@ -38,7 +38,7 @@ describe(getName(__filename), () => { }); it('sanitize _authtoken with high trust', () => { - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ exposeAllEnv: true }); process.env.TEST_TOKEN = 'test'; setNpmrc( // eslint-disable-next-line no-template-curly-in-string diff --git a/lib/datasource/npm/npmrc.ts b/lib/datasource/npm/npmrc.ts index dae13dfca01852..3641998d365c9a 100644 --- a/lib/datasource/npm/npmrc.ts +++ b/lib/datasource/npm/npmrc.ts @@ -61,13 +61,13 @@ export function setNpmrc(input?: string): void { npmrcRaw = input; logger.debug('Setting npmrc'); npmrc = ini.parse(input.replace(/\\n/g, '\n')); - const { trustLevel } = getAdminConfig(); + const { exposeAllEnv } = getAdminConfig(); for (const [key, val] of Object.entries(npmrc)) { - if (trustLevel !== 'high') { + if (!exposeAllEnv) { sanitize(key, val); } if ( - trustLevel !== 'high' && + !exposeAllEnv && key.endsWith('registry') && val && val.includes('localhost') @@ -80,7 +80,7 @@ export function setNpmrc(input?: string): void { return; } } - if (trustLevel !== 'high') { + if (!exposeAllEnv) { return; } for (const key of Object.keys(npmrc)) { diff --git a/lib/manager/composer/artifacts.spec.ts b/lib/manager/composer/artifacts.spec.ts index d7798754387c6c..fca585b9583432 100644 --- a/lib/manager/composer/artifacts.spec.ts +++ b/lib/manager/composer/artifacts.spec.ts @@ -30,6 +30,7 @@ const config = { localDir: join('/tmp/github/some/repo'), cacheDir: join('/tmp/renovate/cache'), composerIgnorePlatformReqs: true, + ignoreScripts: false, }; const repoStatus = partial({ @@ -46,7 +47,7 @@ describe('.updateArtifacts()', () => { await setUtilConfig(config); docker.resetPrefetchedImages(); hostRules.clear(); - setAdminConfig(); + setAdminConfig({ allowScripts: false }); }); it('returns if no composer.lock found', async () => { expect( @@ -63,7 +64,7 @@ describe('.updateArtifacts()', () => { const execSnapshots = mockExecAll(exec); fs.readLocalFile.mockReturnValueOnce('Current composer.lock' as any); git.getRepoStatus.mockResolvedValue(repoStatus); - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ allowScripts: true }); expect( await composer.updateArtifacts({ packageFileName: 'composer.json', diff --git a/lib/manager/composer/artifacts.ts b/lib/manager/composer/artifacts.ts index 9515106780c284..bffbe7510c707e 100644 --- a/lib/manager/composer/artifacts.ts +++ b/lib/manager/composer/artifacts.ts @@ -151,7 +151,7 @@ export async function updateArtifacts({ args += ' --ignore-platform-reqs'; } args += ' --no-ansi --no-interaction'; - if (getAdminConfig().trustLevel !== 'high' || config.ignoreScripts) { + if (!getAdminConfig().allowScripts || config.ignoreScripts) { args += ' --no-scripts --no-autoloader'; } logger.debug({ cmd, args }, 'composer command'); diff --git a/lib/manager/npm/extract/index.ts b/lib/manager/npm/extract/index.ts index 7bccc130f11d2a..aacf7d55444bef 100644 --- a/lib/manager/npm/extract/index.ts +++ b/lib/manager/npm/extract/index.ts @@ -107,7 +107,7 @@ export async function extractPackageFile( npmrc = npmrc.replace(/(^|\n)package-lock.*?(\n|$)/g, '\n'); } if (is.string(npmrc)) { - if (npmrc.includes('=${') && getAdminConfig().trustLevel !== 'high') { + if (npmrc.includes('=${') && !getAdminConfig().exposeAllEnv) { logger.debug('Discarding .npmrc file with variables'); ignoreNpmrcFile = true; npmrc = undefined; diff --git a/lib/manager/npm/post-update/lerna.spec.ts b/lib/manager/npm/post-update/lerna.spec.ts index 0dddb7c585fe5d..b5a596d671bbc5 100644 --- a/lib/manager/npm/post-update/lerna.spec.ts +++ b/lib/manager/npm/post-update/lerna.spec.ts @@ -109,7 +109,7 @@ describe(getName(__filename), () => { }); it('allows scripts for trust level high', async () => { const execSnapshots = mockExecAll(exec); - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ allowScripts: true }); const res = await lernaHelper.generateLockFiles( lernaPkgFile('npm'), 'some-dir', diff --git a/lib/manager/npm/post-update/lerna.ts b/lib/manager/npm/post-update/lerna.ts index acba413c40c108..2ce9e38d4a8362 100644 --- a/lib/manager/npm/post-update/lerna.ts +++ b/lib/manager/npm/post-update/lerna.ts @@ -72,10 +72,7 @@ export async function generateLockFiles( return { error: false }; } let lernaCommand = `lerna bootstrap --no-ci --ignore-scripts -- `; - if ( - getAdminConfig().trustLevel === 'high' && - config.ignoreScripts !== false - ) { + if (getAdminConfig().allowScripts && config.ignoreScripts !== false) { cmdOptions = cmdOptions.replace('--ignore-scripts ', ''); lernaCommand = lernaCommand.replace('--ignore-scripts ', ''); } @@ -96,7 +93,7 @@ export async function generateLockFiles( }, }; // istanbul ignore if - if (getAdminConfig().trustLevel === 'high') { + if (getAdminConfig().exposeAllEnv) { execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; } diff --git a/lib/manager/npm/post-update/npm.ts b/lib/manager/npm/post-update/npm.ts index 0025d620fe4c76..a11bce39231f08 100644 --- a/lib/manager/npm/post-update/npm.ts +++ b/lib/manager/npm/post-update/npm.ts @@ -71,7 +71,7 @@ export async function generateLockFile( }, }; // istanbul ignore if - if (getAdminConfig().trustLevel === 'high') { + if (getAdminConfig().exposeAllEnv) { execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; } diff --git a/lib/manager/npm/post-update/pnpm.ts b/lib/manager/npm/post-update/pnpm.ts index 6541a412870a23..b9842631f96f53 100644 --- a/lib/manager/npm/post-update/pnpm.ts +++ b/lib/manager/npm/post-update/pnpm.ts @@ -50,7 +50,7 @@ export async function generateLockFile( }, }; // istanbul ignore if - if (getAdminConfig().trustLevel === 'high') { + if (getAdminConfig().exposeAllEnv) { execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; } @@ -62,7 +62,7 @@ export async function generateLockFile( } cmd = 'pnpm'; let args = 'install --recursive --lockfile-only'; - if (getAdminConfig().trustLevel !== 'high' || config.ignoreScripts) { + if (!getAdminConfig().allowScripts || config.ignoreScripts) { args += ' --ignore-scripts'; args += ' --ignore-pnpmfile'; } diff --git a/lib/manager/npm/post-update/yarn.ts b/lib/manager/npm/post-update/yarn.ts index 34aed8c7cdbf68..5e7d4958273365 100644 --- a/lib/manager/npm/post-update/yarn.ts +++ b/lib/manager/npm/post-update/yarn.ts @@ -102,7 +102,7 @@ export async function generateLockFile( extraEnv.YARN_ENABLE_IMMUTABLE_INSTALLS = 'false'; extraEnv.YARN_HTTP_TIMEOUT = '100000'; } - if (getAdminConfig().trustLevel !== 'high' || config.ignoreScripts) { + if (!getAdminConfig().allowScripts || config.ignoreScripts) { if (isYarn1) { cmdOptions += ' --ignore-scripts'; } else { @@ -121,7 +121,7 @@ export async function generateLockFile( }, }; // istanbul ignore if - if (getAdminConfig().trustLevel === 'high') { + if (getAdminConfig().exposeAllEnv) { execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; } diff --git a/lib/manager/pip_requirements/extract.spec.ts b/lib/manager/pip_requirements/extract.spec.ts index 6226ab5fc424da..9607c03eebc135 100644 --- a/lib/manager/pip_requirements/extract.spec.ts +++ b/lib/manager/pip_requirements/extract.spec.ts @@ -129,7 +129,7 @@ describe(getName(__filename), () => { }); it('should replace env vars in high trust mode', () => { process.env.PIP_TEST_TOKEN = 'its-a-secret'; - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ exposeAllEnv: true }); const res = extractPackageFile(requirements7, 'unused_file_name', {}); expect(res.registryUrls).toEqual([ 'https://pypi.org/pypi/', diff --git a/lib/manager/pip_requirements/extract.ts b/lib/manager/pip_requirements/extract.ts index 87e2ffaec01963..87fc491b410ce2 100644 --- a/lib/manager/pip_requirements/extract.ts +++ b/lib/manager/pip_requirements/extract.ts @@ -84,7 +84,7 @@ export function extractPackageFile( res.registryUrls = registryUrls.map((url) => { // handle the optional quotes in eg. `--extra-index-url "https://foo.bar"` const cleaned = url.replace(/^"/, '').replace(/"$/, ''); - if (getAdminConfig().trustLevel !== 'high') { + if (!getAdminConfig().exposeAllEnv) { return cleaned; } // interpolate any environment variables diff --git a/lib/util/exec/env.spec.ts b/lib/util/exec/env.spec.ts index e3a0eabc258ad3..ebc1c16900a513 100644 --- a/lib/util/exec/env.spec.ts +++ b/lib/util/exec/env.spec.ts @@ -58,7 +58,7 @@ describe('getChildProcess environment when trustlevel set to low', () => { describe('getChildProcessEnv when trustlevel set to high', () => { it('returns process.env if trustlevel set to high', () => { - setAdminConfig({ trustLevel: 'high' }); + setAdminConfig({ exposeAllEnv: true }); expect(getChildProcessEnv()).toMatchObject(process.env); }); }); diff --git a/lib/util/exec/env.ts b/lib/util/exec/env.ts index 38950e4e867a95..faffd61bf81526 100644 --- a/lib/util/exec/env.ts +++ b/lib/util/exec/env.ts @@ -17,7 +17,7 @@ export function getChildProcessEnv( customEnvVars: string[] = [] ): NodeJS.ProcessEnv { const env: NodeJS.ProcessEnv = {}; - if (getAdminConfig().trustLevel === 'high') { + if (getAdminConfig().exposeAllEnv) { return { ...env, ...process.env }; } const envVars = [...basicEnvVars, ...customEnvVars]; diff --git a/lib/util/exec/exec.spec.ts b/lib/util/exec/exec.spec.ts index f5a67fbda53284..e5db81a628a4e8 100644 --- a/lib/util/exec/exec.spec.ts +++ b/lib/util/exec/exec.spec.ts @@ -194,7 +194,7 @@ describe(getName(__filename), () => { maxBuffer: 10485760, }, ], - adminConfig: { trustLevel: 'high' }, + adminConfig: { exposeAllEnv: true }, }, ], diff --git a/lib/workers/branch/index.spec.ts b/lib/workers/branch/index.spec.ts index a38f6cce331b99..73d68242507905 100644 --- a/lib/workers/branch/index.spec.ts +++ b/lib/workers/branch/index.spec.ts @@ -736,7 +736,7 @@ describe(getName(__filename), () => { const adminConfig = { allowedPostUpgradeCommands: ['^echo {{{versioning}}}$'], allowPostUpgradeCommandTemplating: true, - trustLevel: 'high', + exposeAllEnv: true, }; setAdminConfig(adminConfig); @@ -816,7 +816,7 @@ describe(getName(__filename), () => { const adminConfig = { allowedPostUpgradeCommands: ['^exit 1$'], allowPostUpgradeCommandTemplating: true, - trustLevel: 'high', + exposeAllEnv: true, }; setAdminConfig(adminConfig); @@ -885,7 +885,7 @@ describe(getName(__filename), () => { const adminConfig = { allowedPostUpgradeCommands: ['^echo {{{versioning}}}$'], allowPostUpgradeCommandTemplating: false, - trustLevel: 'high', + exposeAllEnv: true, }; setAdminConfig(adminConfig); const result = await branchWorker.processBranch({ @@ -965,7 +965,7 @@ describe(getName(__filename), () => { const adminConfig = { allowedPostUpgradeCommands: ['^echo {{{depName}}}$'], allowPostUpgradeCommandTemplating: true, - trustLevel: 'high', + exposeAllEnv: true, }; setAdminConfig(adminConfig); From 13bbc5d6a2847dd147ac6f8a3f79c44adcc75643 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 21 Apr 2021 09:04:47 +0200 Subject: [PATCH 11/52] feat(config): remove manager additionalBranchPrefix defaults (#9373) Resets any language or manager` additionalBranchPrefix` values to empty string. Add the `compatibility:additionalBranchPrefix` prefix to restore previous behavior. BREAKING CHANGE: Removal of default `additionalBranchPrefix` values will cause branch names to change for docker/helm/buildkite/cargo/homebrew. --- docs/usage/configuration-options.md | 2 +- docs/usage/configuration-templates.md | 3 +-- lib/config/presets/index.ts | 1 + lib/config/presets/internal/compatibility.ts | 24 ++++++++++++++++++++ lib/config/presets/internal/index.ts | 2 ++ lib/datasource/docker/index.ts | 1 - lib/datasource/helm/index.ts | 1 - lib/manager/buildkite/index.ts | 1 - lib/manager/cargo/index.ts | 1 - lib/manager/homebrew/index.ts | 1 - lib/workers/repository/updates/flatten.ts | 9 -------- 11 files changed, 29 insertions(+), 17 deletions(-) create mode 100644 lib/config/presets/internal/compatibility.ts diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index 522eb4fe24a59d..b82cf05f174de7 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -69,7 +69,7 @@ With the above config: ## additionalBranchPrefix This value defaults to an empty string, and is typically not necessary. -Some managers populate this field for historical reasons, for example we use `docker-` for Docker branches, so they may look like `renovate/docker-ubuntu-16.x`. +Some managers previously populated this field, but they no longer do so by default. You normally don't need to configure this, but one example where it can be useful is combining with `parentDir` in monorepos to split PRs based on where the package definition is located, e.g. ```json diff --git a/docs/usage/configuration-templates.md b/docs/usage/configuration-templates.md index 10911f76f2857f..c239ac69fe898a 100644 --- a/docs/usage/configuration-templates.md +++ b/docs/usage/configuration-templates.md @@ -21,8 +21,7 @@ Most users will be happy with the default `branchPrefix` of `renovate/`, but you Say you don't want the forward slashes, in that case you would use `renovate-` as your `branchPrefix`. The onboarding PR will always use `renovate/configure`. -`additionalBranchPrefix` is optional and by default is empty for all JavaScript dependencies. -We use `docker-` for all Docker updates, branches will look like this: `renovate/docker-ubuntu-16.x`. +`additionalBranchPrefix` is optional and by default is empty. `branchTopic` depends on the package manager and upgrade type, so you will see a lot of variety. This is probably a setting you want to change yourself. diff --git a/lib/config/presets/index.ts b/lib/config/presets/index.ts index 356d47782ecccd..7e71fc68e1716f 100644 --- a/lib/config/presets/index.ts +++ b/lib/config/presets/index.ts @@ -100,6 +100,7 @@ export function parsePreset(input: string): ParsedPreset { str = str.slice(0, str.indexOf('(')); } const presetsPackages = [ + 'compatibility', 'config', 'default', 'docker', diff --git a/lib/config/presets/internal/compatibility.ts b/lib/config/presets/internal/compatibility.ts new file mode 100644 index 00000000000000..ce1175f569fb34 --- /dev/null +++ b/lib/config/presets/internal/compatibility.ts @@ -0,0 +1,24 @@ +import { Preset } from '../types'; + +export const presets: Record = { + additionalBranchPrefix: { + buildkite: { + additionalBranchPrefix: 'buildkite-', + }, + cargo: { + additionalBranchPrefix: 'rust-', + }, + docker: { + additionalBranchPrefix: 'docker-', + }, + homebrew: { + additionalBranchPrefix: 'homebrew-', + }, + packageRules: [ + { + matchDatasources: ['helm'], + additionalBranchPrefix: 'helm-', + }, + ], + }, +}; diff --git a/lib/config/presets/internal/index.ts b/lib/config/presets/internal/index.ts index fbbdd6a790ede3..e152b9747e19d7 100644 --- a/lib/config/presets/internal/index.ts +++ b/lib/config/presets/internal/index.ts @@ -1,4 +1,5 @@ import type { Preset, PresetConfig } from '../types'; +import * as compatibilityPreset from './compatibility'; import * as configPreset from './config'; import * as defaultPreset from './default'; import * as dockerPreset from './docker'; @@ -13,6 +14,7 @@ import * as schedulePreset from './schedule'; import * as workaroundsPreset from './workarounds'; export const groups: Record> = { + compatibility: compatibilityPreset.presets, config: configPreset.presets, default: defaultPreset.presets, docker: dockerPreset.presets, diff --git a/lib/datasource/docker/index.ts b/lib/datasource/docker/index.ts index 7cc5bc301f6c01..cbc83ef5c5a81c 100644 --- a/lib/datasource/docker/index.ts +++ b/lib/datasource/docker/index.ts @@ -26,7 +26,6 @@ export const defaultVersioning = dockerVersioning.id; export const registryStrategy = 'first'; export const defaultConfig = { - additionalBranchPrefix: 'docker-', commitMessageTopic: '{{{depName}}} Docker tag', major: { enabled: false }, commitMessageExtra: diff --git a/lib/datasource/helm/index.ts b/lib/datasource/helm/index.ts index ea1105841ac2d0..af28e7caee5fbe 100644 --- a/lib/datasource/helm/index.ts +++ b/lib/datasource/helm/index.ts @@ -17,7 +17,6 @@ export const defaultRegistryUrls = ['https://charts.helm.sh/stable']; export const registryStrategy = 'first'; export const defaultConfig = { - additionalBranchPrefix: 'helm-', commitMessageTopic: 'Helm release {{depName}}', group: { commitMessageTopic: '{{{groupName}}} Helm releases', diff --git a/lib/manager/buildkite/index.ts b/lib/manager/buildkite/index.ts index a97b1018ed28c4..d678d7fd3c206d 100644 --- a/lib/manager/buildkite/index.ts +++ b/lib/manager/buildkite/index.ts @@ -7,5 +7,4 @@ export const defaultConfig = { commitMessageTopic: 'buildkite plugin {{depName}}', commitMessageExtra: 'to {{#if isMajor}}v{{{newMajor}}}{{else}}{{{newValue}}}{{/if}}', - additionalBranchPrefix: 'buildkite-', }; diff --git a/lib/manager/cargo/index.ts b/lib/manager/cargo/index.ts index e18f8527d5244c..e91db57470e3be 100644 --- a/lib/manager/cargo/index.ts +++ b/lib/manager/cargo/index.ts @@ -10,7 +10,6 @@ export { extractPackageFile, updateArtifacts, language }; export const defaultConfig = { commitMessageTopic: 'Rust crate {{depName}}', - additionalBranchPrefix: 'rust-', fileMatch: ['(^|/)Cargo.toml$'], versioning: cargoVersioning.id, rangeStrategy: 'bump', diff --git a/lib/manager/homebrew/index.ts b/lib/manager/homebrew/index.ts index 62bb3b08a55d92..b45e932cf7f9a7 100644 --- a/lib/manager/homebrew/index.ts +++ b/lib/manager/homebrew/index.ts @@ -3,6 +3,5 @@ export { updateDependency } from './update'; export const defaultConfig = { commitMessageTopic: 'Homebrew Formula {{depName}}', - additionalBranchPrefix: 'homebrew-', fileMatch: ['^Formula/[^/]+[.]rb$'], }; diff --git a/lib/workers/repository/updates/flatten.ts b/lib/workers/repository/updates/flatten.ts index 6261b851c88ca9..7c7ef3008846ab 100644 --- a/lib/workers/repository/updates/flatten.ts +++ b/lib/workers/repository/updates/flatten.ts @@ -4,7 +4,6 @@ import { mergeChildConfig, } from '../../../config'; import type { RenovateConfig } from '../../../config/types'; -import { LANGUAGE_DOCKER } from '../../../constants/languages'; import { getDefaultConfig } from '../../../datasource'; import { get } from '../../../manager'; import { applyPackageRules } from '../../../util/package-rules'; @@ -27,14 +26,6 @@ export function applyUpdateConfig(input: BranchUpgradeConfig): any { .replace(/-+/, '-') .toLowerCase() : undefined; - if ( - updateConfig.language === LANGUAGE_DOCKER && - /(^|\/)node$/.exec(updateConfig.depName) && - updateConfig.depName !== 'calico/node' - ) { - updateConfig.additionalBranchPrefix = ''; - updateConfig.depNameSanitized = 'node'; - } generateBranchName(updateConfig); return updateConfig; } From 0500042d1d0151c416a1c45fa42641ec4f217824 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 21 Apr 2021 09:05:17 +0200 Subject: [PATCH 12/52] feat: updateType=patch (#9393) Changes behavior so that patch updateType is not rewritten to minor by default. Closes #2818 BREAKING CHANGE: patch updates are not considered updateType=minor by default. --- docs/usage/configuration-options.md | 1 - docs/usage/faq.md | 5 +- lib/config/definitions.ts | 3 +- .../lookup/__snapshots__/index.spec.ts.snap | 64 +++++++++---------- .../repository/process/lookup/index.spec.ts | 8 +-- .../repository/process/lookup/update-type.ts | 5 +- 6 files changed, 39 insertions(+), 47 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index b82cf05f174de7..aaf2fd8b912372 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -1517,7 +1517,6 @@ For example to apply a special label for Major updates: ## patch Add to this object if you wish to define rules that apply only to patch updates. -Only applies if `separateMinorPatch` is set to true. ## php diff --git a/docs/usage/faq.md b/docs/usage/faq.md index bcf253b27896bf..5c71756c2c5e31 100644 --- a/docs/usage/faq.md +++ b/docs/usage/faq.md @@ -208,10 +208,7 @@ To learn more read the section below. You can see in the example above that Renovate won't normally open a PR for the `snorgleborf` patch release. -There are 2 ways to tell Renovate to open a separate PR for the patch release: - -- Set `separateMinorPatch` to `true` -- Set `automerge` to the value: `"patch"` +You can tell Renovate to open a separate PR for the patch release by setting `separateMinorPatch` to `true`. In both cases, Renovate will open 3 PRs: diff --git a/lib/config/definitions.ts b/lib/config/definitions.ts index 92b85aadaf02af..7ba77d22b16033 100644 --- a/lib/config/definitions.ts +++ b/lib/config/definitions.ts @@ -1077,8 +1077,7 @@ const options: RenovateOptions[] = [ }, { name: 'patch', - description: - 'Configuration to apply when an update type is patch. Only applies if `separateMinorPatch` is set to true.', + description: 'Configuration to apply when an update type is patch.', stage: 'package', type: 'object', default: {}, diff --git a/lib/workers/repository/process/lookup/__snapshots__/index.spec.ts.snap b/lib/workers/repository/process/lookup/__snapshots__/index.spec.ts.snap index 35d60b78c71ea5..871c729a8f4b3a 100644 --- a/lib/workers/repository/process/lookup/__snapshots__/index.spec.ts.snap +++ b/lib/workers/repository/process/lookup/__snapshots__/index.spec.ts.snap @@ -50,7 +50,7 @@ Array [ "newValue": "==0.9.7", "newVersion": "0.9.7", "releaseTimestamp": "2013-09-04T17:07:22.948Z", - "updateType": "minor", + "updateType": "patch", }, Object { "bucket": "major", @@ -446,30 +446,7 @@ Array [ "newValue": "0.9.7", "newVersion": "0.9.7", "releaseTimestamp": "2013-09-04T17:07:22.948Z", - "updateType": "minor", - }, - Object { - "bucket": "major", - "newMajor": 1, - "newMinor": 4, - "newValue": "1.4.1", - "newVersion": "1.4.1", - "releaseTimestamp": "2015-05-17T04:25:07.299Z", - "updateType": "major", - }, -] -`; - -exports[`workers/repository/process/lookup/index .lookupUpdates() returns minor update if separate patches not configured 1`] = ` -Array [ - Object { - "bucket": "non-major", - "newMajor": 0, - "newMinor": 9, - "newValue": "0.9.7", - "newVersion": "0.9.7", - "releaseTimestamp": "2013-09-04T17:07:22.948Z", - "updateType": "minor", + "updateType": "patch", }, Object { "bucket": "major", @@ -552,6 +529,29 @@ Array [ ] `; +exports[`workers/repository/process/lookup/index .lookupUpdates() returns patch update even if separate patches not configured 1`] = ` +Array [ + Object { + "bucket": "non-major", + "newMajor": 0, + "newMinor": 9, + "newValue": "0.9.7", + "newVersion": "0.9.7", + "releaseTimestamp": "2013-09-04T17:07:22.948Z", + "updateType": "patch", + }, + Object { + "bucket": "major", + "newMajor": 1, + "newMinor": 4, + "newValue": "1.4.1", + "newVersion": "1.4.1", + "releaseTimestamp": "2015-05-17T04:25:07.299Z", + "updateType": "major", + }, +] +`; + exports[`workers/repository/process/lookup/index .lookupUpdates() returns patch update if separateMinorPatch 1`] = ` Array [ Object { @@ -617,7 +617,7 @@ Array [ "newValue": "3.1.0-dev.20180813", "newVersion": "3.1.0-dev.20180813", "releaseTimestamp": "2018-08-13T19:05:14.347Z", - "updateType": "minor", + "updateType": "patch", }, ] `; @@ -631,7 +631,7 @@ Array [ "newValue": "2.5.17-beta.0", "newVersion": "2.5.17-beta.0", "releaseTimestamp": "2018-03-23T23:29:13.819Z", - "updateType": "minor", + "updateType": "patch", }, ] `; @@ -655,7 +655,7 @@ Array [ "newValue": "3.0.1-insiders.20180726", "newVersion": "3.0.1-insiders.20180726", "releaseTimestamp": "2018-07-26T18:20:51.679Z", - "updateType": "minor", + "updateType": "patch", }, ] `; @@ -682,7 +682,7 @@ Array [ "newValue": "3.0.1-insiders.20180726", "newVersion": "3.0.1-insiders.20180726", "releaseTimestamp": "2018-07-26T18:20:51.679Z", - "updateType": "minor", + "updateType": "patch", }, ] `; @@ -696,7 +696,7 @@ Array [ "newValue": "3.0.1", "newVersion": "3.0.1", "releaseTimestamp": "2018-07-30T16:21:13.150Z", - "updateType": "minor", + "updateType": "patch", }, ] `; @@ -723,7 +723,7 @@ Array [ "newValue": "^0.0.35", "newVersion": "0.0.35", "releaseTimestamp": "2017-04-27T16:59:06.479Z", - "updateType": "minor", + "updateType": "patch", }, ] `; @@ -1503,7 +1503,7 @@ Array [ "newValue": "1.0.1", "newVersion": "1.0.1", "releaseTimestamp": "2014-03-11T18:47:17.560Z", - "updateType": "minor", + "updateType": "patch", }, ] `; diff --git a/lib/workers/repository/process/lookup/index.spec.ts b/lib/workers/repository/process/lookup/index.spec.ts index 93413f8a63acdb..1edb6aa299597f 100644 --- a/lib/workers/repository/process/lookup/index.spec.ts +++ b/lib/workers/repository/process/lookup/index.spec.ts @@ -186,7 +186,7 @@ describe(getName(__filename), () => { Error(CONFIG_VALIDATION) ); }); - it('returns minor update if separate patches not configured', async () => { + it('returns patch update even if separate patches not configured', async () => { config.currentValue = '0.9.0'; config.rangeStrategy = 'pin'; config.depName = 'q'; @@ -195,8 +195,8 @@ describe(getName(__filename), () => { const res = await lookup.lookupUpdates(config); expect(res.updates).toMatchSnapshot(); expect(res.updates).toHaveLength(2); - expect(res.updates[0].updateType).not.toEqual('patch'); - expect(res.updates[1].updateType).not.toEqual('patch'); + expect(res.updates[0].updateType).toEqual('patch'); + expect(res.updates[1].updateType).toEqual('major'); }); it('returns minor update if automerging both patch and minor', async () => { config.patch = { @@ -212,7 +212,7 @@ describe(getName(__filename), () => { nock('https://registry.npmjs.org').get('/q').reply(200, qJson); const res = await lookup.lookupUpdates(config); expect(res.updates).toMatchSnapshot(); - expect(res.updates[0].updateType).toEqual('minor'); + expect(res.updates[0].updateType).toEqual('patch'); }); it('returns patch update if separateMinorPatch', async () => { config.separateMinorPatch = true; diff --git a/lib/workers/repository/process/lookup/update-type.ts b/lib/workers/repository/process/lookup/update-type.ts index 956d7b310a88ed..90768a16d11d3f 100644 --- a/lib/workers/repository/process/lookup/update-type.ts +++ b/lib/workers/repository/process/lookup/update-type.ts @@ -19,8 +19,5 @@ export function getUpdateType( if (versioning.getMinor(newVersion) > versioning.getMinor(currentVersion)) { return 'minor'; } - if (config.separateMinorPatch) { - return 'patch'; - } - return 'minor'; + return 'patch'; } From 0f3faff278973082722071052c636d3d4597a5fc Mon Sep 17 00:00:00 2001 From: Sebastian Poxhofer Date: Sun, 4 Apr 2021 14:48:52 +0200 Subject: [PATCH 13/52] feat(terraform): rework dep types (#9116) Improves the `depType` values returned by the terraform manager. Closes #8792 BREAKING CHANGE: Values for extracted `depType` in terraform manager have changed, please see the `terraform` manager readme for details. --- .../__snapshots__/extract.spec.ts.snap | 87 ++++++++++--------- lib/manager/terraform/extract.ts | 7 +- lib/manager/terraform/modules.ts | 6 +- lib/manager/terraform/providers.ts | 2 +- lib/manager/terraform/readme.md | 41 ++++++--- lib/manager/terraform/required-providers.ts | 8 ++ lib/manager/terraform/required-version.ts | 1 + lib/manager/terraform/resources.ts | 5 +- 8 files changed, 98 insertions(+), 59 deletions(-) diff --git a/lib/manager/terraform/__snapshots__/extract.spec.ts.snap b/lib/manager/terraform/__snapshots__/extract.spec.ts.snap index a7c0567b1cf466..1fba3faa42c84d 100644 --- a/lib/manager/terraform/__snapshots__/extract.spec.ts.snap +++ b/lib/manager/terraform/__snapshots__/extract.spec.ts.snap @@ -7,7 +7,7 @@ Object { "currentValue": "1.0.1", "datasource": "helm", "depName": "redis", - "depType": "helm", + "depType": "helm_release", "registryUrls": Array [ "https://charts.helm.sh/stable", ], @@ -15,7 +15,7 @@ Object { Object { "datasource": "helm", "depName": "redis", - "depType": "helm", + "depType": "helm_release", "registryUrls": Array [ "https://charts.helm.sh/stable", ], @@ -23,7 +23,7 @@ Object { Object { "datasource": "helm", "depName": "./charts/example", - "depType": "helm", + "depType": "helm_release", "registryUrls": Array [ undefined, ], @@ -33,7 +33,7 @@ Object { "currentValue": "4.0.1", "datasource": "helm", "depName": undefined, - "depType": "helm", + "depType": "helm_release", "registryUrls": Array [ "https://charts.helm.sh/stable", ], @@ -43,7 +43,7 @@ Object { "currentValue": "5.0.1", "datasource": "helm", "depName": "redis", - "depType": "helm", + "depType": "helm_release", "registryUrls": Array [ "https://charts.helm.sh/stable", ], @@ -52,7 +52,7 @@ Object { "currentValue": "6.0.1", "datasource": "helm", "depName": "redis", - "depType": "helm", + "depType": "helm_release", "registryUrls": Array [ undefined, ], @@ -68,86 +68,86 @@ Object { "currentValue": "v1.0.0", "datasource": "github-tags", "depName": "github.com/hashicorp/example", - "depType": "github", + "depType": "module", "lookupName": "hashicorp/example", }, Object { "currentValue": "next", "datasource": "github-tags", "depName": "github.com/hashicorp/example", - "depType": "github", + "depType": "module", "lookupName": "hashicorp/example", }, Object { "currentValue": "tfmodule_one-v0.0.9", "datasource": "github-tags", "depName": "github.com/githubuser/myrepo", - "depType": "github", + "depType": "module", "lookupName": "githubuser/myrepo", }, Object { "currentValue": "v1.0.0", "datasource": "github-tags", "depName": "github.com/hashicorp/example.2.3", - "depType": "github", + "depType": "module", "lookupName": "hashicorp/example.2.3", }, Object { "currentValue": "v1.0.0", "datasource": "github-tags", "depName": "github.com/hashicorp/example.2.3", - "depType": "github", + "depType": "module", "lookupName": "hashicorp/example.2.3", }, Object { "currentValue": "0.1.0", "datasource": "terraform-module", "depName": "hashicorp/consul/aws", - "depType": "terraform", + "depType": "module", }, Object { "currentValue": "v0.1.0", "datasource": "github-tags", "depName": "github.com/tieto-cem/terraform-aws-ecs-task-definition", - "depType": "github", + "depType": "module", "lookupName": "tieto-cem/terraform-aws-ecs-task-definition", }, Object { "currentValue": "v0.1.0", "datasource": "github-tags", "depName": "github.com/tieto-cem/terraform-aws-ecs-task-definition", - "depType": "github", + "depType": "module", "lookupName": "tieto-cem/terraform-aws-ecs-task-definition", }, Object { "currentValue": "v2.0.0", "datasource": "github-tags", "depName": "github.com/hashicorp/example", - "depType": "github", + "depType": "module", "lookupName": "hashicorp/example", }, Object { "datasource": "terraform-module", "depName": "terraform-aws-modules/security-group/aws", - "depType": "terraform", + "depType": "module", }, Object { "currentValue": "<= 2.4.0", "datasource": "terraform-module", "depName": "terraform-aws-modules/security-group/aws", - "depType": "terraform", + "depType": "module", }, Object { "currentValue": "1.28.3", "datasource": "terraform-module", "depName": "particuleio/addons/kubernetes", - "depType": "terraform", + "depType": "module", }, Object { "currentValue": "~> 1.1.0", "datasource": "terraform-module", "depName": "app.terraform.io/example-corp/k8s-cluster/azurerm", - "depType": "terraform", + "depType": "module", "registryUrls": Array [ "https://app.terraform.io", ], @@ -156,7 +156,7 @@ Object { "currentValue": "~> 1.1", "datasource": "terraform-module", "depName": "app.terraform.io/example-corp/k8s-cluster/azurerm", - "depType": "terraform", + "depType": "module", "registryUrls": Array [ "https://app.terraform.io", ], @@ -165,7 +165,7 @@ Object { "currentValue": "~~ 1.1", "datasource": "terraform-module", "depName": "app.terraform.io/example-corp/k8s-cluster/azurerm", - "depType": "terraform", + "depType": "module", "registryUrls": Array [ "https://app.terraform.io", ], @@ -174,7 +174,7 @@ Object { "currentValue": ">= 1.0.0, <= 2.0.0", "datasource": "terraform-module", "depName": "hashicorp/consul/aws", - "depType": "terraform", + "depType": "module", }, Object { "skipReason": "local", @@ -186,89 +186,90 @@ Object { "currentValue": "1.36.1", "datasource": "terraform-provider", "depName": "azurerm", - "depType": "terraform", + "depType": "provider", }, Object { "currentValue": "=2.4", "datasource": "terraform-provider", "depName": "gitlab", - "depType": "terraform", + "depType": "provider", }, Object { "currentValue": "=1.3", "datasource": "terraform-provider", "depName": "gitlab", - "depType": "terraform", + "depType": "provider", }, Object { "datasource": "terraform-provider", "depName": "helm", - "depType": "terraform", + "depType": "provider", }, Object { "currentValue": "V1.9", "datasource": "terraform-provider", "depName": "newrelic", - "depType": "terraform", + "depType": "provider", }, Object { "currentValue": "v1.0.0", "datasource": "git-tags", "depName": "bitbucket.com/hashicorp/example", - "depType": "gitTags", + "depType": "module", "lookupName": "https://bitbucket.com/hashicorp/example", }, Object { "currentValue": "v1.0.0", "datasource": "git-tags", "depName": "bitbucket.com/hashicorp/example", - "depType": "gitTags", + "depType": "module", "lookupName": "https://bitbucket.com/hashicorp/example", }, Object { "currentValue": "next", "datasource": "git-tags", "depName": "bitbucket.com/hashicorp/example", - "depType": "gitTags", + "depType": "module", "lookupName": "https://bitbucket.com/hashicorp/example", }, Object { "currentValue": "v1.0.1", "datasource": "git-tags", "depName": "bitbucket.com/hashicorp/example", - "depType": "gitTags", + "depType": "module", "lookupName": "https://bitbucket.com/hashicorp/example", }, Object { "currentValue": "v1.0.2", "datasource": "git-tags", "depName": "bitbucket.com/hashicorp/example", - "depType": "gitTags", + "depType": "module", "lookupName": "http://bitbucket.com/hashicorp/example", }, Object { "currentValue": "v1.0.3", "datasource": "git-tags", "depName": "bitbucket.com/hashicorp/example", - "depType": "gitTags", + "depType": "module", "lookupName": "ssh://git@bitbucket.com/hashicorp/example", }, Object { "currentValue": ">= 2.7.0", "datasource": "terraform-provider", "depName": "aws", - "depType": "terraform", + "depType": "required_provider", }, Object { "currentValue": ">= 2.0.0", "datasource": "terraform-provider", "depName": "azurerm", - "depType": "terraform", + "depType": "required_provider", }, Object { "currentValue": ">= 0.13", "datasource": "github-tags", "depName": "hashicorp/terraform", + "depType": "required_version", "extractVersion": "v(?.*)$", "lineNumber": 230, }, @@ -276,7 +277,7 @@ Object { "currentValue": "2.7.2", "datasource": "terraform-provider", "depName": "docker", - "depType": "terraform", + "depType": "required_provider", "registryUrls": Array [ "https://releases.hashicorp.com", ], @@ -285,34 +286,34 @@ Object { "currentValue": "2.7.0", "datasource": "terraform-provider", "depName": "aws", - "depType": "terraform", + "depType": "required_provider", "lookupName": "aws", }, Object { "currentValue": "=2.27.0", "datasource": "terraform-provider", "depName": "azurerm", - "depType": "terraform", + "depType": "required_provider", }, Object { "currentValue": "1.2.4", "datasource": "terraform-provider", "depName": "invalid", - "depType": "terraform", + "depType": "required_provider", "skipReason": "unsupported-url", }, Object { "currentValue": "1.2.4", "datasource": "terraform-provider", "depName": "helm", - "depType": "terraform", + "depType": "required_provider", "lookupName": "hashicorp/helm", }, Object { "currentValue": ">= 1.0", "datasource": "terraform-provider", "depName": "kubernetes", - "depType": "terraform", + "depType": "required_provider", "lookupName": "hashicorp/kubernetes", "registryUrls": Array [ "https://terraform.example.com", @@ -324,6 +325,7 @@ Object { "currentValue": "1.7.8", "datasource": "docker", "depName": "nginx", + "depType": "docker_image", "replaceString": "nginx:1.7.8", }, Object { @@ -332,6 +334,7 @@ Object { Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", "datasource": "docker", + "depType": "docker_image", "replaceString": "\${data.docker_registry_image.ubuntu.name}", "skipReason": "contains-variable", }, @@ -341,6 +344,7 @@ Object { "currentValue": "1.7.8", "datasource": "docker", "depName": "nginx", + "depType": "docker_container", "replaceString": "nginx:1.7.8", }, Object { @@ -352,6 +356,7 @@ Object { "currentValue": "v1", "datasource": "docker", "depName": "repo.mycompany.com:8080/foo-service", + "depType": "docker_service", "replaceString": "repo.mycompany.com:8080/foo-service:v1", }, Object { diff --git a/lib/manager/terraform/extract.ts b/lib/manager/terraform/extract.ts index 4658a80336cbe7..0048bde408dc4a 100644 --- a/lib/manager/terraform/extract.ts +++ b/lib/manager/terraform/extract.ts @@ -5,7 +5,10 @@ import { analyzeTerraformProvider, extractTerraformProvider, } from './providers'; -import { extractTerraformRequiredProviders } from './required-providers'; +import { + analyzeTerraformRequiredProvider, + extractTerraformRequiredProviders, +} from './required-providers'; import { analyseTerraformVersion, extractTerraformRequiredVersion, @@ -98,6 +101,8 @@ export function extractPackageFile(content: string): PackageFile | null { deps.forEach((dep) => { switch (dep.managerData.terraformDependencyType) { case TerraformDependencyTypes.required_providers: + analyzeTerraformRequiredProvider(dep); + break; case TerraformDependencyTypes.provider: analyzeTerraformProvider(dep); break; diff --git a/lib/manager/terraform/modules.ts b/lib/manager/terraform/modules.ts index f3336a1ab7ff09..692c120328e77f 100644 --- a/lib/manager/terraform/modules.ts +++ b/lib/manager/terraform/modules.ts @@ -30,12 +30,12 @@ export function analyseTerraformModule(dep: PackageDependency): void { /* eslint-disable no-param-reassign */ if (githubRefMatch) { dep.lookupName = githubRefMatch.groups.project.replace(/\.git$/, ''); - dep.depType = 'github'; + dep.depType = 'module'; dep.depName = 'github.com/' + dep.lookupName; dep.currentValue = githubRefMatch.groups.tag; dep.datasource = datasourceGithubTags.id; } else if (gitTagsRefMatch) { - dep.depType = 'gitTags'; + dep.depType = 'module'; if (gitTagsRefMatch.groups.path.includes('//')) { logger.debug('Terraform module contains subdirectory'); dep.depName = gitTagsRefMatch.groups.path.split('//')[0]; @@ -56,7 +56,7 @@ export function analyseTerraformModule(dep: PackageDependency): void { if (hostnameMatch) { dep.registryUrls = [`https://${hostnameMatch.groups.hostname}`]; } - dep.depType = 'terraform'; + dep.depType = 'module'; dep.depName = moduleParts.join('/'); dep.datasource = datasourceTerraformModule.id; } diff --git a/lib/manager/terraform/providers.ts b/lib/manager/terraform/providers.ts index 7be0e7653a3889..aa06ad0d73609c 100644 --- a/lib/manager/terraform/providers.ts +++ b/lib/manager/terraform/providers.ts @@ -61,7 +61,7 @@ export function extractTerraformProvider( export function analyzeTerraformProvider(dep: PackageDependency): void { /* eslint-disable no-param-reassign */ - dep.depType = 'terraform'; + dep.depType = 'provider'; dep.depName = dep.managerData.moduleName; dep.datasource = datasourceTerraformProvider.id; diff --git a/lib/manager/terraform/readme.md b/lib/manager/terraform/readme.md index 4dd83219332888..9d3138c89cb327 100644 --- a/lib/manager/terraform/readme.md +++ b/lib/manager/terraform/readme.md @@ -1,21 +1,38 @@ -Currently Terraform support is limited to Terraform registry sources and GitHub sources that include SemVer refs, e.g. like `github.com/hashicorp/example?ref=v1.0.0`. +Currently, Terraform supports renovating the following dependencies, where sub points represent hosting options of the dependencies: -Fixed versions like the following will receive a PR whenever there is a newer version available: +- modules + - GitTags + - GithubTags + - TerraformRegistry ( Public and Private ) +- providers ( deprecated in Terraform 0.13.0 ) + - TerraformRegistry ( Public and Private ) +- required_providers block ( Terraform >= 0.13.0) + - TerraformRegistry ( Public and Private ) +- required_version +- helm_release + - chart repository ( Public and Private ) +- docker\_\* + - Docker registry ( Public and Private ) -``` -module "consul" { - source = "hashicorp/consul/aws" - version = "0.0.5" - servers = 3 -} -``` - -The following _range_ constraints are also supported: +Terraform range constraints are supported: - `>= 1.2.0`: version 1.2.0 or newer - `<= 1.2.0`: version 1.2.0 or older - `~> 1.2.0`: any non-beta version >= 1.2.0 and < 1.3.0, e.g. 1.2.X - `~> 1.2`: any non-beta version >= 1.2.0 and < 2.0.0, e.g. 1.X.Y -- `>= 1.0.0`, <= 2.0.0`: any version between 1.0.0 and 2.0.0 inclusive +- `>= 1.0.0, <= 2.0.0`: any version between 1.0.0 and 2.0.0 inclusive + +For fine-grained control, e.g. to turn off only parts of this manager, there are following `depTypes` provided: + +| resource | depType | +| --------------------------- | :---------------: | +| terraform provider | provider | +| required terraform provider | required_provider | +| required terraform version | required_version | +| terraform module | module | +| helm release | helm_release | +| docker container | docker_container | +| docker image | docker_image | +| docker service | docker_service | If you need to change the versioning format, read the [versioning](https://docs.renovatebot.com/modules/versioning/) documentation to learn more. diff --git a/lib/manager/terraform/required-providers.ts b/lib/manager/terraform/required-providers.ts index 9319737a69c94f..44b1186210c23e 100644 --- a/lib/manager/terraform/required-providers.ts +++ b/lib/manager/terraform/required-providers.ts @@ -1,4 +1,5 @@ import type { PackageDependency } from '../types'; +import { analyzeTerraformProvider } from './providers'; import { ExtractionResult, TerraformDependencyTypes, @@ -72,3 +73,10 @@ export function extractTerraformRequiredProviders( } while (line.trim() !== '}'); return { lineNumber, dependencies: deps }; } + +export function analyzeTerraformRequiredProvider(dep: PackageDependency): void { + /* eslint-disable no-param-reassign */ + analyzeTerraformProvider(dep); + dep.depType = `required_provider`; + /* eslint-enable no-param-reassign */ +} diff --git a/lib/manager/terraform/required-version.ts b/lib/manager/terraform/required-version.ts index f5deb89a8b87fd..c8bb1e4dad6f32 100644 --- a/lib/manager/terraform/required-version.ts +++ b/lib/manager/terraform/required-version.ts @@ -48,6 +48,7 @@ export function extractTerraformRequiredVersion( export function analyseTerraformVersion(dep: PackageDependency): void { /* eslint-disable no-param-reassign */ + dep.depType = 'required_version'; dep.datasource = datasourceGithubTags.id; dep.depName = 'hashicorp/terraform'; dep.extractVersion = 'v(?.*)$'; diff --git a/lib/manager/terraform/resources.ts b/lib/manager/terraform/resources.ts index 62c986261c8806..4937a8e98ef4d6 100644 --- a/lib/manager/terraform/resources.ts +++ b/lib/manager/terraform/resources.ts @@ -73,6 +73,7 @@ export function analyseTerraformResource( case TerraformResourceTypes.docker_container: if (dep.managerData.image) { applyDockerDependency(dep, dep.managerData.image); + dep.depType = 'docker_container'; } else { dep.skipReason = SkipReason.InvalidDependencySpecification; } @@ -81,6 +82,7 @@ export function analyseTerraformResource( case TerraformResourceTypes.docker_image: if (dep.managerData.name) { applyDockerDependency(dep, dep.managerData.name); + dep.depType = 'docker_image'; } else { dep.skipReason = SkipReason.InvalidDependencySpecification; } @@ -89,6 +91,7 @@ export function analyseTerraformResource( case TerraformResourceTypes.docker_service: if (dep.managerData.image) { applyDockerDependency(dep, dep.managerData.image); + dep.depType = 'docker_service'; } else { dep.skipReason = SkipReason.InvalidDependencySpecification; } @@ -100,7 +103,7 @@ export function analyseTerraformResource( } else if (checkIfStringIsPath(dep.managerData.chart)) { dep.skipReason = SkipReason.LocalChart; } - dep.depType = 'helm'; + dep.depType = 'helm_release'; dep.registryUrls = [dep.managerData.repository]; dep.depName = dep.managerData.chart; dep.datasource = datasourceHelm.id; From 4d3cf59838596369e830de58eb7680c8dcd03d3c Mon Sep 17 00:00:00 2001 From: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com> Date: Sun, 4 Apr 2021 14:50:26 +0200 Subject: [PATCH 14/52] docs: improve sentences (#9395) --- docs/usage/self-hosted-configuration.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index 7b2bbd01ad6e75..931d24e8ccc6cc 100644 --- a/docs/usage/self-hosted-configuration.md +++ b/docs/usage/self-hosted-configuration.md @@ -192,10 +192,11 @@ e.g. ## exposeAllEnv -By default, Renovate will only pass a limited set of environment variables to package managers. -Potentially, there could be leaks of confidential data if a script you don't trust enumerates all values in env, so set this to true only if you trust the repositories which the bot runs against. +By default, Renovate only passes a limited set of environment variables to package managers. +Confidential data can be leaked if a malicious script enumerates all environment variables. +Set `exposeAllEnv` to `true` only if you have reviewed (and trust) the repositories which Renovate bot runs against. -Setting this to true will also allow for variable substitution in `.npmrc` files. +Setting this to `true` will also allow for variable substitution in `.npmrc` files. ## force From 6e40baea6a6f8b0c834982bdb609ee5f22519349 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Mon, 5 Apr 2021 17:35:38 +0200 Subject: [PATCH 15/52] docs: outdated remove trustLevel doc references --- docs/usage/configuration-options.md | 1 - docs/usage/self-hosted-configuration.md | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index aaf2fd8b912372..c7b4c91d667881 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -1541,7 +1541,6 @@ If enabled Renovate will pin Docker images by means of their SHA256 digest and n Post-upgrade tasks are commands that are executed by Renovate after a dependency has been updated but before the commit is created. The intention is to run any additional command line tools that would modify existing files or generate new files when a dependency changes. -This is only available on Renovate instances that have a `trustLevel` of 'high'. Each command must match at least one of the patterns defined in `allowedPostUpgradeTasks` in order to be executed. If the list of allowed tasks is empty then no tasks will be executed. diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index 931d24e8ccc6cc..2525f100708a0d 100644 --- a/docs/usage/self-hosted-configuration.md +++ b/docs/usage/self-hosted-configuration.md @@ -60,14 +60,12 @@ npx ng update @angular/core --from=10.0.0 --to=11.0.0 --migrate-only --allow-dir A list of regular expressions that determine which commands in `postUpgradeTasks` are allowed to be executed. If this list is empty then no tasks will be executed. -Also you need to have `"trustLevel": "high"`, otherwise these tasks will be ignored. e.g. ```json { - "allowedPostUpgradeCommands": ["^tslint --fix$", "^tslint --[a-z]+$"], - "trustLevel": "high" + "allowedPostUpgradeCommands": ["^tslint --fix$", "^tslint --[a-z]+$"] } ``` From 59d728b16bbdf8bf1630dceaccef11d629a56d7e Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 21 Apr 2021 17:55:23 +0200 Subject: [PATCH 16/52] refactor: skipInstalls -> artifactUpdateApproach (#9119) Renames skipInstalls to artifactUpdateApproach and changes from boolean to enum. BREAKING CHANGE: skipInstalls has been changed to artifactsUpdateApproach --- docs/usage/self-hosted-configuration.md | 14 +++++----- .../__snapshots__/migration.spec.ts.snap | 2 ++ lib/config/definitions.ts | 9 +++--- lib/config/migration.spec.ts | 2 ++ lib/config/migration.ts | 7 +++++ .../extract/__snapshots__/index.spec.ts.snap | 28 +++++++++---------- lib/manager/npm/extract/index.ts | 24 +++++----------- lib/manager/npm/post-update/lerna.spec.ts | 8 +++--- lib/manager/npm/post-update/lerna.ts | 6 ++-- lib/manager/npm/post-update/npm.spec.ts | 20 ++++++------- lib/manager/npm/post-update/npm.ts | 4 +-- lib/manager/npm/post-update/yarn.ts | 2 +- lib/manager/types.ts | 5 +--- .../__snapshots__/manager-files.spec.ts.snap | 2 +- 14 files changed, 66 insertions(+), 67 deletions(-) diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index 2525f100708a0d..f3567222b3f933 100644 --- a/docs/usage/self-hosted-configuration.md +++ b/docs/usage/self-hosted-configuration.md @@ -28,7 +28,7 @@ module.exports = { In the `renovate.json` file, define the commands and files to be included in the final commit. -The command to install dependencies (`npm ci --ignore-scripts`) is necessary because, by default, the installation of dependencies is skipped (see the `skipInstalls` admin option). +The command to install dependencies (`npm ci --ignore-scripts`) is necessary because, by default, the installation of dependencies is skipped (see the `artifactUpdateApproach` admin option). ```json { @@ -69,6 +69,12 @@ e.g. } ``` +## artifactUpdateApproach + +By default, Renovate will use the most efficient approach to updating package files and lock files, which in most cases skips the need to perform a full module install by the bot. +If this is set to 'deep', then a full install of modules will be done. +This is currently applicable to `npm` and `yarn` only, and automatically set to `deep` when a full install is detected as necessary. + ## autodiscover When you enable `autodiscover`, by default, Renovate will run on _every_ repository that the bot account can access. @@ -377,12 +383,6 @@ It could then be used in a repository config or preset like so: Secret names must start with a upper or lower case character and can contain only characters, digits, or underscores. -## skipInstalls - -By default, Renovate will use the most efficient approach to updating package files and lock files, which in most cases skips the need to perform a full module install by the bot. -If this is set to false, then a full install of modules will be done. -This is currently applicable to `npm` and `lerna`/`npm` only, and only used in cases where bugs in `npm` result in incorrect lock files being updated. - ## token ## username diff --git a/lib/config/__snapshots__/migration.spec.ts.snap b/lib/config/__snapshots__/migration.spec.ts.snap index a9d93e6307f2b3..27d5183112d3f3 100644 --- a/lib/config/__snapshots__/migration.spec.ts.snap +++ b/lib/config/__snapshots__/migration.spec.ts.snap @@ -80,6 +80,7 @@ Object { "additionalBranchPrefix": "{{parentDir}}-", "allowCustomCrateRegistries": true, "allowScripts": true, + "artifactUpdateApproach": "shallow", "autodiscover": true, "automerge": false, "automergeType": "branch", @@ -173,6 +174,7 @@ Object { "versioning": "maven", }, Object { + "artifactUpdateApproach": "deep", "matchDepTypes": Array [ "peerDependencies", ], diff --git a/lib/config/definitions.ts b/lib/config/definitions.ts index 7ba77d22b16033..6db106c11f72c6 100644 --- a/lib/config/definitions.ts +++ b/lib/config/definitions.ts @@ -564,11 +564,12 @@ const options: RenovateOptions[] = [ type: 'boolean', }, { - name: 'skipInstalls', + name: 'artifactUpdateApproach', description: - 'Skip installing modules/dependencies if lock file updating is possible alone.', - type: 'boolean', - default: null, + 'Whether to employ a deep or shallow approach to artifact updating.', + type: 'string', + allowedValues: ['auto', 'deep', 'shallow'], + default: 'auto', admin: true, }, { diff --git a/lib/config/migration.spec.ts b/lib/config/migration.spec.ts index 6f19f5c6cacffe..477b523b2ead92 100644 --- a/lib/config/migration.spec.ts +++ b/lib/config/migration.spec.ts @@ -52,6 +52,7 @@ describe(getName(__filename), () => { binarySource: 'auto', automergeMinor: true, automergePatch: true, + skipInstalls: true, masterIssue: 'true', masterIssueTitle: 'foo', gomodTidy: true, @@ -95,6 +96,7 @@ describe(getName(__filename), () => { ], peerDependencies: { versionStrategy: 'widen', + skipInstalls: false, }, packageRules: [ { diff --git a/lib/config/migration.ts b/lib/config/migration.ts index 32ddd4566b6eaa..982da884faa34c 100644 --- a/lib/config/migration.ts +++ b/lib/config/migration.ts @@ -172,6 +172,13 @@ export function migrateConfig( migratedConfig[key] = val.replace(/{{depNameShort}}/g, '{{depName}}'); } else if (key === 'gitFs') { delete migratedConfig.gitFs; + } else if (key === 'skipInstalls') { + delete migratedConfig.skipInstalls; + if (val) { + migratedConfig.artifactUpdateApproach = 'shallow'; + } else { + migratedConfig.artifactUpdateApproach = 'deep'; + } } else if (key === 'rebaseStalePrs') { delete migratedConfig.rebaseStalePrs; if (!migratedConfig.rebaseWhen) { diff --git a/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap b/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap index e0b886ce2fb95c..3200c3f4e36426 100644 --- a/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap +++ b/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap @@ -15,6 +15,7 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -23,7 +24,6 @@ Object { "packageJsonName": undefined, "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -139,6 +139,7 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": true, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -147,7 +148,6 @@ Object { "packageJsonName": undefined, "packageJsonType": "library", "pnpmShrinkwrap": undefined, - "skipInstalls": false, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -303,6 +303,7 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -311,7 +312,6 @@ Object { "packageJsonName": undefined, "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -353,6 +353,7 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -361,7 +362,6 @@ Object { "packageJsonName": undefined, "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": false, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -414,6 +414,7 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -422,7 +423,6 @@ Object { "packageJsonName": undefined, "packageJsonType": "library", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -469,6 +469,7 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -477,7 +478,6 @@ Object { "packageJsonName": undefined, "packageJsonType": "library", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -606,6 +606,7 @@ Object { "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": "lerna.json", }, "npmLock": undefined, @@ -614,7 +615,6 @@ Object { "packageJsonName": "renovate", "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -743,6 +743,7 @@ Object { "lernaClient": "yarn", "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": "lerna.json", }, "npmLock": undefined, @@ -751,7 +752,6 @@ Object { "packageJsonName": "renovate", "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -880,6 +880,7 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -888,7 +889,6 @@ Object { "packageJsonName": "renovate", "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": "yarn.lock", "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -903,6 +903,7 @@ Object { "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": "lerna.json", }, "npmLock": undefined, @@ -911,7 +912,6 @@ Object { "packageJsonName": "@a/b", "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": Array [ "packages/*", @@ -1042,6 +1042,7 @@ Object { "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": "lerna.json", }, "npmLock": undefined, @@ -1050,7 +1051,6 @@ Object { "packageJsonName": "renovate", "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -1065,6 +1065,7 @@ Object { "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": "lerna.json", }, "npmLock": undefined, @@ -1073,7 +1074,6 @@ Object { "packageJsonName": "@a/b", "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": Array [ "packages/*", @@ -1090,6 +1090,7 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -1098,7 +1099,6 @@ Object { "packageJsonName": "@a/b", "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": Array [ "packages/*", @@ -1229,6 +1229,7 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -1237,7 +1238,6 @@ Object { "packageJsonName": "renovate", "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, diff --git a/lib/manager/npm/extract/index.ts b/lib/manager/npm/extract/index.ts index aacf7d55444bef..727484819f6183 100644 --- a/lib/manager/npm/extract/index.ts +++ b/lib/manager/npm/extract/index.ts @@ -126,7 +126,7 @@ export async function extractPackageFile( let lernaJsonFile: string; let lernaPackages: string[]; let lernaClient: 'yarn' | 'npm'; - let hasFancyRefs = false; + let hasFileRefs = false; let lernaJson: { packages: string[]; npmClient: string; @@ -224,7 +224,6 @@ export async function extractPackageFile( if (dep.currentValue.startsWith('npm:')) { dep.npmPackageAlias = true; - hasFancyRefs = true; const valSplit = dep.currentValue.replace('npm:', '').split('@'); if (valSplit.length === 2) { dep.lookupName = valSplit[0]; @@ -238,7 +237,11 @@ export async function extractPackageFile( } if (dep.currentValue.startsWith('file:')) { dep.skipReason = SkipReason.File; - hasFancyRefs = true; + // https://github.com/npm/cli/issues/1432 + // Explanation: + // - npm install --package-lock-only is buggy for transitive deps in file: references + // - So we set artifactUpdateApproach to false if file: refs are found *and* the user hasn't explicitly set the value already + hasFileRefs = true; return dep; } if (isValid(dep.currentValue)) { @@ -344,19 +347,6 @@ export async function extractPackageFile( return null; } } - let skipInstalls = config.skipInstalls; - if (skipInstalls === null) { - if (hasFancyRefs) { - // https://github.com/npm/cli/issues/1432 - // Explanation: - // - npm install --package-lock-only is buggy for transitive deps in file: and npm: references - // - So we set skipInstalls to false if file: or npm: refs are found *and* the user hasn't explicitly set the value already - logger.debug('Automatically setting skipInstalls to false'); - skipInstalls = false; - } else { - skipInstalls = true; - } - } return { deps, @@ -368,11 +358,11 @@ export async function extractPackageFile( yarnrc, ...lockFiles, managerData: { + hasFileRefs, lernaJsonFile, }, lernaClient, lernaPackages, - skipInstalls, yarnWorkspacesPackages, constraints, }; diff --git a/lib/manager/npm/post-update/lerna.spec.ts b/lib/manager/npm/post-update/lerna.spec.ts index b5a596d671bbc5..7ba6d474d67c37 100644 --- a/lib/manager/npm/post-update/lerna.spec.ts +++ b/lib/manager/npm/post-update/lerna.spec.ts @@ -47,26 +47,26 @@ describe(getName(__filename), () => { }); it('generates package-lock.json files', async () => { const execSnapshots = mockExecAll(exec); - const skipInstalls = true; + const artifactUpdateApproach = 'shallow'; const res = await lernaHelper.generateLockFiles( lernaPkgFile('npm'), 'some-dir', {}, {}, - skipInstalls + artifactUpdateApproach ); expect(res.error).toBe(false); expect(execSnapshots).toMatchSnapshot(); }); it('performs full npm install', async () => { const execSnapshots = mockExecAll(exec); - const skipInstalls = false; + const artifactUpdateApproach = 'deep'; const res = await lernaHelper.generateLockFiles( lernaPkgFile('npm'), 'some-dir', {}, {}, - skipInstalls + artifactUpdateApproach ); expect(res.error).toBe(false); expect(execSnapshots).toMatchSnapshot(); diff --git a/lib/manager/npm/post-update/lerna.ts b/lib/manager/npm/post-update/lerna.ts index 2ce9e38d4a8362..89946ac87a974a 100644 --- a/lib/manager/npm/post-update/lerna.ts +++ b/lib/manager/npm/post-update/lerna.ts @@ -33,7 +33,7 @@ export async function generateLockFiles( cwd: string, config: PostUpdateConfig, env: NodeJS.ProcessEnv, - skipInstalls?: boolean + artifactUpdateApproach?: string ): Promise { const lernaClient = lernaPackageFile.lernaClient; if (!lernaClient) { @@ -52,7 +52,7 @@ export async function generateLockFiles( installYarn += `@${quote(yarnCompatibility)}`; } preCommands.push(installYarn); - if (skipInstalls !== false) { + if (artifactUpdateApproach !== 'deep') { preCommands.push(getOptimizeCommand()); } cmdOptions = '--ignore-scripts --ignore-engines --ignore-platform'; @@ -64,7 +64,7 @@ export async function generateLockFiles( } preCommands.push(installNpm, 'hash -d npm'); cmdOptions = '--ignore-scripts --no-audit'; - if (skipInstalls !== false) { + if (artifactUpdateApproach !== 'deep') { cmdOptions += ' --package-lock-only'; } } else { diff --git a/lib/manager/npm/post-update/npm.spec.ts b/lib/manager/npm/post-update/npm.spec.ts index f235cb63cc2af1..d17d200d5d37c3 100644 --- a/lib/manager/npm/post-update/npm.spec.ts +++ b/lib/manager/npm/post-update/npm.spec.ts @@ -26,7 +26,7 @@ describe('generateLockFile', () => { it('generates lock files', async () => { const execSnapshots = mockExecAll(exec); fs.readFile = jest.fn(() => 'package-lock-contents') as never; - const skipInstalls = true; + const artifactUpdateApproach = 'deep'; const dockerMapDotfiles = true; const postUpdateOptions = ['npmDedupe']; const updates = [ @@ -36,7 +36,7 @@ describe('generateLockFile', () => { 'some-dir', {}, 'package-lock.json', - { dockerMapDotfiles, skipInstalls, postUpdateOptions }, + { dockerMapDotfiles, artifactUpdateApproach, postUpdateOptions }, updates ); expect(fs.readFile).toHaveBeenCalledTimes(1); @@ -47,7 +47,7 @@ describe('generateLockFile', () => { it('performs lock file updates', async () => { const execSnapshots = mockExecAll(exec); fs.readFile = jest.fn(() => 'package-lock-contents') as never; - const skipInstalls = true; + const artifactUpdateApproach = 'shallow'; const updates = [ { depName: 'some-dep', newVersion: '1.0.1', isLockfileUpdate: true }, ]; @@ -55,7 +55,7 @@ describe('generateLockFile', () => { 'some-dir', {}, 'package-lock.json', - { skipInstalls }, + { artifactUpdateApproach }, updates ); expect(fs.readFile).toHaveBeenCalledTimes(1); @@ -68,12 +68,12 @@ describe('generateLockFile', () => { fs.pathExists.mockResolvedValueOnce(true); fs.move = jest.fn(); fs.readFile = jest.fn(() => 'package-lock-contents') as never; - const skipInstalls = true; + const artifactUpdateApproach = 'shallow'; const res = await npmHelper.generateLockFile( 'some-dir', {}, 'npm-shrinkwrap.json', - { skipInstalls } + { artifactUpdateApproach } ); expect(fs.pathExists).toHaveBeenCalledWith( upath.join('some-dir', 'package-lock.json') @@ -97,12 +97,12 @@ describe('generateLockFile', () => { fs.pathExists.mockResolvedValueOnce(false); fs.move = jest.fn(); fs.readFile = jest.fn((_, _1) => 'package-lock-contents') as never; - const skipInstalls = true; + const artifactUpdateApproach = 'shallow'; const res = await npmHelper.generateLockFile( 'some-dir', {}, 'npm-shrinkwrap.json', - { skipInstalls } + { artifactUpdateApproach } ); expect(fs.pathExists).toHaveBeenCalledWith( upath.join('some-dir', 'package-lock.json') @@ -120,13 +120,13 @@ describe('generateLockFile', () => { it('performs full install', async () => { const execSnapshots = mockExecAll(exec); fs.readFile = jest.fn(() => 'package-lock-contents') as never; - const skipInstalls = false; + const artifactUpdateApproach = 'deep'; const binarySource = BinarySource.Global; const res = await npmHelper.generateLockFile( 'some-dir', {}, 'package-lock.json', - { skipInstalls, binarySource } + { artifactUpdateApproach, binarySource } ); expect(fs.readFile).toHaveBeenCalledTimes(1); expect(res.error).toBeUndefined(); diff --git a/lib/manager/npm/post-update/npm.ts b/lib/manager/npm/post-update/npm.ts index a11bce39231f08..305bcfb09917f8 100644 --- a/lib/manager/npm/post-update/npm.ts +++ b/lib/manager/npm/post-update/npm.ts @@ -26,7 +26,7 @@ export async function generateLockFile( upgrades: Upgrade[] = [] ): Promise { logger.debug(`Spawning npm install to create ${cwd}/${filename}`); - const { skipInstalls, postUpdateOptions } = config; + const { artifactUpdateApproach } = config; let lockFile = null; try { @@ -49,7 +49,7 @@ export async function generateLockFile( const preCommands = [installNpm, 'hash -d npm']; const commands = []; let cmdOptions = ''; - if (postUpdateOptions?.includes('npmDedupe') || skipInstalls === false) { + if (artifactUpdateApproach === 'deep') { logger.debug('Performing node_modules install'); cmdOptions += '--ignore-scripts --no-audit'; } else { diff --git a/lib/manager/npm/post-update/yarn.ts b/lib/manager/npm/post-update/yarn.ts index 5e7d4958273365..be153bbee74291 100644 --- a/lib/manager/npm/post-update/yarn.ts +++ b/lib/manager/npm/post-update/yarn.ts @@ -82,7 +82,7 @@ export async function generateLockFile( CI: 'true', }; - if (isYarn1 && config.skipInstalls !== false) { + if (isYarn1 && config.artifactUpdateApproach !== 'deep') { const { offlineMirror, yarnPath } = await checkYarnrc(cwd); if (!offlineMirror) { logger.debug('Updating yarn.lock only - skipping node_modules'); diff --git a/lib/manager/types.ts b/lib/manager/types.ts index 2c167ecc539103..a0e31935fe05eb 100644 --- a/lib/manager/types.ts +++ b/lib/manager/types.ts @@ -25,7 +25,6 @@ export interface ExtractConfig extends ManagerConfig { aliases?: Record; ignoreNpmrcFile?: boolean; yarnrc?: string; - skipInstalls?: boolean; versioning?: string; updateInternalDeps?: boolean; } @@ -100,7 +99,6 @@ export interface PackageFile> packageJsonType?: 'app' | 'library'; packageFileVersion?: string; parent?: string; - skipInstalls?: boolean; yarnrc?: string; yarnWorkspacesPackages?: string[] | string; matchStrings?: string[]; @@ -277,8 +275,7 @@ export interface PostUpdateConfig extends ManagerConfig, Record { cacheDir?: string; updatedPackageFiles?: File[]; postUpdateOptions?: string[]; - skipInstalls?: boolean; - + artifactUpdateApproach?: 'auto' | 'deep' | 'shallow'; platform?: string; upgrades?: Upgrade[]; npmLock?: string; diff --git a/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap b/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap index 7b05cb15e52b9f..917cd12286f155 100644 --- a/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap +++ b/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap @@ -18,6 +18,7 @@ Array [ "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { + "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -27,7 +28,6 @@ Array [ "packageJsonName": undefined, "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": undefined, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, From 13ece707d4ba04a8f62a8c7d84a3d47253b96f26 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Tue, 6 Apr 2021 13:06:40 +0200 Subject: [PATCH 17/52] feat(npm): remove ignoreNpmrcFile support (#9409) Removes support for the ignoreNpmrcFile config option. BREAKING CHANGE: ignoreNpmrcFile is no longer supported. Use an empty string for config.npmrc instead. --- docs/usage/configuration-options.md | 7 ---- .../__snapshots__/migration.spec.ts.snap | 1 + lib/config/definitions.ts | 6 --- lib/config/migration.spec.ts | 1 + lib/config/migration.ts | 3 ++ .../extract/__snapshots__/index.spec.ts.snap | 14 ------- lib/manager/npm/extract/index.spec.ts | 16 +++++++- lib/manager/npm/extract/index.ts | 39 ++++++++----------- lib/manager/npm/post-update/index.ts | 3 -- lib/manager/types.ts | 3 +- .../__snapshots__/manager-files.spec.ts.snap | 1 - lib/workers/repository/init/config.ts | 1 - 12 files changed, 37 insertions(+), 58 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index c7b4c91d667881..b21d513dc1b8a5 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -969,13 +969,6 @@ The above is the same as if you wrote this package rule: } ``` -## ignoreNpmrcFile - -By default, Renovate will look for and use any `.npmrc` file it finds in a repository. -Additionally, it will be read in by `npm` or `yarn` at the time of lock file generation. -Sometimes this causes problems, for example if the file contains placeholder values, so you can configure this to `true` and Renovate will ignore any `.npmrc` files it finds and temporarily remove the file before running `npm install` or `yarn install`. -Renovate will try to configure this to `true` also if you have configured any `npmrc` string within your config file. - ## ignorePaths Using this setting, you can selectively ignore package files that you don't want Renovate autodiscovering. diff --git a/lib/config/__snapshots__/migration.spec.ts.snap b/lib/config/__snapshots__/migration.spec.ts.snap index 27d5183112d3f3..c9c32342a28022 100644 --- a/lib/config/__snapshots__/migration.spec.ts.snap +++ b/lib/config/__snapshots__/migration.spec.ts.snap @@ -125,6 +125,7 @@ Object { "minor": Object { "automerge": true, }, + "npmrc": "", "nvmrc": Object { "packageRules": Array [ Object { diff --git a/lib/config/definitions.ts b/lib/config/definitions.ts index 6db106c11f72c6..bc4584035147ff 100644 --- a/lib/config/definitions.ts +++ b/lib/config/definitions.ts @@ -572,12 +572,6 @@ const options: RenovateOptions[] = [ default: 'auto', admin: true, }, - { - name: 'ignoreNpmrcFile', - description: 'Whether to ignore any .npmrc file found in repository.', - type: 'boolean', - default: false, - }, { name: 'autodiscover', description: 'Autodiscover all repositories.', diff --git a/lib/config/migration.spec.ts b/lib/config/migration.spec.ts index 477b523b2ead92..ba6fff96902167 100644 --- a/lib/config/migration.spec.ts +++ b/lib/config/migration.spec.ts @@ -44,6 +44,7 @@ describe(getName(__filename), () => { onboarding: 'false' as never, multipleMajorPrs: true, gitFs: false, + ignoreNpmrcFile: true, separateMajorReleases: true, separatePatchReleases: true, suppressNotifications: ['lockFileErrors', 'prEditNotification'], diff --git a/lib/config/migration.ts b/lib/config/migration.ts index 982da884faa34c..64cbd52c81ff19 100644 --- a/lib/config/migration.ts +++ b/lib/config/migration.ts @@ -207,6 +207,9 @@ export function migrateConfig( migratedConfig.allowScripts ??= true; migratedConfig.exposeAllEnv ??= true; } + } else if (key === 'ignoreNpmrcFile') { + delete migratedConfig.ignoreNpmrcFile; + migratedConfig.npmrc ||= ''; } else if ( key === 'branchName' && is.string(val) && diff --git a/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap b/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap index 3200c3f4e36426..ec3e8ca7139576 100644 --- a/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap +++ b/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap @@ -11,7 +11,6 @@ Object { "skipReason": "invalid-name", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { @@ -135,7 +134,6 @@ Object { "prettyDepType": "engine", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { @@ -299,7 +297,6 @@ Object { "sourceUrl": "https://github.com/owner/n", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { @@ -349,7 +346,6 @@ Object { "skipReason": "unknown-version", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { @@ -410,7 +406,6 @@ Object { "skipReason": "unknown-volta", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { @@ -465,7 +460,6 @@ Object { "skipReason": "unknown-version", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { @@ -602,7 +596,6 @@ Object { "prettyDepType": "resolutions", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { @@ -739,7 +732,6 @@ Object { "prettyDepType": "resolutions", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": "yarn", "lernaPackages": undefined, "managerData": Object { @@ -876,7 +868,6 @@ Object { "prettyDepType": "resolutions", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { @@ -899,7 +890,6 @@ exports[`manager/npm/extract/index .extractPackageFile() finds complex yarn work Object { "constraints": Object {}, "deps": Array [], - "ignoreNpmrcFile": undefined, "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { @@ -1038,7 +1028,6 @@ Object { "prettyDepType": "resolutions", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { @@ -1061,7 +1050,6 @@ exports[`manager/npm/extract/index .extractPackageFile() finds simple yarn works Object { "constraints": Object {}, "deps": Array [], - "ignoreNpmrcFile": undefined, "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { @@ -1086,7 +1074,6 @@ exports[`manager/npm/extract/index .extractPackageFile() finds simple yarn works Object { "constraints": Object {}, "deps": Array [], - "ignoreNpmrcFile": undefined, "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { @@ -1225,7 +1212,6 @@ Object { "prettyDepType": "resolutions", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { diff --git a/lib/manager/npm/extract/index.spec.ts b/lib/manager/npm/extract/index.spec.ts index fa78521e8218ba..e4d6bac61dc2b0 100644 --- a/lib/manager/npm/extract/index.spec.ts +++ b/lib/manager/npm/extract/index.spec.ts @@ -113,6 +113,20 @@ describe(getName(__filename), () => { ); expect(res.npmrc).toBeDefined(); }); + it('ignores .npmrc when config.npmrc is defined', async () => { + fs.readLocalFile = jest.fn((fileName) => { + if (fileName === '.npmrc') { + return 'some-npmrc\n'; + } + return null; + }); + const res = await npmExtract.extractPackageFile( + input01Content, + 'package.json', + { npmrc: 'some-configured-npmrc' } + ); + expect(res.npmrc).toBeUndefined(); + }); it('finds and discards .npmrc', async () => { fs.readLocalFile = jest.fn((fileName) => { if (fileName === '.npmrc') { @@ -126,7 +140,7 @@ describe(getName(__filename), () => { 'package.json', {} ); - expect(res.npmrc).toBeUndefined(); + expect(res.npmrc).toEqual(''); }); it('finds lerna', async () => { fs.readLocalFile = jest.fn((fileName) => { diff --git a/lib/manager/npm/extract/index.ts b/lib/manager/npm/extract/index.ts index 727484819f6183..cbc04c1596e629 100644 --- a/lib/manager/npm/extract/index.ts +++ b/lib/manager/npm/extract/index.ts @@ -6,11 +6,7 @@ import * as datasourceGithubTags from '../../../datasource/github-tags'; import { id as npmId } from '../../../datasource/npm'; import { logger } from '../../../logger'; import { SkipReason } from '../../../types'; -import { - deleteLocalFile, - getSiblingFileName, - readLocalFile, -} from '../../../util/fs'; +import { getSiblingFileName, readLocalFile } from '../../../util/fs'; import * as nodeVersioning from '../../../versioning/node'; import { isValid, isVersion } from '../../../versioning/npm'; import type { @@ -95,26 +91,24 @@ export async function extractPackageFile( delete lockFiles.shrinkwrapJson; let npmrc: string; - let ignoreNpmrcFile: boolean; const npmrcFileName = getSiblingFileName(fileName, '.npmrc'); - // istanbul ignore if - if (config.ignoreNpmrcFile) { - await deleteLocalFile(npmrcFileName); - } else { - npmrc = await readLocalFile(npmrcFileName, 'utf8'); - if (npmrc?.includes('package-lock')) { - logger.debug('Stripping package-lock setting from npmrc'); - npmrc = npmrc.replace(/(^|\n)package-lock.*?(\n|$)/g, '\n'); - } - if (is.string(npmrc)) { + const npmrcContent = await readLocalFile(npmrcFileName, 'utf8'); + if (is.string(npmrcContent)) { + if (is.string(config.npmrc)) { + logger.debug( + { npmrcFileName }, + 'Repo .npmrc file is ignored due to presence of config.npmrc' + ); + } else { + npmrc = npmrcContent; + if (npmrc?.includes('package-lock')) { + logger.debug('Stripping package-lock setting from .npmrc'); + npmrc = npmrc.replace(/(^|\n)package-lock.*?(\n|$)/g, '\n'); + } if (npmrc.includes('=${') && !getAdminConfig().exposeAllEnv) { - logger.debug('Discarding .npmrc file with variables'); - ignoreNpmrcFile = true; - npmrc = undefined; - await deleteLocalFile(npmrcFileName); + logger.debug('Overriding .npmrc file with variables'); + npmrc = ''; } - } else { - npmrc = undefined; } } const yarnrcFileName = getSiblingFileName(fileName, '.yarnrc'); @@ -354,7 +348,6 @@ export async function extractPackageFile( packageFileVersion, packageJsonType, npmrc, - ignoreNpmrcFile, yarnrc, ...lockFiles, managerData: { diff --git a/lib/manager/npm/post-update/index.ts b/lib/manager/npm/post-update/index.ts index 083272c1612b0f..aa992b653e70e8 100644 --- a/lib/manager/npm/post-update/index.ts +++ b/lib/manager/npm/post-update/index.ts @@ -144,9 +144,6 @@ export async function writeExistingFiles( } catch (err) /* istanbul ignore next */ { logger.warn({ npmrcFilename, err }, 'Error writing .npmrc'); } - } else if (config.ignoreNpmrcFile) { - logger.debug('Removing ignored .npmrc file before artifact generation'); - await remove(npmrcFilename); } if (packageFile.yarnrc) { logger.debug(`Writing .yarnrc to ${basedir}`); diff --git a/lib/manager/types.ts b/lib/manager/types.ts index a0e31935fe05eb..d19073f1ff208b 100644 --- a/lib/manager/types.ts +++ b/lib/manager/types.ts @@ -23,7 +23,7 @@ export interface ExtractConfig extends ManagerConfig { endpoint?: string; gradle?: { timeout?: number }; aliases?: Record; - ignoreNpmrcFile?: boolean; + npmrc?: string; yarnrc?: string; versioning?: string; updateInternalDeps?: boolean; @@ -89,7 +89,6 @@ export interface PackageFile> datasource?: string; registryUrls?: string[]; deps: PackageDependency[]; - ignoreNpmrcFile?: boolean; lernaClient?: string; lernaPackages?: string[]; mavenProps?: Record; diff --git a/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap b/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap index 917cd12286f155..579ce1c3515dc0 100644 --- a/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap +++ b/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap @@ -14,7 +14,6 @@ Array [ "prettyDepType": "dependency", }, ], - "ignoreNpmrcFile": undefined, "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { diff --git a/lib/workers/repository/init/config.ts b/lib/workers/repository/init/config.ts index fb802acef351f8..15a92b1e2f9b1a 100644 --- a/lib/workers/repository/init/config.ts +++ b/lib/workers/repository/init/config.ts @@ -203,7 +203,6 @@ export async function mergeRenovateConfig( 'Ignoring any .npmrc files in repository due to configured npmrc' ); npmApi.setNpmrc(resolvedConfig.npmrc); - resolvedConfig.ignoreNpmrcFile = true; } // istanbul ignore if if (resolvedConfig.hostRules) { From e7b5be9a154eeb5b19b72a4dcd10dcb5a1d951f1 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Tue, 6 Apr 2021 14:20:07 +0200 Subject: [PATCH 18/52] feat(npm): remove ~/.npmrc support (#9400) Drops support for reading `.npmrc` from the bot's home directory. BREAKING CHANGE: Renovate will no longer read from ~/.npmrc. Configure `npmrc` in config instead. --- docs/development/local-development.md | 1 - docs/usage/private-modules.md | 16 +--------------- .../npm/__snapshots__/index.spec.ts.snap | 2 +- lib/datasource/npm/index.spec.ts | 2 +- lib/datasource/npm/npmrc.spec.ts | 2 +- lib/datasource/npm/npmrc.ts | 10 +++++----- 6 files changed, 9 insertions(+), 24 deletions(-) diff --git a/docs/development/local-development.md b/docs/development/local-development.md index 06de394c7a06bf..da8d7ac4678e63 100644 --- a/docs/development/local-development.md +++ b/docs/development/local-development.md @@ -75,7 +75,6 @@ The Renovate project uses the [Yarn](https://github.com/yarnpkg/yarn) package ma To ensure everything is working properly on your end, you must: -1. Make sure you don't have a local `.npmrc` file that overrides npm's default registry 1. Install all dependencies with `yarn install` 1. Make a build with `yarn build`, which should pass with no errors 1. Verify all tests pass and have 100% test coverage, by running `yarn test` diff --git a/docs/usage/private-modules.md b/docs/usage/private-modules.md index 2c8e596f774dc9..de8f6e3a801f4a 100644 --- a/docs/usage/private-modules.md +++ b/docs/usage/private-modules.md @@ -33,8 +33,6 @@ The recommended approaches in order of preference are: **Self-hosted hostRules**: Configure a hostRules entry in the bot's `config.js` with the `hostType`, `hostName` and `token` specified -**Self-hosted .npmrc**: copy an `.npmrc` file to the home dir of the bot. - **Renovate App with private modules from npmjs.org**: Add an encrypted `npmToken` to your Renovate config **Renovate App with a private registry**: Add an unencrypted `npmrc` plus an encrypted `npmToken` in config @@ -66,21 +64,9 @@ module.exports = { **NOTE:** Do not use `NPM_TOKEN` as an environment variable. -### Commit .npmrc file into repository - -One approach that many projects use for private repositories is to simply check in an authenticated `.npmrc` into the repository that is then shared between all developers. -Therefore anyone running `npm install` or `yarn install` from the project root will be automatically authenticated with npm without having to distribute npm logins to every developer and make sure they've run `npm login` first before installing. - -The good news is that this works for Renovate too. -If Renovate detects a `.npmrc` or `.yarnrc` file then it will use it for its install. - -Does not work if using binarySource=docker. -_This method will be deprecated soon_ - ### Add npmrc string to Renovate config -The above solution maybe have a downside that all users of the repository (e.g. developers) will also use any `.npmrc` that is checked into the repository, instead of their own one in `~/.npmrc`. -To avoid this, you can instead add your `.npmrc` authentication line to your Renovate config under the field `npmrc`. e.g. a `renovate.json` might look like this: +You can add an `.npmrc` authentication line to your Renovate config under the field `npmrc`. e.g. a `renovate.json` might look like this: ```json { diff --git a/lib/datasource/npm/__snapshots__/index.spec.ts.snap b/lib/datasource/npm/__snapshots__/index.spec.ts.snap index ac9065cc23dea7..847462a985443d 100644 --- a/lib/datasource/npm/__snapshots__/index.spec.ts.snap +++ b/lib/datasource/npm/__snapshots__/index.spec.ts.snap @@ -522,7 +522,7 @@ Array [ exports[`datasource/npm/index should use default registry if missing from npmrc 1`] = ` Object { "name": "foobar", - "registryUrl": "https://registry.npmjs.org", + "registryUrl": "https://registry.npmjs.org/", "releases": Array [ Object { "releaseTimestamp": "2018-05-06T05:21:53.000Z", diff --git a/lib/datasource/npm/index.spec.ts b/lib/datasource/npm/index.spec.ts index d5091d722de3ad..d398428ebf8c67 100644 --- a/lib/datasource/npm/index.spec.ts +++ b/lib/datasource/npm/index.spec.ts @@ -314,7 +314,7 @@ describe(getName(__filename), () => { setNpmrc(npmrcContent); setNpmrc(npmrcContent); setNpmrc(); - expect(getNpmrc()).toBeNull(); + expect(getNpmrc()).toEqual({}); }); it('should use default registry if missing from npmrc', async () => { diff --git a/lib/datasource/npm/npmrc.spec.ts b/lib/datasource/npm/npmrc.spec.ts index 41fff3d27c3457..ed44bfee821bb1 100644 --- a/lib/datasource/npm/npmrc.spec.ts +++ b/lib/datasource/npm/npmrc.spec.ts @@ -51,6 +51,6 @@ describe(getName(__filename), () => { it('ignores localhost', () => { setNpmrc(`registry=http://localhost`); expect(sanitize.add).toHaveBeenCalledTimes(0); - expect(getNpmrc()).toBeNull(); + expect(getNpmrc()).toEqual({}); }); }); diff --git a/lib/datasource/npm/npmrc.ts b/lib/datasource/npm/npmrc.ts index 3641998d365c9a..b7d700acac3c6a 100644 --- a/lib/datasource/npm/npmrc.ts +++ b/lib/datasource/npm/npmrc.ts @@ -9,8 +9,8 @@ import type { OutgoingHttpHeaders } from '../../util/http/types'; import { maskToken } from '../../util/mask'; import { add } from '../../util/sanitize'; -let npmrc: Record | null = null; -let npmrcRaw: string; +let npmrc: Record = {}; +let npmrcRaw = ''; export type Npmrc = Record; @@ -89,8 +89,8 @@ export function setNpmrc(input?: string): void { } } else if (npmrc) { logger.debug('Resetting npmrc'); - npmrc = null; - npmrcRaw = null; + npmrc = {}; + npmrcRaw = ''; } } @@ -106,7 +106,7 @@ export function resolvePackage(packageName: string): PackageResolution { try { registryUrl = getRegistryUrl(scope, getNpmrc()); } catch (err) { - registryUrl = 'https://registry.npmjs.org'; + registryUrl = 'https://registry.npmjs.org/'; } const packageUrl = url.resolve( registryUrl, From cbf8ea4e550a25cef5b762a1c83059374ca96684 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 21 Apr 2021 09:08:10 +0200 Subject: [PATCH 19/52] feat(config): delay preset resolution until after platform initialization (#9415) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Delay config preset resolution in admin config until after platform initialization. This will enable resolution of private “local>…” presets to work. BREAKING CHANGE: Config presets will be resolved after platform initialization, so from now on platform credentials cannot be placed in presets. --- lib/config/index.ts | 9 ++++----- lib/constants/error-messages.ts | 1 + lib/workers/global/index.ts | 12 ++++++++++++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/lib/config/index.ts b/lib/config/index.ts index a005f9bf1ee8ed..366813c25a0c80 100644 --- a/lib/config/index.ts +++ b/lib/config/index.ts @@ -7,7 +7,6 @@ import * as defaultsParser from './defaults'; import * as definitions from './definitions'; import * as envParser from './env'; import * as fileParser from './file'; -import { resolveConfigPresets } from './presets'; import type { GlobalConfig, ManagerConfig, @@ -47,10 +46,10 @@ export async function parseConfigs( logger.debug('Parsing configs'); // Get configs - const defaultConfig = await resolveConfigPresets(defaultsParser.getConfig()); - const fileConfig = await resolveConfigPresets(fileParser.getConfig(env)); - const cliConfig = await resolveConfigPresets(cliParser.getConfig(argv)); - const envConfig = await resolveConfigPresets(envParser.getConfig(env)); + const defaultConfig = defaultsParser.getConfig(); + const fileConfig = fileParser.getConfig(env); + const cliConfig = cliParser.getConfig(argv); + const envConfig = envParser.getConfig(env); let config: GlobalConfig = mergeChildConfig(fileConfig, envConfig); config = mergeChildConfig(config, cliConfig); diff --git a/lib/constants/error-messages.ts b/lib/constants/error-messages.ts index b032e18fcee8a2..eec1bbff1ecdff 100644 --- a/lib/constants/error-messages.ts +++ b/lib/constants/error-messages.ts @@ -12,6 +12,7 @@ export const PLATFORM_RATE_LIMIT_EXCEEDED = 'rate-limit-exceeded'; // Config Error export const CONFIG_VALIDATION = 'config-validation'; +export const CONFIG_PRESETS_INVALID = 'config-presets-invalid'; export const CONFIG_SECRETS_EXPOSED = 'config-secrets-exposed'; export const CONFIG_SECRETS_INVALID = 'config-secrets-invalid'; diff --git a/lib/workers/global/index.ts b/lib/workers/global/index.ts index 0d7978fb735f75..d7715983fe8c8c 100644 --- a/lib/workers/global/index.ts +++ b/lib/workers/global/index.ts @@ -5,12 +5,14 @@ import { satisfies } from 'semver'; import upath from 'upath'; import * as pkg from '../../../package.json'; import * as configParser from '../../config'; +import { resolveConfigPresets } from '../../config/presets'; import { validateConfigSecrets } from '../../config/secrets'; import type { GlobalConfig, RenovateConfig, RenovateRepository, } from '../../config/types'; +import { CONFIG_PRESETS_INVALID } from '../../constants/error-messages'; import { getProblems, logger, setMeta } from '../../logger'; import { setUtilConfig } from '../../util'; import * as hostRules from '../../util/host-rules'; @@ -70,6 +72,14 @@ function checkEnv(): void { } } +export async function validatePresets(config: GlobalConfig): Promise { + try { + await resolveConfigPresets(config); + } catch (err) /* istanbul ignore next */ { + throw new Error(CONFIG_PRESETS_INVALID); + } +} + export async function start(): Promise { let config: GlobalConfig; try { @@ -78,6 +88,8 @@ export async function start(): Promise { // initialize all submodules config = await globalInitialize(config); + await validatePresets(config); + checkEnv(); // validate secrets. Will throw and abort if invalid From ac7a5c4d93317e9c35274cb7af65ebeac1525a15 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Sat, 10 Apr 2021 06:23:11 +0200 Subject: [PATCH 20/52] feat: drop dockerMapDotFiles (#9417) Drops support for dockerMapDotfiles BREAKING CHANGE: dockerMapDotfiles is no longer supported --- docs/usage/self-hosted-configuration.md | 11 ---- lib/config/definitions.ts | 8 --- .../__snapshots__/lerna.spec.ts.snap | 59 ------------------- lib/manager/npm/post-update/lerna.spec.ts | 16 +---- lib/manager/npm/post-update/lerna.ts | 7 --- lib/manager/npm/post-update/npm.spec.ts | 3 +- lib/manager/npm/post-update/npm.ts | 6 -- lib/manager/npm/post-update/pnpm.spec.ts | 1 - lib/manager/npm/post-update/pnpm.ts | 6 -- lib/manager/npm/post-update/yarn.spec.ts | 2 - lib/manager/npm/post-update/yarn.ts | 6 -- 11 files changed, 2 insertions(+), 123 deletions(-) diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index f3567222b3f933..58a81776bb32bb 100644 --- a/docs/usage/self-hosted-configuration.md +++ b/docs/usage/self-hosted-configuration.md @@ -164,17 +164,6 @@ You would use put this in your configuration file: If you pulled a new `node` image, the final image would be `ghcr.io/renovatebot/node` instead of `docker.io/renovate/node`. -## dockerMapDotfiles - -This is used if you want to map "dotfiles" from your host computer home directory to containers that Renovate creates, e.g. for updating lock files. -Currently applicable to `.npmrc` only. - -```json -{ - "dockerMapDotfiles": true -} -``` - ## dockerUser Override default user and group used by Docker-based binaries. diff --git a/lib/config/definitions.ts b/lib/config/definitions.ts index bc4584035147ff..54f8f9eb9a71df 100644 --- a/lib/config/definitions.ts +++ b/lib/config/definitions.ts @@ -254,14 +254,6 @@ const options: RenovateOptions[] = [ type: 'object', default: false, }, - { - name: 'dockerMapDotfiles', - description: - 'Map relevant home directory dotfiles into containers when binarySource=docker.', - admin: true, - type: 'boolean', - default: false, - }, { name: 'dockerChildPrefix', description: diff --git a/lib/manager/npm/post-update/__snapshots__/lerna.spec.ts.snap b/lib/manager/npm/post-update/__snapshots__/lerna.spec.ts.snap index e8f5d06c35c0a7..4dc615e84774c2 100644 --- a/lib/manager/npm/post-update/__snapshots__/lerna.spec.ts.snap +++ b/lib/manager/npm/post-update/__snapshots__/lerna.spec.ts.snap @@ -236,65 +236,6 @@ Array [ ] `; -exports[`manager/npm/post-update/lerna generateLockFiles() maps dot files 1`] = ` -Array [ - Object { - "cmd": "lerna info || echo \\"Ignoring lerna info failure\\"", - "options": Object { - "cwd": "some-dir", - "encoding": "utf-8", - "env": Object { - "HOME": "/home/user", - "HTTPS_PROXY": "https://example.com", - "HTTP_PROXY": "http://example.com", - "LANG": "en_US.UTF-8", - "LC_ALL": "en_US", - "NO_PROXY": "localhost", - "PATH": "/tmp/path", - }, - "maxBuffer": 10485760, - "timeout": 900000, - }, - }, - Object { - "cmd": "npm install --ignore-scripts --no-audit --package-lock-only", - "options": Object { - "cwd": "some-dir", - "encoding": "utf-8", - "env": Object { - "HOME": "/home/user", - "HTTPS_PROXY": "https://example.com", - "HTTP_PROXY": "http://example.com", - "LANG": "en_US.UTF-8", - "LC_ALL": "en_US", - "NO_PROXY": "localhost", - "PATH": "/tmp/path", - }, - "maxBuffer": 10485760, - "timeout": 900000, - }, - }, - Object { - "cmd": "lerna bootstrap --no-ci --ignore-scripts -- --ignore-scripts --no-audit --package-lock-only", - "options": Object { - "cwd": "some-dir", - "encoding": "utf-8", - "env": Object { - "HOME": "/home/user", - "HTTPS_PROXY": "https://example.com", - "HTTP_PROXY": "http://example.com", - "LANG": "en_US.UTF-8", - "LC_ALL": "en_US", - "NO_PROXY": "localhost", - "PATH": "/tmp/path", - }, - "maxBuffer": 10485760, - "timeout": 900000, - }, - }, -] -`; - exports[`manager/npm/post-update/lerna generateLockFiles() performs full npm install 1`] = ` Array [ Object { diff --git a/lib/manager/npm/post-update/lerna.spec.ts b/lib/manager/npm/post-update/lerna.spec.ts index 7ba6d474d67c37..8e771c6eab2bcc 100644 --- a/lib/manager/npm/post-update/lerna.spec.ts +++ b/lib/manager/npm/post-update/lerna.spec.ts @@ -93,27 +93,13 @@ describe(getName(__filename), () => { expect(res.error).toBe(false); expect(execSnapshots).toMatchSnapshot(); }); - it('maps dot files', async () => { - const execSnapshots = mockExecAll(exec); - const res = await lernaHelper.generateLockFiles( - lernaPkgFile('npm'), - 'some-dir', - { - dockerMapDotfiles: true, - constraints: { npm: '^6.0.0' }, - }, - {} - ); - expect(res.error).toBe(false); - expect(execSnapshots).toMatchSnapshot(); - }); it('allows scripts for trust level high', async () => { const execSnapshots = mockExecAll(exec); setAdminConfig({ allowScripts: true }); const res = await lernaHelper.generateLockFiles( lernaPkgFile('npm'), 'some-dir', - {}, + { constraints: { npm: '^6.0.0' } }, {} ); expect(res.error).toBe(false); diff --git a/lib/manager/npm/post-update/lerna.ts b/lib/manager/npm/post-update/lerna.ts index 89946ac87a974a..e66c779dedba42 100644 --- a/lib/manager/npm/post-update/lerna.ts +++ b/lib/manager/npm/post-update/lerna.ts @@ -1,6 +1,5 @@ import semver, { validRange } from 'semver'; import { quote } from 'shlex'; -import { join } from 'upath'; import { getAdminConfig } from '../../../config/admin'; import { TEMPORARY_ERROR } from '../../../constants/error-messages'; import { logger } from '../../../logger'; @@ -97,12 +96,6 @@ export async function generateLockFiles( execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; } - if (config.dockerMapDotfiles) { - const homeDir = - process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE; - const homeNpmrc = join(homeDir, '.npmrc'); - execOptions.docker.volumes = [[homeNpmrc, '/home/ubuntu/.npmrc']]; - } const lernaVersion = getLernaVersion(lernaPackageFile); logger.debug('Using lerna version ' + lernaVersion); preCommands.push(`npm i -g lerna@${quote(lernaVersion)}`); diff --git a/lib/manager/npm/post-update/npm.spec.ts b/lib/manager/npm/post-update/npm.spec.ts index d17d200d5d37c3..08a02a81165659 100644 --- a/lib/manager/npm/post-update/npm.spec.ts +++ b/lib/manager/npm/post-update/npm.spec.ts @@ -27,7 +27,6 @@ describe('generateLockFile', () => { const execSnapshots = mockExecAll(exec); fs.readFile = jest.fn(() => 'package-lock-contents') as never; const artifactUpdateApproach = 'deep'; - const dockerMapDotfiles = true; const postUpdateOptions = ['npmDedupe']; const updates = [ { depName: 'some-dep', newVersion: '1.0.1', isLockfileUpdate: false }, @@ -36,7 +35,7 @@ describe('generateLockFile', () => { 'some-dir', {}, 'package-lock.json', - { dockerMapDotfiles, artifactUpdateApproach, postUpdateOptions }, + { artifactUpdateApproach, postUpdateOptions }, updates ); expect(fs.readFile).toHaveBeenCalledTimes(1); diff --git a/lib/manager/npm/post-update/npm.ts b/lib/manager/npm/post-update/npm.ts index 305bcfb09917f8..31e78e3c9595a7 100644 --- a/lib/manager/npm/post-update/npm.ts +++ b/lib/manager/npm/post-update/npm.ts @@ -75,12 +75,6 @@ export async function generateLockFile( execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; } - if (config.dockerMapDotfiles) { - const homeDir = - process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE; - const homeNpmrc = join(homeDir, '.npmrc'); - execOptions.docker.volumes = [[homeNpmrc, '/home/ubuntu/.npmrc']]; - } if (!upgrades.every((upgrade) => upgrade.isLockfileUpdate)) { // This command updates the lock file based on package.json diff --git a/lib/manager/npm/post-update/pnpm.spec.ts b/lib/manager/npm/post-update/pnpm.spec.ts index f1146a0d018a09..195690f3d41cf7 100644 --- a/lib/manager/npm/post-update/pnpm.spec.ts +++ b/lib/manager/npm/post-update/pnpm.spec.ts @@ -24,7 +24,6 @@ describe('generateLockFile', () => { env.getChildProcessEnv.mockReturnValue(envMock.basic); }); it('generates lock files', async () => { - config.dockerMapDotfiles = true; const execSnapshots = mockExecAll(exec); fs.readFile = jest.fn(() => 'package-lock-contents') as never; const res = await pnpmHelper.generateLockFile('some-dir', {}, config); diff --git a/lib/manager/npm/post-update/pnpm.ts b/lib/manager/npm/post-update/pnpm.ts index b9842631f96f53..f6a802fc609a01 100644 --- a/lib/manager/npm/post-update/pnpm.ts +++ b/lib/manager/npm/post-update/pnpm.ts @@ -54,12 +54,6 @@ export async function generateLockFile( execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; } - if (config.dockerMapDotfiles) { - const homeDir = - process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE; - const homeNpmrc = join(homeDir, '.npmrc'); - execOptions.docker.volumes = [[homeNpmrc, '/home/ubuntu/.npmrc']]; - } cmd = 'pnpm'; let args = 'install --recursive --lockfile-only'; if (!getAdminConfig().allowScripts || config.ignoreScripts) { diff --git a/lib/manager/npm/post-update/yarn.spec.ts b/lib/manager/npm/post-update/yarn.spec.ts index 0274362190686b..84173a6d8232a8 100644 --- a/lib/manager/npm/post-update/yarn.spec.ts +++ b/lib/manager/npm/post-update/yarn.spec.ts @@ -54,7 +54,6 @@ describe(getName(__filename), () => { ); }); const config = { - dockerMapDotfiles: true, constraints: { yarn: yarnCompatibility, }, @@ -140,7 +139,6 @@ describe(getName(__filename), () => { ); }); const config = { - dockerMapDotfiles: true, constraints: { yarn: yarnCompatibility, }, diff --git a/lib/manager/npm/post-update/yarn.ts b/lib/manager/npm/post-update/yarn.ts index be153bbee74291..d7756d9fc7b64f 100644 --- a/lib/manager/npm/post-update/yarn.ts +++ b/lib/manager/npm/post-update/yarn.ts @@ -125,12 +125,6 @@ export async function generateLockFile( execOptions.extraEnv.NPM_AUTH = env.NPM_AUTH; execOptions.extraEnv.NPM_EMAIL = env.NPM_EMAIL; } - if (config.dockerMapDotfiles) { - const homeDir = - process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE; - const homeNpmrc = join(homeDir, '.npmrc'); - execOptions.docker.volumes = [[homeNpmrc, '/home/ubuntu/.npmrc']]; - } // This command updates the lock file based on package.json commands.push(`yarn install ${cmdOptions}`.trim()); From b22a0355aa36507cf0c5cb7fee021cf5a7fd6db1 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 7 Apr 2021 09:55:22 +0200 Subject: [PATCH 21/52] refactor(config): explicit migration string check --- lib/config/migration.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/config/migration.ts b/lib/config/migration.ts index 64cbd52c81ff19..aa109e44fe7c6d 100644 --- a/lib/config/migration.ts +++ b/lib/config/migration.ts @@ -209,7 +209,9 @@ export function migrateConfig( } } else if (key === 'ignoreNpmrcFile') { delete migratedConfig.ignoreNpmrcFile; - migratedConfig.npmrc ||= ''; + if (!is.string(migratedConfig.npmrc)) { + migratedConfig.npmrc = ''; + } } else if ( key === 'branchName' && is.string(val) && From 3a1980811c335edaaee8814f9b54fd34851a5ee5 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Fri, 9 Apr 2021 16:15:43 +0200 Subject: [PATCH 22/52] feat: group:Nodejs (#9469) Remove hardcoded Node.js rules from docker extract and instead add group:nodeJs to group:recommended BREAKING CHANGE: node images founds in Dockerfiles will no longer have hardcoded commitMessageTopic. Add group:Nodejs or config:base to extends for backwards compatibility. --- lib/config/presets/internal/group.ts | 14 +++++++++++++ .../__snapshots__/extract.spec.ts.snap | 5 ----- .../__snapshots__/extract.spec.ts.snap | 1 - .../__snapshots__/extract.spec.ts.snap | 2 -- .../__snapshots__/extract.spec.ts.snap | 20 ------------------- lib/manager/dockerfile/extract.ts | 8 -------- .../__snapshots__/extract.spec.ts.snap | 1 - .../__snapshots__/extract.spec.ts.snap | 1 - .../__snapshots__/extract.spec.ts.snap | 1 - 9 files changed, 14 insertions(+), 39 deletions(-) diff --git a/lib/config/presets/internal/group.ts b/lib/config/presets/internal/group.ts index edfcd3b643464b..20a4c9a135f8b7 100644 --- a/lib/config/presets/internal/group.ts +++ b/lib/config/presets/internal/group.ts @@ -29,10 +29,24 @@ const staticGroups = { }, ], }, + nodeJs: { + description: + "Group anything that looks like Node.js together so that it's updated together", + packageRules: [ + { + matchDatasources: ['docker'], + matchPackageNames: ['node'], + matchPackagePatterns: ['/node$'], + excludePackageNames: ['calico/node'], + commitMessageTopic: 'Node.js', + }, + ], + }, recommended: { description: 'Use curated list of recommended non-monorepo package groupings', extends: [ + 'group:nodeJs', 'group:allApollographql', 'group:fortawesome', 'group:fusionjs', diff --git a/lib/manager/circleci/__snapshots__/extract.spec.ts.snap b/lib/manager/circleci/__snapshots__/extract.spec.ts.snap index 099414ce7920f5..e6ff11b229c9b1 100644 --- a/lib/manager/circleci/__snapshots__/extract.spec.ts.snap +++ b/lib/manager/circleci/__snapshots__/extract.spec.ts.snap @@ -4,7 +4,6 @@ exports[`manager/circleci/extract extractPackageFile() extracts image without le Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "14.8.0", "datasource": "docker", @@ -20,7 +19,6 @@ exports[`manager/circleci/extract extractPackageFile() extracts multiple image l Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": undefined, "datasource": "docker", @@ -31,7 +29,6 @@ Array [ }, Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "4", "datasource": "docker", @@ -42,7 +39,6 @@ Array [ }, Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "6", "datasource": "docker", @@ -53,7 +49,6 @@ Array [ }, Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "8.9.0", "datasource": "docker", diff --git a/lib/manager/cloudbuild/__snapshots__/extract.spec.ts.snap b/lib/manager/cloudbuild/__snapshots__/extract.spec.ts.snap index ffd3d8a3be8486..6bffda93dcec3e 100644 --- a/lib/manager/cloudbuild/__snapshots__/extract.spec.ts.snap +++ b/lib/manager/cloudbuild/__snapshots__/extract.spec.ts.snap @@ -12,7 +12,6 @@ Array [ }, Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "12", "datasource": "docker", diff --git a/lib/manager/docker-compose/__snapshots__/extract.spec.ts.snap b/lib/manager/docker-compose/__snapshots__/extract.spec.ts.snap index ce8eb2b879c7e3..6867cb5fa55d5f 100644 --- a/lib/manager/docker-compose/__snapshots__/extract.spec.ts.snap +++ b/lib/manager/docker-compose/__snapshots__/extract.spec.ts.snap @@ -12,7 +12,6 @@ Array [ }, Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "10.0.0", "datasource": "docker", @@ -148,7 +147,6 @@ Array [ }, Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "10.0.0", "datasource": "docker", diff --git a/lib/manager/dockerfile/__snapshots__/extract.spec.ts.snap b/lib/manager/dockerfile/__snapshots__/extract.spec.ts.snap index c1ebae9f7b88c3..7b7696e59e5ab1 100644 --- a/lib/manager/dockerfile/__snapshots__/extract.spec.ts.snap +++ b/lib/manager/dockerfile/__snapshots__/extract.spec.ts.snap @@ -4,7 +4,6 @@ exports[`manager/dockerfile/extract extractPackageFile() detects ["stage"] and [ Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "8.15.1-alpine", "datasource": "docker", @@ -123,7 +122,6 @@ exports[`manager/dockerfile/extract extractPackageFile() extracts images on adja Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": "sha256:d743b4141b02fcfb8beb68f92b4cd164f60ee457bf2d053f36785bf86de16b0d", "currentValue": "8.11.3-alpine", "datasource": "docker", @@ -147,7 +145,6 @@ exports[`manager/dockerfile/extract extractPackageFile() extracts multiple FROM Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "6.12.3", "datasource": "docker", @@ -185,7 +182,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles abnormal spacin Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "8.7.0", "datasource": "docker", @@ -214,7 +210,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles comments 1`] = Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": undefined, "datasource": "docker", @@ -229,7 +224,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles custom hosts 1` Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "8", "datasource": "docker", @@ -244,7 +238,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles custom hosts an Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "8-alpine", "datasource": "docker", @@ -259,7 +252,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles custom hosts wi Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "8", "datasource": "docker", @@ -274,7 +266,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles custom hosts wi Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "8", "datasource": "docker", @@ -289,7 +280,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles custom hosts wi Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": undefined, "datasource": "docker", @@ -304,7 +294,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles digest 1`] = ` Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": "sha256:eb85fc5b1198f5e1ec025ea07586bdbbf397e7d82df66c90d7511f533517e063", "currentValue": undefined, "datasource": "docker", @@ -319,7 +308,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles from as 1`] = ` Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "8.9.0-alpine", "datasource": "docker", @@ -334,7 +322,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles naked dep 1`] = Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": undefined, "datasource": "docker", @@ -349,7 +336,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles namespaced imag Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "8", "datasource": "docker", @@ -364,7 +350,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles tag 1`] = ` Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "8.9.0-alpine", "datasource": "docker", @@ -379,7 +364,6 @@ exports[`manager/dockerfile/extract extractPackageFile() handles tag and digest Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": "sha256:eb85fc5b1198f5e1ec025ea07586bdbbf397e7d82df66c90d7511f533517e063", "currentValue": "8.9.0", "datasource": "docker", @@ -409,7 +393,6 @@ exports[`manager/dockerfile/extract extractPackageFile() is case insensitive 1`] Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": undefined, "datasource": "docker", @@ -424,7 +407,6 @@ exports[`manager/dockerfile/extract extractPackageFile() skips index reference C Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "6.12.3", "datasource": "docker", @@ -439,7 +421,6 @@ exports[`manager/dockerfile/extract extractPackageFile() skips named multistage Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "6.12.3", "datasource": "docker", @@ -454,7 +435,6 @@ exports[`manager/dockerfile/extract extractPackageFile() skips named multistage Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "6.12.3", "datasource": "docker", diff --git a/lib/manager/dockerfile/extract.ts b/lib/manager/dockerfile/extract.ts index fae09b1aff9eab..01d9e58af7be95 100644 --- a/lib/manager/dockerfile/extract.ts +++ b/lib/manager/dockerfile/extract.ts @@ -48,14 +48,6 @@ export function getDep( '{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}'; } dep.datasource = datasourceDocker.id; - if ( - dep.depName && - (dep.depName === 'node' || dep.depName.endsWith('/node')) && - dep.depName !== 'calico/node' - ) { - dep.commitMessageTopic = 'Node.js'; - } - if (dep.depName === 'ubuntu') { dep.versioning = ubuntuVersioning.id; } diff --git a/lib/manager/droneci/__snapshots__/extract.spec.ts.snap b/lib/manager/droneci/__snapshots__/extract.spec.ts.snap index 3723edeab59ae7..4d74cfdddd02b0 100644 --- a/lib/manager/droneci/__snapshots__/extract.spec.ts.snap +++ b/lib/manager/droneci/__snapshots__/extract.spec.ts.snap @@ -13,7 +13,6 @@ Array [ }, Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": "sha256:36adc17e9cceab32179d3314da9cb9c737ffb11f0de4e688f407ad6d9ca32201", "currentValue": "10.0.0", "datasource": "docker", diff --git a/lib/manager/github-actions/__snapshots__/extract.spec.ts.snap b/lib/manager/github-actions/__snapshots__/extract.spec.ts.snap index 900449a8c59363..d7d3f17dee9b11 100644 --- a/lib/manager/github-actions/__snapshots__/extract.spec.ts.snap +++ b/lib/manager/github-actions/__snapshots__/extract.spec.ts.snap @@ -67,7 +67,6 @@ Array [ }, Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": "sha256:7b65413af120ec5328077775022c78101f103258a1876ec2f83890bce416e896", "currentValue": "6", "datasource": "docker", diff --git a/lib/manager/gitlabci/__snapshots__/extract.spec.ts.snap b/lib/manager/gitlabci/__snapshots__/extract.spec.ts.snap index 0cb54034e6210a..89a2a0259235a0 100644 --- a/lib/manager/gitlabci/__snapshots__/extract.spec.ts.snap +++ b/lib/manager/gitlabci/__snapshots__/extract.spec.ts.snap @@ -148,7 +148,6 @@ Array [ "deps": Array [ Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "12", "datasource": "docker", From 247fa7b98de098693031497305f32033ef2c2999 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Fri, 9 Apr 2021 17:04:43 +0200 Subject: [PATCH 23/52] feat(docker): enable major updates by default (#9470) Removes default settings which disabled docker major updates by default. BREAKING CHANGE: Major updates for docker will now be enabled by default. --- lib/datasource/docker/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/datasource/docker/index.ts b/lib/datasource/docker/index.ts index cbc83ef5c5a81c..368c8c070b2d9f 100644 --- a/lib/datasource/docker/index.ts +++ b/lib/datasource/docker/index.ts @@ -27,7 +27,6 @@ export const registryStrategy = 'first'; export const defaultConfig = { commitMessageTopic: '{{{depName}}} Docker tag', - major: { enabled: false }, commitMessageExtra: 'to v{{#if isMajor}}{{{newMajor}}}{{else}}{{{newVersion}}}{{/if}}', digest: { From d592239410a59ac08f80ae5e09e7543e81d7499f Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Sat, 10 Apr 2021 06:31:07 +0200 Subject: [PATCH 24/52] chore: update snapshot --- lib/manager/docker-compose/__snapshots__/extract.spec.ts.snap | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/manager/docker-compose/__snapshots__/extract.spec.ts.snap b/lib/manager/docker-compose/__snapshots__/extract.spec.ts.snap index 6867cb5fa55d5f..716a76d5bdd2c3 100644 --- a/lib/manager/docker-compose/__snapshots__/extract.spec.ts.snap +++ b/lib/manager/docker-compose/__snapshots__/extract.spec.ts.snap @@ -79,7 +79,6 @@ Array [ }, Object { "autoReplaceStringTemplate": "{{depName}}{{#if newValue}}:{{newValue}}{{/if}}{{#if newDigest}}@{{newDigest}}{{/if}}", - "commitMessageTopic": "Node.js", "currentDigest": undefined, "currentValue": "10.0.0", "datasource": "docker", From 5e3806f3e220f18f5579d789029b456d8f464114 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Sat, 10 Apr 2021 06:53:58 +0200 Subject: [PATCH 25/52] feat(npm): retain npmrc lines without variables (#9484) Instead of ignoring the entire .npmrc file if it contains environment variables, instead just strip out the necessary lines. BREAKING: .npmrc files with environment variables will no longer be completely ignore - instead only the lines with variables will be stripped. --- lib/manager/npm/extract/index.spec.ts | 6 +++--- lib/manager/npm/extract/index.ts | 10 ++++++++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/manager/npm/extract/index.spec.ts b/lib/manager/npm/extract/index.spec.ts index e4d6bac61dc2b0..beda16f2a1b85c 100644 --- a/lib/manager/npm/extract/index.spec.ts +++ b/lib/manager/npm/extract/index.spec.ts @@ -127,11 +127,11 @@ describe(getName(__filename), () => { ); expect(res.npmrc).toBeUndefined(); }); - it('finds and discards .npmrc', async () => { + it('finds and filters .npmrc with variables', async () => { fs.readLocalFile = jest.fn((fileName) => { if (fileName === '.npmrc') { // eslint-disable-next-line - return '//registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN}\n'; + return 'registry=https://registry.npmjs.org\n//registry.npmjs.org/:_authToken=${NPM_AUTH_TOKEN}\n'; } return null; }); @@ -140,7 +140,7 @@ describe(getName(__filename), () => { 'package.json', {} ); - expect(res.npmrc).toEqual(''); + expect(res.npmrc).toEqual('registry=https://registry.npmjs.org\n'); }); it('finds lerna', async () => { fs.readLocalFile = jest.fn((fileName) => { diff --git a/lib/manager/npm/extract/index.ts b/lib/manager/npm/extract/index.ts index cbc04c1596e629..7d745f386604d9 100644 --- a/lib/manager/npm/extract/index.ts +++ b/lib/manager/npm/extract/index.ts @@ -106,8 +106,14 @@ export async function extractPackageFile( npmrc = npmrc.replace(/(^|\n)package-lock.*?(\n|$)/g, '\n'); } if (npmrc.includes('=${') && !getAdminConfig().exposeAllEnv) { - logger.debug('Overriding .npmrc file with variables'); - npmrc = ''; + logger.debug( + { npmrcFileName }, + 'Stripping .npmrc file of lines with variables' + ); + npmrc = npmrc + .split('\n') + .filter((line) => !line.includes('=${')) + .join('\n'); } } } From 572749a3980ccd952699c1baf6f4303f899921ab Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Wed, 21 Apr 2021 17:53:57 +0200 Subject: [PATCH 26/52] refactor: artifactUpdateApproach -> skipInstalls Roll back the previous refactor. --- docs/usage/self-hosted-configuration.md | 14 +++++----- .../__snapshots__/migration.spec.ts.snap | 2 -- lib/config/definitions.ts | 9 +++--- lib/config/migration.spec.ts | 2 -- lib/config/migration.ts | 7 ----- .../extract/__snapshots__/index.spec.ts.snap | 28 +++++++++---------- lib/manager/npm/extract/index.ts | 19 +++++++++---- lib/manager/npm/post-update/lerna.spec.ts | 8 +++--- lib/manager/npm/post-update/lerna.ts | 6 ++-- lib/manager/npm/post-update/npm.spec.ts | 20 ++++++------- lib/manager/npm/post-update/npm.ts | 4 +-- lib/manager/npm/post-update/yarn.ts | 2 +- lib/manager/types.ts | 5 +++- .../__snapshots__/manager-files.spec.ts.snap | 2 +- 14 files changed, 64 insertions(+), 64 deletions(-) diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index 58a81776bb32bb..86c10c63deae4d 100644 --- a/docs/usage/self-hosted-configuration.md +++ b/docs/usage/self-hosted-configuration.md @@ -28,7 +28,7 @@ module.exports = { In the `renovate.json` file, define the commands and files to be included in the final commit. -The command to install dependencies (`npm ci --ignore-scripts`) is necessary because, by default, the installation of dependencies is skipped (see the `artifactUpdateApproach` admin option). +The command to install dependencies (`npm ci --ignore-scripts`) is necessary because, by default, the installation of dependencies is skipped (see the `skipInstalls` admin option). ```json { @@ -69,12 +69,6 @@ e.g. } ``` -## artifactUpdateApproach - -By default, Renovate will use the most efficient approach to updating package files and lock files, which in most cases skips the need to perform a full module install by the bot. -If this is set to 'deep', then a full install of modules will be done. -This is currently applicable to `npm` and `yarn` only, and automatically set to `deep` when a full install is detected as necessary. - ## autodiscover When you enable `autodiscover`, by default, Renovate will run on _every_ repository that the bot account can access. @@ -372,6 +366,12 @@ It could then be used in a repository config or preset like so: Secret names must start with a upper or lower case character and can contain only characters, digits, or underscores. +## skipInstalls + +By default, Renovate will use the most efficient approach to updating package files and lock files, which in most cases skips the need to perform a full module install by the bot. +If this is set to false, then a full install of modules will be done. +This is currently applicable to `npm` and `lerna`/`npm` only, and only used in cases where bugs in `npm` result in incorrect lock files being updated. + ## token ## username diff --git a/lib/config/__snapshots__/migration.spec.ts.snap b/lib/config/__snapshots__/migration.spec.ts.snap index c9c32342a28022..7713dfac4bc167 100644 --- a/lib/config/__snapshots__/migration.spec.ts.snap +++ b/lib/config/__snapshots__/migration.spec.ts.snap @@ -80,7 +80,6 @@ Object { "additionalBranchPrefix": "{{parentDir}}-", "allowCustomCrateRegistries": true, "allowScripts": true, - "artifactUpdateApproach": "shallow", "autodiscover": true, "automerge": false, "automergeType": "branch", @@ -175,7 +174,6 @@ Object { "versioning": "maven", }, Object { - "artifactUpdateApproach": "deep", "matchDepTypes": Array [ "peerDependencies", ], diff --git a/lib/config/definitions.ts b/lib/config/definitions.ts index 54f8f9eb9a71df..76dcf0d28c0de3 100644 --- a/lib/config/definitions.ts +++ b/lib/config/definitions.ts @@ -556,12 +556,11 @@ const options: RenovateOptions[] = [ type: 'boolean', }, { - name: 'artifactUpdateApproach', + name: 'skipInstalls', description: - 'Whether to employ a deep or shallow approach to artifact updating.', - type: 'string', - allowedValues: ['auto', 'deep', 'shallow'], - default: 'auto', + 'Skip installing modules/dependencies if lock file updating is possible alone.', + type: 'boolean', + default: null, admin: true, }, { diff --git a/lib/config/migration.spec.ts b/lib/config/migration.spec.ts index ba6fff96902167..eb384c3abe331e 100644 --- a/lib/config/migration.spec.ts +++ b/lib/config/migration.spec.ts @@ -53,7 +53,6 @@ describe(getName(__filename), () => { binarySource: 'auto', automergeMinor: true, automergePatch: true, - skipInstalls: true, masterIssue: 'true', masterIssueTitle: 'foo', gomodTidy: true, @@ -97,7 +96,6 @@ describe(getName(__filename), () => { ], peerDependencies: { versionStrategy: 'widen', - skipInstalls: false, }, packageRules: [ { diff --git a/lib/config/migration.ts b/lib/config/migration.ts index aa109e44fe7c6d..559a1d8c1a6a81 100644 --- a/lib/config/migration.ts +++ b/lib/config/migration.ts @@ -172,13 +172,6 @@ export function migrateConfig( migratedConfig[key] = val.replace(/{{depNameShort}}/g, '{{depName}}'); } else if (key === 'gitFs') { delete migratedConfig.gitFs; - } else if (key === 'skipInstalls') { - delete migratedConfig.skipInstalls; - if (val) { - migratedConfig.artifactUpdateApproach = 'shallow'; - } else { - migratedConfig.artifactUpdateApproach = 'deep'; - } } else if (key === 'rebaseStalePrs') { delete migratedConfig.rebaseStalePrs; if (!migratedConfig.rebaseWhen) { diff --git a/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap b/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap index ec3e8ca7139576..4898775c004ac5 100644 --- a/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap +++ b/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap @@ -14,7 +14,6 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -23,6 +22,7 @@ Object { "packageJsonName": undefined, "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -137,7 +137,6 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": true, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -146,6 +145,7 @@ Object { "packageJsonName": undefined, "packageJsonType": "library", "pnpmShrinkwrap": undefined, + "skipInstalls": false, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -300,7 +300,6 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -309,6 +308,7 @@ Object { "packageJsonName": undefined, "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -349,7 +349,6 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -358,6 +357,7 @@ Object { "packageJsonName": undefined, "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -409,7 +409,6 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -418,6 +417,7 @@ Object { "packageJsonName": undefined, "packageJsonType": "library", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -463,7 +463,6 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -472,6 +471,7 @@ Object { "packageJsonName": undefined, "packageJsonType": "library", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -599,7 +599,6 @@ Object { "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": "lerna.json", }, "npmLock": undefined, @@ -608,6 +607,7 @@ Object { "packageJsonName": "renovate", "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -735,7 +735,6 @@ Object { "lernaClient": "yarn", "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": "lerna.json", }, "npmLock": undefined, @@ -744,6 +743,7 @@ Object { "packageJsonName": "renovate", "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -871,7 +871,6 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -880,6 +879,7 @@ Object { "packageJsonName": "renovate", "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": "yarn.lock", "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -893,7 +893,6 @@ Object { "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": "lerna.json", }, "npmLock": undefined, @@ -902,6 +901,7 @@ Object { "packageJsonName": "@a/b", "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": Array [ "packages/*", @@ -1031,7 +1031,6 @@ Object { "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": "lerna.json", }, "npmLock": undefined, @@ -1040,6 +1039,7 @@ Object { "packageJsonName": "renovate", "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, @@ -1053,7 +1053,6 @@ Object { "lernaClient": "npm", "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": "lerna.json", }, "npmLock": undefined, @@ -1062,6 +1061,7 @@ Object { "packageJsonName": "@a/b", "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": Array [ "packages/*", @@ -1077,7 +1077,6 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -1086,6 +1085,7 @@ Object { "packageJsonName": "@a/b", "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": Array [ "packages/*", @@ -1215,7 +1215,6 @@ Object { "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -1224,6 +1223,7 @@ Object { "packageJsonName": "renovate", "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": true, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, diff --git a/lib/manager/npm/extract/index.ts b/lib/manager/npm/extract/index.ts index 7d745f386604d9..c10c120f9a87cd 100644 --- a/lib/manager/npm/extract/index.ts +++ b/lib/manager/npm/extract/index.ts @@ -237,10 +237,6 @@ export async function extractPackageFile( } if (dep.currentValue.startsWith('file:')) { dep.skipReason = SkipReason.File; - // https://github.com/npm/cli/issues/1432 - // Explanation: - // - npm install --package-lock-only is buggy for transitive deps in file: references - // - So we set artifactUpdateApproach to false if file: refs are found *and* the user hasn't explicitly set the value already hasFileRefs = true; return dep; } @@ -347,6 +343,19 @@ export async function extractPackageFile( return null; } } + let skipInstalls = config.skipInstalls; + if (skipInstalls === null) { + if (hasFileRefs) { + // https://github.com/npm/cli/issues/1432 + // Explanation: + // - npm install --package-lock-only is buggy for transitive deps in file: references + // - So we set skipInstalls to false if file: refs are found *and* the user hasn't explicitly set the value already + logger.debug('Automatically setting skipInstalls to false'); + skipInstalls = false; + } else { + skipInstalls = true; + } + } return { deps, @@ -357,11 +366,11 @@ export async function extractPackageFile( yarnrc, ...lockFiles, managerData: { - hasFileRefs, lernaJsonFile, }, lernaClient, lernaPackages, + skipInstalls, yarnWorkspacesPackages, constraints, }; diff --git a/lib/manager/npm/post-update/lerna.spec.ts b/lib/manager/npm/post-update/lerna.spec.ts index 8e771c6eab2bcc..267bef2c31d306 100644 --- a/lib/manager/npm/post-update/lerna.spec.ts +++ b/lib/manager/npm/post-update/lerna.spec.ts @@ -47,26 +47,26 @@ describe(getName(__filename), () => { }); it('generates package-lock.json files', async () => { const execSnapshots = mockExecAll(exec); - const artifactUpdateApproach = 'shallow'; + const skipInstalls = true; const res = await lernaHelper.generateLockFiles( lernaPkgFile('npm'), 'some-dir', {}, {}, - artifactUpdateApproach + skipInstalls ); expect(res.error).toBe(false); expect(execSnapshots).toMatchSnapshot(); }); it('performs full npm install', async () => { const execSnapshots = mockExecAll(exec); - const artifactUpdateApproach = 'deep'; + const skipInstalls = false; const res = await lernaHelper.generateLockFiles( lernaPkgFile('npm'), 'some-dir', {}, {}, - artifactUpdateApproach + skipInstalls ); expect(res.error).toBe(false); expect(execSnapshots).toMatchSnapshot(); diff --git a/lib/manager/npm/post-update/lerna.ts b/lib/manager/npm/post-update/lerna.ts index e66c779dedba42..4cf0bc54750c0c 100644 --- a/lib/manager/npm/post-update/lerna.ts +++ b/lib/manager/npm/post-update/lerna.ts @@ -32,7 +32,7 @@ export async function generateLockFiles( cwd: string, config: PostUpdateConfig, env: NodeJS.ProcessEnv, - artifactUpdateApproach?: string + skipInstalls?: boolean ): Promise { const lernaClient = lernaPackageFile.lernaClient; if (!lernaClient) { @@ -51,7 +51,7 @@ export async function generateLockFiles( installYarn += `@${quote(yarnCompatibility)}`; } preCommands.push(installYarn); - if (artifactUpdateApproach !== 'deep') { + if (skipInstalls !== false) { preCommands.push(getOptimizeCommand()); } cmdOptions = '--ignore-scripts --ignore-engines --ignore-platform'; @@ -63,7 +63,7 @@ export async function generateLockFiles( } preCommands.push(installNpm, 'hash -d npm'); cmdOptions = '--ignore-scripts --no-audit'; - if (artifactUpdateApproach !== 'deep') { + if (skipInstalls !== false) { cmdOptions += ' --package-lock-only'; } } else { diff --git a/lib/manager/npm/post-update/npm.spec.ts b/lib/manager/npm/post-update/npm.spec.ts index 08a02a81165659..b896545b9bde2e 100644 --- a/lib/manager/npm/post-update/npm.spec.ts +++ b/lib/manager/npm/post-update/npm.spec.ts @@ -26,7 +26,7 @@ describe('generateLockFile', () => { it('generates lock files', async () => { const execSnapshots = mockExecAll(exec); fs.readFile = jest.fn(() => 'package-lock-contents') as never; - const artifactUpdateApproach = 'deep'; + const skipInstalls = true; const postUpdateOptions = ['npmDedupe']; const updates = [ { depName: 'some-dep', newVersion: '1.0.1', isLockfileUpdate: false }, @@ -35,7 +35,7 @@ describe('generateLockFile', () => { 'some-dir', {}, 'package-lock.json', - { artifactUpdateApproach, postUpdateOptions }, + { skipInstalls, postUpdateOptions }, updates ); expect(fs.readFile).toHaveBeenCalledTimes(1); @@ -46,7 +46,7 @@ describe('generateLockFile', () => { it('performs lock file updates', async () => { const execSnapshots = mockExecAll(exec); fs.readFile = jest.fn(() => 'package-lock-contents') as never; - const artifactUpdateApproach = 'shallow'; + const skipInstalls = true; const updates = [ { depName: 'some-dep', newVersion: '1.0.1', isLockfileUpdate: true }, ]; @@ -54,7 +54,7 @@ describe('generateLockFile', () => { 'some-dir', {}, 'package-lock.json', - { artifactUpdateApproach }, + { skipInstalls }, updates ); expect(fs.readFile).toHaveBeenCalledTimes(1); @@ -67,12 +67,12 @@ describe('generateLockFile', () => { fs.pathExists.mockResolvedValueOnce(true); fs.move = jest.fn(); fs.readFile = jest.fn(() => 'package-lock-contents') as never; - const artifactUpdateApproach = 'shallow'; + const skipInstalls = true; const res = await npmHelper.generateLockFile( 'some-dir', {}, 'npm-shrinkwrap.json', - { artifactUpdateApproach } + { skipInstalls } ); expect(fs.pathExists).toHaveBeenCalledWith( upath.join('some-dir', 'package-lock.json') @@ -96,12 +96,12 @@ describe('generateLockFile', () => { fs.pathExists.mockResolvedValueOnce(false); fs.move = jest.fn(); fs.readFile = jest.fn((_, _1) => 'package-lock-contents') as never; - const artifactUpdateApproach = 'shallow'; + const skipInstalls = true; const res = await npmHelper.generateLockFile( 'some-dir', {}, 'npm-shrinkwrap.json', - { artifactUpdateApproach } + { skipInstalls } ); expect(fs.pathExists).toHaveBeenCalledWith( upath.join('some-dir', 'package-lock.json') @@ -119,13 +119,13 @@ describe('generateLockFile', () => { it('performs full install', async () => { const execSnapshots = mockExecAll(exec); fs.readFile = jest.fn(() => 'package-lock-contents') as never; - const artifactUpdateApproach = 'deep'; + const skipInstalls = false; const binarySource = BinarySource.Global; const res = await npmHelper.generateLockFile( 'some-dir', {}, 'package-lock.json', - { artifactUpdateApproach, binarySource } + { skipInstalls, binarySource } ); expect(fs.readFile).toHaveBeenCalledTimes(1); expect(res.error).toBeUndefined(); diff --git a/lib/manager/npm/post-update/npm.ts b/lib/manager/npm/post-update/npm.ts index 31e78e3c9595a7..8b28332155c787 100644 --- a/lib/manager/npm/post-update/npm.ts +++ b/lib/manager/npm/post-update/npm.ts @@ -26,7 +26,7 @@ export async function generateLockFile( upgrades: Upgrade[] = [] ): Promise { logger.debug(`Spawning npm install to create ${cwd}/${filename}`); - const { artifactUpdateApproach } = config; + const { skipInstalls, postUpdateOptions } = config; let lockFile = null; try { @@ -49,7 +49,7 @@ export async function generateLockFile( const preCommands = [installNpm, 'hash -d npm']; const commands = []; let cmdOptions = ''; - if (artifactUpdateApproach === 'deep') { + if (postUpdateOptions?.includes('npmDedupe') || skipInstalls === false) { logger.debug('Performing node_modules install'); cmdOptions += '--ignore-scripts --no-audit'; } else { diff --git a/lib/manager/npm/post-update/yarn.ts b/lib/manager/npm/post-update/yarn.ts index d7756d9fc7b64f..f555bcbce78f02 100644 --- a/lib/manager/npm/post-update/yarn.ts +++ b/lib/manager/npm/post-update/yarn.ts @@ -82,7 +82,7 @@ export async function generateLockFile( CI: 'true', }; - if (isYarn1 && config.artifactUpdateApproach !== 'deep') { + if (isYarn1 && config.skipInstalls !== false) { const { offlineMirror, yarnPath } = await checkYarnrc(cwd); if (!offlineMirror) { logger.debug('Updating yarn.lock only - skipping node_modules'); diff --git a/lib/manager/types.ts b/lib/manager/types.ts index d19073f1ff208b..c73d71f4775962 100644 --- a/lib/manager/types.ts +++ b/lib/manager/types.ts @@ -25,6 +25,7 @@ export interface ExtractConfig extends ManagerConfig { aliases?: Record; npmrc?: string; yarnrc?: string; + skipInstalls?: boolean; versioning?: string; updateInternalDeps?: boolean; } @@ -98,6 +99,7 @@ export interface PackageFile> packageJsonType?: 'app' | 'library'; packageFileVersion?: string; parent?: string; + skipInstalls?: boolean; yarnrc?: string; yarnWorkspacesPackages?: string[] | string; matchStrings?: string[]; @@ -274,7 +276,8 @@ export interface PostUpdateConfig extends ManagerConfig, Record { cacheDir?: string; updatedPackageFiles?: File[]; postUpdateOptions?: string[]; - artifactUpdateApproach?: 'auto' | 'deep' | 'shallow'; + skipInstalls?: boolean; + platform?: string; upgrades?: Upgrade[]; npmLock?: string; diff --git a/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap b/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap index 579ce1c3515dc0..52bad56bc98bae 100644 --- a/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap +++ b/lib/workers/repository/extract/__snapshots__/manager-files.spec.ts.snap @@ -17,7 +17,6 @@ Array [ "lernaClient": undefined, "lernaPackages": undefined, "managerData": Object { - "hasFileRefs": false, "lernaJsonFile": undefined, }, "npmLock": undefined, @@ -27,6 +26,7 @@ Array [ "packageJsonName": undefined, "packageJsonType": "app", "pnpmShrinkwrap": undefined, + "skipInstalls": undefined, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, From 6232b654be38e63d78ac97278f372d7daf80836a Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Thu, 22 Apr 2021 07:58:49 +0200 Subject: [PATCH 27/52] chore: revert hasFancyRefs --- .../npm/extract/__snapshots__/index.spec.ts.snap | 2 +- lib/manager/npm/extract/index.ts | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap b/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap index 4898775c004ac5..4d7be39d441995 100644 --- a/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap +++ b/lib/manager/npm/extract/__snapshots__/index.spec.ts.snap @@ -357,7 +357,7 @@ Object { "packageJsonName": undefined, "packageJsonType": "app", "pnpmShrinkwrap": undefined, - "skipInstalls": true, + "skipInstalls": false, "yarnLock": undefined, "yarnWorkspacesPackages": undefined, "yarnrc": undefined, diff --git a/lib/manager/npm/extract/index.ts b/lib/manager/npm/extract/index.ts index c10c120f9a87cd..b6192925fe83f7 100644 --- a/lib/manager/npm/extract/index.ts +++ b/lib/manager/npm/extract/index.ts @@ -126,7 +126,7 @@ export async function extractPackageFile( let lernaJsonFile: string; let lernaPackages: string[]; let lernaClient: 'yarn' | 'npm'; - let hasFileRefs = false; + let hasFancyRefs = false; let lernaJson: { packages: string[]; npmClient: string; @@ -224,6 +224,7 @@ export async function extractPackageFile( if (dep.currentValue.startsWith('npm:')) { dep.npmPackageAlias = true; + hasFancyRefs = true; const valSplit = dep.currentValue.replace('npm:', '').split('@'); if (valSplit.length === 2) { dep.lookupName = valSplit[0]; @@ -237,7 +238,7 @@ export async function extractPackageFile( } if (dep.currentValue.startsWith('file:')) { dep.skipReason = SkipReason.File; - hasFileRefs = true; + hasFancyRefs = true; return dep; } if (isValid(dep.currentValue)) { @@ -345,11 +346,11 @@ export async function extractPackageFile( } let skipInstalls = config.skipInstalls; if (skipInstalls === null) { - if (hasFileRefs) { + if (hasFancyRefs) { // https://github.com/npm/cli/issues/1432 // Explanation: - // - npm install --package-lock-only is buggy for transitive deps in file: references - // - So we set skipInstalls to false if file: refs are found *and* the user hasn't explicitly set the value already + // - npm install --package-lock-only is buggy for transitive deps in file: and npm: references + // - So we set skipInstalls to false if file: or npm: refs are found *and* the user hasn't explicitly set the value already logger.debug('Automatically setting skipInstalls to false'); skipInstalls = false; } else { From 61abc03a2e644e7766c52af394b30c9c311fe5e1 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Thu, 22 Apr 2021 09:16:40 +0200 Subject: [PATCH 28/52] feat(config): validate packageRules matchUpdateTypes combos (#9649) --- .../__snapshots__/validation.spec.ts.snap | 9 ++++++ lib/config/validation.spec.ts | 17 +++++++++++ lib/config/validation.ts | 28 +++++++++++++++++++ 3 files changed, 54 insertions(+) diff --git a/lib/config/__snapshots__/validation.spec.ts.snap b/lib/config/__snapshots__/validation.spec.ts.snap index c13b732365e535..6ae432f8ec8c02 100644 --- a/lib/config/__snapshots__/validation.spec.ts.snap +++ b/lib/config/__snapshots__/validation.spec.ts.snap @@ -164,6 +164,15 @@ Array [ ] `; +exports[`config/validation validateConfig(config) errors if invalid combinations in packageRules 1`] = ` +Array [ + Object { + "message": "packageRules[0]: packageRules cannot combine both matchUpdateTypes and registryUrls. Rule: {\\"matchUpdateTypes\\":[\\"major\\"],\\"registryUrls\\":[\\"https://registry.npmjs.org\\"]}", + "topic": "Configuration Error", + }, +] +`; + exports[`config/validation validateConfig(config) errors if language or manager objects are nested 1`] = ` Array [ Object { diff --git a/lib/config/validation.spec.ts b/lib/config/validation.spec.ts index fe9582f4b37b71..2535fa4318097a 100644 --- a/lib/config/validation.spec.ts +++ b/lib/config/validation.spec.ts @@ -585,5 +585,22 @@ describe(getName(__filename), () => { expect(warnings).toMatchSnapshot(); expect(errors).toHaveLength(0); }); + it('errors if invalid combinations in packageRules', async () => { + const config = { + packageRules: [ + { + matchUpdateTypes: ['major'], + registryUrls: ['https://registry.npmjs.org'], + }, + ], + } as any; + const { warnings, errors } = await configValidation.validateConfig( + config, + true + ); + expect(warnings).toHaveLength(0); + expect(errors).toHaveLength(1); + expect(errors).toMatchSnapshot(); + }); }); }); diff --git a/lib/config/validation.ts b/lib/config/validation.ts index 2fed4ee6a6d85d..fde19e6814dffa 100644 --- a/lib/config/validation.ts +++ b/lib/config/validation.ts @@ -325,6 +325,34 @@ export async function validateConfig( message, }); } + // It's too late to apply any of these options once you already have updates determined + const preLookupOptions = [ + 'extractVersion', + 'followTag', + 'ignoreDeps', + 'ignoreUnstable', + 'rangeStrategy', + 'registryUrls', + 'respectLatest', + 'rollbackPrs', + 'separateMajorMinor', + 'separateMinorPatch', + 'separateMultipleMajor', + 'versioning', + ]; + if (is.nonEmptyArray(resolvedRule.matchUpdateTypes)) { + for (const option of preLookupOptions) { + if (resolvedRule[option] !== undefined) { + const message = `${currentPath}[${subIndex}]: packageRules cannot combine both matchUpdateTypes and ${option}. Rule: ${JSON.stringify( + packageRule + )}`; + errors.push({ + topic: 'Configuration Error', + message, + }); + } + } + } } else { errors.push({ topic: 'Configuration Error', From e0deef3bc24e8e192a2a234b81992ef2b1717ed7 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Thu, 22 Apr 2021 09:55:14 +0200 Subject: [PATCH 29/52] fix: disallow allowedVersions and matchUpdateTypes Closes #9172 --- lib/config/validation.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/config/validation.ts b/lib/config/validation.ts index fde19e6814dffa..abecfb0fcd9418 100644 --- a/lib/config/validation.ts +++ b/lib/config/validation.ts @@ -327,6 +327,7 @@ export async function validateConfig( } // It's too late to apply any of these options once you already have updates determined const preLookupOptions = [ + 'allowedVersions', 'extractVersion', 'followTag', 'ignoreDeps', From 33b9ec86979548d97fe04aea4ab71f74db3e9f77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Mond=C3=A9jar?= Date: Thu, 22 Apr 2021 13:18:16 +0200 Subject: [PATCH 30/52] Add 'setup.cfg' to supported Python PMs (#9679) --- docs/usage/python.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/usage/python.md b/docs/usage/python.md index 50ac4a2d5f43b6..b753e4e990b02b 100644 --- a/docs/usage/python.md +++ b/docs/usage/python.md @@ -9,7 +9,8 @@ Renovate supports the following Python package managers: - `pip` (e.g. `requirements.txt`, `requirements.pip`) files - `pipenv` (e.g. `Pipfile`) -- `setup.py` +- `setup.py` file +- `setup.cfg` file ## Versioning support From ef447c7ab9ef0b4ea47469caf58a72bae15021ce Mon Sep 17 00:00:00 2001 From: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com> Date: Thu, 22 Apr 2021 13:34:37 +0200 Subject: [PATCH 31/52] docs: update supportPolicy table (#9680) --- docs/usage/node.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/usage/node.md b/docs/usage/node.md index b665bfb1fbb384..6ac798e6759952 100644 --- a/docs/usage/node.md +++ b/docs/usage/node.md @@ -30,18 +30,18 @@ When Renovate processes your project's repository it will look for the files lis ## Configuring Support Policy -Renovate supports a [`supportPolicy`](/configuration-options/#supportpolicy) option that can be passed the following values and associated versions (current as of Feb 2021): +Renovate supports a [`supportPolicy`](/configuration-options/#supportpolicy) option that can be passed the following values and associated versions (current as of April 2021): **Default:** `lts` | supportPolicy | versions | description | | ------------- | -------------- | -------------------------------------------------------- | -| all | 10, 12, 14, 15 | All releases that have not passed their end date | -| lts | 10, 12, 14 | All releases classified as LTS, including in maintenance | -| active | 14, 15 | All releases not in maintenance | +| all | 12, 14, 15, 16 | All releases that have not passed their end date | +| lts | 12, 14 | All releases classified as LTS, including in maintenance | +| active | 14, 16 | All releases not in maintenance | | lts_active | 14 | All releases both LTS and active | | lts_latest | 14 | The latest LTS release | -| current | 15 | The latest release from "all" | +| current | 16 | The latest release from "all" | The version numbers associated with each support policy will be updated as new versions of Node.js are released, moved to LTS or maintenance, etc. From 43907c16968f47e80f4e30d6ca3d41163ff2fdb6 Mon Sep 17 00:00:00 2001 From: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com> Date: Thu, 22 Apr 2021 15:45:42 +0200 Subject: [PATCH 32/52] docs: update preset hosting docs (#8591) Co-authored-by: Michael Kriese --- docs/usage/config-presets.md | 80 ++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 39 deletions(-) diff --git a/docs/usage/config-presets.md b/docs/usage/config-presets.md index 33e3ec8ad446b8..29a7962d5ef162 100644 --- a/docs/usage/config-presets.md +++ b/docs/usage/config-presets.md @@ -119,45 +119,6 @@ Parameters must be strings, non-quoted, and separated by commas if there are mor If you find that you are repeating config a lot, you might consider publishing one of these types of parameterised presets yourself. Or if you think your preset would be valuable for others, please contribute a PR to the Renovate repository. -## How to Publish Preset Configs - -If you manage multiple repositories using Renovate and want the same custom config across all or most of them, then you might want to consider publishing your own preset config so that you can "extend" it in every applicable repository. -That way when you want to change your Renovate configuration you can make the change in one location rather than having to copy/paste it to every repository individually. - -Let's say that your username on npm and elsewhere is "fastcore". -In that case, you can choose between publishing your preset config package as `@fastcore/renovate-config` or `renovate-config-fastcore`. -Let's assume you choose `renovate-config-fastcore` as the package name: - -You then need to publish the `renovate-config-fastcore` package where the `package.json` contains the field `renovate-config` and then put your config under the field `default`. -For example: - -```json -{ - "name": "renovate-config-fastcore", - "version": "0.0.1", - ... - "renovate-config": { - "default": { - "extends": ["config:base", "schedule:nonOfficeHours"] - } - } -} -``` - -Then in each of your repositories you can add your Renovate config like: - -```json - "extends": ["fastcore"] -``` - -Any repository including this config will then adopt the rules of the default `library` preset but schedule it on weeknights or weekends. - -Note: if you prefer to publish using the namespace `@fastcore/renovate-config` then you would use the `@` prefix instead: - -```json - "extends": ["@fastcore"] -``` - ## GitHub-hosted Presets It is also possible to host your preset config using just a regular GitHub repository and without needing to publish it to npmjs. @@ -236,3 +197,44 @@ For example the result may be: "extends": ["local>myorgname/.github:renovate-config"] } ``` + +## npm-hosted presets + +Using npm-hosted presets is deprecated, we recommend you do not follow these instructions and instead use a `local` preset. + +If you manage multiple repositories using Renovate and want the same custom config across all or most of them, then you might want to consider publishing your own preset config so that you can "extend" it in every applicable repository. +That way when you want to change your Renovate configuration you can make the change in one location rather than having to copy/paste it to every repository individually. + +Let's say that your username on npm and elsewhere is "fastcore". +In that case, you can choose between publishing your preset config package as `@fastcore/renovate-config` or `renovate-config-fastcore`. +Let's assume you choose `renovate-config-fastcore` as the package name. + +You then need to publish the `renovate-config-fastcore` package where the `package.json` contains the field `renovate-config` and then put your config under the field `default`. +For example: + +```json +{ + "name": "renovate-config-fastcore", + "version": "0.0.1", + ... + "renovate-config": { + "default": { + "extends": ["config:base", "schedule:nonOfficeHours"] + } + } +} +``` + +Then in each of your repositories you can add your Renovate config like: + +```json + "extends": ["fastcore"] +``` + +Any repository including this config will then adopt the rules of the default `library` preset but schedule it on weeknights or weekends. + +Note: if you prefer to publish using the namespace `@fastcore/renovate-config` then you would use the `@` prefix instead: + +```json + "extends": ["@fastcore"] +``` From e0488a3ebbd8ddc5bbe3d1a303ec4cf31ad6cf7f Mon Sep 17 00:00:00 2001 From: Michael Kriese Date: Thu, 22 Apr 2021 16:03:47 +0200 Subject: [PATCH 33/52] fix(worker): wrong no branch delete on dry-run (#9682) --- lib/workers/branch/index.spec.ts | 1 + lib/workers/branch/index.ts | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/workers/branch/index.spec.ts b/lib/workers/branch/index.spec.ts index 73d68242507905..097e78b5490a7e 100644 --- a/lib/workers/branch/index.spec.ts +++ b/lib/workers/branch/index.spec.ts @@ -372,6 +372,7 @@ describe(getName(__filename), () => { await branchWorker.processBranch(config); expect(automerge.tryBranchAutomerge).toHaveBeenCalledTimes(1); expect(prWorker.ensurePr).toHaveBeenCalledTimes(0); + expect(git.deleteBranch).toHaveBeenCalledTimes(0); }); it('returns if branch exists and prCreation set to approval', async () => { getUpdated.getUpdatedPackageFiles.mockResolvedValueOnce({ diff --git a/lib/workers/branch/index.ts b/lib/workers/branch/index.ts index ae25f57494cff1..d5359e2028110a 100644 --- a/lib/workers/branch/index.ts +++ b/lib/workers/branch/index.ts @@ -372,7 +372,11 @@ export async function processBranch( const mergeStatus = await tryBranchAutomerge(config); logger.debug(`mergeStatus=${mergeStatus}`); if (mergeStatus === 'automerged') { - await deleteBranchSilently(config.branchName); + if (getAdminConfig().dryRun) { + logger.info('DRY-RUN: Would delete branch' + config.branchName); + } else { + await deleteBranchSilently(config.branchName); + } logger.debug('Branch is automerged - returning'); return { branchExists: false, result: BranchResult.Automerged }; } From cf460434a052e7bfba9c56a63d2d0a6c8b7083a1 Mon Sep 17 00:00:00 2001 From: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com> Date: Thu, 22 Apr 2021 16:32:12 +0200 Subject: [PATCH 34/52] build: migrate from master branch to main (#8663) --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- .github/auto-cancel-actions.yml | 2 +- .github/contributing.md | 2 +- .github/label-actions.yml | 2 +- .github/prettifier.yml | 2 +- .github/pull_request_template.md | 2 +- .github/workflows/build.yml | 4 ++-- .github/workflows/codeql-analysis.yml | 4 ++-- .github/workflows/ws_scan.yaml | 4 ++-- .releaserc | 2 +- docs/development/design-decisions.md | 2 +- docs/development/local-development.md | 4 ++-- docs/development/triage-guide.md | 2 +- docs/usage/dependency-pinning.md | 2 +- docs/usage/self-hosting.md | 2 +- readme.md | 6 +++--- 16 files changed, 22 insertions(+), 22 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index c0b87e4faac295..b1930fcb1fa3c9 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -37,7 +37,7 @@ Copy/paste any log here, between the starting and ending backticks **Have you created a minimal reproduction repository?** -Please read the [minimal reproductions documentation](https://github.com/renovatebot/renovate/blob/master/docs/development/minimal-reproductions.md) to learn how to make a good minimal reproduction repository. +Please read the [minimal reproductions documentation](https://github.com/renovatebot/renovate/blob/main/docs/development/minimal-reproductions.md) to learn how to make a good minimal reproduction repository. - [ ] I have provided a minimal reproduction repository - [ ] I don't have time for that, but it happens in a public repository I have linked to diff --git a/.github/auto-cancel-actions.yml b/.github/auto-cancel-actions.yml index 901ddfc5ee6c61..cfdd9c1527ce0b 100644 --- a/.github/auto-cancel-actions.yml +++ b/.github/auto-cancel-actions.yml @@ -1,5 +1,5 @@ version: 1 push: branches: - - '!master' + - '!main' pull_request: diff --git a/.github/contributing.md b/.github/contributing.md index ad9f3418782832..2a3f581c9bd126 100644 --- a/.github/contributing.md +++ b/.github/contributing.md @@ -16,7 +16,7 @@ If you've found a **bug** or have a **feature request** then please create an is ## Code If you would like to fix a bug or implement a feature, please fork the repository and create a Pull Request. -More information on getting set up locally can be found in [docs/development/local-development.md](https://github.com/renovatebot/renovate/blob/master/docs/development/local-development.md). +More information on getting set up locally can be found in [docs/development/local-development.md](https://github.com/renovatebot/renovate/blob/main/docs/development/local-development.md). Before you start any Pull Request, it's recommended that you create an issue to discuss first if you have any doubts about requirement or implementation. That way you can be sure that the maintainer(s) agree on what to change and how, and you can hopefully get a quick merge afterwards. diff --git a/.github/label-actions.yml b/.github/label-actions.yml index c1fc61728c79d0..0a9f4560ed87e7 100644 --- a/.github/label-actions.yml +++ b/.github/label-actions.yml @@ -8,7 +8,7 @@ A minimal reproduction helps us with this. - To get started, please read our guide on [minimal reproductions](https://github.com/renovatebot/renovate/blob/master/docs/development/minimal-reproductions.md) to understand what is needed. + To get started, please read our guide on [minimal reproductions](https://github.com/renovatebot/renovate/blob/main/docs/development/minimal-reproductions.md) to understand what is needed. We may close the issue if you have not provided a minimal reproduction within two weeks. diff --git a/.github/prettifier.yml b/.github/prettifier.yml index b947472423e4c3..f05a3bc764aae2 100644 --- a/.github/prettifier.yml +++ b/.github/prettifier.yml @@ -1,4 +1,4 @@ commitMessage: 'Apply prettier formatting fix' excludeBranches: - - master + - main pullsOnly: true diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 119d5e8a2dc122..04df248f5066c7 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -24,7 +24,7 @@ I have verified these changes via: - [ ] No new tests but ran on a real repository, or - [ ] Both unit tests + ran on a real repository - + diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7dccfacde6a1bb..841316ae3ffce8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,7 +3,7 @@ name: build on: push: branches: - - master + - main - v24 workflow_dispatch: @@ -14,7 +14,7 @@ on: env: # Currently no way to detect automatically (#8153) - DEFAULT_BRANCH: master + DEFAULT_BRANCH: main YARN_MODULES_CACHE_KEY: v1 YARN_PACKAGE_CACHE_KEY: v1 YARN_CACHE_FOLDER: .cache/yarn diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e2fed2d20a604b..03e6566f709937 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -2,10 +2,10 @@ name: 'Code scanning - action' on: push: - branches: [master] + branches: [main] pull_request: # The branches below must be a subset of the branches above - branches: [master] + branches: [main] schedule: - cron: '0 13 * * 1' diff --git a/.github/workflows/ws_scan.yaml b/.github/workflows/ws_scan.yaml index d264533f6132b5..b4b6003775ead5 100644 --- a/.github/workflows/ws_scan.yaml +++ b/.github/workflows/ws_scan.yaml @@ -2,7 +2,7 @@ name: whitesource-scan on: push: - branches: [master] + branches: [main] jobs: WS_SCAN: @@ -14,4 +14,4 @@ jobs: run: curl -LJO https://github.com/whitesource/unified-agent-distribution/releases/latest/download/wss-unified-agent.jar - name: Run UA scan - run: java -jar wss-unified-agent.jar -d $GITHUB_WORKSPACE -noConfig true -apiKey ${{ secrets.WS_ORG_TOKEN }} -product W4D -project "Renovate OS - master" -resolveAllDependencies false -npm_resolveDependencies true + run: java -jar wss-unified-agent.jar -d $GITHUB_WORKSPACE -noConfig true -apiKey ${{ secrets.WS_ORG_TOKEN }} -product W4D -project "Renovate OS - main" -resolveAllDependencies false -npm_resolveDependencies true diff --git a/.releaserc b/.releaserc index e6ca1a4e3d47cc..9b2d1fa5f896d6 100644 --- a/.releaserc +++ b/.releaserc @@ -90,7 +90,7 @@ "channel": "v24" }, { - "name": "master" + "name": "main" } ] } diff --git a/docs/development/design-decisions.md b/docs/development/design-decisions.md index 51526ce7d3c3d8..240640799f4f96 100644 --- a/docs/development/design-decisions.md +++ b/docs/development/design-decisions.md @@ -80,7 +80,7 @@ This allows users to close unwelcome upgrade PRs and not worry about them being With the default behavior of one branch per dependency, it's often the case that a PR gets merge conflicts after an adjacent dependency update is merged. Although platforms often have a web interface for simple merge conflicts, this is still annoying to resolve manually. -`renovate` will rebase any unmergeable branches and add the latest necessary commit on top of the most recent `master` commit. +`renovate` will rebase any unmergeable branches and add the latest necessary commit on top of the most recent `main` commit. Note: `renovate` will only do this if the original branch hasn't been modified by anyone else. diff --git a/docs/development/local-development.md b/docs/development/local-development.md index da8d7ac4678e63..75c10b72ea6b2b 100644 --- a/docs/development/local-development.md +++ b/docs/development/local-development.md @@ -149,9 +149,9 @@ You usually don't need to fix any Prettier errors by hand. ## Keeping your Renovate fork up to date -First of all, never commit to the `master` branch of your fork - always use a "feature" branch like `feat/1234-add-yarn-parsing`. +First of all, never commit to the `main` branch of your fork - always use a "feature" branch like `feat/1234-add-yarn-parsing`. -Make sure your fork is up to date with the Renovate `master` branch, check this each time before you create a new branch. +Make sure your fork is up to date with the Renovate `main` branch, check this each time before you create a new branch. To do this, see these GitHub guides: [Configuring a remote for a fork](https://help.github.com/articles/configuring-a-remote-for-a-fork/) diff --git a/docs/development/triage-guide.md b/docs/development/triage-guide.md index 10f42c79bdc8b0..796863a58c4dcb 100644 --- a/docs/development/triage-guide.md +++ b/docs/development/triage-guide.md @@ -26,7 +26,7 @@ Don't be afraid to ask for help. ### Apply labels to issues All issues should have labels attached to them. -Read the [issue-labeling guide](https://github.com/renovatebot/renovate/blob/master/docs/development/issue-labeling.md) to get all the necessary info. +Read the [issue-labeling guide](https://github.com/renovatebot/renovate/blob/main/docs/development/issue-labeling.md) to get all the necessary info. In general try to make a good-faith effort to label things correctly. diff --git a/docs/usage/dependency-pinning.md b/docs/usage/dependency-pinning.md index 5329ab5a7e3a49..909f647984b5d4 100644 --- a/docs/usage/dependency-pinning.md +++ b/docs/usage/dependency-pinning.md @@ -223,6 +223,6 @@ If/when this starts bothering you, add Renovate rules to reduce the volume, such ## References This is a "living" document and we plan to update it whenever we think of something new or someone makes a valid point we've missed or misunderstood. -[GitHub Location](https://github.com/renovatebot/renovate/blob/master/website/docs/dependency-pinning.md) +[GitHub Location](https://github.com/renovatebot/renovate/blob/main/website/docs/dependency-pinning.md) Updated 2018-01-19 after [excellent feedback on lockfiles](https://github.com/commitizen/cz-conventional-changelog-default-export/pull/4#issuecomment-358038966) by [@LinusU](https://github.com/LinusU) diff --git a/docs/usage/self-hosting.md b/docs/usage/self-hosting.md index d17d179c95bc14..199b3c3965debb 100644 --- a/docs/usage/self-hosting.md +++ b/docs/usage/self-hosting.md @@ -20,7 +20,7 @@ The same goes for any other third party binary tool like `gradle` or `poetry` - ### Docker Renovate is available for Docker via an automated build [renovate/renovate](https://hub.docker.com/r/renovate/renovate/). -It builds `latest` based on the `master` branch and all semver tags are published too. +It builds `latest` based on the `main` branch and all semver tags are published too. For example, all the following are valid tags: ```sh diff --git a/readme.md b/readme.md index df5f704c90fedd..dd2f2ecf68b505 100644 --- a/readme.md +++ b/readme.md @@ -5,8 +5,8 @@ Automated dependency updates. Multi-platform and multi-language. -[![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](https://raw.githubusercontent.com/renovatebot/renovate/master/license) -[![codecov](https://codecov.io/gh/renovatebot/renovate/branch/master/graph/badge.svg)](https://codecov.io/gh/renovatebot/renovate) +[![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](https://raw.githubusercontent.com/renovatebot/renovate/main/license) +[![codecov](https://codecov.io/gh/renovatebot/renovate/branch/main/graph/badge.svg)](https://codecov.io/gh/renovatebot/renovate) [![Renovate enabled](https://img.shields.io/badge/renovate-enabled-brightgreen.svg)](https://renovatebot.com/) [![Build status](https://github.com/renovatebot/renovate/workflows/build/badge.svg)](https://github.com/renovatebot/renovate/actions) @@ -65,7 +65,7 @@ If you are not on github.com or gitlab.com, or you prefer to run your own instan - Run the `renovate/renovate` Docker Hub image (same content/versions as the CLI tool), run it on a schedule - Run the `renovate/renovate:slim` Docker Hub image if you only use package managers that don't need third party binaries (e.g. JS, Docker, Nuget, pip) -[More details on the self-hosting development](https://github.com/renovatebot/renovate/blob/master/docs/usage/self-hosting.md). +[More details on the self-hosting development](https://github.com/renovatebot/renovate/blob/main/docs/usage/self-hosting.md). ## Contributing From 8c0f7c12ef76b2e539fd731932f5a15040f51f1d Mon Sep 17 00:00:00 2001 From: Michael Kriese Date: Thu, 22 Apr 2021 17:11:26 +0200 Subject: [PATCH 35/52] fix(npm): repect allowScripts & ignoreScripts (#9684) Co-authored-by: Rhys Arkins --- .../npm/post-update/__snapshots__/npm.spec.ts.snap | 6 +++--- lib/manager/npm/post-update/npm.ts | 9 +++++++-- lib/manager/types.ts | 1 + 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/manager/npm/post-update/__snapshots__/npm.spec.ts.snap b/lib/manager/npm/post-update/__snapshots__/npm.spec.ts.snap index ca01a58982538b..bba9f265872a67 100644 --- a/lib/manager/npm/post-update/__snapshots__/npm.spec.ts.snap +++ b/lib/manager/npm/post-update/__snapshots__/npm.spec.ts.snap @@ -7,7 +7,7 @@ exports[`generateLockFile finds npm globally 1`] = `Array []`; exports[`generateLockFile generates lock files 1`] = ` Array [ Object { - "cmd": "npm install --ignore-scripts --no-audit", + "cmd": "npm install --no-audit --ignore-scripts", "options": Object { "cwd": "some-dir", "encoding": "utf-8", @@ -50,7 +50,7 @@ exports[`generateLockFile performs full install 1`] = `Array []`; exports[`generateLockFile performs lock file maintenance 1`] = ` Array [ Object { - "cmd": "npm install --package-lock-only --ignore-scripts --no-audit", + "cmd": "npm install --package-lock-only --no-audit --ignore-scripts", "options": Object { "cwd": "some-dir", "encoding": "utf-8", @@ -73,7 +73,7 @@ Array [ exports[`generateLockFile performs lock file updates 1`] = ` Array [ Object { - "cmd": "npm install --package-lock-only --ignore-scripts --no-audit some-dep@1.0.1", + "cmd": "npm install --package-lock-only --no-audit --ignore-scripts some-dep@1.0.1", "options": Object { "cwd": "some-dir", "encoding": "utf-8", diff --git a/lib/manager/npm/post-update/npm.ts b/lib/manager/npm/post-update/npm.ts index 8b28332155c787..9405b604056a2b 100644 --- a/lib/manager/npm/post-update/npm.ts +++ b/lib/manager/npm/post-update/npm.ts @@ -51,11 +51,16 @@ export async function generateLockFile( let cmdOptions = ''; if (postUpdateOptions?.includes('npmDedupe') || skipInstalls === false) { logger.debug('Performing node_modules install'); - cmdOptions += '--ignore-scripts --no-audit'; + cmdOptions += '--no-audit'; } else { logger.debug('Updating lock file only'); - cmdOptions += '--package-lock-only --ignore-scripts --no-audit'; + cmdOptions += '--package-lock-only --no-audit'; } + + if (!getAdminConfig().allowScripts || config.ignoreScripts) { + cmdOptions += ' --ignore-scripts'; + } + const tagConstraint = await getNodeConstraint(config); const execOptions: ExecOptions = { cwd, diff --git a/lib/manager/types.ts b/lib/manager/types.ts index c73d71f4775962..5cccc8a481b3ab 100644 --- a/lib/manager/types.ts +++ b/lib/manager/types.ts @@ -277,6 +277,7 @@ export interface PostUpdateConfig extends ManagerConfig, Record { updatedPackageFiles?: File[]; postUpdateOptions?: string[]; skipInstalls?: boolean; + ignoreScripts?: boolean; platform?: string; upgrades?: Upgrade[]; From 2cc751a0a1ba2e0d3bc35f51eed4cdaf07f8282c Mon Sep 17 00:00:00 2001 From: Florian Greinacher Date: Thu, 22 Apr 2021 21:16:58 +0200 Subject: [PATCH 36/52] feat: ignore unavailable users (#9406) --- docs/usage/configuration-options.md | 6 ++ lib/config/definitions.ts | 6 ++ lib/config/types.ts | 1 + .../gitlab/__snapshots__/index.spec.ts.snap | 77 +++++++++++++++++++ lib/platform/gitlab/http.ts | 13 ++++ lib/platform/gitlab/index.spec.ts | 40 ++++++++++ lib/platform/gitlab/index.ts | 14 +++- lib/platform/gitlab/types.ts | 8 ++ lib/platform/types.ts | 1 + .../pr/__snapshots__/index.spec.ts.snap | 22 ++++++ lib/workers/pr/index.spec.ts | 10 +++ lib/workers/pr/index.ts | 11 +++ lib/workers/repository/init/index.spec.ts | 15 +++- lib/workers/repository/init/index.ts | 10 +++ 14 files changed, 232 insertions(+), 2 deletions(-) diff --git a/docs/usage/configuration-options.md b/docs/usage/configuration-options.md index b21d513dc1b8a5..cf9b4062f3ac60 100644 --- a/docs/usage/configuration-options.md +++ b/docs/usage/configuration-options.md @@ -631,6 +631,12 @@ Because `fileMatch` is mergeable, you don't need to duplicate the defaults and c If you configure `fileMatch` then it must be within a manager object (e.g. `dockerfile` in the above example). The full list of supported managers can be found [here](https://docs.renovatebot.com/modules/manager/). +## filterUnavailableUsers + +When this option is enabled PRs are not assigned to users that are unavailable. +This option only works on platforms that support the concept of user availability. +For now, you can only use this option on the GitLab platform. + ## followTag Caution: advanced functionality. Only use it if you're sure you know what you're doing. diff --git a/lib/config/definitions.ts b/lib/config/definitions.ts index 76dcf0d28c0de3..3c77b49792aaa2 100644 --- a/lib/config/definitions.ts +++ b/lib/config/definitions.ts @@ -1497,6 +1497,12 @@ const options: RenovateOptions[] = [ type: 'boolean', default: false, }, + { + name: 'filterUnavailableUsers', + description: 'Filter reviewers and assignees based on their availability.', + type: 'boolean', + default: false, + }, { name: 'reviewersSampleSize', description: 'Take a random sample of given size from reviewers.', diff --git a/lib/config/types.ts b/lib/config/types.ts index 2ef022c21c49b8..cbbbd973379c4e 100644 --- a/lib/config/types.ts +++ b/lib/config/types.ts @@ -207,6 +207,7 @@ export interface AssigneesAndReviewersConfig { reviewers?: string[]; reviewersSampleSize?: number; additionalReviewers?: string[]; + filterUnavailableUsers?: boolean; } export type UpdateType = diff --git a/lib/platform/gitlab/__snapshots__/index.spec.ts.snap b/lib/platform/gitlab/__snapshots__/index.spec.ts.snap index e5778843549a5f..f63b6d3f9fa792 100644 --- a/lib/platform/gitlab/__snapshots__/index.spec.ts.snap +++ b/lib/platform/gitlab/__snapshots__/index.spec.ts.snap @@ -798,6 +798,83 @@ Array [ ] `; +exports[`platform/gitlab/index filterUnavailableUsers(users) filters users that are busy 1`] = ` +Array [ + "john", +] +`; + +exports[`platform/gitlab/index filterUnavailableUsers(users) filters users that are busy 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate, br", + "authorization": "Bearer abc123", + "host": "gitlab.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://gitlab.com/api/v4/users/maria/status", + }, + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate, br", + "authorization": "Bearer abc123", + "host": "gitlab.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://gitlab.com/api/v4/users/john/status", + }, +] +`; + +exports[`platform/gitlab/index filterUnavailableUsers(users) keeps users with failing requests 1`] = ` +Array [ + "maria", +] +`; + +exports[`platform/gitlab/index filterUnavailableUsers(users) keeps users with failing requests 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate, br", + "authorization": "Bearer abc123", + "host": "gitlab.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://gitlab.com/api/v4/users/maria/status", + }, +] +`; + +exports[`platform/gitlab/index filterUnavailableUsers(users) keeps users with missing availability 1`] = ` +Array [ + "maria", +] +`; + +exports[`platform/gitlab/index filterUnavailableUsers(users) keeps users with missing availability 2`] = ` +Array [ + Object { + "headers": Object { + "accept": "application/json", + "accept-encoding": "gzip, deflate, br", + "authorization": "Bearer abc123", + "host": "gitlab.com", + "user-agent": "https://github.com/renovatebot/renovate", + }, + "method": "GET", + "url": "https://gitlab.com/api/v4/users/maria/status", + }, +] +`; + exports[`platform/gitlab/index findIssue() finds issue 1`] = ` Array [ Object { diff --git a/lib/platform/gitlab/http.ts b/lib/platform/gitlab/http.ts index 51a836de629ab2..bab2b0f80378cd 100644 --- a/lib/platform/gitlab/http.ts +++ b/lib/platform/gitlab/http.ts @@ -1,4 +1,6 @@ +import { logger } from '../../logger'; import { GitlabHttp } from '../../util/http/gitlab'; +import type { GitlabUserStatus } from './types'; export const gitlabApi = new GitlabHttp(); @@ -7,3 +9,14 @@ export async function getUserID(username: string): Promise { await gitlabApi.getJson<{ id: number }[]>(`users?username=${username}`) ).body[0].id; } + +export async function isUserBusy(user: string): Promise { + try { + const url = `/users/${user}/status`; + const userStatus = (await gitlabApi.getJson(url)).body; + return userStatus.availability === 'busy'; + } catch (err) { + logger.warn({ err }, 'Failed to get user status'); + return false; + } +} diff --git a/lib/platform/gitlab/index.spec.ts b/lib/platform/gitlab/index.spec.ts index b60e0ac2eed26b..9f31a17ae240cb 100644 --- a/lib/platform/gitlab/index.spec.ts +++ b/lib/platform/gitlab/index.spec.ts @@ -1614,4 +1614,44 @@ These updates have all been created already. Click a checkbox below to force a r expect(httpMock.getTrace()).toMatchSnapshot(); }); }); + describe('filterUnavailableUsers(users)', () => { + it('filters users that are busy', async () => { + httpMock + .scope(gitlabApiHost) + .get('/api/v4/users/maria/status') + .reply(200, { + availability: 'busy', + }) + .get('/api/v4/users/john/status') + .reply(200, { + availability: 'not_set', + }); + const filteredUsers = await gitlab.filterUnavailableUsers([ + 'maria', + 'john', + ]); + expect(filteredUsers).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); + + it('keeps users with missing availability', async () => { + httpMock + .scope(gitlabApiHost) + .get('/api/v4/users/maria/status') + .reply(200, {}); + const filteredUsers = await gitlab.filterUnavailableUsers(['maria']); + expect(filteredUsers).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); + + it('keeps users with failing requests', async () => { + httpMock + .scope(gitlabApiHost) + .get('/api/v4/users/maria/status') + .reply(404); + const filteredUsers = await gitlab.filterUnavailableUsers(['maria']); + expect(filteredUsers).toMatchSnapshot(); + expect(httpMock.getTrace()).toMatchSnapshot(); + }); + }); }); diff --git a/lib/platform/gitlab/index.ts b/lib/platform/gitlab/index.ts index 8ea18a0cd42b3b..6faaf766cc14ce 100755 --- a/lib/platform/gitlab/index.ts +++ b/lib/platform/gitlab/index.ts @@ -40,7 +40,7 @@ import type { UpdatePrConfig, } from '../types'; import { smartTruncate } from '../utils/pr-body'; -import { getUserID, gitlabApi } from './http'; +import { getUserID, gitlabApi, isUserBusy } from './http'; import { getMR, updateMR } from './merge-request'; import type { GitLabMergeRequest, @@ -1067,3 +1067,15 @@ export async function ensureCommentRemoval({ export function getVulnerabilityAlerts(): Promise { return Promise.resolve([]); } + +export async function filterUnavailableUsers( + users: string[] +): Promise { + const filteredUsers = []; + for (const user of users) { + if (!(await isUserBusy(user))) { + filteredUsers.push(user); + } + } + return filteredUsers; +} diff --git a/lib/platform/gitlab/types.ts b/lib/platform/gitlab/types.ts index 607b3e973ea0c1..f35eba0b51b4c5 100644 --- a/lib/platform/gitlab/types.ts +++ b/lib/platform/gitlab/types.ts @@ -51,3 +51,11 @@ export interface RepoResponse { merge_method: MergeMethod; path_with_namespace: string; } + +// See https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/graphql/types/user_status_type.rb +export interface GitlabUserStatus { + message?: string; + message_html?: string; + emoji?: string; + availability: 'not_set' | 'busy'; +} diff --git a/lib/platform/types.ts b/lib/platform/types.ts index 89345dc4518d35..467dafdd67cf1a 100644 --- a/lib/platform/types.ts +++ b/lib/platform/types.ts @@ -177,4 +177,5 @@ export interface Platform { ): Promise; getBranchPr(branchName: string): Promise; initPlatform(config: PlatformParams): Promise; + filterUnavailableUsers?(users: string[]): Promise; } diff --git a/lib/workers/pr/__snapshots__/index.spec.ts.snap b/lib/workers/pr/__snapshots__/index.spec.ts.snap index 13361625d53546..a3941ef731a1e4 100644 --- a/lib/workers/pr/__snapshots__/index.spec.ts.snap +++ b/lib/workers/pr/__snapshots__/index.spec.ts.snap @@ -184,6 +184,28 @@ Array [ ] `; +exports[`workers/pr/index ensurePr should filter assignees and reviewers based on their availability 1`] = ` +Array [ + Array [ + undefined, + Array [ + "foo", + ], + ], +] +`; + +exports[`workers/pr/index ensurePr should filter assignees and reviewers based on their availability 2`] = ` +Array [ + Array [ + undefined, + Array [ + "foo", + ], + ], +] +`; + exports[`workers/pr/index ensurePr should return modified existing PR 1`] = ` Object { "body": "This PR contains the following updates:\\n\\n| Package | Type | Update | Change |\\n|---|---|---|---|\\n| [dummy](https://dummy.com) ([source](https://github.com/renovateapp/dummy), [changelog](https://github.com/renovateapp/dummy/changelog.md)) | devDependencies | minor | \`1.0.0\` -> \`1.1.0\` |\\n\\n---\\n\\n### Release Notes\\n\\n
\\nrenovateapp/dummy\\n\\n### [\`v1.1.0\`](https://github.com/renovateapp/dummy/compare/v1.0.0...v1.1.0)\\n\\n[Compare Source](https://github.com/renovateapp/dummy/compare/v1.0.0...v1.1.0)\\n\\n
\\n\\n---\\n\\n### Configuration\\n\\n:date: **Schedule**: \\"before 5am\\" (UTC).\\n\\n:vertical_traffic_light: **Automerge**: Enabled.\\n\\n:recycle: **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.\\n\\n:no_bell: **Ignore**: Close this PR and you won't be reminded about this update again.\\n\\n---\\n\\n - [ ] If you want to rebase/retry this PR, check this box.\\n\\n---\\n\\nThis PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).", diff --git a/lib/workers/pr/index.spec.ts b/lib/workers/pr/index.spec.ts index 47d8de271219cd..507d51cda845c7 100644 --- a/lib/workers/pr/index.spec.ts +++ b/lib/workers/pr/index.spec.ts @@ -410,6 +410,16 @@ describe(getName(__filename), () => { expect(platform.addReviewers).toHaveBeenCalledTimes(1); expect(platform.addReviewers.mock.calls).toMatchSnapshot(); }); + it('should filter assignees and reviewers based on their availability', async () => { + config.assignees = ['foo', 'bar']; + config.reviewers = ['foo', 'bar']; + config.filterUnavailableUsers = true; + platform.filterUnavailableUsers = jest.fn(); + platform.filterUnavailableUsers.mockResolvedValue(['foo']); + await prWorker.ensurePr(config); + expect(platform.addAssignees.mock.calls).toMatchSnapshot(); + expect(platform.addReviewers.mock.calls).toMatchSnapshot(); + }); it('should determine assignees from code owners', async () => { config.assigneesFromCodeOwners = true; codeOwnersMock.codeOwnersForPr.mockResolvedValueOnce(['@john', '@maria']); diff --git a/lib/workers/pr/index.ts b/lib/workers/pr/index.ts index 0ddb2aab61b461..92efafb868ae10 100644 --- a/lib/workers/pr/index.ts +++ b/lib/workers/pr/index.ts @@ -33,6 +33,15 @@ async function addCodeOwners( return [...new Set(assigneesOrReviewers.concat(await codeOwnersForPr(pr)))]; } +function filterUnavailableUsers( + config: RenovateConfig, + users: string[] +): Promise { + return config.filterUnavailableUsers && platform.filterUnavailableUsers + ? platform.filterUnavailableUsers(users) + : Promise.resolve(users); +} + export async function addAssigneesReviewers( config: RenovateConfig, pr: Pr @@ -41,6 +50,7 @@ export async function addAssigneesReviewers( if (config.assigneesFromCodeOwners) { assignees = await addCodeOwners(assignees, pr); } + assignees = await filterUnavailableUsers(config, assignees); if (assignees.length > 0) { try { assignees = assignees.map(noLeadingAtSymbol); @@ -70,6 +80,7 @@ export async function addAssigneesReviewers( if (config.additionalReviewers.length > 0) { reviewers = reviewers.concat(config.additionalReviewers); } + reviewers = await filterUnavailableUsers(config, reviewers); if (reviewers.length > 0) { try { reviewers = [...new Set(reviewers.map(noLeadingAtSymbol))]; diff --git a/lib/workers/repository/init/index.spec.ts b/lib/workers/repository/init/index.spec.ts index 63a04cbcce1624..71fcba1b876f99 100644 --- a/lib/workers/repository/init/index.spec.ts +++ b/lib/workers/repository/init/index.spec.ts @@ -1,4 +1,4 @@ -import { getName, mocked } from '../../../../test/util'; +import { getName, logger, mocked } from '../../../../test/util'; import * as _secrets from '../../../config/secrets'; import * as _onboarding from '../onboarding/branch'; import * as _apis from './apis'; @@ -29,5 +29,18 @@ describe(getName(__filename), () => { const renovateConfig = await initRepo({}); expect(renovateConfig).toMatchSnapshot(); }); + it('warns on unsupported options', async () => { + apis.initApis.mockResolvedValue({} as never); + onboarding.checkOnboardingBranch.mockResolvedValueOnce({}); + config.getRepoConfig.mockResolvedValueOnce({ + filterUnavailableUsers: true, + }); + config.mergeRenovateConfig.mockResolvedValueOnce({}); + secrets.applySecretsToConfig.mockReturnValueOnce({} as never); + await initRepo({}); + expect(logger.logger.warn).toHaveBeenCalledWith( + "Configuration option 'filterUnavailableUsers' is not supported on the current platform 'undefined'." + ); + }); }); }); diff --git a/lib/workers/repository/init/index.ts b/lib/workers/repository/init/index.ts index 07a47f1f4cf828..735e1fd44b739f 100644 --- a/lib/workers/repository/init/index.ts +++ b/lib/workers/repository/init/index.ts @@ -1,6 +1,7 @@ import { applySecretsToConfig } from '../../../config/secrets'; import type { RenovateConfig } from '../../../config/types'; import { logger } from '../../../logger'; +import { platform } from '../../../platform'; import { clone } from '../../../util/clone'; import { setUserRepoConfig } from '../../../util/git'; import { checkIfConfigured } from '../configured'; @@ -13,6 +14,14 @@ function initializeConfig(config: RenovateConfig): RenovateConfig { return { ...clone(config), errors: [], warnings: [], branchList: [] }; } +function warnOnUnsupportedOptions(config: RenovateConfig): void { + if (config.filterUnavailableUsers && !platform.filterUnavailableUsers) { + logger.warn( + `Configuration option 'filterUnavailableUsers' is not supported on the current platform '${config.platform}'.` + ); + } +} + export async function initRepo( config_: RenovateConfig ): Promise { @@ -21,6 +30,7 @@ export async function initRepo( config = await initApis(config); config = await getRepoConfig(config); checkIfConfigured(config); + warnOnUnsupportedOptions(config); config = applySecretsToConfig(config); await setUserRepoConfig(config); config = await detectVulnerabilityAlerts(config); From 2aa4b64abff87c05dac25d954cc8141707e071f5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 22 Apr 2021 21:27:44 +0000 Subject: [PATCH 37/52] chore(deps): update dependency ts-jest to v26.5.5 (#9690) Co-authored-by: Renovate Bot --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 63478b25c2fee2..f8de906355bfe5 100644 --- a/package.json +++ b/package.json @@ -258,7 +258,7 @@ "shelljs": "0.8.4", "strip-ansi": "6.0.0", "tmp-promise": "3.0.2", - "ts-jest": "26.5.4", + "ts-jest": "26.5.5", "ts-node": "9.1.1", "type-fest": "0.21.3", "typescript": "4.2.4" diff --git a/yarn.lock b/yarn.lock index 26c8522ff8ffe4..efe7d33ca4eeff 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10041,10 +10041,10 @@ ts-essentials@^4.0.0: resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-4.0.0.tgz#506c42b270bbd0465574b90416533175b09205ab" integrity sha512-uQJX+SRY9mtbKU+g9kl5Fi7AEMofPCvHfJkQlaygpPmHPZrtgaBqbWFOYyiA47RhnSwwnXdepUJrgqUYxoUyhQ== -ts-jest@26.5.4: - version "26.5.4" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-26.5.4.tgz#207f4c114812a9c6d5746dd4d1cdf899eafc9686" - integrity sha512-I5Qsddo+VTm94SukBJ4cPimOoFZsYTeElR2xy6H2TOVs+NsvgYglW8KuQgKoApOKuaU/Ix/vrF9ebFZlb5D2Pg== +ts-jest@26.5.5: + version "26.5.5" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-26.5.5.tgz#e40481b6ee4dd162626ba481a2be05fa57160ea5" + integrity sha512-7tP4m+silwt1NHqzNRAPjW1BswnAhopTdc2K3HEkRZjF0ZG2F/e/ypVH0xiZIMfItFtD3CX0XFbwPzp9fIEUVg== dependencies: bs-logger "0.x" buffer-from "1.x" From ed0605ebc3af49264b2a51dc197dfc4d9314d793 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 22 Apr 2021 23:45:25 +0000 Subject: [PATCH 38/52] chore(deps): update dependency @types/node to v14.14.41 (#9694) Co-authored-by: Renovate Bot --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index f8de906355bfe5..a48404bebd6bb6 100644 --- a/package.json +++ b/package.json @@ -217,7 +217,7 @@ "@types/markdown-table": "2.0.0", "@types/moo": "0.5.4", "@types/nock": "10.0.3", - "@types/node": "14.14.37", + "@types/node": "14.14.41", "@types/node-emoji": "1.8.1", "@types/parse-link-header": "1.0.0", "@types/registry-auth-token": "4.2.0", diff --git a/yarn.lock b/yarn.lock index efe7d33ca4eeff..f50834a75d5c61 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1581,10 +1581,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.25.tgz#15967a7b577ff81383f9b888aa6705d43fbbae93" integrity sha512-EPpXLOVqDvisVxtlbvzfyqSsFeQxltFbluZNRndIb8tr9KiBnYNLzrc1N3pyKUCww2RNrfHDViqDWWE1LCJQtQ== -"@types/node@14.14.37": - version "14.14.37" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.37.tgz#a3dd8da4eb84a996c36e331df98d82abd76b516e" - integrity sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw== +"@types/node@14.14.41": + version "14.14.41" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.41.tgz#d0b939d94c1d7bd53d04824af45f1139b8c45615" + integrity sha512-dueRKfaJL4RTtSa7bWeTK1M+VH+Gns73oCgzvYfHZywRCoPSd8EkXBL0mZ9unPTveBn+D9phZBaxuzpwjWkW0g== "@types/node@^13.7.0": version "13.13.41" From 9e2d2763ca065fd225cddcd21a713b035bea6e3b Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 23 Apr 2021 05:44:07 +0000 Subject: [PATCH 39/52] chore(deps): update dependency markdownlint-cli2 to v0.1.3 (#9696) Co-authored-by: Renovate Bot --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index a48404bebd6bb6..a1d6570f3334cf 100644 --- a/package.json +++ b/package.json @@ -247,7 +247,7 @@ "jest-junit": "12.0.0", "jest-mock-extended": "1.0.13", "jest-silent-reporter": "0.5.0", - "markdownlint-cli2": "0.0.15", + "markdownlint-cli2": "0.1.3", "mockdate": "3.0.5", "nock": "13.0.11", "npm-run-all": "4.1.5", diff --git a/yarn.lock b/yarn.lock index f50834a75d5c61..efd67fcc5f8384 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6745,10 +6745,10 @@ markdownlint-cli2-formatter-default@^0.0.2: resolved "https://registry.yarnpkg.com/markdownlint-cli2-formatter-default/-/markdownlint-cli2-formatter-default-0.0.2.tgz#76f1a064d70966178dfe3bb489af9423d830ca79" integrity sha512-jIz1X3SIC8sX4NDFqQFUXL+JEtfnDoN4i+xocEu+etcxGX455pHb6sx86f/yVk4mKJ2o7aNe2ydSx9an22BfBg== -markdownlint-cli2@0.0.15: - version "0.0.15" - resolved "https://registry.yarnpkg.com/markdownlint-cli2/-/markdownlint-cli2-0.0.15.tgz#c35407d0dc0e7ba5ed02e8693305dfdf4b6a9beb" - integrity sha512-XXJ0qd8mhsSUPdIAi4jUK7PFpc0hG/jCXNj7589cX9Ywg9umynOMaUrbcLpSiRTzzVFrKIN5VLxunA6oG+I7YQ== +markdownlint-cli2@0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/markdownlint-cli2/-/markdownlint-cli2-0.1.3.tgz#15ac14edea7816c96978f5f1de9256e637b691c5" + integrity sha512-4pbrSEDe/G9PjJnrxKXKTQXyXERHvFH+RjvZrCRiNrVPB0p1/wmQXCkdsKNWlaf+gc4gz4k9u1fj2x28GvFenw== dependencies: globby "~11.0.3" markdownlint "~0.23.1" From 37a8e2822951941b512bd707db42c4ddd0d25b8c Mon Sep 17 00:00:00 2001 From: Nils Andresen Date: Fri, 23 Apr 2021 09:43:19 +0200 Subject: [PATCH 40/52] fix(cake): quoted references (#9692) Co-authored-by: Michael Kriese --- lib/manager/cake/__fixtures__/build.cake | 1 + lib/manager/cake/__snapshots__/index.spec.ts.snap | 5 +++++ lib/manager/cake/index.ts | 7 ++++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/manager/cake/__fixtures__/build.cake b/lib/manager/cake/__fixtures__/build.cake index 4cdbf4d0496313..f3d942b91997e7 100644 --- a/lib/manager/cake/__fixtures__/build.cake +++ b/lib/manager/cake/__fixtures__/build.cake @@ -1,5 +1,6 @@ foo #addin nuget:?package=Foo.Foo&version=1.1.1 +#addin "nuget:?package=Bim.Bim&version=6.6.6" #tool nuget:https://example.com?package=Bar.Bar&version=2.2.2 #module nuget:file:///tmp/?package=Baz.Baz&version=3.3.3 // #module nuget:?package=Qux.Qux&version=4.4.4 diff --git a/lib/manager/cake/__snapshots__/index.spec.ts.snap b/lib/manager/cake/__snapshots__/index.spec.ts.snap index a6e389b1fc832f..8df0548df51e2a 100644 --- a/lib/manager/cake/__snapshots__/index.spec.ts.snap +++ b/lib/manager/cake/__snapshots__/index.spec.ts.snap @@ -8,6 +8,11 @@ Object { "datasource": "nuget", "depName": "Foo.Foo", }, + Object { + "currentValue": "6.6.6", + "datasource": "nuget", + "depName": "Bim.Bim", + }, Object { "currentValue": "2.2.2", "datasource": "nuget", diff --git a/lib/manager/cake/index.ts b/lib/manager/cake/index.ts index 60cb08b985172d..74415c75d33449 100644 --- a/lib/manager/cake/index.ts +++ b/lib/manager/cake/index.ts @@ -17,6 +17,10 @@ const lexerStates = { dependency: { match: /^#(?:addin|tool|module)\s+(?:nuget|dotnet):.*$/, }, + dependencyQuoted: { + match: /^#(?:addin|tool|module)\s+"(?:nuget|dotnet):[^"]+"\s*$/, + value: (s: string) => s.trim().slice(1, -1), + }, unknown: { match: /[^]/, lineBreaks: true }, }, }; @@ -26,6 +30,7 @@ function parseDependencyLine(line: string): PackageDependency | null { let url = line.replace(/^[^:]*:/, ''); const isEmptyHost = url.startsWith('?'); url = isEmptyHost ? `http://localhost/${url}` : url; + const { origin: registryUrl, protocol, searchParams } = new URL(url); const depName = searchParams.get('package'); @@ -54,7 +59,7 @@ export function extractPackageFile(content: string): PackageFile { let token = lexer.next(); while (token) { const { type, value } = token; - if (type === 'dependency') { + if (type === 'dependency' || type === 'dependencyQuoted') { const dep = parseDependencyLine(value); if (dep) { deps.push(dep); From 5716077f9949b5e3bbf0d06be553bfb86c86641a Mon Sep 17 00:00:00 2001 From: Sergei Zharinov Date: Fri, 23 Apr 2021 14:24:18 +0400 Subject: [PATCH 41/52] refactor: Cache moo lexer instances (#9697) --- lib/manager/bazel/extract.ts | 6 +++--- lib/manager/cake/index.ts | 5 ++--- lib/manager/gradle-lite/tokenizer.ts | 5 ++--- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/lib/manager/bazel/extract.ts b/lib/manager/bazel/extract.ts index 5c42fade649e22..9a20d2699d916c 100644 --- a/lib/manager/bazel/extract.ts +++ b/lib/manager/bazel/extract.ts @@ -53,7 +53,7 @@ function parseUrl(urlString: string): UrlParsedResult | null { return null; } -const dummyLexer = { +const lexer = moo.states({ main: { lineComment: { match: /#.*?$/ }, leftParen: { match: '(' }, @@ -103,11 +103,11 @@ const dummyLexer = { stringFinish: { match: "'", pop: 1 }, char: { match: /[^]/, lineBreaks: true }, }, -}; +}); function parseContent(content: string): string[] { - const lexer = moo.states(dummyLexer); lexer.reset(content); + let balance = 0; let def: null | string = null; diff --git a/lib/manager/cake/index.ts b/lib/manager/cake/index.ts index 74415c75d33449..50d04007f97a92 100644 --- a/lib/manager/cake/index.ts +++ b/lib/manager/cake/index.ts @@ -10,7 +10,7 @@ export const defaultConfig = { fileMatch: ['\\.cake$'], }; -const lexerStates = { +const lexer = moo.states({ main: { lineComment: { match: /\/\/.*?$/ }, multiLineComment: { match: /\/\*[^]*?\*\//, lineBreaks: true }, @@ -23,7 +23,7 @@ const lexerStates = { }, unknown: { match: /[^]/, lineBreaks: true }, }, -}; +}); function parseDependencyLine(line: string): PackageDependency | null { try { @@ -54,7 +54,6 @@ function parseDependencyLine(line: string): PackageDependency | null { export function extractPackageFile(content: string): PackageFile { const deps = []; - const lexer = moo.states(lexerStates); lexer.reset(content); let token = lexer.next(); while (token) { diff --git a/lib/manager/gradle-lite/tokenizer.ts b/lib/manager/gradle-lite/tokenizer.ts index 904cf29b161111..b37722fae2b873 100644 --- a/lib/manager/gradle-lite/tokenizer.ts +++ b/lib/manager/gradle-lite/tokenizer.ts @@ -19,7 +19,7 @@ const escapedChars = { }, }; -export const rawLexer = { +const lexer = moo.states({ // Top-level Groovy lexemes main: { [TokenType.LineComment]: { match: /\/\/.*?$/ }, @@ -104,7 +104,7 @@ export const rawLexer = { [TokenType.RightBrace]: { match: '}', pop: 1 }, [TokenType.UnknownLexeme]: { match: /[^]/, lineBreaks: true }, }, -}; +}); /* Turn UnknownLexeme chars to UnknownFragment strings @@ -213,7 +213,6 @@ function filterTokens({ type }: Token): boolean { } export function extractRawTokens(input: string): Token[] { - const lexer = moo.states(rawLexer); lexer.reset(input); return Array.from(lexer).map( ({ type, offset, value }) => ({ type, offset, value } as Token) From c862b5b4b52664f3a3d87d6e573ca4baa6c89960 Mon Sep 17 00:00:00 2001 From: Muhammad Rehan Saeed Date: Fri, 23 Apr 2021 13:17:28 +0100 Subject: [PATCH 42/52] feat(presets): Add HotChocolate monorepo (#9700) --- lib/config/presets/internal/monorepo.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/config/presets/internal/monorepo.ts b/lib/config/presets/internal/monorepo.ts index caa89112cee590..eee396525cad08 100644 --- a/lib/config/presets/internal/monorepo.ts +++ b/lib/config/presets/internal/monorepo.ts @@ -88,6 +88,7 @@ const repoGroups = { hamcrest: 'https://github.com/hamcrest/JavaHamcrest', Hangfire: 'https://github.com/HangfireIO/Hangfire', hapijs: 'https://github.com/hapijs', + HotChocolate: 'https://github.com/ChilliCream/hotchocolate', infrastructure: 'https://github.com/instructure/instructure-ui', istanbuljs: 'https://github.com/istanbuljs/istanbuljs', jasmine: 'https://github.com/jasmine/jasmine', From feb1bd61e49c6080a3be5583be3c3caa2928c751 Mon Sep 17 00:00:00 2001 From: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com> Date: Fri, 23 Apr 2021 16:46:30 +0200 Subject: [PATCH 43/52] docs: rewrite private npm module support (#8906) --- docs/usage/private-modules.md | 138 ++-------------------------- docs/usage/private-npm-modules.md | 145 ++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+), 133 deletions(-) create mode 100644 docs/usage/private-npm-modules.md diff --git a/docs/usage/private-modules.md b/docs/usage/private-modules.md index de8f6e3a801f4a..f64a6dfe4eb656 100644 --- a/docs/usage/private-modules.md +++ b/docs/usage/private-modules.md @@ -1,138 +1,10 @@ --- -title: Private npm module support -description: How to support private npm modules when using Renovate +title: Private module support +description: How to support private modules when using Renovate --- -# Private npm module support +# Private module support -## When are npm private modules used? +## npm -Private npm modules are used at two times during Renovate's process. - -### 1. Module lookup - -If a private npm module is listed as a dependency in a `package.json`, then Renovate will attempt to keep it up-to-date by querying the npm registry like it would for any other package. -Hence, by default with no configuration a private package lookup will fail, because of lack of credentials. -This means it won't be "renovated" and its version will remain unchanged in the package file unless you update it manually. -These failures don't affect Renovate's ability to look up _other_ modules in the same package file. - -Assuming the private module lookup succeeds (solutions for that are described later in this document) then private package versions will be kept up-to-date like public package versions are. - -### 2. Lock file generation - -If you are using a lock file (e.g. Yarn's `yarn.lock` or npm's `package-lock.json`) then Renovate needs to update that lock file whenever _any_ package listed in your package file is updated to a new version. - -To do this, Renovate will run `npm install` or equivalent and save the resulting lock file. -If a private module hasn't been updated, it _usually_ won't matter to npm/Yarn because they won't attempt to update its lock file entry anyway. -However it's possible that the install will fail if it attempts to look up that private module for some reason, even when that private module is not the main one being updated. -It's therefore better to provide Renovate with all the credentials it needs to look up private packages. - -## Supported npm authentication approaches - -The recommended approaches in order of preference are: - -**Self-hosted hostRules**: Configure a hostRules entry in the bot's `config.js` with the `hostType`, `hostName` and `token` specified - -**Renovate App with private modules from npmjs.org**: Add an encrypted `npmToken` to your Renovate config - -**Renovate App with a private registry**: Add an unencrypted `npmrc` plus an encrypted `npmToken` in config - -All the various approaches are described below: - -### Add hostRule to bots config - -Define `hostRules` like this: - -```js -module.exports = { - hostRules: [ - { - hostType: 'npm', - hostName: 'registry.npmjs.org', - token: process.env.NPMJS_TOKEN, - }, - { - hostType: 'npm', - baseUrl: - 'https://pkgs.dev.azure.com/{organization}/_packaging/{feed}/npm/registry/', - username: 'VssSessionToken', - password: process.env.AZURE_NPM_TOKEN, - }, - ], -}; -``` - -**NOTE:** Do not use `NPM_TOKEN` as an environment variable. - -### Add npmrc string to Renovate config - -You can add an `.npmrc` authentication line to your Renovate config under the field `npmrc`. e.g. a `renovate.json` might look like this: - -```json -{ - "npmrc": "//some.registry.com/:_authToken=abcdefghi-1234-jklmno-aac6-12345567889" -} -``` - -If configured like this, Renovate will use this to authenticate with npm and will ignore any `.npmrc` files(s) it finds checked into the repository. - -### Add npmToken to Renovate config - -If you are using the main npmjs registry then you can configure just the npmToken instead: - -```json -{ - "npmToken": "abcdefghi-1234-jklmno-aac6-12345567889" -} -``` - -### Add an encrypted npm token to Renovate config - -If you don't wish for all users of the repository to be able to see the unencrypted token, you can encrypt it with Renovate's public key instead, so that only Renovate can decrypt it. - -Go to , paste in your npm token, click "Encrypt", then copy the encrypted result. - -Add the encrypted result inside an `encrypted` object like this: - -```json -{ - "encrypted": { - "npmToken": "xxT19RIdhAh09lkhdrK39HzKNBn3etoLZAwHdeJ25cX+5y52a9kAC7flXmdw5JrkciN08aQuRNqDaKxp53IVptB5AYOnQPrt8MCT+x0zHgp4A1zv1QOV84I6uugdWpFSjPUkmLGMgULudEZJMlY/dAn/IVwf/IImqwazY8eHyJAA4vyUqKkL9SXzHjvS+OBonQ/9/AHYYKmDJwT8vLSRCKrXxJCdUfH7ZnikZbFqjnURJ9nGUHP44rlYJ7PFl05RZ+X5WuZG/A27S5LuBvguyQGcw8A2AZilHSDta9S/4eG6kb22jX87jXTrT6orUkxh2WHI/xvNUEout0gxwWMDkA==" - } -} -``` - -If you have no `.npmrc` file then Renovate will create one for you, pointing to the default npmjs registry. -If instead you use an alternative registry or need an `.npmrc` file for some other reason, you should configure it too and substitute the npm token with `${NPM_TOKEN}` for it to be replaced. e.g. - -```json -{ - "encrypted": { - "npmToken": "xxT19RIdhAh09lkhdrK39HzKNBn3etoLZAwHdeJ25cX+5y52a9kAC7flXmdw5JrkciN08aQuRNqDaKxp53IVptB5AYOnQPrt8MCT+x0zHgp4A1zv1QOV84I6uugdWpFSjPUkmLGMgULudEZJMlY/dAn/IVwf/IImqwazY8eHyJAA4vyUqKkL9SXzHjvS+OBonQ/9/AHYYKmDJwT8vLSRCKrXxJCdUfH7ZnikZbFqjnURJ9nGUHP44rlYJ7PFl05RZ+X5WuZG/A27S5LuBvguyQGcw8A2AZilHSDta9S/4eG6kb22jX87jXTrT6orUkxh2WHI/xvNUEout0gxwWMDkA==" - }, - "npmrc": "registry=https://my.custom.registry/npm\n//my.custom.registry/npm:_authToken=${NPM_TOKEN}" -} -``` - -Renovate will then use the following logic: - -1. If no `npmrc` string is present in config then one will be created with the `_authToken` pointing to the default npmjs registry -2. If an `npmrc` string is present and contains `${NPM_TOKEN}` then that placeholder will be replaced with the decrypted token -3. If an `npmrc` string is present but doesn't contain `${NPM_TOKEN}` then the file will have `_authToken=` appended to it - -### Encrypted entire .npmrc file into config - -Copy the entire .npmrc, replace newlines with `\n` chars, and then try encrypting it at - -You will then get an encrypted string that you can substitute into your renovate.json instead. -The result will now look something like this: - -```json -{ - "encrypted": { - "npmrc": "WOTWu+jliBtXYz3CU2eI7dDyMIvSJKS2N5PEHZmLB3XKT3vLaaYTGCU6m92Q9FgdaM/q2wLYun2JrTP4GPaW8eGZ3iiG1cm7lgOR5xPnkCzz0DUmSf6Cc/6geeVeSFdJ0zqlEAhdNMyJ4pUW6iQxC3WJKgM/ADvFtme077Acvc0fhCXv0XvbNSbtUwHF/gD6OJ0r2qlIzUMGJk/eI254xo5SwWVctc1iZS9LW+L0/CKjqhWh4SbyglP3lKE5shg3q7mzWDZepa/nJmAnNmXdoVO2aPPeQCG3BKqCtCfvLUUU/0LvnJ2SbQ1obyzL7vhh2OF/VsATS5cxbHvoX/hxWQ==" - } -} -``` - -However be aware that if your `.npmrc` is too long to encrypt then the above command will fail. +Please see [Private npm module support](./private-npm-modules) diff --git a/docs/usage/private-npm-modules.md b/docs/usage/private-npm-modules.md new file mode 100644 index 00000000000000..d7efa9c7fad7f5 --- /dev/null +++ b/docs/usage/private-npm-modules.md @@ -0,0 +1,145 @@ +--- +title: Private npm module support +description: How to support private npm modules when using Renovate +--- + +# Private npm module support + +## When are npm private modules used? + +Private npm modules are used at two times during Renovate's process: + +1. Module lookup +1. Lock file generation + +This is explained in more detail below. + +### Module lookup + +If a private npm module is listed as a dependency in the `package.json` file Renovate attempts to keep it up-to-date. +Renovate queries the npm registry like it does for any other package. +By default Renovate runs without any credentials, and so any private package lookup will fail. +This means, that any private package will not be renovated, and must be updated manually. +The failure to authenticate doesn't affect Renovate's ability to look up _other_ modules in the same package file. + +You can fix the private package lookup problem by providing the Renovate bot with the proper credentials. +This is described later in this document. + +Assuming the private module lookup succeeds then private package versions will be kept up-to-date like the public package versions are. + +### Lock file generation + +If you use a lock file (e.g. Yarn's `yarn.lock` or npm's `package-lock.json`) then Renovate must update that lock file whenever _any_ package listed in your package file is updated to a new version. + +To do this, Renovate runs `npm install` or equivalent and saves the resulting lock file. +If a private module hasn't been updated, it _usually_ won't matter to npm/Yarn because they won't attempt to update its lock file entry anyway. +However it's possible that the install will fail if it attempts to look up that private module for some reason, even when that private module is not the main one being updated. +It's therefore better to provide Renovate with all the credentials it needs to look up private packages. + +## Supported npm authentication approaches + +The recommended approaches in order of preference are: + +1. **Self-hosted hostRules**: Configure a hostRules entry in the bot's `config.js` with the `hostType`, `hostName` and `token` specified +1. **Renovate App with private modules from npmjs.org**: Add an encrypted `npmToken` to your Renovate config +1. **Renovate App with a private registry**: Add an unencrypted `npmrc` plus an encrypted `npmToken` in config + +These approaches are described in full below. + +### Add hostRule to bots config + +Define `hostRules` like this: + +```js +module.exports = { + hostRules: [ + { + hostType: 'npm', + hostName: 'registry.npmjs.org', + token: process.env.NPMJS_TOKEN, + }, + { + hostType: 'npm', + baseUrl: + 'https://pkgs.dev.azure.com/{organization}/_packaging/{feed}/npm/registry/', + username: 'VssSessionToken', + password: process.env.AZURE_NPM_TOKEN, + }, + ], +}; +``` + +**NOTE:** Do not use `NPM_TOKEN` as an environment variable. + +### Add npmrc string to Renovate config + +You can add an `.npmrc` authentication line to your Renovate config under the field `npmrc`. e.g. a `renovate.json` might look like this: + +```json +{ + "npmrc": "//some.registry.com/:_authToken=abcdefghi-1234-jklmno-aac6-12345567889" +} +``` + +If configured like this, Renovate will use this to authenticate with npm and will ignore any `.npmrc` files(s) it finds checked into the repository. + +### Add npmToken to Renovate config + +If you are using the main npmjs registry then you can configure just the `npmToken` instead: + +```json +{ + "npmToken": "abcdefghi-1234-jklmno-aac6-12345567889" +} +``` + +### Add an encrypted npm token to Renovate config + +If you don't want all users of the repository to see the unencrypted token, you can encrypt it with Renovate's public key instead, so that only Renovate can decrypt it. + +Go to , paste in your npm token, click "Encrypt", then copy the encrypted result. + +Paste the encrypted result inside an `encrypted` object like this: + +```json +{ + "encrypted": { + "npmToken": "xxT19RIdhAh09lkhdrK39HzKNBn3etoLZAwHdeJ25cX+5y52a9kAC7flXmdw5JrkciN08aQuRNqDaKxp53IVptB5AYOnQPrt8MCT+x0zHgp4A1zv1QOV84I6uugdWpFSjPUkmLGMgULudEZJMlY/dAn/IVwf/IImqwazY8eHyJAA4vyUqKkL9SXzHjvS+OBonQ/9/AHYYKmDJwT8vLSRCKrXxJCdUfH7ZnikZbFqjnURJ9nGUHP44rlYJ7PFl05RZ+X5WuZG/A27S5LuBvguyQGcw8A2AZilHSDta9S/4eG6kb22jX87jXTrT6orUkxh2WHI/xvNUEout0gxwWMDkA==" + } +} +``` + +If you have no `.npmrc` file then Renovate creates one for you, pointing to the default npmjs registry. +If instead you use an alternative registry or need an `.npmrc` file for some other reason, you should configure it too and substitute the npm token with `${NPM_TOKEN}` for it to be replaced. e.g. + +```json +{ + "encrypted": { + "npmToken": "xxT19RIdhAh09lkhdrK39HzKNBn3etoLZAwHdeJ25cX+5y52a9kAC7flXmdw5JrkciN08aQuRNqDaKxp53IVptB5AYOnQPrt8MCT+x0zHgp4A1zv1QOV84I6uugdWpFSjPUkmLGMgULudEZJMlY/dAn/IVwf/IImqwazY8eHyJAA4vyUqKkL9SXzHjvS+OBonQ/9/AHYYKmDJwT8vLSRCKrXxJCdUfH7ZnikZbFqjnURJ9nGUHP44rlYJ7PFl05RZ+X5WuZG/A27S5LuBvguyQGcw8A2AZilHSDta9S/4eG6kb22jX87jXTrT6orUkxh2WHI/xvNUEout0gxwWMDkA==" + }, + "npmrc": "registry=https://my.custom.registry/npm\n//my.custom.registry/npm:_authToken=${NPM_TOKEN}" +} +``` + +Renovate will then use the following logic: + +1. If no `npmrc` string is present in config then one will be created with the `_authToken` pointing to the default npmjs registry +1. If an `npmrc` string is present and contains `${NPM_TOKEN}` then that placeholder will be replaced with the decrypted token +1. If an `npmrc` string is present but doesn't contain `${NPM_TOKEN}` then the file will have `_authToken=` appended to it + +### Encrypted entire .npmrc file into config + +Copy the entire `.npmrc`, replace newlines with `\n` characters , and then try encrypting it at . + +You will then get an encrypted string that you can substitute into your `renovate.json` instead. +The end-result looks like this: + +```json +{ + "encrypted": { + "npmrc": "WOTWu+jliBtXYz3CU2eI7dDyMIvSJKS2N5PEHZmLB3XKT3vLaaYTGCU6m92Q9FgdaM/q2wLYun2JrTP4GPaW8eGZ3iiG1cm7lgOR5xPnkCzz0DUmSf6Cc/6geeVeSFdJ0zqlEAhdNMyJ4pUW6iQxC3WJKgM/ADvFtme077Acvc0fhCXv0XvbNSbtUwHF/gD6OJ0r2qlIzUMGJk/eI254xo5SwWVctc1iZS9LW+L0/CKjqhWh4SbyglP3lKE5shg3q7mzWDZepa/nJmAnNmXdoVO2aPPeQCG3BKqCtCfvLUUU/0LvnJ2SbQ1obyzL7vhh2OF/VsATS5cxbHvoX/hxWQ==" + } +} +``` + +However be aware that if your `.npmrc` is too long to encrypt then the above command will fail. From b2552756323d46f99b3c63bb228e7d7b5cc1a8b1 Mon Sep 17 00:00:00 2001 From: Sergei Zharinov Date: Fri, 23 Apr 2021 20:58:48 +0400 Subject: [PATCH 44/52] refactor(test): Load fixtures with helpers (#9699) Co-authored-by: Michael Kriese --- lib/config/decrypt.spec.ts | 5 +- lib/config/presets/index.spec.ts | 8 +- lib/datasource/cdnjs/index.spec.ts | 16 +--- lib/datasource/crate/index.spec.ts | 11 +-- lib/datasource/dart/index.spec.ts | 10 +-- .../galaxy-collection/index.spec.ts | 33 ++++---- lib/datasource/galaxy/index.spec.ts | 13 +--- lib/datasource/git-refs/index.spec.ts | 8 +- lib/datasource/git-tags/index.spec.ts | 8 +- lib/datasource/gradle-version/index.spec.ts | 14 +--- lib/datasource/helm/index.spec.ts | 8 +- lib/datasource/hex/index.spec.ts | 9 +-- lib/datasource/jenkins-plugins/index.spec.ts | 13 +++- lib/datasource/maven/index.spec.ts | 22 ++---- lib/datasource/nuget/index.spec.ts | 76 +++++-------------- lib/datasource/packagist/index.spec.ts | 35 +++------ lib/datasource/pypi/index.spec.ts | 29 +++---- lib/datasource/repology/index.spec.ts | 28 ++----- lib/datasource/ruby-version/index.spec.ts | 8 +- .../rubygems/__fixtures__/rubygems-org.txt | 18 +++++ lib/datasource/rubygems/index.spec.ts | 25 +----- lib/datasource/sbt-package/index.spec.ts | 15 +--- lib/datasource/sbt-plugin/index.spec.ts | 15 +--- lib/datasource/terraform-module/index.spec.ts | 17 ++--- .../terraform-provider/index.spec.ts | 17 ++--- lib/manager/ansible-galaxy/extract.spec.ts | 33 ++------ lib/manager/ansible/extract.spec.ts | 13 +--- lib/manager/azure-pipelines/extract.spec.ts | 20 ++--- lib/manager/batect-wrapper/extract.spec.ts | 14 +--- lib/manager/bazel/extract.spec.ts | 26 ++----- lib/manager/bazel/update.spec.ts | 21 +---- lib/manager/buildkite/extract.spec.ts | 23 ++---- lib/manager/bundler/extract.spec.ts | 76 +++++-------------- lib/manager/bundler/gemfile.spec.ts | 8 +- lib/manager/bundler/locked-version.spec.ts | 29 +++---- lib/manager/cake/index.spec.ts | 8 +- lib/manager/cargo/extract.spec.ts | 39 ++-------- lib/manager/cdnurl/extract.spec.ts | 9 +-- lib/manager/circleci/extract.spec.ts | 18 +---- lib/manager/cloudbuild/extract.spec.ts | 8 +- lib/manager/cocoapods/extract.spec.ts | 16 +--- lib/manager/composer/extract.spec.ts | 33 ++------ lib/manager/deps-edn/extract.spec.ts | 10 +-- lib/manager/docker-compose/extract.spec.ts | 21 ++--- lib/manager/dockerfile/extract.spec.ts | 14 +--- lib/manager/droneci/extract.spec.ts | 9 +-- lib/manager/github-actions/extract.spec.ts | 14 +--- lib/manager/gitlabci-include/extract.spec.ts | 8 +- lib/manager/gomod/extract.spec.ts | 9 +-- lib/manager/gomod/update.spec.ts | 7 +- lib/manager/gradle-lite/parser.spec.ts | 14 ++-- lib/manager/gradle-wrapper/extract.spec.ts | 30 ++------ lib/manager/helm-values/extract.spec.ts | 15 ++-- lib/manager/helmfile/extract.spec.ts | 9 +-- lib/manager/homebrew/extract.spec.ts | 25 ++---- lib/manager/homebrew/update.spec.ts | 13 +--- lib/manager/html/extract.spec.ts | 14 +--- lib/manager/jenkins/extract.spec.ts | 32 ++------ lib/manager/kubernetes/extract.spec.ts | 26 ++----- lib/manager/kustomize/extract.spec.ts | 54 +++---------- lib/manager/leiningen/extract.spec.ts | 10 +-- lib/manager/maven/extract.spec.ts | 15 +--- lib/manager/maven/index.spec.ts | 23 ++---- lib/manager/meteor/extract.spec.ts | 10 +-- lib/manager/mix/extract.spec.ts | 9 +-- lib/manager/npm/extract/index.spec.ts | 29 ++++--- lib/manager/npm/extract/npm.spec.ts | 13 ++-- lib/manager/npm/extract/yarn.spec.ts | 20 ++--- .../npm/update/dependency/index.spec.ts | 12 +-- .../locked-dependency/dep-constraints.spec.ts | 12 +-- .../locked-dependency/get-locked.spec.ts | 8 +- .../update/locked-dependency/index.spec.ts | 42 +++------- .../locked-dependency/parent-version.spec.ts | 8 +- lib/manager/pip_requirements/extract.spec.ts | 42 ++-------- .../__snapshots__/index.spec.ts.snap | 8 +- lib/manager/pip_setup/index.spec.ts | 11 +-- lib/manager/pipenv/extract.spec.ts | 28 ++----- lib/manager/poetry/artifacts.spec.ts | 8 +- lib/manager/poetry/extract.spec.ts | 68 +++-------------- lib/manager/pre-commit/extract.spec.ts | 45 +++++------ lib/manager/pub/extract.spec.ts | 14 +--- lib/manager/regex/index.spec.ts | 19 +---- lib/manager/sbt/extract.spec.ts | 34 +++------ lib/manager/setup-cfg/extract.spec.ts | 8 +- lib/manager/swift/index.spec.ts | 9 +-- lib/manager/terraform/extract.spec.ts | 7 +- lib/manager/terragrunt/extract.spec.ts | 5 +- lib/manager/travis/extract.spec.ts | 9 +-- lib/manager/travis/update.spec.ts | 9 +-- lib/platform/github/index.spec.ts | 15 ++-- lib/platform/utils/pr-body.spec.ts | 12 +-- .../utils/read-only-issue-body.spec.ts | 12 +-- lib/workers/branch/auto-replace.spec.ts | 9 +-- .../pr/changelog/release-notes.spec.ts | 41 ++++------ .../repository/dependency-dashboard.spec.ts | 27 ++----- .../repository/process/lookup/index.spec.ts | 35 ++++++--- test/util.ts | 26 +++++++ 97 files changed, 573 insertions(+), 1318 deletions(-) create mode 100644 lib/datasource/rubygems/__fixtures__/rubygems-org.txt diff --git a/lib/config/decrypt.spec.ts b/lib/config/decrypt.spec.ts index f0f604e60a3a18..c79072a5159fab 100644 --- a/lib/config/decrypt.spec.ts +++ b/lib/config/decrypt.spec.ts @@ -1,10 +1,9 @@ -import fs from 'fs'; -import { getName } from '../../test/util'; +import { getName, loadFixture } from '../../test/util'; import { setAdminConfig } from './admin'; import { decryptConfig } from './decrypt'; import type { RenovateConfig } from './types'; -const privateKey = fs.readFileSync('lib/config/keys/__fixtures__/private.pem'); +const privateKey = loadFixture(__filename, 'private.pem', 'keys'); describe(getName(__filename), () => { describe('decryptConfig()', () => { diff --git a/lib/config/presets/index.spec.ts b/lib/config/presets/index.spec.ts index 08acc21349fc43..38e7e4f982ad51 100644 --- a/lib/config/presets/index.spec.ts +++ b/lib/config/presets/index.spec.ts @@ -1,6 +1,5 @@ -import { getName, mocked } from '../../../test/util'; +import { getName, loadJsonFixture, mocked } from '../../../test/util'; import type { RenovateConfig } from '../types'; -import presetIkatyang from './__fixtures__/renovate-config-ikatyang.json'; import * as _local from './local'; import * as _npm from './npm'; import { @@ -17,6 +16,11 @@ jest.mock('./local'); const npm = mocked(_npm); const local = mocked(_local); +const presetIkatyang = loadJsonFixture( + __filename, + 'renovate-config-ikatyang.json' +); + npm.getPreset = jest.fn(({ packageName, presetName }) => { if (packageName === 'renovate-config-ikatyang') { return presetIkatyang.versions[presetIkatyang['dist-tags'].latest][ diff --git a/lib/datasource/cdnjs/index.spec.ts b/lib/datasource/cdnjs/index.spec.ts index 8535027de59767..6e6165ee1f647d 100644 --- a/lib/datasource/cdnjs/index.spec.ts +++ b/lib/datasource/cdnjs/index.spec.ts @@ -1,21 +1,11 @@ -import fs from 'fs'; import { getPkgReleases } from '..'; import * as httpMock from '../../../test/http-mock'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { EXTERNAL_HOST_ERROR } from '../../constants/error-messages'; import { id as datasource } from '.'; -let res1 = fs.readFileSync( - 'lib/datasource/cdnjs/__fixtures__/d3-force.json', - 'utf8' -); -res1 = JSON.parse(res1); - -let res2 = fs.readFileSync( - 'lib/datasource/cdnjs/__fixtures__/bulma.json', - 'utf8' -); -res2 = JSON.parse(res2); +const res1 = loadFixture(__filename, 'd3-force.json'); +const res2 = loadFixture(__filename, 'bulma.json'); const baseUrl = 'https://api.cdnjs.com/'; diff --git a/lib/datasource/crate/index.spec.ts b/lib/datasource/crate/index.spec.ts index dd8e79fdefb2cb..8bcf8fe19c08b0 100644 --- a/lib/datasource/crate/index.spec.ts +++ b/lib/datasource/crate/index.spec.ts @@ -5,7 +5,7 @@ import { DirectoryResult, dir } from 'tmp-promise'; import { dirname, join } from 'upath'; import { getPkgReleases } from '..'; import * as httpMock from '../../../test/http-mock'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { setAdminConfig } from '../../config/admin'; import * as memCache from '../../util/cache/memory'; import { setFsConfig } from '../../util/fs'; @@ -20,12 +20,9 @@ import { jest.mock('simple-git'); const simpleGit: any = _simpleGit; -const res1 = fs.readFileSync('lib/datasource/crate/__fixtures__/libc', 'utf8'); -const res2 = fs.readFileSync( - 'lib/datasource/crate/__fixtures__/amethyst', - 'utf8' -); -const res3 = fs.readFileSync('lib/datasource/crate/__fixtures__/mypkg', 'utf8'); +const res1 = loadFixture(__filename, 'libc'); +const res2 = loadFixture(__filename, 'amethyst'); +const res3 = loadFixture(__filename, 'mypkg'); const baseUrl = 'https://raw.githubusercontent.com/rust-lang/crates.io-index/master/'; diff --git a/lib/datasource/dart/index.spec.ts b/lib/datasource/dart/index.spec.ts index 5228b332bf5ca1..abc986a028b1bc 100644 --- a/lib/datasource/dart/index.spec.ts +++ b/lib/datasource/dart/index.spec.ts @@ -1,15 +1,9 @@ -import fs from 'fs'; import { getPkgReleases } from '..'; import * as httpMock from '../../../test/http-mock'; -import { getName } from '../../../test/util'; +import { getName, loadJsonFixture } from '../../../test/util'; import { id as datasource } from '.'; -const body: any = JSON.parse( - fs.readFileSync( - 'lib/datasource/dart/__fixtures__/shared_preferences.json', - 'utf8' - ) -); +const body = loadJsonFixture(__filename, 'shared_preferences.json'); const baseUrl = 'https://pub.dartlang.org/api/packages/'; diff --git a/lib/datasource/galaxy-collection/index.spec.ts b/lib/datasource/galaxy-collection/index.spec.ts index b7583d605de991..32acd8d69a10a1 100644 --- a/lib/datasource/galaxy-collection/index.spec.ts +++ b/lib/datasource/galaxy-collection/index.spec.ts @@ -1,29 +1,28 @@ -import fs from 'fs'; import { getPkgReleases } from '..'; import * as httpMock from '../../../test/http-mock'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { id as datasource } from '.'; -const communityKubernetesBase = fs.readFileSync( - 'lib/datasource/galaxy-collection/__fixtures__/community_kubernetes_base.json', - 'utf8' +const communityKubernetesBase = loadFixture( + __filename, + 'community_kubernetes_base.json' ); -const communityKubernetesVersions = fs.readFileSync( - 'lib/datasource/galaxy-collection/__fixtures__/community_kubernetes_versions.json', - 'utf8' +const communityKubernetesVersions = loadFixture( + __filename, + 'community_kubernetes_versions.json' ); -const communityKubernetesDetails121 = fs.readFileSync( - 'lib/datasource/galaxy-collection/__fixtures__/community_kubernetes_version_details_1.2.1.json', - 'utf8' +const communityKubernetesDetails121 = loadFixture( + __filename, + 'community_kubernetes_version_details_1.2.1.json' ); -const communityKubernetesDetails120 = fs.readFileSync( - 'lib/datasource/galaxy-collection/__fixtures__/community_kubernetes_version_details_1.2.0.json', - 'utf8' +const communityKubernetesDetails120 = loadFixture( + __filename, + 'community_kubernetes_version_details_1.2.0.json' ); -const communityKubernetesDetails0111 = fs.readFileSync( - 'lib/datasource/galaxy-collection/__fixtures__/community_kubernetes_version_details_0.11.1.json', - 'utf8' +const communityKubernetesDetails0111 = loadFixture( + __filename, + 'community_kubernetes_version_details_0.11.1.json' ); const baseUrl = 'https://galaxy.ansible.com'; diff --git a/lib/datasource/galaxy/index.spec.ts b/lib/datasource/galaxy/index.spec.ts index 6fb54511189fad..4786daa7281fa5 100644 --- a/lib/datasource/galaxy/index.spec.ts +++ b/lib/datasource/galaxy/index.spec.ts @@ -1,18 +1,11 @@ -import fs from 'fs'; import { getPkgReleases } from '..'; import * as httpMock from '../../../test/http-mock'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { id as datasource } from '.'; -const res1 = fs.readFileSync( - 'lib/datasource/galaxy/__fixtures__/timezone', - 'utf8' -); -const empty = fs.readFileSync( - 'lib/datasource/galaxy/__fixtures__/empty', - 'utf8' -); +const res1 = loadFixture(__filename, 'timezone'); +const empty = loadFixture(__filename, 'empty'); const baseUrl = 'https://galaxy.ansible.com/'; diff --git a/lib/datasource/git-refs/index.spec.ts b/lib/datasource/git-refs/index.spec.ts index c60b8eb241bbe2..5e0dc5c31faac9 100644 --- a/lib/datasource/git-refs/index.spec.ts +++ b/lib/datasource/git-refs/index.spec.ts @@ -1,7 +1,6 @@ -import fs from 'fs-extra'; import _simpleGit from 'simple-git'; import { getPkgReleases } from '..'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { id as datasource, getDigest } from '.'; jest.mock('simple-git'); @@ -9,10 +8,7 @@ const simpleGit: any = _simpleGit; const depName = 'https://github.com/example/example.git'; -const lsRemote1 = fs.readFileSync( - 'lib/datasource/git-refs/__fixtures__/ls-remote-1.txt', - 'utf8' -); +const lsRemote1 = loadFixture(__filename, 'ls-remote-1.txt'); describe(getName(__filename), () => { describe('getReleases', () => { diff --git a/lib/datasource/git-tags/index.spec.ts b/lib/datasource/git-tags/index.spec.ts index c449c78d429562..d1309fa51d89c8 100644 --- a/lib/datasource/git-tags/index.spec.ts +++ b/lib/datasource/git-tags/index.spec.ts @@ -1,7 +1,6 @@ -import fs from 'fs-extra'; import _simpleGit from 'simple-git'; import { getPkgReleases } from '..'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { id as datasource, getDigest } from '.'; jest.mock('simple-git'); @@ -9,10 +8,7 @@ const simpleGit: any = _simpleGit; const depName = 'https://github.com/example/example.git'; -const lsRemote1 = fs.readFileSync( - 'lib/datasource/git-refs/__fixtures__/ls-remote-1.txt', - 'utf8' -); +const lsRemote1 = loadFixture(__filename, 'ls-remote-1.txt', '../git-refs'); describe(getName(__filename), () => { describe('getReleases', () => { diff --git a/lib/datasource/gradle-version/index.spec.ts b/lib/datasource/gradle-version/index.spec.ts index fc9ac0b290a3f8..dd527dc0e1396f 100644 --- a/lib/datasource/gradle-version/index.spec.ts +++ b/lib/datasource/gradle-version/index.spec.ts @@ -1,14 +1,11 @@ -import fs from 'fs'; import { GetPkgReleasesConfig, GetReleasesConfig, getPkgReleases } from '..'; import * as httpMock from '../../../test/http-mock'; -import { getName, partial } from '../../../test/util'; +import { getName, loadJsonFixture, partial } from '../../../test/util'; import { ExternalHostError } from '../../types/errors/external-host-error'; import { id as versioning } from '../../versioning/gradle'; import { id as datasource, getReleases } from '.'; -const allResponse: any = fs.readFileSync( - 'lib/datasource/gradle-version/__fixtures__/all.json' -); +const allResponse: any = loadJsonFixture(__filename, 'all.json'); let config: GetPkgReleasesConfig; @@ -32,7 +29,7 @@ describe(getName(__filename), () => { httpMock .scope('https://services.gradle.org/') .get('/versions/all') - .reply(200, JSON.parse(allResponse)); + .reply(200, allResponse); const res = await getPkgReleases(config); expect(res).toMatchSnapshot(); expect(res).not.toBeNull(); @@ -44,10 +41,7 @@ describe(getName(__filename), () => { }); it('calls configured registryUrls', async () => { - httpMock - .scope('https://foo.bar') - .get('/') - .reply(200, JSON.parse(allResponse)); + httpMock.scope('https://foo.bar').get('/').reply(200, allResponse); httpMock .scope('http://baz.qux') diff --git a/lib/datasource/helm/index.spec.ts b/lib/datasource/helm/index.spec.ts index 5e572990251bee..37e9a119201c45 100644 --- a/lib/datasource/helm/index.spec.ts +++ b/lib/datasource/helm/index.spec.ts @@ -1,14 +1,10 @@ -import fs from 'fs'; import { getPkgReleases } from '..'; import * as httpMock from '../../../test/http-mock'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { id as datasource } from '.'; // Truncated index.yaml file -const indexYaml = fs.readFileSync( - 'lib/datasource/helm/__fixtures__/index.yaml', - 'utf8' -); +const indexYaml = loadFixture(__filename, 'index.yaml'); describe(getName(__filename), () => { describe('getReleases', () => { diff --git a/lib/datasource/hex/index.spec.ts b/lib/datasource/hex/index.spec.ts index 44f72778b8f92d..4357cf966fe18c 100644 --- a/lib/datasource/hex/index.spec.ts +++ b/lib/datasource/hex/index.spec.ts @@ -1,18 +1,13 @@ -import fs from 'fs'; import { getPkgReleases } from '..'; import * as httpMock from '../../../test/http-mock'; -import { getName } from '../../../test/util'; +import { getName, loadJsonFixture } from '../../../test/util'; import { EXTERNAL_HOST_ERROR } from '../../constants/error-messages'; import * as _hostRules from '../../util/host-rules'; import { id as datasource } from '.'; const hostRules: any = _hostRules; -let res1 = fs.readFileSync( - 'lib/datasource/hex/__fixtures__/certifi.json', - 'utf8' -); -res1 = JSON.parse(res1); +const res1 = loadJsonFixture(__filename, 'certifi.json'); jest.mock('../../util/host-rules'); diff --git a/lib/datasource/jenkins-plugins/index.spec.ts b/lib/datasource/jenkins-plugins/index.spec.ts index 8de09d668839ad..3943760e88860d 100644 --- a/lib/datasource/jenkins-plugins/index.spec.ts +++ b/lib/datasource/jenkins-plugins/index.spec.ts @@ -1,12 +1,19 @@ import { getPkgReleases } from '..'; import * as httpMock from '../../../test/http-mock'; -import { getName } from '../../../test/util'; +import { getName, loadJsonFixture } from '../../../test/util'; import * as versioning from '../../versioning/docker'; -import jenkinsPluginsVersions from './__fixtures__/plugin-versions.json'; -import jenkinsPluginsInfo from './__fixtures__/update-center.actual.json'; import { resetCache } from './get'; import * as jenkins from '.'; +const jenkinsPluginsVersions = loadJsonFixture( + __filename, + 'plugin-versions.json' +); +const jenkinsPluginsInfo = loadJsonFixture( + __filename, + 'update-center.actual.json' +); + describe(getName(__filename), () => { describe('getReleases', () => { const SKIP_CACHE = process.env.RENOVATE_SKIP_CACHE; diff --git a/lib/datasource/maven/index.spec.ts b/lib/datasource/maven/index.spec.ts index 9eb446dbf8816e..9a411bb8e26bad 100644 --- a/lib/datasource/maven/index.spec.ts +++ b/lib/datasource/maven/index.spec.ts @@ -1,8 +1,6 @@ -import fs from 'fs'; import nock from 'nock'; -import { resolve } from 'upath'; import { Release, getPkgReleases } from '..'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { EXTERNAL_HOST_ERROR } from '../../constants/error-messages'; import * as hostRules from '../../util/host-rules'; import * as mavenVersioning from '../../versioning/maven'; @@ -10,20 +8,14 @@ import { id as datasource } from '.'; const MYSQL_VERSIONS = ['6.0.5', '6.0.6', '8.0.7', '8.0.8', '8.0.9']; -const MYSQL_MAVEN_METADATA = fs.readFileSync( - resolve( - __dirname, - './__fixtures__/repo1.maven.org/maven2/mysql/mysql-connector-java/maven-metadata.xml' - ), - 'utf8' +const MYSQL_MAVEN_METADATA = loadFixture( + __filename, + 'repo1.maven.org/maven2/mysql/mysql-connector-java/maven-metadata.xml' ); -const MYSQL_MAVEN_MYSQL_POM = fs.readFileSync( - resolve( - __dirname, - './__fixtures__/repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.12/mysql-connector-java-8.0.12.pom' - ), - 'utf8' +const MYSQL_MAVEN_MYSQL_POM = loadFixture( + __filename, + 'repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.12/mysql-connector-java-8.0.12.pom' ); const config = { diff --git a/lib/datasource/nuget/index.spec.ts b/lib/datasource/nuget/index.spec.ts index c8ecb5a1da68d8..777089b4ec3f87 100644 --- a/lib/datasource/nuget/index.spec.ts +++ b/lib/datasource/nuget/index.spec.ts @@ -1,7 +1,6 @@ -import fs from 'fs'; import { getPkgReleases } from '..'; import * as httpMock from '../../../test/http-mock'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import * as _hostRules from '../../util/host-rules'; import { id as versioning } from '../../versioning/nuget'; import { id as datasource, parseRegistryUrl } from '.'; @@ -10,81 +9,48 @@ const hostRules: any = _hostRules; jest.mock('../../util/host-rules'); -const pkgInfoV3FromNuget = fs.readFileSync( - 'lib/datasource/nuget/__fixtures__/nunit/v3_nuget_org.xml', - 'utf8' -); -const pkgListV3Registration = fs.readFileSync( - 'lib/datasource/nuget/__fixtures__/nunit/v3_registration.json', - 'utf8' +const pkgInfoV3FromNuget = loadFixture(__filename, 'nunit/v3_nuget_org.xml'); +const pkgListV3Registration = loadFixture( + __filename, + 'nunit/v3_registration.json' ); -const pkgListV2 = fs.readFileSync( - 'lib/datasource/nuget/__fixtures__/nunit/v2.xml', - 'utf8' -); -const pkgListV2NoGitHubProjectUrl = fs.readFileSync( - 'lib/datasource/nuget/__fixtures__/nunit/v2_noGitHubProjectUrl.xml', - 'utf8' -); -const pkgListV2NoRelease = fs.readFileSync( - 'lib/datasource/nuget/__fixtures__/nunit/v2_no_release.xml', - 'utf8' +const pkgListV2 = loadFixture(__filename, 'nunit/v2.xml'); +const pkgListV2NoGitHubProjectUrl = loadFixture( + __filename, + 'nunit/v2_noGitHubProjectUrl.xml' ); -const pkgListV2WithoutProjectUrl = fs.readFileSync( - 'lib/datasource/nuget/__fixtures__/nunit/v2_withoutProjectUrl.xml', - 'utf8' +const pkgListV2NoRelease = loadFixture(__filename, 'nunit/v2_no_release.xml'); +const pkgListV2WithoutProjectUrl = loadFixture( + __filename, + 'nunit/v2_withoutProjectUrl.xml' ); -const pkgListV2Page1of2 = fs.readFileSync( - 'lib/datasource/nuget/__fixtures__/nunit/v2_paginated_1.xml', - 'utf8' -); -const pkgListV2Page2of2 = fs.readFileSync( - 'lib/datasource/nuget/__fixtures__/nunit/v2_paginated_2.xml', - 'utf8' -); +const pkgListV2Page1of2 = loadFixture(__filename, 'nunit/v2_paginated_1.xml'); +const pkgListV2Page2of2 = loadFixture(__filename, 'nunit/v2_paginated_2.xml'); -const nugetIndexV3 = fs.readFileSync( - 'lib/datasource/nuget/__fixtures__/v3_index.json', - 'utf8' -); +const nugetIndexV3 = loadFixture(__filename, 'v3_index.json'); const nlogMocks = [ { url: '/v3/registration5-gz-semver2/nlog/index.json', - result: fs.readFileSync( - 'lib/datasource/nuget/__fixtures__/nlog/v3_registration.json', - 'utf8' - ), + result: loadFixture(__filename, 'nlog/v3_registration.json'), }, { url: '/v3/registration5-gz-semver2/nlog/page/1.0.0.505/4.4.0-beta5.json', - result: fs.readFileSync( - 'lib/datasource/nuget/__fixtures__/nlog/v3_catalog_1.json', - 'utf8' - ), + result: loadFixture(__filename, 'nlog/v3_catalog_1.json'), }, { url: '/v3/registration5-gz-semver2/nlog/page/4.4.0-beta6/4.6.0-rc2.json', - result: fs.readFileSync( - 'lib/datasource/nuget/__fixtures__/nlog/v3_catalog_2.json', - 'utf8' - ), + result: loadFixture(__filename, 'nlog/v3_catalog_2.json'), }, { url: '/v3/registration5-gz-semver2/nlog/page/4.6.0-rc3/5.0.0-beta11.json', - result: fs.readFileSync( - 'lib/datasource/nuget/__fixtures__/nlog/v3_catalog_3.json', - 'utf8' - ), + result: loadFixture(__filename, 'nlog/v3_catalog_3.json'), }, { url: '/v3-flatcontainer/nlog/4.7.3/nlog.nuspec', - result: fs.readFileSync( - 'lib/datasource/nuget/__fixtures__/nlog/nuspec.xml', - 'utf8' - ), + result: loadFixture(__filename, 'nlog/nuspec.xml'), }, ]; diff --git a/lib/datasource/packagist/index.spec.ts b/lib/datasource/packagist/index.spec.ts index 33132089277815..556339f47b8b59 100644 --- a/lib/datasource/packagist/index.spec.ts +++ b/lib/datasource/packagist/index.spec.ts @@ -1,7 +1,6 @@ -import fs from 'fs'; import { getPkgReleases } from '..'; import * as httpMock from '../../../test/http-mock'; -import { getName } from '../../../test/util'; +import { getName, loadJsonFixture } from '../../../test/util'; import * as _hostRules from '../../util/host-rules'; import * as composerVersioning from '../../versioning/composer'; import { id as versioning } from '../../versioning/loose'; @@ -11,15 +10,9 @@ jest.mock('../../util/host-rules'); const hostRules = _hostRules; -const includesJson: any = fs.readFileSync( - 'lib/datasource/packagist/__fixtures__/includes.json' -); -const beytJson: any = fs.readFileSync( - 'lib/datasource/packagist/__fixtures__/1beyt.json' -); -const mailchimpJson: any = fs.readFileSync( - 'lib/datasource/packagist/__fixtures__/mailchimp-api.json' -); +const includesJson: any = loadJsonFixture(__filename, 'includes.json'); +const beytJson: any = loadJsonFixture(__filename, '1beyt.json'); +const mailchimpJson: any = loadJsonFixture(__filename, 'mailchimp-api.json'); const baseUrl = 'https://packagist.org'; @@ -143,7 +136,7 @@ describe(getName(__filename), () => { .get('/packages.json') .reply(200, packagesJson) .get('/include/all$afbf74d51f31c7cbb5ff10304f9290bfb4f4e68b.json') - .reply(200, JSON.parse(includesJson)); + .reply(200, includesJson); const res = await getPkgReleases({ ...config, datasource, @@ -227,7 +220,7 @@ describe(getName(__filename), () => { .get( '/p/wpackagist-plugin/1beyt$b574a802b5bf20a58c0f027e73aea2a75d23a6f654afc298a8dc467331be316a.json' ) - .reply(200, JSON.parse(beytJson)); + .reply(200, beytJson); const res = await getPkgReleases({ ...config, datasource, @@ -269,10 +262,7 @@ describe(getName(__filename), () => { '/p/providers-2018-09$14346045d7a7261cb3a12a6b7a1a7c4151982530347b115e5e277d879cad1942.json' ) .reply(200, fileJson); - httpMock - .scope(baseUrl) - .get('/p/some/other.json') - .reply(200, JSON.parse(beytJson)); + httpMock.scope(baseUrl).get('/p/some/other.json').reply(200, beytJson); const res = await getPkgReleases({ ...config, datasource, @@ -304,7 +294,7 @@ describe(getName(__filename), () => { .get( '/p/wpackagist-plugin/1beyt$b574a802b5bf20a58c0f027e73aea2a75d23a6f654afc298a8dc467331be316a.json' ) - .reply(200, JSON.parse(beytJson)); + .reply(200, beytJson); const res = await getPkgReleases({ ...config, datasource, @@ -334,10 +324,7 @@ describe(getName(__filename), () => { .scope('https://composer.renovatebot.com') .get('/packages.json') .reply(200, packagesJson); - httpMock - .scope(baseUrl) - .get('/p/some/other.json') - .reply(200, JSON.parse(beytJson)); + httpMock.scope(baseUrl).get('/p/some/other.json').reply(200, beytJson); const res = await getPkgReleases({ ...config, datasource, @@ -351,7 +338,7 @@ describe(getName(__filename), () => { httpMock .scope(baseUrl) .get('/p/drewm/mailchimp-api.json') - .reply(200, JSON.parse(mailchimpJson)); + .reply(200, mailchimpJson); config.registryUrls = ['https://packagist.org']; expect( await getPkgReleases({ @@ -367,7 +354,7 @@ describe(getName(__filename), () => { httpMock .scope(baseUrl) .get('/p/drewm/mailchimp-api.json') - .reply(200, JSON.parse(mailchimpJson)); + .reply(200, mailchimpJson); config.registryUrls = []; expect( await getPkgReleases({ diff --git a/lib/datasource/pypi/index.spec.ts b/lib/datasource/pypi/index.spec.ts index 75c8c8efcc6b43..6a36bba660daa5 100644 --- a/lib/datasource/pypi/index.spec.ts +++ b/lib/datasource/pypi/index.spec.ts @@ -1,27 +1,20 @@ -import fs from 'fs'; import { getPkgReleases } from '..'; import * as httpMock from '../../../test/http-mock'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import * as hostRules from '../../util/host-rules'; import { id as datasource } from '.'; -const res1: any = fs.readFileSync( - 'lib/datasource/pypi/__fixtures__/azure-cli-monitor.json' +const res1: any = loadFixture(__filename, 'azure-cli-monitor.json'); +const res2: any = loadFixture(__filename, 'azure-cli-monitor-updated.json'); +const htmlResponse = loadFixture(__filename, 'versions-html.html'); +const badResponse = loadFixture(__filename, 'versions-html-badfile.html'); +const dataRequiresPythonResponse = loadFixture( + __filename, + 'versions-html-data-requires-python.html' ); -const res2: any = fs.readFileSync( - 'lib/datasource/pypi/__fixtures__/azure-cli-monitor-updated.json' -); -const htmlResponse = fs.readFileSync( - 'lib/datasource/pypi/__fixtures__/versions-html.html' -); -const badResponse = fs.readFileSync( - 'lib/datasource/pypi/__fixtures__/versions-html-badfile.html' -); -const dataRequiresPythonResponse = fs.readFileSync( - 'lib/datasource/pypi/__fixtures__/versions-html-data-requires-python.html' -); -const mixedHyphensResponse = fs.readFileSync( - 'lib/datasource/pypi/__fixtures__/versions-html-mixed-hyphens.html' +const mixedHyphensResponse = loadFixture( + __filename, + 'versions-html-mixed-hyphens.html' ); const baseUrl = 'https://pypi.org/pypi'; diff --git a/lib/datasource/repology/index.spec.ts b/lib/datasource/repology/index.spec.ts index 1079805e3a709c..9323908ac1642f 100644 --- a/lib/datasource/repology/index.spec.ts +++ b/lib/datasource/repology/index.spec.ts @@ -1,7 +1,6 @@ -import fs from 'fs'; import { getPkgReleases } from '..'; import * as httpMock from '../../../test/http-mock'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { EXTERNAL_HOST_ERROR } from '../../constants/error-messages'; import { id as versioning } from '../../versioning/loose'; import { RepologyPackage, id as datasource } from '.'; @@ -46,26 +45,11 @@ const mockResolverCall = ( } }; -const fixtureNginx = fs.readFileSync( - `${__dirname}/__fixtures__/nginx.json`, - 'utf8' -); -const fixtureGccDefaults = fs.readFileSync( - `${__dirname}/__fixtures__/gcc-defaults.json`, - 'utf8' -); -const fixtureGcc = fs.readFileSync( - `${__dirname}/__fixtures__/gcc.json`, - 'utf8' -); -const fixturePulseaudio = fs.readFileSync( - `${__dirname}/__fixtures__/pulseaudio.json`, - 'utf8' -); -const fixtureJdk = fs.readFileSync( - `${__dirname}/__fixtures__/openjdk.json`, - 'utf8' -); +const fixtureNginx = loadFixture(__filename, `nginx.json`); +const fixtureGccDefaults = loadFixture(__filename, `gcc-defaults.json`); +const fixtureGcc = loadFixture(__filename, `gcc.json`); +const fixturePulseaudio = loadFixture(__filename, `pulseaudio.json`); +const fixtureJdk = loadFixture(__filename, `openjdk.json`); describe(getName(__filename), () => { describe('getReleases', () => { diff --git a/lib/datasource/ruby-version/index.spec.ts b/lib/datasource/ruby-version/index.spec.ts index 759931897df364..2f95bcfa918996 100644 --- a/lib/datasource/ruby-version/index.spec.ts +++ b/lib/datasource/ruby-version/index.spec.ts @@ -1,13 +1,9 @@ -import fs from 'fs'; import { getPkgReleases } from '..'; import * as httpMock from '../../../test/http-mock'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { id as datasource } from '.'; -const rubyReleasesHtml = fs.readFileSync( - 'lib/datasource/ruby-version/__fixtures__/releases.html', - 'utf8' -); +const rubyReleasesHtml = loadFixture(__filename, 'releases.html'); describe(getName(__filename), () => { describe('getReleases', () => { diff --git a/lib/datasource/rubygems/__fixtures__/rubygems-org.txt b/lib/datasource/rubygems/__fixtures__/rubygems-org.txt new file mode 100644 index 00000000000000..69564ff592b916 --- /dev/null +++ b/lib/datasource/rubygems/__fixtures__/rubygems-org.txt @@ -0,0 +1,18 @@ +created_at: 2017-03-27T04:38:13+00:00 +--- +- 1 05d0116933ba44b0b5d0ee19bfd35ccc +.cat 0.0.1 631fd60a806eaf5026c86fff3155c289 +0mq 0.1.0,0.1.1,0.1.2,0.2.0,0.2.1,0.3.0,0.4.0,0.4.1,0.5.0,0.5.1,0.5.2,0.5.3 6146193f8f7e944156b0b42ec37bad3e +0xffffff 0.0.1,0.1.0 0a4a9aeae24152cdb467be02f40482f9 +10to1-crack 0.1.1,0.1.2,0.1.3 e7218e76477e2137355d2e7ded094925 +1234567890_ 1.0,1.1 233e818c2db65d2dad9f9ea9a27b1a30 +12_hour_time 0.0.2,0.0.3,0.0.4 4e58bc03e301f704950410b713c20b69 +16watts-fluently 0.3.0,0.3.1 555088e2b18e97e0293cab1d90dbb0d2 +189seg 0.0.1 c4d329f7d3eb88b6e602358968be0242 +196demo 0.0.0 e00c558565f7b03a438fbd93d854b7de +1_as_identity_function 1.0.0,1.0.1 bee2f0fbbc3c5c83008c0b8fc64cb168 +1and1 1.1 1853e4495b036ddc5da2035523d48f0d +1hdoc 0.1.3,0.2.0,0.2.2,0.2.3,0.2.4 7076f29c196df12047a3700c4d6e5915 +1pass 0.1.0,0.1.1,0.1.2 d209547aae4b8f3d67123f18f738ac99 +1pass -0.1.2 abcdef +21-day-challenge-countdown 0.1.0,0.1.1,0.1.2 57e8873fe713063f4e54e85bbbd709bb diff --git a/lib/datasource/rubygems/index.spec.ts b/lib/datasource/rubygems/index.spec.ts index 29c849d9f289c3..92df66b559aba3 100644 --- a/lib/datasource/rubygems/index.spec.ts +++ b/lib/datasource/rubygems/index.spec.ts @@ -1,30 +1,13 @@ import { getPkgReleases } from '..'; import * as httpMock from '../../../test/http-mock'; -import { getName } from '../../../test/util'; +import { getName, loadFixture, loadJsonFixture } from '../../../test/util'; import * as rubyVersioning from '../../versioning/ruby'; -import railsInfo from './__fixtures__/rails/info.json'; -import railsVersions from './__fixtures__/rails/versions.json'; import { resetCache } from './get-rubygems-org'; import * as rubygems from '.'; -const rubygemsOrgVersions = `created_at: 2017-03-27T04:38:13+00:00 ---- -- 1 05d0116933ba44b0b5d0ee19bfd35ccc -.cat 0.0.1 631fd60a806eaf5026c86fff3155c289 -0mq 0.1.0,0.1.1,0.1.2,0.2.0,0.2.1,0.3.0,0.4.0,0.4.1,0.5.0,0.5.1,0.5.2,0.5.3 6146193f8f7e944156b0b42ec37bad3e -0xffffff 0.0.1,0.1.0 0a4a9aeae24152cdb467be02f40482f9 -10to1-crack 0.1.1,0.1.2,0.1.3 e7218e76477e2137355d2e7ded094925 -1234567890_ 1.0,1.1 233e818c2db65d2dad9f9ea9a27b1a30 -12_hour_time 0.0.2,0.0.3,0.0.4 4e58bc03e301f704950410b713c20b69 -16watts-fluently 0.3.0,0.3.1 555088e2b18e97e0293cab1d90dbb0d2 -189seg 0.0.1 c4d329f7d3eb88b6e602358968be0242 -196demo 0.0.0 e00c558565f7b03a438fbd93d854b7de -1_as_identity_function 1.0.0,1.0.1 bee2f0fbbc3c5c83008c0b8fc64cb168 -1and1 1.1 1853e4495b036ddc5da2035523d48f0d -1hdoc 0.1.3,0.2.0,0.2.2,0.2.3,0.2.4 7076f29c196df12047a3700c4d6e5915 -1pass 0.1.0,0.1.1,0.1.2 d209547aae4b8f3d67123f18f738ac99 -1pass -0.1.2 abcdef -21-day-challenge-countdown 0.1.0,0.1.1,0.1.2 57e8873fe713063f4e54e85bbbd709bb`; +const rubygemsOrgVersions = loadFixture(__filename, 'rubygems-org.txt'); +const railsInfo = loadJsonFixture(__filename, 'rails/info.json'); +const railsVersions = loadJsonFixture(__filename, 'rails/versions.json'); describe(getName(__filename), () => { describe('getReleases', () => { diff --git a/lib/datasource/sbt-package/index.spec.ts b/lib/datasource/sbt-package/index.spec.ts index ba30b93ad56bfd..2616a41293cae8 100644 --- a/lib/datasource/sbt-package/index.spec.ts +++ b/lib/datasource/sbt-package/index.spec.ts @@ -1,22 +1,13 @@ -import fs from 'fs'; import nock from 'nock'; -import upath from 'upath'; import { getPkgReleases } from '..'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import * as mavenVersioning from '../../versioning/maven'; import { MAVEN_REPO } from '../maven/common'; import { parseIndexDir } from '../sbt-plugin/util'; import * as sbtPlugin from '.'; -const mavenIndexHtml = fs.readFileSync( - upath.resolve(__dirname, `./__fixtures__/maven-index.html`), - 'utf8' -); - -const sbtPluginIndex = fs.readFileSync( - upath.resolve(__dirname, `./__fixtures__/sbt-plugins-index.html`), - 'utf8' -); +const mavenIndexHtml = loadFixture(__filename, `maven-index.html`); +const sbtPluginIndex = loadFixture(__filename, `sbt-plugins-index.html`); describe(getName(__filename), () => { it('parses Maven index directory', () => { diff --git a/lib/datasource/sbt-plugin/index.spec.ts b/lib/datasource/sbt-plugin/index.spec.ts index ab8cd3e9f7cc07..b8228ab50091c8 100644 --- a/lib/datasource/sbt-plugin/index.spec.ts +++ b/lib/datasource/sbt-plugin/index.spec.ts @@ -1,22 +1,13 @@ -import fs from 'fs'; import nock from 'nock'; -import upath from 'upath'; import { getPkgReleases } from '..'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import * as mavenVersioning from '../../versioning/maven'; import { MAVEN_REPO } from '../maven/common'; import { parseIndexDir } from './util'; import * as sbtPlugin from '.'; -const mavenIndexHtml = fs.readFileSync( - upath.resolve(__dirname, `./__fixtures__/maven-index.html`), - 'utf8' -); - -const sbtPluginIndex = fs.readFileSync( - upath.resolve(__dirname, `./__fixtures__/sbt-plugins-index.html`), - 'utf8' -); +const mavenIndexHtml = loadFixture(__filename, `maven-index.html`); +const sbtPluginIndex = loadFixture(__filename, `sbt-plugins-index.html`); describe(getName(__filename), () => { it('parses Maven index directory', () => { diff --git a/lib/datasource/terraform-module/index.spec.ts b/lib/datasource/terraform-module/index.spec.ts index d7d1d0b7abac6d..2d08c2dd29677e 100644 --- a/lib/datasource/terraform-module/index.spec.ts +++ b/lib/datasource/terraform-module/index.spec.ts @@ -1,17 +1,16 @@ -import fs from 'fs'; import { getPkgReleases } from '..'; import * as httpMock from '../../../test/http-mock'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { id as datasource } from '.'; -const consulData: any = fs.readFileSync( - 'lib/datasource/terraform-module/__fixtures__/registry-consul.json' +const consulData: any = loadFixture(__filename, 'registry-consul.json'); +const serviceDiscoveryResult: any = loadFixture( + __filename, + 'service-discovery.json' ); -const serviceDiscoveryResult: any = fs.readFileSync( - 'lib/datasource/terraform-module/__fixtures__/service-discovery.json' -); -const serviceDiscoveryCustomResult: any = fs.readFileSync( - 'lib/datasource/terraform-module/__fixtures__/service-custom-discovery.json' +const serviceDiscoveryCustomResult: any = loadFixture( + __filename, + 'service-custom-discovery.json' ); const baseUrl = 'https://registry.terraform.io'; diff --git a/lib/datasource/terraform-provider/index.spec.ts b/lib/datasource/terraform-provider/index.spec.ts index c7725e2c744573..44dfa44b294f2e 100644 --- a/lib/datasource/terraform-provider/index.spec.ts +++ b/lib/datasource/terraform-provider/index.spec.ts @@ -1,17 +1,16 @@ -import fs from 'fs'; import { getPkgReleases } from '..'; import * as httpMock from '../../../test/http-mock'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { id as datasource, defaultRegistryUrls } from '.'; -const consulData: any = fs.readFileSync( - 'lib/datasource/terraform-provider/__fixtures__/azurerm-provider.json' +const consulData: any = loadFixture(__filename, 'azurerm-provider.json'); +const hashicorpReleases: any = loadFixture( + __filename, + 'releaseBackendIndex.json' ); -const hashicorpReleases: any = fs.readFileSync( - 'lib/datasource/terraform-provider/__fixtures__/releaseBackendIndex.json' -); -const serviceDiscoveryResult: any = fs.readFileSync( - 'lib/datasource/terraform-module/__fixtures__/service-discovery.json' +const serviceDiscoveryResult: any = loadFixture( + __filename, + 'service-discovery.json' ); const primaryUrl = defaultRegistryUrls[0]; diff --git a/lib/manager/ansible-galaxy/extract.spec.ts b/lib/manager/ansible-galaxy/extract.spec.ts index b4f68b6f10abc8..dd3593801e3754 100644 --- a/lib/manager/ansible-galaxy/extract.spec.ts +++ b/lib/manager/ansible-galaxy/extract.spec.ts @@ -1,31 +1,12 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import extractPackageFile, { getSliceEndNumber } from './extract'; -const yamlFile1 = readFileSync( - 'lib/manager/ansible-galaxy/__fixtures__/requirements01.yml', - 'utf8' -); -const yamlFile2 = readFileSync( - 'lib/manager/ansible-galaxy/__fixtures__/requirements02.yml', - 'utf8' -); -const helmRequirements = readFileSync( - 'lib/manager/ansible-galaxy/__fixtures__/helmRequirements.yml', - 'utf8' -); -const collections1 = readFileSync( - 'lib/manager/ansible-galaxy/__fixtures__/collections1.yml', - 'utf8' -); -const collections2 = readFileSync( - 'lib/manager/ansible-galaxy/__fixtures__/collections2.yml', - 'utf8' -); -const galaxy = readFileSync( - 'lib/manager/ansible-galaxy/__fixtures__/galaxy.yml', - 'utf8' -); +const yamlFile1 = loadFixture(__filename, 'requirements01.yml'); +const yamlFile2 = loadFixture(__filename, 'requirements02.yml'); +const helmRequirements = loadFixture(__filename, 'helmRequirements.yml'); +const collections1 = loadFixture(__filename, 'collections1.yml'); +const collections2 = loadFixture(__filename, 'collections2.yml'); +const galaxy = loadFixture(__filename, 'galaxy.yml'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/ansible/extract.spec.ts b/lib/manager/ansible/extract.spec.ts index 8b96d583d5fe98..3e068cf4062230 100644 --- a/lib/manager/ansible/extract.spec.ts +++ b/lib/manager/ansible/extract.spec.ts @@ -1,15 +1,8 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import extractPackageFile from './extract'; -const yamlFile1 = readFileSync( - 'lib/manager/ansible/__fixtures__/main1.yaml', - 'utf8' -); -const yamlFile2 = readFileSync( - 'lib/manager/ansible/__fixtures__/main2.yaml', - 'utf8' -); +const yamlFile1 = loadFixture(__filename, 'main1.yaml'); +const yamlFile2 = loadFixture(__filename, 'main2.yaml'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/azure-pipelines/extract.spec.ts b/lib/manager/azure-pipelines/extract.spec.ts index 5ac96ae7ecf416..72dd4fcfad25d8 100644 --- a/lib/manager/azure-pipelines/extract.spec.ts +++ b/lib/manager/azure-pipelines/extract.spec.ts @@ -1,5 +1,4 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractContainer, extractPackageFile, @@ -7,19 +6,16 @@ import { parseAzurePipelines, } from './extract'; -const azurePipelines = readFileSync( - 'lib/manager/azure-pipelines/__fixtures__/azure-pipelines.yaml', - 'utf8' -); +const azurePipelines = loadFixture(__filename, 'azure-pipelines.yaml'); -const azurePipelinesInvalid = readFileSync( - 'lib/manager/azure-pipelines/__fixtures__/azure-pipelines-invalid.yaml', - 'utf8' +const azurePipelinesInvalid = loadFixture( + __filename, + 'azure-pipelines-invalid.yaml' ); -const azurePipelinesNoDependency = readFileSync( - 'lib/manager/azure-pipelines/__fixtures__/azure-pipelines-no-dependency.yaml', - 'utf8' +const azurePipelinesNoDependency = loadFixture( + __filename, + 'azure-pipelines-no-dependency.yaml' ); describe(getName(__filename), () => { diff --git a/lib/manager/batect-wrapper/extract.spec.ts b/lib/manager/batect-wrapper/extract.spec.ts index fe854eb3692511..06393f3cd2f7e5 100644 --- a/lib/manager/batect-wrapper/extract.spec.ts +++ b/lib/manager/batect-wrapper/extract.spec.ts @@ -1,19 +1,11 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { id as githubReleaseDatasource } from '../../datasource/github-releases'; import { id as semverVersioning } from '../../versioning/semver'; import type { PackageDependency } from '../types'; import { extractPackageFile } from './extract'; -const validWrapperContent = readFileSync( - 'lib/manager/batect-wrapper/__fixtures__/valid-wrapper', - 'utf8' -); - -const malformedWrapperContent = readFileSync( - 'lib/manager/batect-wrapper/__fixtures__/malformed-wrapper', - 'utf8' -); +const validWrapperContent = loadFixture(__filename, 'valid-wrapper'); +const malformedWrapperContent = loadFixture(__filename, 'malformed-wrapper'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/bazel/extract.spec.ts b/lib/manager/bazel/extract.spec.ts index 23523f8359ca0f..be6a208c17bbfd 100644 --- a/lib/manager/bazel/extract.spec.ts +++ b/lib/manager/bazel/extract.spec.ts @@ -1,26 +1,10 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; -const workspaceFile = readFileSync( - 'lib/manager/bazel/__fixtures__/WORKSPACE1', - 'utf8' -); - -const workspace2File = readFileSync( - 'lib/manager/bazel/__fixtures__/WORKSPACE2', - 'utf8' -); - -const workspace3File = readFileSync( - 'lib/manager/bazel/__fixtures__/WORKSPACE3', - 'utf8' -); - -const fileWithBzlExtension = readFileSync( - 'lib/manager/bazel/__fixtures__/repositories.bzl', - 'utf8' -); +const workspaceFile = loadFixture(__filename, 'WORKSPACE1'); +const workspace2File = loadFixture(__filename, 'WORKSPACE2'); +const workspace3File = loadFixture(__filename, 'WORKSPACE3'); +const fileWithBzlExtension = loadFixture(__filename, 'repositories.bzl'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/bazel/update.spec.ts b/lib/manager/bazel/update.spec.ts index 41d5fadef24fb0..db2b6bc82a6009 100644 --- a/lib/manager/bazel/update.spec.ts +++ b/lib/manager/bazel/update.spec.ts @@ -1,25 +1,12 @@ -import { readFileSync } from 'fs'; import { Readable } from 'stream'; -import { resolve } from 'upath'; import * as httpMock from '../../../test/http-mock'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import type { UpdateType } from '../../config/types'; import { updateDependency } from './update'; -const content = readFileSync( - resolve('lib/manager/bazel/__fixtures__/WORKSPACE1'), - 'utf8' -); - -const contentContainerPull = readFileSync( - resolve('lib/manager/bazel/__fixtures__/container_pull'), - 'utf8' -); - -const fileWithBzlExtension = readFileSync( - 'lib/manager/bazel/__fixtures__/repositories.bzl', - 'utf8' -); +const content = loadFixture(__filename, 'WORKSPACE1'); +const contentContainerPull = loadFixture(__filename, 'container_pull'); +const fileWithBzlExtension = loadFixture(__filename, 'repositories.bzl'); /* git_repository( diff --git a/lib/manager/buildkite/extract.spec.ts b/lib/manager/buildkite/extract.spec.ts index 3d9704d1733425..911da7d3c9bf3a 100644 --- a/lib/manager/buildkite/extract.spec.ts +++ b/lib/manager/buildkite/extract.spec.ts @@ -1,23 +1,10 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; -const pipeline1 = readFileSync( - 'lib/manager/buildkite/__fixtures__/pipeline1.yml', - 'utf8' -); -const pipeline2 = readFileSync( - 'lib/manager/buildkite/__fixtures__/pipeline2.yml', - 'utf8' -); -const pipeline3 = readFileSync( - 'lib/manager/buildkite/__fixtures__/pipeline3.yml', - 'utf8' -); -const pipeline4 = readFileSync( - 'lib/manager/buildkite/__fixtures__/pipeline4.yml', - 'utf8' -); +const pipeline1 = loadFixture(__filename, 'pipeline1.yml'); +const pipeline2 = loadFixture(__filename, 'pipeline2.yml'); +const pipeline3 = loadFixture(__filename, 'pipeline3.yml'); +const pipeline4 = loadFixture(__filename, 'pipeline4.yml'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/bundler/extract.spec.ts b/lib/manager/bundler/extract.spec.ts index a70326a8cf8503..baefc8e48a5df9 100644 --- a/lib/manager/bundler/extract.spec.ts +++ b/lib/manager/bundler/extract.spec.ts @@ -1,67 +1,33 @@ -import { readFileSync } from 'fs'; -import { fs, getName } from '../../../test/util'; +import { fs, getName, loadFixture } from '../../../test/util'; import { isValid } from '../../versioning/ruby'; import { extractPackageFile } from './extract'; jest.mock('../../util/fs'); -const railsGemfile = readFileSync( - 'lib/manager/bundler/__fixtures__/Gemfile.rails', - 'utf8' -); -const railsGemfileLock = readFileSync( - 'lib/manager/bundler/__fixtures__/Gemfile.rails.lock', - 'utf8' -); +const railsGemfile = loadFixture(__filename, 'Gemfile.rails'); +const railsGemfileLock = loadFixture(__filename, 'Gemfile.rails.lock'); -const sourceGroupGemfile = readFileSync( - 'lib/manager/bundler/__fixtures__/Gemfile.sourceGroup', - 'utf8' -); -const webPackerGemfile = readFileSync( - 'lib/manager/bundler/__fixtures__/Gemfile.webpacker', - 'utf8' -); -const webPackerGemfileLock = readFileSync( - 'lib/manager/bundler/__fixtures__/Gemfile.webpacker.lock', - 'utf8' -); -const mastodonGemfile = readFileSync( - 'lib/manager/bundler/__fixtures__/Gemfile.mastodon', - 'utf8' -); -const mastodonGemfileLock = readFileSync( - 'lib/manager/bundler/__fixtures__/Gemfile.mastodon.lock', - 'utf8' -); -const rubyCIGemfileLock = readFileSync( - 'lib/manager/bundler/__fixtures__/Gemfile.rubyci.lock', - 'utf8' -); +const sourceGroupGemfile = loadFixture(__filename, 'Gemfile.sourceGroup'); +const webPackerGemfile = loadFixture(__filename, 'Gemfile.webpacker'); +const webPackerGemfileLock = loadFixture(__filename, 'Gemfile.webpacker.lock'); +const mastodonGemfile = loadFixture(__filename, 'Gemfile.mastodon'); +const mastodonGemfileLock = loadFixture(__filename, 'Gemfile.mastodon.lock'); +const rubyCIGemfileLock = loadFixture(__filename, 'Gemfile.rubyci.lock'); -const rubyCIGemfile = readFileSync( - 'lib/manager/bundler/__fixtures__/Gemfile.rubyci', - 'utf8' -); -const gitlabFossGemfileLock = readFileSync( - 'lib/manager/bundler/__fixtures__/Gemfile.gitlab-foss.lock', - 'utf8' -); -const gitlabFossGemfile = readFileSync( - 'lib/manager/bundler/__fixtures__/Gemfile.gitlab-foss', - 'utf8' -); -const sourceBlockGemfile = readFileSync( - 'lib/manager/bundler/__fixtures__/Gemfile.sourceBlock', - 'utf8' +const rubyCIGemfile = loadFixture(__filename, 'Gemfile.rubyci'); +const gitlabFossGemfileLock = loadFixture( + __filename, + 'Gemfile.gitlab-foss.lock' ); -const sourceBlockWithNewLinesGemfileLock = readFileSync( - 'lib/manager/bundler/__fixtures__/Gemfile.sourceBlockWithNewLines.lock', - 'utf8' +const gitlabFossGemfile = loadFixture(__filename, 'Gemfile.gitlab-foss'); +const sourceBlockGemfile = loadFixture(__filename, 'Gemfile.sourceBlock'); +const sourceBlockWithNewLinesGemfileLock = loadFixture( + __filename, + 'Gemfile.sourceBlockWithNewLines.lock' ); -const sourceBlockWithNewLinesGemfile = readFileSync( - 'lib/manager/bundler/__fixtures__/Gemfile.sourceBlockWithNewLines', - 'utf8' +const sourceBlockWithNewLinesGemfile = loadFixture( + __filename, + 'Gemfile.sourceBlockWithNewLines' ); function validateGems(raw, parsed) { diff --git a/lib/manager/bundler/gemfile.spec.ts b/lib/manager/bundler/gemfile.spec.ts index cee947b8a84b7f..a066c10e2f6017 100644 --- a/lib/manager/bundler/gemfile.spec.ts +++ b/lib/manager/bundler/gemfile.spec.ts @@ -1,10 +1,8 @@ -import { readFileSync } from 'fs'; +import { loadFixture } from '../../../test/util'; import { extractLockFileEntries } from './locked-version'; -const gemLockFile = readFileSync( - 'lib/manager/bundler/__fixtures__/Gemfile.rails.lock', - 'utf8' -); +const gemLockFile = loadFixture(__filename, 'Gemfile.rails.lock'); + describe('extract lib/manager/bundler/gemfile.rails.lock', () => { it('matches the expected output', () => { expect(extractLockFileEntries(gemLockFile)).toMatchSnapshot(); diff --git a/lib/manager/bundler/locked-version.spec.ts b/lib/manager/bundler/locked-version.spec.ts index 6670a10aa49115..6401691b7bb25f 100644 --- a/lib/manager/bundler/locked-version.spec.ts +++ b/lib/manager/bundler/locked-version.spec.ts @@ -1,26 +1,15 @@ -import { readFileSync } from 'fs'; +import { loadFixture } from '../../../test/util'; import { extractLockFileEntries } from './locked-version'; -const railsGemfileLock = readFileSync( - 'lib/manager/bundler/__fixtures__/Gemfile.rails.lock', - 'utf8' -); -const webPackerGemfileLock = readFileSync( - 'lib/manager/bundler/__fixtures__/Gemfile.webpacker.lock', - 'utf8' -); -const mastodonGemfileLock = readFileSync( - 'lib/manager/bundler/__fixtures__/Gemfile.mastodon.lock', - 'utf8' -); -const rubyCIGemfileLock = readFileSync( - 'lib/manager/bundler/__fixtures__/Gemfile.rubyci.lock', - 'utf8' -); -const gitlabFossGemfileLock = readFileSync( - 'lib/manager/bundler/__fixtures__/Gemfile.gitlab-foss.lock', - 'utf8' +const railsGemfileLock = loadFixture(__filename, 'Gemfile.rails.lock'); +const webPackerGemfileLock = loadFixture(__filename, 'Gemfile.webpacker.lock'); +const mastodonGemfileLock = loadFixture(__filename, 'Gemfile.mastodon.lock'); +const rubyCIGemfileLock = loadFixture(__filename, 'Gemfile.rubyci.lock'); +const gitlabFossGemfileLock = loadFixture( + __filename, + 'Gemfile.gitlab-foss.lock' ); + describe('/lib/manager/bundler/locked-version', () => { test('Parse Rails Gem Lock File', () => { const parsedLockEntries = extractLockFileEntries(railsGemfileLock); diff --git a/lib/manager/cake/index.spec.ts b/lib/manager/cake/index.spec.ts index c354776c5e0c94..eae570413174cd 100644 --- a/lib/manager/cake/index.spec.ts +++ b/lib/manager/cake/index.spec.ts @@ -1,11 +1,7 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from '.'; -const content = readFileSync( - 'lib/manager/cake/__fixtures__/build.cake', - 'utf8' -); +const content = loadFixture(__filename, 'build.cake'); describe(getName(__filename), () => { it('extracts', () => { diff --git a/lib/manager/cargo/extract.spec.ts b/lib/manager/cargo/extract.spec.ts index cfaf0d624c9d33..761785d8031a7f 100644 --- a/lib/manager/cargo/extract.spec.ts +++ b/lib/manager/cargo/extract.spec.ts @@ -1,39 +1,16 @@ -import { readFileSync } from 'fs'; import { dir } from 'tmp-promise'; import { join } from 'upath'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { setFsConfig, writeLocalFile } from '../../util/fs'; import { extractPackageFile } from './extract'; -const cargo1toml = readFileSync( - 'lib/manager/cargo/__fixtures__/Cargo.1.toml', - 'utf8' -); -const cargo2toml = readFileSync( - 'lib/manager/cargo/__fixtures__/Cargo.2.toml', - 'utf8' -); -const cargo3toml = readFileSync( - 'lib/manager/cargo/__fixtures__/Cargo.3.toml', - 'utf8' -); -const cargo4toml = readFileSync( - 'lib/manager/cargo/__fixtures__/Cargo.4.toml', - 'utf8' -); -const cargo5toml = readFileSync( - 'lib/manager/cargo/__fixtures__/Cargo.5.toml', - 'utf8' -); - -const cargo6configtoml = readFileSync( - 'lib/manager/cargo/__fixtures__/cargo.6.config.toml', - 'utf8' -); -const cargo6toml = readFileSync( - 'lib/manager/cargo/__fixtures__/Cargo.6.toml', - 'utf8' -); +const cargo1toml = loadFixture(__filename, 'Cargo.1.toml'); +const cargo2toml = loadFixture(__filename, 'Cargo.2.toml'); +const cargo3toml = loadFixture(__filename, 'Cargo.3.toml'); +const cargo4toml = loadFixture(__filename, 'Cargo.4.toml'); +const cargo5toml = loadFixture(__filename, 'Cargo.5.toml'); +const cargo6configtoml = loadFixture(__filename, 'cargo.6.config.toml'); +const cargo6toml = loadFixture(__filename, 'Cargo.6.toml'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/cdnurl/extract.spec.ts b/lib/manager/cdnurl/extract.spec.ts index 0a01f316df7612..7d03a1539fed13 100644 --- a/lib/manager/cdnurl/extract.spec.ts +++ b/lib/manager/cdnurl/extract.spec.ts @@ -1,12 +1,7 @@ -import { readFileSync } from 'fs'; -import { resolve } from 'upath'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from '.'; -const input = readFileSync( - resolve(__dirname, `./__fixtures__/sample.txt`), - 'utf8' -); +const input = loadFixture(__filename, `sample.txt`); describe(getName(__filename), () => { it('extractPackageFile', () => { diff --git a/lib/manager/circleci/extract.spec.ts b/lib/manager/circleci/extract.spec.ts index fc25189c5871b3..dc31c4a5a59b5c 100644 --- a/lib/manager/circleci/extract.spec.ts +++ b/lib/manager/circleci/extract.spec.ts @@ -1,19 +1,9 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; -const file1 = readFileSync( - 'lib/manager/circleci/__fixtures__/config.yml', - 'utf8' -); -const file2 = readFileSync( - 'lib/manager/circleci/__fixtures__/config2.yml', - 'utf8' -); -const file3 = readFileSync( - 'lib/manager/circleci/__fixtures__/config3.yml', - 'utf8' -); +const file1 = loadFixture(__filename, 'config.yml'); +const file2 = loadFixture(__filename, 'config2.yml'); +const file3 = loadFixture(__filename, 'config3.yml'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/cloudbuild/extract.spec.ts b/lib/manager/cloudbuild/extract.spec.ts index 116a38c644b384..4301cf5ccec8bb 100644 --- a/lib/manager/cloudbuild/extract.spec.ts +++ b/lib/manager/cloudbuild/extract.spec.ts @@ -1,11 +1,7 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; -const file1 = readFileSync( - 'lib/manager/cloudbuild/__fixtures__/cloudbuild.yml', - 'utf8' -); +const file1 = loadFixture(__filename, 'cloudbuild.yml'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/cocoapods/extract.spec.ts b/lib/manager/cocoapods/extract.spec.ts index 09d456474f43c4..d8e5d18dcb3278 100644 --- a/lib/manager/cocoapods/extract.spec.ts +++ b/lib/manager/cocoapods/extract.spec.ts @@ -1,18 +1,8 @@ -import fs from 'fs-extra'; -import upath from 'upath'; - -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from '.'; -const simplePodfile = fs.readFileSync( - upath.resolve(__dirname, './__fixtures__/Podfile.simple'), - 'utf-8' -); - -const complexPodfile = fs.readFileSync( - upath.resolve(__dirname, './__fixtures__/Podfile.complex'), - 'utf-8' -); +const simplePodfile = loadFixture(__filename, 'Podfile.simple'); +const complexPodfile = loadFixture(__filename, 'Podfile.complex'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/composer/extract.spec.ts b/lib/manager/composer/extract.spec.ts index 04bf9d7121ffdd..f7dc652ef6df87 100644 --- a/lib/manager/composer/extract.spec.ts +++ b/lib/manager/composer/extract.spec.ts @@ -1,33 +1,14 @@ -import { readFileSync } from 'fs'; -import { fs, getName } from '../../../test/util'; +import { fs, getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; jest.mock('../../util/fs'); -const requirements1 = readFileSync( - 'lib/manager/composer/__fixtures__/composer1.json', - 'utf8' -); -const requirements2 = readFileSync( - 'lib/manager/composer/__fixtures__/composer2.json', - 'utf8' -); -const requirements3 = readFileSync( - 'lib/manager/composer/__fixtures__/composer3.json', - 'utf8' -); -const requirements4 = readFileSync( - 'lib/manager/composer/__fixtures__/composer4.json', - 'utf8' -); -const requirements5 = readFileSync( - 'lib/manager/composer/__fixtures__/composer5.json', - 'utf8' -); -const requirements5Lock = readFileSync( - 'lib/manager/composer/__fixtures__/composer5.lock', - 'utf8' -); +const requirements1 = loadFixture(__filename, 'composer1.json'); +const requirements2 = loadFixture(__filename, 'composer2.json'); +const requirements3 = loadFixture(__filename, 'composer3.json'); +const requirements4 = loadFixture(__filename, 'composer4.json'); +const requirements5 = loadFixture(__filename, 'composer5.json'); +const requirements5Lock = loadFixture(__filename, 'composer5.lock'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/deps-edn/extract.spec.ts b/lib/manager/deps-edn/extract.spec.ts index dd550044a7196c..b240919bb75bdd 100644 --- a/lib/manager/deps-edn/extract.spec.ts +++ b/lib/manager/deps-edn/extract.spec.ts @@ -1,13 +1,7 @@ -/* eslint-disable no-template-curly-in-string */ -import { readFileSync } from 'fs'; -import { resolve } from 'upath'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; -const depsEdn = readFileSync( - resolve(__dirname, `./__fixtures__/deps.edn`), - 'utf8' -); +const depsEdn = loadFixture(__filename, 'deps.edn'); describe(getName(__filename), () => { it('extractPackageFile', () => { diff --git a/lib/manager/docker-compose/extract.spec.ts b/lib/manager/docker-compose/extract.spec.ts index 915e00345f0f1c..4cca8cd425415c 100644 --- a/lib/manager/docker-compose/extract.spec.ts +++ b/lib/manager/docker-compose/extract.spec.ts @@ -1,20 +1,11 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; -const yamlFile1 = readFileSync( - 'lib/manager/docker-compose/__fixtures__/docker-compose.1.yml', - 'utf8' -); - -const yamlFile3 = readFileSync( - 'lib/manager/docker-compose/__fixtures__/docker-compose.3.yml', - 'utf8' -); - -const yamlFile3NoVersion = readFileSync( - 'lib/manager/docker-compose/__fixtures__/docker-compose.3-no-version.yml', - 'utf8' +const yamlFile1 = loadFixture(__filename, 'docker-compose.1.yml'); +const yamlFile3 = loadFixture(__filename, 'docker-compose.3.yml'); +const yamlFile3NoVersion = loadFixture( + __filename, + 'docker-compose.3-no-version.yml' ); describe(getName(__filename), () => { diff --git a/lib/manager/dockerfile/extract.spec.ts b/lib/manager/dockerfile/extract.spec.ts index fcdf3409bcb4d6..6a72adff49ac56 100644 --- a/lib/manager/dockerfile/extract.spec.ts +++ b/lib/manager/dockerfile/extract.spec.ts @@ -1,16 +1,8 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile, getDep } from './extract'; -const d1 = readFileSync( - 'lib/manager/dockerfile/__fixtures__/1.Dockerfile', - 'utf8' -); - -const d2 = readFileSync( - 'lib/manager/dockerfile/__fixtures__/2.Dockerfile', - 'utf8' -); +const d1 = loadFixture(__filename, '1.Dockerfile'); +const d2 = loadFixture(__filename, '2.Dockerfile'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/droneci/extract.spec.ts b/lib/manager/droneci/extract.spec.ts index 585137d56d0d85..3855871bb729f7 100644 --- a/lib/manager/droneci/extract.spec.ts +++ b/lib/manager/droneci/extract.spec.ts @@ -1,13 +1,8 @@ -import { readFileSync } from 'fs'; -import { resolve } from 'upath'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; -const droneYAML = readFileSync( - resolve('lib/manager/droneci/__fixtures__/.drone.yml'), - 'utf8' -); +const droneYAML = loadFixture(__filename, '.drone.yml'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/github-actions/extract.spec.ts b/lib/manager/github-actions/extract.spec.ts index 9e607beda7426c..96b57906990614 100644 --- a/lib/manager/github-actions/extract.spec.ts +++ b/lib/manager/github-actions/extract.spec.ts @@ -1,16 +1,8 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; -const workflow1 = readFileSync( - 'lib/manager/github-actions/__fixtures__/workflow.yml.1', - 'utf8' -); - -const workflow2 = readFileSync( - 'lib/manager/github-actions/__fixtures__/workflow.yml.2', - 'utf8' -); +const workflow1 = loadFixture(__filename, 'workflow.yml.1'); +const workflow2 = loadFixture(__filename, 'workflow.yml.2'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/gitlabci-include/extract.spec.ts b/lib/manager/gitlabci-include/extract.spec.ts index f7083030c5e110..d0e561f84c941b 100644 --- a/lib/manager/gitlabci-include/extract.spec.ts +++ b/lib/manager/gitlabci-include/extract.spec.ts @@ -1,11 +1,7 @@ -import fs from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; -const yamlFile = fs.readFileSync( - 'lib/manager/gitlabci-include/__fixtures__/gitlab-ci.1.yaml', - 'utf8' -); +const yamlFile = loadFixture(__filename, 'gitlab-ci.1.yaml'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/gomod/extract.spec.ts b/lib/manager/gomod/extract.spec.ts index d0ae06a506032d..e24ba7a50eee1a 100644 --- a/lib/manager/gomod/extract.spec.ts +++ b/lib/manager/gomod/extract.spec.ts @@ -1,10 +1,9 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; -const gomod1 = readFileSync('lib/manager/gomod/__fixtures__/1/go.mod', 'utf8'); -const gomod2 = readFileSync('lib/manager/gomod/__fixtures__/2/go.mod', 'utf8'); -const gomod3 = readFileSync('lib/manager/gomod/__fixtures__/3/go.mod', 'utf8'); +const gomod1 = loadFixture(__filename, '1/go.mod'); +const gomod2 = loadFixture(__filename, '2/go.mod'); +const gomod3 = loadFixture(__filename, '3/go.mod'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/gomod/update.spec.ts b/lib/manager/gomod/update.spec.ts index 6dfba946bf02b0..eb03ca3cfc6806 100644 --- a/lib/manager/gomod/update.spec.ts +++ b/lib/manager/gomod/update.spec.ts @@ -1,10 +1,9 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import type { UpdateType } from '../../config/types'; import { updateDependency } from './update'; -const gomod1 = readFileSync('lib/manager/gomod/__fixtures__/1/go.mod', 'utf8'); -const gomod2 = readFileSync('lib/manager/gomod/__fixtures__/2/go.mod', 'utf8'); +const gomod1 = loadFixture(__filename, '1/go.mod'); +const gomod2 = loadFixture(__filename, '2/go.mod'); describe(getName(__filename), () => { describe('updateDependency', () => { diff --git a/lib/manager/gradle-lite/parser.spec.ts b/lib/manager/gradle-lite/parser.spec.ts index 560d365dbdf88a..972653ff4bff10 100644 --- a/lib/manager/gradle-lite/parser.spec.ts +++ b/lib/manager/gradle-lite/parser.spec.ts @@ -1,13 +1,7 @@ -import { readFileSync } from 'fs'; -import path from 'path'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { GOOGLE_REPO, JCENTER_REPO, MAVEN_REPO } from './common'; import { parseGradle, parseProps } from './parser'; -function getGradleFile(fileName: string): string { - return readFileSync(path.resolve(__dirname, fileName), 'utf8'); -} - describe(getName(__filename), () => { it('handles end of input', () => { expect(parseGradle('version = ').deps).toBeEmpty(); @@ -162,8 +156,10 @@ describe(getName(__filename), () => { ]); }); it('parses fixture from "gradle" manager', () => { - const content = getGradleFile( - `../gradle/__fixtures__/build.gradle.example1` + const content = loadFixture( + __filename, + 'build.gradle.example1', + '../gradle' ); const { deps } = parseGradle(content, {}, 'build.gradle'); deps.forEach((dep) => { diff --git a/lib/manager/gradle-wrapper/extract.spec.ts b/lib/manager/gradle-wrapper/extract.spec.ts index b3d3a149d131c7..f436ccdafdc953 100644 --- a/lib/manager/gradle-wrapper/extract.spec.ts +++ b/lib/manager/gradle-wrapper/extract.spec.ts @@ -1,27 +1,13 @@ -import { readFileSync } from 'fs'; -import { resolve } from 'upath'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; -const propertiesFile1 = readFileSync( - resolve(__dirname, './__fixtures__/gradle-wrapper-1.properties'), - 'utf8' -); -const propertiesFile2 = readFileSync( - resolve(__dirname, './__fixtures__/gradle-wrapper-2.properties'), - 'utf8' -); -const propertiesFile3 = readFileSync( - resolve(__dirname, './__fixtures__/gradle-wrapper-3.properties'), - 'utf8' -); -const propertiesFile4 = readFileSync( - resolve(__dirname, './__fixtures__/gradle-wrapper-4.properties'), - 'utf8' -); -const whitespacePropertiesFile = readFileSync( - resolve(__dirname, './__fixtures__/gradle-wrapper-whitespace.properties'), - 'utf8' +const propertiesFile1 = loadFixture(__filename, 'gradle-wrapper-1.properties'); +const propertiesFile2 = loadFixture(__filename, 'gradle-wrapper-2.properties'); +const propertiesFile3 = loadFixture(__filename, 'gradle-wrapper-3.properties'); +const propertiesFile4 = loadFixture(__filename, 'gradle-wrapper-4.properties'); +const whitespacePropertiesFile = loadFixture( + __filename, + 'gradle-wrapper-whitespace.properties' ); describe(getName(__filename), () => { diff --git a/lib/manager/helm-values/extract.spec.ts b/lib/manager/helm-values/extract.spec.ts index 3db74c265e3d8c..53fbc347837df3 100644 --- a/lib/manager/helm-values/extract.spec.ts +++ b/lib/manager/helm-values/extract.spec.ts @@ -1,15 +1,14 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; -const helmDefaultChartInitValues = readFileSync( - 'lib/manager/helm-values/__fixtures__/default_chart_init_values.yaml', - 'utf8' +const helmDefaultChartInitValues = loadFixture( + __filename, + 'default_chart_init_values.yaml' ); -const helmMultiAndNestedImageValues = readFileSync( - 'lib/manager/helm-values/__fixtures__/multi_and_nested_image_values.yaml', - 'utf8' +const helmMultiAndNestedImageValues = loadFixture( + __filename, + 'multi_and_nested_image_values.yaml' ); describe(getName(__filename), () => { diff --git a/lib/manager/helmfile/extract.spec.ts b/lib/manager/helmfile/extract.spec.ts index 7c983e6c7a807a..3a3888575aae4c 100644 --- a/lib/manager/helmfile/extract.spec.ts +++ b/lib/manager/helmfile/extract.spec.ts @@ -1,11 +1,8 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; -const multidocYaml = readFileSync( - 'lib/manager/helmfile/__fixtures__/multidoc.yaml', - 'utf8' -); +const multidocYaml = loadFixture(__filename, 'multidoc.yaml'); + describe(getName(__filename), () => { describe('extractPackageFile()', () => { beforeEach(() => { diff --git a/lib/manager/homebrew/extract.spec.ts b/lib/manager/homebrew/extract.spec.ts index d4c61f7d27f3e4..b4e8f6d8d87662 100644 --- a/lib/manager/homebrew/extract.spec.ts +++ b/lib/manager/homebrew/extract.spec.ts @@ -1,24 +1,11 @@ -import fs from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; -const aalib = fs.readFileSync( - 'lib/manager/homebrew/__fixtures__/aalib.rb', - 'utf8' -); -const aap = fs.readFileSync('lib/manager/homebrew/__fixtures__/aap.rb', 'utf8'); -const acmetool = fs.readFileSync( - 'lib/manager/homebrew/__fixtures__/acmetool.rb', - 'utf8' -); -const aide = fs.readFileSync( - 'lib/manager/homebrew/__fixtures__/aide.rb', - 'utf8' -); -const ibazel = fs.readFileSync( - 'lib/manager/homebrew/__fixtures__/ibazel.rb', - 'utf8' -); +const aalib = loadFixture(__filename, 'aalib.rb'); +const aap = loadFixture(__filename, 'aap.rb'); +const acmetool = loadFixture(__filename, 'acmetool.rb'); +const aide = loadFixture(__filename, 'aide.rb'); +const ibazel = loadFixture(__filename, 'ibazel.rb'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/homebrew/update.spec.ts b/lib/manager/homebrew/update.spec.ts index 84aafa850acaba..ad7f6df4a7ec8d 100644 --- a/lib/manager/homebrew/update.spec.ts +++ b/lib/manager/homebrew/update.spec.ts @@ -1,17 +1,10 @@ -import fs from 'fs'; import { Readable } from 'stream'; import * as httpMock from '../../../test/http-mock'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { updateDependency } from './update'; -const aide = fs.readFileSync( - 'lib/manager/homebrew/__fixtures__/aide.rb', - 'utf8' -); -const ibazel = fs.readFileSync( - 'lib/manager/homebrew/__fixtures__/ibazel.rb', - 'utf8' -); +const aide = loadFixture(__filename, 'aide.rb'); +const ibazel = loadFixture(__filename, 'ibazel.rb'); const baseUrl = 'https://github.com'; diff --git a/lib/manager/html/extract.spec.ts b/lib/manager/html/extract.spec.ts index 7f27a8eb30428c..20bfa9720bd4eb 100644 --- a/lib/manager/html/extract.spec.ts +++ b/lib/manager/html/extract.spec.ts @@ -1,16 +1,8 @@ -import { readFileSync } from 'fs'; -import { resolve } from 'upath'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from '.'; -const sample = readFileSync( - resolve(__dirname, `./__fixtures__/sample.html`), - 'utf8' -); -const nothing = readFileSync( - resolve(__dirname, `./__fixtures__/nothing.html`), - 'utf8' -); +const sample = loadFixture(__filename, `sample.html`); +const nothing = loadFixture(__filename, `nothing.html`); describe(getName(__filename), () => { it('extractPackageFile', () => { diff --git a/lib/manager/jenkins/extract.spec.ts b/lib/manager/jenkins/extract.spec.ts index 36775a6e261ffa..b9481d1576ec40 100644 --- a/lib/manager/jenkins/extract.spec.ts +++ b/lib/manager/jenkins/extract.spec.ts @@ -1,29 +1,13 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; -const invalidYamlFile = readFileSync( - 'lib/manager/jenkins/__fixtures__/invalid.yaml', - 'utf8' -); - -const pluginsTextFile = readFileSync( - 'lib/manager/jenkins/__fixtures__/plugins.txt', - 'utf8' -); -const pluginsYamlFile = readFileSync( - 'lib/manager/jenkins/__fixtures__/plugins.yaml', - 'utf8' -); - -const pluginsEmptyTextFile = readFileSync( - 'lib/manager/jenkins/__fixtures__/empty.txt', - 'utf8' -); -const pluginsEmptyYamlFile = readFileSync( - 'lib/manager/jenkins/__fixtures__/empty.yaml', - 'utf8' -); +const invalidYamlFile = loadFixture(__filename, 'invalid.yaml'); + +const pluginsTextFile = loadFixture(__filename, 'plugins.txt'); +const pluginsYamlFile = loadFixture(__filename, 'plugins.yaml'); + +const pluginsEmptyTextFile = loadFixture(__filename, 'empty.txt'); +const pluginsEmptyYamlFile = loadFixture(__filename, 'empty.yaml'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/kubernetes/extract.spec.ts b/lib/manager/kubernetes/extract.spec.ts index 8862eaf8c09383..04fe288e18c451 100644 --- a/lib/manager/kubernetes/extract.spec.ts +++ b/lib/manager/kubernetes/extract.spec.ts @@ -1,26 +1,10 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; -const kubernetesImagesFile = readFileSync( - 'lib/manager/kubernetes/__fixtures__/kubernetes.yaml', - 'utf8' -); - -const kubernetesConfigMapFile = readFileSync( - 'lib/manager/kubernetes/__fixtures__/configmap.yaml', - 'utf8' -); - -const kubernetesArraySyntaxFile = readFileSync( - 'lib/manager/kubernetes/__fixtures__/array-syntax.yaml', - 'utf8' -); - -const otherYamlFile = readFileSync( - 'lib/manager/kubernetes/__fixtures__/gitlab-ci.yaml', - 'utf8' -); +const kubernetesImagesFile = loadFixture(__filename, 'kubernetes.yaml'); +const kubernetesConfigMapFile = loadFixture(__filename, 'configmap.yaml'); +const kubernetesArraySyntaxFile = loadFixture(__filename, 'array-syntax.yaml'); +const otherYamlFile = loadFixture(__filename, 'gitlab-ci.yaml'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/kustomize/extract.spec.ts b/lib/manager/kustomize/extract.spec.ts index f7330ce303e06b..e4da4782aed016 100644 --- a/lib/manager/kustomize/extract.spec.ts +++ b/lib/manager/kustomize/extract.spec.ts @@ -1,5 +1,4 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import * as datasourceDocker from '../../datasource/docker'; import * as datasourceGitTags from '../../datasource/git-tags'; import * as datasourceGitHubTags from '../../datasource/github-tags'; @@ -11,47 +10,18 @@ import { parseKustomize, } from './extract'; -const kustomizeGitSSHBase = readFileSync( - 'lib/manager/kustomize/__fixtures__/gitSshBase.yaml', - 'utf8' +const kustomizeGitSSHBase = loadFixture(__filename, 'gitSshBase.yaml'); +const kustomizeEmpty = loadFixture(__filename, 'kustomizeEmpty.yaml'); +const kustomizeGitSSHSubdir = loadFixture(__filename, 'gitSubdir.yaml'); +const kustomizeHTTP = loadFixture(__filename, 'kustomizeHttp.yaml'); +const kustomizeWithLocal = loadFixture(__filename, 'kustomizeWithLocal.yaml'); +const nonKustomize = loadFixture(__filename, 'service.yaml'); +const gitImages = loadFixture(__filename, 'gitImages.yaml'); +const kustomizeDepsInResources = loadFixture( + __filename, + 'depsInResources.yaml' ); - -const kustomizeEmpty = readFileSync( - 'lib/manager/kustomize/__fixtures__/kustomizeEmpty.yaml', - 'utf8' -); - -const kustomizeGitSSHSubdir = readFileSync( - 'lib/manager/kustomize/__fixtures__/gitSubdir.yaml', - 'utf8' -); - -const kustomizeHTTP = readFileSync( - 'lib/manager/kustomize/__fixtures__/kustomizeHttp.yaml', - 'utf8' -); - -const kustomizeWithLocal = readFileSync( - 'lib/manager/kustomize/__fixtures__/kustomizeWithLocal.yaml', - 'utf8' -); - -const nonKustomize = readFileSync( - 'lib/manager/kustomize/__fixtures__/service.yaml', - 'utf8' -); - -const gitImages = readFileSync( - 'lib/manager/kustomize/__fixtures__/gitImages.yaml', - 'utf8' -); - -const kustomizeDepsInResources = readFileSync( - 'lib/manager/kustomize/__fixtures__/depsInResources.yaml', - 'utf8' -); - -const sha = readFileSync('lib/manager/kustomize/__fixtures__/sha.yaml', 'utf8'); +const sha = loadFixture(__filename, 'sha.yaml'); describe(getName(__filename), () => { it('should successfully parse a valid kustomize file', () => { diff --git a/lib/manager/leiningen/extract.spec.ts b/lib/manager/leiningen/extract.spec.ts index 22a261641037e1..681db83205e449 100644 --- a/lib/manager/leiningen/extract.spec.ts +++ b/lib/manager/leiningen/extract.spec.ts @@ -1,14 +1,8 @@ -/* eslint-disable no-template-curly-in-string */ -import { readFileSync } from 'fs'; -import { resolve } from 'upath'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import * as datasourceClojure from '../../datasource/clojure'; import { extractFromVectors, extractPackageFile, trimAtKey } from './extract'; -const leinProjectClj = readFileSync( - resolve(__dirname, `./__fixtures__/project.clj`), - 'utf8' -); +const leinProjectClj = loadFixture(__filename, `project.clj`); describe(getName(__filename), () => { it('trimAtKey', () => { diff --git a/lib/manager/maven/extract.spec.ts b/lib/manager/maven/extract.spec.ts index 8ba6f952187249..36c443fe3faafd 100644 --- a/lib/manager/maven/extract.spec.ts +++ b/lib/manager/maven/extract.spec.ts @@ -1,18 +1,9 @@ /* eslint-disable no-template-curly-in-string */ -import { readFileSync } from 'fs'; -import { resolve } from 'upath'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackage } from './extract'; -const minimumContent = readFileSync( - resolve(__dirname, `./__fixtures__/minimum.pom.xml`), - 'utf8' -); - -const simpleContent = readFileSync( - resolve(__dirname, `./__fixtures__/simple.pom.xml`), - 'utf8' -); +const minimumContent = loadFixture(__filename, `minimum.pom.xml`); +const simpleContent = loadFixture(__filename, `simple.pom.xml`); describe(getName(__filename), () => { describe('extractDependencies', () => { diff --git a/lib/manager/maven/index.spec.ts b/lib/manager/maven/index.spec.ts index 548b71f42629f9..4be69a337c6dbc 100644 --- a/lib/manager/maven/index.spec.ts +++ b/lib/manager/maven/index.spec.ts @@ -1,27 +1,14 @@ -import { readFileSync } from 'fs'; -import { fs, getName } from '../../../test/util'; +import { fs, getName, loadFixture } from '../../../test/util'; import type { PackageDependency, PackageFile } from '../types'; import { extractPackage, resolveParents } from './extract'; import { extractAllPackageFiles, updateDependency } from '.'; jest.mock('../../util/fs'); -const pomContent = readFileSync( - 'lib/manager/maven/__fixtures__/simple.pom.xml', - 'utf8' -); -const pomParent = readFileSync( - 'lib/manager/maven/__fixtures__/parent.pom.xml', - 'utf8' -); -const pomChild = readFileSync( - 'lib/manager/maven/__fixtures__/child.pom.xml', - 'utf8' -); -const origContent = readFileSync( - 'lib/manager/maven/__fixtures__/grouping.pom.xml', - 'utf8' -); +const pomContent = loadFixture(__filename, 'simple.pom.xml'); +const pomParent = loadFixture(__filename, 'parent.pom.xml'); +const pomChild = loadFixture(__filename, 'child.pom.xml'); +const origContent = loadFixture(__filename, 'grouping.pom.xml'); function selectDep(deps: PackageDependency[], name = 'org.example:quuz') { return deps.find((dep) => dep.depName === name); diff --git a/lib/manager/meteor/extract.spec.ts b/lib/manager/meteor/extract.spec.ts index 6bfb2f18671161..7171f035823bc0 100644 --- a/lib/manager/meteor/extract.spec.ts +++ b/lib/manager/meteor/extract.spec.ts @@ -1,13 +1,7 @@ -import { readFileSync } from 'fs'; -import { resolve } from 'upath'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; -function readFixture(fixture: string) { - return readFileSync(resolve(__dirname, `./__fixtures__/${fixture}`), 'utf8'); -} - -const input01Content = readFixture('package-1.js'); +const input01Content = loadFixture(__filename, 'package-1.js'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/mix/extract.spec.ts b/lib/manager/mix/extract.spec.ts index b350d5750f66f1..834c210a500389 100644 --- a/lib/manager/mix/extract.spec.ts +++ b/lib/manager/mix/extract.spec.ts @@ -1,12 +1,7 @@ -import fs from 'fs-extra'; -import upath from 'upath'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from '.'; -const sample = fs.readFileSync( - upath.resolve(__dirname, './__fixtures__/mix.exs'), - 'utf-8' -); +const sample = loadFixture(__filename, 'mix.exs'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/npm/extract/index.spec.ts b/lib/manager/npm/extract/index.spec.ts index beda16f2a1b85c..b4ea83e1ef2eda 100644 --- a/lib/manager/npm/extract/index.spec.ts +++ b/lib/manager/npm/extract/index.spec.ts @@ -1,6 +1,4 @@ -import { readFileSync } from 'fs'; -import upath from 'upath'; -import { getName } from '../../../../test/util'; +import { getName, loadFixture } from '../../../../test/util'; import { getConfig } from '../../../config/defaults'; import * as _fs from '../../../util/fs'; import * as npmExtract from '.'; @@ -10,18 +8,19 @@ const fs: any = _fs; // TODO: fix types const defaultConfig = getConfig(); -function readFixture(fixture: string) { - return readFileSync( - upath.resolve(__dirname, `../__fixtures__/${fixture}`), - 'utf8' - ); -} - -const input01Content = readFixture('inputs/01.json'); -const workspacesContent = readFixture('inputs/workspaces.json'); -const workspacesSimpleContent = readFixture('inputs/workspaces-simple.json'); -const vendorisedContent = readFixture('is-object.json'); -const invalidNameContent = readFixture('invalid-name.json'); +const input01Content = loadFixture(__filename, 'inputs/01.json', '..'); +const workspacesContent = loadFixture( + __filename, + 'inputs/workspaces.json', + '..' +); +const workspacesSimpleContent = loadFixture( + __filename, + 'inputs/workspaces-simple.json', + '..' +); +const vendorisedContent = loadFixture(__filename, 'is-object.json', '..'); +const invalidNameContent = loadFixture(__filename, 'invalid-name.json', '..'); describe(getName(__filename), () => { describe('.extractPackageFile()', () => { diff --git a/lib/manager/npm/extract/npm.spec.ts b/lib/manager/npm/extract/npm.spec.ts index 4a9962c4027198..1946d3e61eb9b8 100644 --- a/lib/manager/npm/extract/npm.spec.ts +++ b/lib/manager/npm/extract/npm.spec.ts @@ -1,5 +1,4 @@ -import { readFileSync } from 'fs'; -import { fs, getName } from '../../../../test/util'; +import { fs, getName, loadFixture } from '../../../../test/util'; import { getNpmLock } from './npm'; jest.mock('../../../util/fs'); @@ -12,8 +11,10 @@ describe(getName(__filename), () => { expect(Object.keys(res.lockedVersions)).toHaveLength(0); }); it('extracts', async () => { - const plocktest1Lock = readFileSync( - 'lib/manager/npm/__fixtures__/plocktest1/package-lock.json' + const plocktest1Lock = loadFixture( + __filename, + 'plocktest1/package-lock.json', + '..' ); fs.readLocalFile.mockResolvedValueOnce(plocktest1Lock as never); const res = await getNpmLock('package.json'); @@ -21,9 +22,7 @@ describe(getName(__filename), () => { expect(Object.keys(res.lockedVersions)).toHaveLength(7); }); it('extracts npm 7 lockfile', async () => { - const npm7Lock = readFileSync( - 'lib/manager/npm/__fixtures__/npm7/package-lock.json' - ); + const npm7Lock = loadFixture(__filename, 'npm7/package-lock.json', '..'); fs.readLocalFile.mockResolvedValueOnce(npm7Lock as never); const res = await getNpmLock('package.json'); expect(res).toMatchSnapshot(); diff --git a/lib/manager/npm/extract/yarn.spec.ts b/lib/manager/npm/extract/yarn.spec.ts index 9b91d267724422..9882b371471882 100644 --- a/lib/manager/npm/extract/yarn.spec.ts +++ b/lib/manager/npm/extract/yarn.spec.ts @@ -1,5 +1,4 @@ -import { readFileSync } from 'fs'; -import { fs, getName } from '../../../../test/util'; +import { fs, getName, loadFixture } from '../../../../test/util'; import { getYarnLock } from './yarn'; jest.mock('../../../util/fs'); @@ -14,9 +13,10 @@ describe(getName(__filename), () => { }); it('extracts yarn 1', async () => { - const plocktest1Lock = readFileSync( - 'lib/manager/npm/__fixtures__/plocktest1/yarn.lock', - 'utf8' + const plocktest1Lock = loadFixture( + __filename, + 'plocktest1/yarn.lock', + '..' ); fs.readLocalFile.mockResolvedValueOnce(plocktest1Lock); const res = await getYarnLock('package.json'); @@ -27,10 +27,7 @@ describe(getName(__filename), () => { }); it('extracts yarn 2', async () => { - const plocktest1Lock = readFileSync( - 'lib/manager/npm/__fixtures__/yarn2/yarn.lock', - 'utf8' - ); + const plocktest1Lock = loadFixture(__filename, 'yarn2/yarn.lock', '..'); fs.readLocalFile.mockResolvedValueOnce(plocktest1Lock); const res = await getYarnLock('package.json'); expect(res.isYarn1).toBe(false); @@ -40,10 +37,7 @@ describe(getName(__filename), () => { }); it('extracts yarn 2 cache version', async () => { - const plocktest1Lock = readFileSync( - 'lib/manager/npm/__fixtures__/yarn2.2/yarn.lock', - 'utf8' - ); + const plocktest1Lock = loadFixture(__filename, 'yarn2.2/yarn.lock', '..'); fs.readLocalFile.mockResolvedValueOnce(plocktest1Lock); const res = await getYarnLock('package.json'); expect(res.isYarn1).toBe(false); diff --git a/lib/manager/npm/update/dependency/index.spec.ts b/lib/manager/npm/update/dependency/index.spec.ts index a663e644d3a2f4..b2a2c177b3a483 100644 --- a/lib/manager/npm/update/dependency/index.spec.ts +++ b/lib/manager/npm/update/dependency/index.spec.ts @@ -1,15 +1,7 @@ -import fs from 'fs'; -import upath from 'upath'; - -import { getName } from '../../../../../test/util'; +import { getName, loadFixture } from '../../../../../test/util'; import * as npmUpdater from '.'; -function readFixture(fixture: string) { - return fs.readFileSync( - upath.resolve(__dirname, `../../__fixtures__/${fixture}`), - 'utf8' - ); -} +const readFixture = (x: string): string => loadFixture(__filename, x, '../..'); const input01Content = readFixture('inputs/01.json'); const input01GlobContent = readFixture('inputs/01-glob.json'); diff --git a/lib/manager/npm/update/locked-dependency/dep-constraints.spec.ts b/lib/manager/npm/update/locked-dependency/dep-constraints.spec.ts index 47e0122b741f8c..577b9317221bf9 100644 --- a/lib/manager/npm/update/locked-dependency/dep-constraints.spec.ts +++ b/lib/manager/npm/update/locked-dependency/dep-constraints.spec.ts @@ -1,16 +1,10 @@ -import { readFileSync } from 'fs'; -import { resolve } from 'upath'; -import { getName } from '../../../../../test/util'; +import { getName, loadJsonFixture } from '../../../../../test/util'; import { findDepConstraints } from './dep-constraints'; jest.mock('../../../../util/fs'); -const packageJson = JSON.parse( - readFileSync(resolve(__dirname, './__fixtures__/package.json'), 'utf8') -); -const packageLockJson = JSON.parse( - readFileSync(resolve(__dirname, './__fixtures__/package-lock.json'), 'utf8') -); +const packageJson = loadJsonFixture(__filename, 'package.json'); +const packageLockJson = loadJsonFixture(__filename, 'package-lock.json'); describe(getName(__filename), () => { describe('findDepConstraints()', () => { diff --git a/lib/manager/npm/update/locked-dependency/get-locked.spec.ts b/lib/manager/npm/update/locked-dependency/get-locked.spec.ts index f6ee9de18acee9..80370af9e543ac 100644 --- a/lib/manager/npm/update/locked-dependency/get-locked.spec.ts +++ b/lib/manager/npm/update/locked-dependency/get-locked.spec.ts @@ -1,13 +1,9 @@ -import { readFileSync } from 'fs'; -import { resolve } from 'upath'; -import { getName } from '../../../../../test/util'; +import { getName, loadJsonFixture } from '../../../../../test/util'; import { getLockedDependencies } from './get-locked'; jest.mock('../../../../util/fs'); -const packageLockJson = JSON.parse( - readFileSync(resolve(__dirname, './__fixtures__/package-lock.json'), 'utf8') -); +const packageLockJson = loadJsonFixture(__filename, 'package-lock.json'); describe(getName(__filename), () => { describe('getLockedDependencies()', () => { diff --git a/lib/manager/npm/update/locked-dependency/index.spec.ts b/lib/manager/npm/update/locked-dependency/index.spec.ts index b5cff2f0e15a15..ebcda222783838 100644 --- a/lib/manager/npm/update/locked-dependency/index.spec.ts +++ b/lib/manager/npm/update/locked-dependency/index.spec.ts @@ -1,43 +1,19 @@ -import { readFileSync } from 'fs'; -import { resolve } from 'upath'; import * as httpMock from '../../../../../test/http-mock'; -import { getName } from '../../../../../test/util'; +import { getName, loadFixture } from '../../../../../test/util'; import { clone } from '../../../../util/clone'; import type { UpdateLockedConfig } from '../../../types'; import { updateLockedDependency } from '.'; -const packageFileContent = readFileSync( - resolve(__dirname, './__fixtures__/package.json'), - 'utf8' -); -const lockFileContent = readFileSync( - resolve(__dirname, './__fixtures__/package-lock.json'), - 'utf8' -); - -const acceptsJson = JSON.parse( - readFileSync(resolve(__dirname, './__fixtures__/accepts.json'), 'utf8') -); - -const expressJson = JSON.parse( - readFileSync(resolve(__dirname, './__fixtures__/express.json'), 'utf8') -); - -const mimeJson = JSON.parse( - readFileSync(resolve(__dirname, './__fixtures__/mime.json'), 'utf8') -); - +const packageFileContent = loadFixture(__filename, 'package.json'); +const lockFileContent = loadFixture(__filename, 'package-lock.json'); +const acceptsJson = JSON.parse(loadFixture(__filename, 'accepts.json')); +const expressJson = JSON.parse(loadFixture(__filename, 'express.json')); +const mimeJson = JSON.parse(loadFixture(__filename, 'mime.json')); const serveStaticJson = JSON.parse( - readFileSync(resolve(__dirname, './__fixtures__/serve-static.json'), 'utf8') -); - -const sendJson = JSON.parse( - readFileSync(resolve(__dirname, './__fixtures__/send.json'), 'utf8') -); - -const typeIsJson = JSON.parse( - readFileSync(resolve(__dirname, './__fixtures__/type-is.json'), 'utf8') + loadFixture(__filename, 'serve-static.json') ); +const sendJson = JSON.parse(loadFixture(__filename, 'send.json')); +const typeIsJson = JSON.parse(loadFixture(__filename, 'type-is.json')); describe(getName(__filename), () => { describe('updateLockedDependency()', () => { diff --git a/lib/manager/npm/update/locked-dependency/parent-version.spec.ts b/lib/manager/npm/update/locked-dependency/parent-version.spec.ts index ee2e5a7c3d5370..0e5717c181a216 100644 --- a/lib/manager/npm/update/locked-dependency/parent-version.spec.ts +++ b/lib/manager/npm/update/locked-dependency/parent-version.spec.ts @@ -1,12 +1,8 @@ -import { readFileSync } from 'fs'; -import { resolve } from 'upath'; import * as httpMock from '../../../../../test/http-mock'; -import { getName } from '../../../../../test/util'; +import { getName, loadJsonFixture } from '../../../../../test/util'; import { findFirstParentVersion } from './parent-version'; -const expressJson = JSON.parse( - readFileSync(resolve(__dirname, './__fixtures__/express.json'), 'utf8') -); +const expressJson = loadJsonFixture(__filename, 'express.json'); describe(getName(__filename), () => { describe('getLockedDependencies()', () => { diff --git a/lib/manager/pip_requirements/extract.spec.ts b/lib/manager/pip_requirements/extract.spec.ts index 9607c03eebc135..886f6059fe10c0 100644 --- a/lib/manager/pip_requirements/extract.spec.ts +++ b/lib/manager/pip_requirements/extract.spec.ts @@ -1,40 +1,14 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { setAdminConfig } from '../../config/admin'; import { extractPackageFile } from './extract'; -const requirements1 = readFileSync( - 'lib/manager/pip_requirements/__fixtures__/requirements1.txt', - 'utf8' -); -const requirements2 = readFileSync( - 'lib/manager/pip_requirements/__fixtures__/requirements2.txt', - 'utf8' -); -const requirements3 = readFileSync( - 'lib/manager/pip_requirements/__fixtures__/requirements3.txt', - 'utf8' -); - -const requirements4 = readFileSync( - 'lib/manager/pip_requirements/__fixtures__/requirements4.txt', - 'utf8' -); - -const requirements5 = readFileSync( - 'lib/manager/pip_requirements/__fixtures__/requirements5.txt', - 'utf8' -); - -const requirements6 = readFileSync( - 'lib/manager/pip_requirements/__fixtures__/requirements6.txt', - 'utf8' -); - -const requirements7 = readFileSync( - 'lib/manager/pip_requirements/__fixtures__/requirements7.txt', - 'utf8' -); +const requirements1 = loadFixture(__filename, 'requirements1.txt'); +const requirements2 = loadFixture(__filename, 'requirements2.txt'); +const requirements3 = loadFixture(__filename, 'requirements3.txt'); +const requirements4 = loadFixture(__filename, 'requirements4.txt'); +const requirements5 = loadFixture(__filename, 'requirements5.txt'); +const requirements6 = loadFixture(__filename, 'requirements6.txt'); +const requirements7 = loadFixture(__filename, 'requirements7.txt'); describe(getName(__filename), () => { beforeEach(() => { diff --git a/lib/manager/pip_setup/__snapshots__/index.spec.ts.snap b/lib/manager/pip_setup/__snapshots__/index.spec.ts.snap index 69fad81daa3714..540026674ee265 100644 --- a/lib/manager/pip_setup/__snapshots__/index.spec.ts.snap +++ b/lib/manager/pip_setup/__snapshots__/index.spec.ts.snap @@ -390,9 +390,9 @@ Array [ }, }, Object { - "cmd": " \\"lib/manager/pip_setup/__fixtures__/setup.py\\"", + "cmd": " \\"setup.py\\"", "options": Object { - "cwd": "/tmp/github/some/repo/lib/manager/pip_setup/__fixtures__", + "cwd": "/tmp/github/some/repo", "encoding": "utf-8", "env": Object { "HOME": "/home/user", @@ -449,9 +449,9 @@ Array [ }, }, Object { - "cmd": " \\"lib/manager/pip_setup/__fixtures__/setup.py\\"", + "cmd": " \\"setup.py\\"", "options": Object { - "cwd": "/tmp/github/some/repo/lib/manager/pip_setup/__fixtures__", + "cwd": "/tmp/github/some/repo", "encoding": "utf-8", "env": Object { "HOME": "/home/user", diff --git a/lib/manager/pip_setup/index.spec.ts b/lib/manager/pip_setup/index.spec.ts index b5cd418f0c9c81..b81802bc82f6be 100644 --- a/lib/manager/pip_setup/index.spec.ts +++ b/lib/manager/pip_setup/index.spec.ts @@ -1,4 +1,3 @@ -import { readFileSync } from 'fs'; import { ExecSnapshots, envMock, @@ -6,18 +5,16 @@ import { mockExecAll, mockExecSequence, } from '../../../test/exec-util'; -import { env, getName } from '../../../test/util'; +import { env, getName, loadFixture } from '../../../test/util'; import { setUtilConfig } from '../../util'; import { BinarySource } from '../../util/exec/common'; import * as fs from '../../util/fs'; import * as extract from './extract'; import { extractPackageFile } from '.'; -const packageFile = 'lib/manager/pip_setup/__fixtures__/setup.py'; -const content = readFileSync(packageFile, 'utf8'); - -const packageFileJson = 'lib/manager/pip_setup/__fixtures__/setup.py.json'; -const jsonContent = readFileSync(packageFileJson, 'utf8'); +const packageFile = 'setup.py'; +const content = loadFixture(__filename, packageFile); +const jsonContent = loadFixture(__filename, 'setup.py.json'); const config = { localDir: '/tmp/github/some/repo', diff --git a/lib/manager/pipenv/extract.spec.ts b/lib/manager/pipenv/extract.spec.ts index 5e491d6bd3eba5..d302208b924b43 100644 --- a/lib/manager/pipenv/extract.spec.ts +++ b/lib/manager/pipenv/extract.spec.ts @@ -1,29 +1,13 @@ -import fs from 'fs'; -import { fs as fsutil, getName } from '../../../test/util'; +import { fs as fsutil, getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; jest.mock('../../util/fs'); -const pipfile1 = fs.readFileSync( - 'lib/manager/pipenv/__fixtures__/Pipfile1', - 'utf8' -); -const pipfile2 = fs.readFileSync( - 'lib/manager/pipenv/__fixtures__/Pipfile2', - 'utf8' -); -const pipfile3 = fs.readFileSync( - 'lib/manager/pipenv/__fixtures__/Pipfile3', - 'utf8' -); -const pipfile4 = fs.readFileSync( - 'lib/manager/pipenv/__fixtures__/Pipfile4', - 'utf8' -); -const pipfile5 = fs.readFileSync( - 'lib/manager/pipenv/__fixtures__/Pipfile5', - 'utf8' -); +const pipfile1 = loadFixture(__filename, 'Pipfile1'); +const pipfile2 = loadFixture(__filename, 'Pipfile2'); +const pipfile3 = loadFixture(__filename, 'Pipfile3'); +const pipfile4 = loadFixture(__filename, 'Pipfile4'); +const pipfile5 = loadFixture(__filename, 'Pipfile5'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/poetry/artifacts.spec.ts b/lib/manager/poetry/artifacts.spec.ts index c8a8aa9cb8f354..92466cf6aae69b 100644 --- a/lib/manager/poetry/artifacts.spec.ts +++ b/lib/manager/poetry/artifacts.spec.ts @@ -1,9 +1,8 @@ import { exec as _exec } from 'child_process'; -import { readFileSync } from 'fs'; import _fs from 'fs-extra'; import { join } from 'upath'; import { envMock, mockExecAll } from '../../../test/exec-util'; -import { mocked } from '../../../test/util'; +import { loadFixture, mocked } from '../../../test/util'; import * as _datasource from '../../datasource'; import { setExecConfig } from '../../util/exec'; import { BinarySource } from '../../util/exec/common'; @@ -12,10 +11,7 @@ import * as _env from '../../util/exec/env'; import * as _hostRules from '../../util/host-rules'; import { updateArtifacts } from './artifacts'; -const pyproject10toml = readFileSync( - 'lib/manager/poetry/__fixtures__/pyproject.10.toml', - 'utf8' -); +const pyproject10toml = loadFixture(__filename, 'pyproject.10.toml'); jest.mock('fs-extra'); jest.mock('child_process'); diff --git a/lib/manager/poetry/extract.spec.ts b/lib/manager/poetry/extract.spec.ts index 8e69b748625532..5991b47a68fd3d 100644 --- a/lib/manager/poetry/extract.spec.ts +++ b/lib/manager/poetry/extract.spec.ts @@ -1,65 +1,21 @@ -import { readFileSync } from 'fs'; -import { fs, getName } from '../../../test/util'; +import { fs, getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; jest.mock('../../util/fs'); -const pyproject1toml = readFileSync( - 'lib/manager/poetry/__fixtures__/pyproject.1.toml', - 'utf8' -); - -const pyproject2toml = readFileSync( - 'lib/manager/poetry/__fixtures__/pyproject.2.toml', - 'utf8' -); - -const pyproject3toml = readFileSync( - 'lib/manager/poetry/__fixtures__/pyproject.3.toml', - 'utf8' -); - -const pyproject4toml = readFileSync( - 'lib/manager/poetry/__fixtures__/pyproject.4.toml', - 'utf8' -); - -const pyproject5toml = readFileSync( - 'lib/manager/poetry/__fixtures__/pyproject.5.toml', - 'utf8' -); - -const pyproject6toml = readFileSync( - 'lib/manager/poetry/__fixtures__/pyproject.6.toml', - 'utf8' -); - -const pyproject7toml = readFileSync( - 'lib/manager/poetry/__fixtures__/pyproject.7.toml', - 'utf8' -); - -const pyproject8toml = readFileSync( - 'lib/manager/poetry/__fixtures__/pyproject.8.toml', - 'utf8' -); - -const pyproject9toml = readFileSync( - 'lib/manager/poetry/__fixtures__/pyproject.9.toml', - 'utf8' -); +const pyproject1toml = loadFixture(__filename, 'pyproject.1.toml'); +const pyproject2toml = loadFixture(__filename, 'pyproject.2.toml'); +const pyproject3toml = loadFixture(__filename, 'pyproject.3.toml'); +const pyproject4toml = loadFixture(__filename, 'pyproject.4.toml'); +const pyproject5toml = loadFixture(__filename, 'pyproject.5.toml'); +const pyproject6toml = loadFixture(__filename, 'pyproject.6.toml'); +const pyproject7toml = loadFixture(__filename, 'pyproject.7.toml'); +const pyproject8toml = loadFixture(__filename, 'pyproject.8.toml'); +const pyproject9toml = loadFixture(__filename, 'pyproject.9.toml'); // pyproject.10.toml use by artifacts - -const pyproject11toml = readFileSync( - 'lib/manager/poetry/__fixtures__/pyproject.11.toml', - 'utf8' -); - -const pyproject11tomlLock = readFileSync( - 'lib/manager/poetry/__fixtures__/pyproject.11.toml.lock', - 'utf8' -); +const pyproject11toml = loadFixture(__filename, 'pyproject.11.toml'); +const pyproject11tomlLock = loadFixture(__filename, 'pyproject.11.toml.lock'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/pre-commit/extract.spec.ts b/lib/manager/pre-commit/extract.spec.ts index 18f4df48b1cff4..fd9ae0b6c53e40 100644 --- a/lib/manager/pre-commit/extract.spec.ts +++ b/lib/manager/pre-commit/extract.spec.ts @@ -1,41 +1,34 @@ -import { readFileSync } from 'fs'; -import { getName, mocked } from '../../../test/util'; +import { getName, loadFixture, mocked } from '../../../test/util'; import * as _hostRules from '../../util/host-rules'; import { extractPackageFile } from './extract'; jest.mock('../../util/host-rules'); const hostRules = mocked(_hostRules); - const filename = '.pre-commit.yaml'; -const complexPrecommitConfig = readFileSync( - 'lib/manager/pre-commit/__fixtures__/complex.pre-commit-config.yaml', - 'utf8' +const complexPrecommitConfig = loadFixture( + __filename, + 'complex.pre-commit-config.yaml' ); - -const examplePrecommitConfig = readFileSync( - 'lib/manager/pre-commit/__fixtures__/.pre-commit-config.yaml', - 'utf8' +const examplePrecommitConfig = loadFixture( + __filename, + '.pre-commit-config.yaml' ); - -const emptyReposPrecommitConfig = readFileSync( - 'lib/manager/pre-commit/__fixtures__/empty_repos.pre-commit-config.yaml', - 'utf8' +const emptyReposPrecommitConfig = loadFixture( + __filename, + 'empty_repos.pre-commit-config.yaml' ); - -const noReposPrecommitConfig = readFileSync( - 'lib/manager/pre-commit/__fixtures__/no_repos.pre-commit-config.yaml', - 'utf8' +const noReposPrecommitConfig = loadFixture( + __filename, + 'no_repos.pre-commit-config.yaml' ); - -const invalidRepoPrecommitConfig = readFileSync( - 'lib/manager/pre-commit/__fixtures__/invalid_repo.pre-commit-config.yaml', - 'utf8' +const invalidRepoPrecommitConfig = loadFixture( + __filename, + 'invalid_repo.pre-commit-config.yaml' ); - -const enterpriseGitPrecommitConfig = readFileSync( - 'lib/manager/pre-commit/__fixtures__/enterprise.pre-commit-config.yaml', - 'utf8' +const enterpriseGitPrecommitConfig = loadFixture( + __filename, + 'enterprise.pre-commit-config.yaml' ); describe(getName(__filename), () => { diff --git a/lib/manager/pub/extract.spec.ts b/lib/manager/pub/extract.spec.ts index 6130772162eded..1b5c74a5d6c203 100644 --- a/lib/manager/pub/extract.spec.ts +++ b/lib/manager/pub/extract.spec.ts @@ -1,16 +1,8 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from '.'; -const brokenYaml = readFileSync( - 'lib/manager/pub/__fixtures__/update.yaml', - 'utf8' -); - -const packageFile = readFileSync( - 'lib/manager/pub/__fixtures__/extract.yaml', - 'utf8' -); +const brokenYaml = loadFixture(__filename, 'update.yaml'); +const packageFile = loadFixture(__filename, 'extract.yaml'); describe(getName(__filename), () => { describe('extractPackageFile', () => { diff --git a/lib/manager/regex/index.spec.ts b/lib/manager/regex/index.spec.ts index 7d69417eeb6d54..0f944b63a9f877 100644 --- a/lib/manager/regex/index.spec.ts +++ b/lib/manager/regex/index.spec.ts @@ -1,22 +1,11 @@ -import { readFileSync } from 'fs'; -import { resolve } from 'upath'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { logger } from '../../logger'; import type { CustomExtractConfig } from '../types'; import { defaultConfig, extractPackageFile } from '.'; -const dockerfileContent = readFileSync( - resolve(__dirname, `./__fixtures__/Dockerfile`), - 'utf8' -); -const ansibleYamlContent = readFileSync( - resolve(__dirname, `./__fixtures__/ansible.yml`), - 'utf8' -); -const exampleJsonContent = readFileSync( - resolve(__dirname, `./__fixtures__/example.json`), - 'utf8' -); +const dockerfileContent = loadFixture(__filename, `Dockerfile`); +const ansibleYamlContent = loadFixture(__filename, `ansible.yml`); +const exampleJsonContent = loadFixture(__filename, `example.json`); describe(getName(__filename), () => { it('has default config', () => { diff --git a/lib/manager/sbt/extract.spec.ts b/lib/manager/sbt/extract.spec.ts index f4f0453ed4cc41..9ddb9831332636 100644 --- a/lib/manager/sbt/extract.spec.ts +++ b/lib/manager/sbt/extract.spec.ts @@ -1,29 +1,19 @@ -import { readFileSync } from 'fs'; -import { resolve } from 'upath'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; -const sbt = readFileSync( - resolve(__dirname, `./__fixtures__/sample.sbt`), - 'utf8' +const sbt = loadFixture(__filename, `sample.sbt`); +const sbtScalaVersionVariable = loadFixture( + __filename, + `scala-version-variable.sbt` ); -const sbtScalaVersionVariable = readFileSync( - resolve(__dirname, `./__fixtures__/scala-version-variable.sbt`), - 'utf8' +const sbtMissingScalaVersion = loadFixture( + __filename, + `missing-scala-version.sbt` ); -const sbtMissingScalaVersion = readFileSync( - resolve(__dirname, `./__fixtures__/missing-scala-version.sbt`), - 'utf8' -); - -const sbtDependencyFile = readFileSync( - resolve(__dirname, `./__fixtures__/dependency-file.scala`), - 'utf8' -); - -const sbtPrivateVariableDependencyFile = readFileSync( - resolve(__dirname, `./__fixtures__/private-variable-dependency-file.scala`), - 'utf8' +const sbtDependencyFile = loadFixture(__filename, `dependency-file.scala`); +const sbtPrivateVariableDependencyFile = loadFixture( + __filename, + `private-variable-dependency-file.scala` ); describe(getName(__filename), () => { diff --git a/lib/manager/setup-cfg/extract.spec.ts b/lib/manager/setup-cfg/extract.spec.ts index 97d564c32e4209..693c3d6d0be9dc 100644 --- a/lib/manager/setup-cfg/extract.spec.ts +++ b/lib/manager/setup-cfg/extract.spec.ts @@ -1,11 +1,7 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; -const content = readFileSync( - 'lib/manager/setup-cfg/__fixtures__/setup-cfg-1.txt', - 'utf8' -); +const content = loadFixture(__filename, 'setup-cfg-1.txt'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/swift/index.spec.ts b/lib/manager/swift/index.spec.ts index fcc6362a2c3ac1..3c0e90918502ad 100644 --- a/lib/manager/swift/index.spec.ts +++ b/lib/manager/swift/index.spec.ts @@ -1,12 +1,7 @@ -import { readFileSync } from 'fs'; -import { resolve } from 'upath'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; -const pkgContent = readFileSync( - resolve(__dirname, `./__fixtures__/SamplePackage.swift`), - 'utf8' -); +const pkgContent = loadFixture(__filename, `SamplePackage.swift`); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/terraform/extract.spec.ts b/lib/manager/terraform/extract.spec.ts index 11f80a1817c796..b617c39b856374 100644 --- a/lib/manager/terraform/extract.spec.ts +++ b/lib/manager/terraform/extract.spec.ts @@ -1,13 +1,12 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; -const tf1 = readFileSync('lib/manager/terraform/__fixtures__/1.tf', 'utf8'); +const tf1 = loadFixture(__filename, '1.tf'); const tf2 = `module "relative" { source = "../../modules/fe" } `; -const helm = readFileSync('lib/manager/terraform/__fixtures__/helm.tf', 'utf8'); +const helm = loadFixture(__filename, 'helm.tf'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/terragrunt/extract.spec.ts b/lib/manager/terragrunt/extract.spec.ts index 23e68f7d4e0e80..90626f785bbede 100644 --- a/lib/manager/terragrunt/extract.spec.ts +++ b/lib/manager/terragrunt/extract.spec.ts @@ -1,8 +1,7 @@ -import { readFileSync } from 'fs'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; -const tg1 = readFileSync('lib/manager/terragrunt/__fixtures__/2.hcl', 'utf8'); +const tg1 = loadFixture(__filename, '2.hcl'); const tg2 = `terragrunt { source = "../../modules/fe" } diff --git a/lib/manager/travis/extract.spec.ts b/lib/manager/travis/extract.spec.ts index 08ade541405730..8335256c0c672d 100644 --- a/lib/manager/travis/extract.spec.ts +++ b/lib/manager/travis/extract.spec.ts @@ -1,12 +1,7 @@ -import { readFileSync } from 'fs'; -import { resolve } from 'upath'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { extractPackageFile } from './extract'; -const invalidYAML = readFileSync( - resolve('lib/manager/travis/__fixtures__/invalid.yml'), - 'utf8' -); +const invalidYAML = loadFixture(__filename, 'invalid.yml'); describe(getName(__filename), () => { describe('extractPackageFile()', () => { diff --git a/lib/manager/travis/update.spec.ts b/lib/manager/travis/update.spec.ts index 518dbf613248b2..b36897e7f4474b 100644 --- a/lib/manager/travis/update.spec.ts +++ b/lib/manager/travis/update.spec.ts @@ -1,12 +1,7 @@ -import { readFileSync } from 'fs'; -import { resolve } from 'upath'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { updateDependency } from './update'; -const content = readFileSync( - resolve('lib/manager/travis/__fixtures__/travis.yml'), - 'utf8' -); +const content = loadFixture(__filename, 'travis.yml'); describe(getName(__filename), () => { describe('updateDependency', () => { diff --git a/lib/platform/github/index.spec.ts b/lib/platform/github/index.spec.ts index ebcd4a20d0d65d..f6002def84c42c 100644 --- a/lib/platform/github/index.spec.ts +++ b/lib/platform/github/index.spec.ts @@ -1,7 +1,6 @@ -import fs from 'fs-extra'; import { DateTime } from 'luxon'; import * as httpMock from '../../../test/http-mock'; -import { getName, mocked } from '../../../test/util'; +import { getName, loadFixture, mocked } from '../../../test/util'; import { REPOSITORY_NOT_FOUND, REPOSITORY_RENAMED, @@ -42,13 +41,13 @@ describe(getName(__filename), () => { httpMock.reset(); }); - const graphqlOpenPullRequests = fs.readFileSync( - 'lib/platform/github/__fixtures__/graphql/pullrequest-1.json', - 'utf8' + const graphqlOpenPullRequests = loadFixture( + __filename, + 'graphql/pullrequest-1.json' ); - const graphqlClosedPullRequests = fs.readFileSync( - 'lib/platform/github/__fixtures__/graphql/pullrequests-closed.json', - 'utf8' + const graphqlClosedPullRequests = loadFixture( + __filename, + 'graphql/pullrequests-closed.json' ); describe('initPlatform()', () => { diff --git a/lib/platform/utils/pr-body.spec.ts b/lib/platform/utils/pr-body.spec.ts index ab0b3a7cfece7d..873b12529919c6 100644 --- a/lib/platform/utils/pr-body.spec.ts +++ b/lib/platform/utils/pr-body.spec.ts @@ -1,15 +1,9 @@ -import fs from 'fs-extra'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { smartTruncate } from './pr-body'; +const prBody = loadFixture(__filename, 'pr-body.txt'); + describe(getName(__filename), () => { - let prBody: string; - beforeAll(async () => { - prBody = await fs.readFile( - 'lib/platform/utils/__fixtures__/pr-body.txt', - 'utf8' - ); - }); describe('.smartTruncate', () => { it('truncates to 1000', () => { const body = smartTruncate(prBody, 1000); diff --git a/lib/platform/utils/read-only-issue-body.spec.ts b/lib/platform/utils/read-only-issue-body.spec.ts index 440d4b82acaa56..ef98dedc3d7ef9 100644 --- a/lib/platform/utils/read-only-issue-body.spec.ts +++ b/lib/platform/utils/read-only-issue-body.spec.ts @@ -1,15 +1,9 @@ -import fs from 'fs-extra'; -import { getName } from '../../../test/util'; +import { getName, loadFixture } from '../../../test/util'; import { readOnlyIssueBody } from './read-only-issue-body'; +const issueBody = loadFixture(__filename, 'issue-body.txt'); + describe(getName(__filename), () => { - let issueBody: string; - beforeAll(async () => { - issueBody = await fs.readFile( - 'lib/platform/utils/__fixtures__/issue-body.txt', - 'utf8' - ); - }); describe('.readOnlyIssueBody', () => { it('removes all checkbox formatting', () => { expect(readOnlyIssueBody(issueBody)).toEqual( diff --git a/lib/workers/branch/auto-replace.spec.ts b/lib/workers/branch/auto-replace.spec.ts index 0bf06f454badb6..125d9237d34620 100644 --- a/lib/workers/branch/auto-replace.spec.ts +++ b/lib/workers/branch/auto-replace.spec.ts @@ -1,15 +1,10 @@ -import { readFileSync } from 'fs'; -import { resolve } from 'upath'; -import { defaultConfig, getName } from '../../../test/util'; +import { defaultConfig, getName, loadFixture } from '../../../test/util'; import { WORKER_FILE_UPDATE_FAILED } from '../../constants/error-messages'; import { extractPackageFile } from '../../manager/html'; import type { BranchUpgradeConfig } from '../types'; import { doAutoReplace } from './auto-replace'; -const sampleHtml = readFileSync( - resolve(__dirname, `../../manager/html/__fixtures__/sample.html`), - 'utf8' -); +const sampleHtml = loadFixture(__filename, 'sample.html', `../../manager/html`); jest.mock('../../util/fs'); diff --git a/lib/workers/pr/changelog/release-notes.spec.ts b/lib/workers/pr/changelog/release-notes.spec.ts index aca57ac8c44f2b..f28f25f667f182 100644 --- a/lib/workers/pr/changelog/release-notes.spec.ts +++ b/lib/workers/pr/changelog/release-notes.spec.ts @@ -1,7 +1,6 @@ -import fs from 'fs-extra'; import { DateTime } from 'luxon'; import * as httpMock from '../../../../test/http-mock'; -import { getName, mocked } from '../../../../test/util'; +import { getName, loadFixture, mocked } from '../../../../test/util'; import * as _hostRules from '../../../util/host-rules'; import { addReleaseNotes, @@ -16,33 +15,19 @@ jest.mock('../../../util/host-rules'); const hostRules = mocked(_hostRules); -const angularJsChangelogMd = fs.readFileSync( - 'lib/workers/pr/__fixtures__/angular-js.md', - 'utf8' +const angularJsChangelogMd = loadFixture(__filename, 'angular-js.md', '..'); +const jestChangelogMd = loadFixture(__filename, 'jest.md', '..'); +const jsYamlChangelogMd = loadFixture(__filename, 'js-yaml.md', '..'); +const yargsChangelogMd = loadFixture(__filename, 'yargs.md', '..'); +const adapterutilsChangelogMd = loadFixture( + __filename, + 'adapter-utils.md', + '..' ); -const jestChangelogMd = fs.readFileSync( - 'lib/workers/pr/__fixtures__/jest.md', - 'utf8' -); - -const jsYamlChangelogMd = fs.readFileSync( - 'lib/workers/pr/__fixtures__/js-yaml.md', - 'utf8' -); - -const yargsChangelogMd = fs.readFileSync( - 'lib/workers/pr/__fixtures__/yargs.md', - 'utf8' -); - -const adapterutilsChangelogMd = fs.readFileSync( - 'lib/workers/pr/__fixtures__/adapter-utils.md', - 'utf8' -); - -const gitterWebappChangelogMd = fs.readFileSync( - 'lib/workers/pr/__fixtures__/gitter-webapp.md', - 'utf8' +const gitterWebappChangelogMd = loadFixture( + __filename, + 'gitter-webapp.md', + '..' ); const githubTreeResponse = { diff --git a/lib/workers/repository/dependency-dashboard.spec.ts b/lib/workers/repository/dependency-dashboard.spec.ts index 67bf63f17c86fb..35f20a00daf67e 100644 --- a/lib/workers/repository/dependency-dashboard.spec.ts +++ b/lib/workers/repository/dependency-dashboard.spec.ts @@ -1,10 +1,10 @@ -import fs from 'fs'; import { ERROR, WARN } from 'bunyan'; import { mock } from 'jest-mock-extended'; import { RenovateConfig, getConfig, getName, + loadFixture, logger, platform, } from '../../../test/util'; @@ -239,10 +239,7 @@ describe(getName(__filename), () => { config.dependencyDashboardTitle ); expect(platform.ensureIssue.mock.calls[0][0].body).toBe( - fs.readFileSync( - 'lib/workers/repository/__fixtures__/master-issue_with_8_PR.txt', - 'utf8' - ) + loadFixture(__filename, 'master-issue_with_8_PR.txt') ); expect(platform.getBranchPr).toHaveBeenCalledTimes(0); expect(platform.findPr).toHaveBeenCalledTimes(0); @@ -282,10 +279,7 @@ describe(getName(__filename), () => { config.dependencyDashboardTitle ); expect(platform.ensureIssue.mock.calls[0][0].body).toBe( - fs.readFileSync( - 'lib/workers/repository/__fixtures__/master-issue_with_2_PR_edited.txt', - 'utf8' - ) + loadFixture(__filename, 'master-issue_with_2_PR_edited.txt') ); expect(platform.getBranchPr).toHaveBeenCalledTimes(2); expect(platform.getBranchPr.mock.calls[0][0]).toBe('branchName1'); @@ -335,10 +329,7 @@ describe(getName(__filename), () => { config.dependencyDashboardTitle ); expect(platform.ensureIssue.mock.calls[0][0].body).toBe( - fs.readFileSync( - 'lib/workers/repository/__fixtures__/master-issue_with_3_PR_in_progress.txt', - 'utf8' - ) + loadFixture(__filename, 'master-issue_with_3_PR_in_progress.txt') ); expect(platform.getBranchPr).toHaveBeenCalledTimes(3); expect(platform.getBranchPr.mock.calls[0][0]).toBe('branchName1'); @@ -382,10 +373,7 @@ describe(getName(__filename), () => { config.dependencyDashboardTitle ); expect(platform.ensureIssue.mock.calls[0][0].body).toBe( - fs.readFileSync( - 'lib/workers/repository/__fixtures__/master-issue_with_2_PR_closed_ignored.txt', - 'utf8' - ) + loadFixture(__filename, 'master-issue_with_2_PR_closed_ignored.txt') ); expect(platform.getBranchPr).toHaveBeenCalledTimes(0); expect(platform.findPr).toHaveBeenCalledTimes(2); @@ -443,10 +431,7 @@ describe(getName(__filename), () => { config.dependencyDashboardTitle ); expect(platform.ensureIssue.mock.calls[0][0].body).toBe( - fs.readFileSync( - 'lib/workers/repository/__fixtures__/master-issue_with_3_PR_in_approval.txt', - 'utf8' - ) + loadFixture(__filename, 'master-issue_with_3_PR_in_approval.txt') ); expect(platform.findPr).toHaveBeenCalledTimes(0); diff --git a/lib/workers/repository/process/lookup/index.spec.ts b/lib/workers/repository/process/lookup/index.spec.ts index 1edb6aa299597f..d457c3a565ee53 100644 --- a/lib/workers/repository/process/lookup/index.spec.ts +++ b/lib/workers/repository/process/lookup/index.spec.ts @@ -1,12 +1,11 @@ import nock from 'nock'; -import { getConfig, getName, mocked, partial } from '../../../../../test/util'; -import qJson from '../../../../config/npm/__fixtures__/01.json'; -import helmetJson from '../../../../config/npm/__fixtures__/02.json'; -import coffeelintJson from '../../../../config/npm/__fixtures__/coffeelint.json'; -import nextJson from '../../../../config/npm/__fixtures__/next.json'; -import typescriptJson from '../../../../config/npm/__fixtures__/typescript.json'; -import vueJson from '../../../../config/npm/__fixtures__/vue.json'; -import webpackJson from '../../../../config/npm/__fixtures__/webpack.json'; +import { + getConfig, + getName, + loadJsonFixture, + mocked, + partial, +} from '../../../../../test/util'; import { CONFIG_VALIDATION } from '../../../../constants/error-messages'; import * as datasourceDocker from '../../../../datasource/docker'; import { id as datasourceDockerId } from '../../../../datasource/docker'; @@ -29,7 +28,25 @@ jest.mock('../../../../datasource/docker'); jest.mock('../../../../datasource/git-refs'); jest.mock('../../../../datasource/github-releases'); -qJson.latestVersion = '1.4.1'; +const fixtureRoot = '../../../../config/npm'; +const qJson = { + ...loadJsonFixture(__filename, '01.json', fixtureRoot), + latestVersion: '1.4.1', +}; +const helmetJson = loadJsonFixture(__filename, '02.json', fixtureRoot); +const coffeelintJson = loadJsonFixture( + __filename, + 'coffeelint.json', + fixtureRoot +); +const nextJson = loadJsonFixture(__filename, 'next.json', fixtureRoot); +const typescriptJson = loadJsonFixture( + __filename, + 'typescript.json', + fixtureRoot +); +const vueJson = loadJsonFixture(__filename, 'vue.json', fixtureRoot); +const webpackJson = loadJsonFixture(__filename, 'webpack.json', fixtureRoot); const docker = mocked(datasourceDocker) as any; docker.defaultRegistryUrls = ['https://index.docker.io']; diff --git a/test/util.ts b/test/util.ts index 06f596fb1e85e6..e45057b9d29099 100644 --- a/test/util.ts +++ b/test/util.ts @@ -1,5 +1,7 @@ import crypto from 'crypto'; +import { readFileSync } from 'fs'; import { expect } from '@jest/globals'; +import upath from 'upath'; import { getConfig } from '../lib/config/defaults'; import type { RenovateConfig as _RenovateConfig } from '../lib/config/types'; import * as _logger from '../lib/logger'; @@ -44,6 +46,30 @@ export function getName(file: string): string { return name; } +export function loadFixture( + currentFile: string, + fixtureFile: string, + fixtureRoot = '.' +): string { + const callerDir = upath.dirname(currentFile); + const fixtureAbsFile = upath.join( + callerDir, + fixtureRoot, + '__fixtures__', + fixtureFile + ); + return readFileSync(fixtureAbsFile, { encoding: 'utf8' }); +} + +export function loadJsonFixture( + currentFile: string, + fixtureFile: string, + fixtureRoot = '.' +): T { + const rawFixture = loadFixture(currentFile, fixtureFile, fixtureRoot); + return JSON.parse(rawFixture) as T; +} + /** * Can be used to search and replace strings in jest snapshots. * @example From 108a00bad4707de24f077eec274fb2e4ee0d8fe5 Mon Sep 17 00:00:00 2001 From: Ross Rasmussen Date: Fri, 23 Apr 2021 10:32:45 -0700 Subject: [PATCH 45/52] fix(terraform): support github repo source url with underscores (#9661) Co-authored-by: Michael Kriese Co-authored-by: Rhys Arkins --- lib/manager/terraform/modules.spec.ts | 64 ++++++++++++++++++++++++++ lib/manager/terraform/modules.ts | 4 +- lib/manager/terragrunt/modules.spec.ts | 64 ++++++++++++++++++++++++++ lib/manager/terragrunt/modules.ts | 4 +- 4 files changed, 132 insertions(+), 4 deletions(-) create mode 100644 lib/manager/terraform/modules.spec.ts create mode 100644 lib/manager/terragrunt/modules.spec.ts diff --git a/lib/manager/terraform/modules.spec.ts b/lib/manager/terraform/modules.spec.ts new file mode 100644 index 00000000000000..2dcf3a594f8c3c --- /dev/null +++ b/lib/manager/terraform/modules.spec.ts @@ -0,0 +1,64 @@ +import { getName } from '../../../test/util'; +import { gitTagsRefMatchRegex, githubRefMatchRegex } from './modules'; + +describe(getName(__filename), () => { + describe('githubRefMatchRegex', () => { + it('should split project and tag from source', () => { + const { project, tag } = githubRefMatchRegex.exec( + 'github.com/hashicorp/example?ref=v1.0.0' + ).groups; + expect(project).toBe('hashicorp/example'); + expect(tag).toBe('v1.0.0'); + }); + + it('should parse alpha-numeric characters as well as dots, underscores, and dashes in repo names', () => { + const { project } = githubRefMatchRegex.exec( + 'github.com/hashicorp/example.repo-123?ref=v1.0.0' + ).groups; + expect(project).toBe('hashicorp/example.repo-123'); + }); + }); + describe('gitTagsRefMatchRegex', () => { + it('should split project and tag from source', () => { + const http = gitTagsRefMatchRegex.exec( + 'http://github.com/hashicorp/example?ref=v1.0.0' + ).groups; + const https = gitTagsRefMatchRegex.exec( + 'https://github.com/hashicorp/example?ref=v1.0.0' + ).groups; + const ssh = gitTagsRefMatchRegex.exec( + 'ssh://github.com/hashicorp/example?ref=v1.0.0' + ).groups; + + expect(http.project).toBe('hashicorp/example'); + expect(http.tag).toBe('v1.0.0'); + + expect(https.project).toBe('hashicorp/example'); + expect(https.tag).toBe('v1.0.0'); + + expect(ssh.project).toBe('hashicorp/example'); + expect(ssh.tag).toBe('v1.0.0'); + }); + + it('should parse alpha-numeric characters as well as dots, underscores, and dashes in repo names', () => { + const http = gitTagsRefMatchRegex.exec( + 'http://github.com/hashicorp/example.repo-123?ref=v1.0.0' + ).groups; + const https = gitTagsRefMatchRegex.exec( + 'https://github.com/hashicorp/example.repo-123?ref=v1.0.0' + ).groups; + const ssh = gitTagsRefMatchRegex.exec( + 'ssh://github.com/hashicorp/example.repo-123?ref=v1.0.0' + ).groups; + + expect(http.project).toBe('hashicorp/example.repo-123'); + expect(http.tag).toBe('v1.0.0'); + + expect(https.project).toBe('hashicorp/example.repo-123'); + expect(https.tag).toBe('v1.0.0'); + + expect(ssh.project).toBe('hashicorp/example.repo-123'); + expect(ssh.tag).toBe('v1.0.0'); + }); + }); +}); diff --git a/lib/manager/terraform/modules.ts b/lib/manager/terraform/modules.ts index 692c120328e77f..d4d645565fc0e3 100644 --- a/lib/manager/terraform/modules.ts +++ b/lib/manager/terraform/modules.ts @@ -7,8 +7,8 @@ import type { PackageDependency } from '../types'; import { extractTerraformProvider } from './providers'; import { ExtractionResult, TerraformDependencyTypes } from './util'; -const githubRefMatchRegex = /github.com([/:])(?[^/]+\/[a-z0-9-.]+).*\?ref=(?.*)$/; -const gitTagsRefMatchRegex = /(?:git::)?(?(?:http|https|ssh):\/\/(?:.*@)?(?.*.*\/(?.*\/.*)))\?ref=(?.*)$/; +export const githubRefMatchRegex = /github\.com([/:])(?[^/]+\/[a-z0-9-_.]+).*\?ref=(?.*)$/i; +export const gitTagsRefMatchRegex = /(?:git::)?(?(?:http|https|ssh):\/\/(?:.*@)?(?.*.*\/(?.*\/.*)))\?ref=(?.*)$/; const hostnameMatchRegex = /^(?([\w|\d]+\.)+[\w|\d]+)/; export function extractTerraformModule( diff --git a/lib/manager/terragrunt/modules.spec.ts b/lib/manager/terragrunt/modules.spec.ts new file mode 100644 index 00000000000000..2dcf3a594f8c3c --- /dev/null +++ b/lib/manager/terragrunt/modules.spec.ts @@ -0,0 +1,64 @@ +import { getName } from '../../../test/util'; +import { gitTagsRefMatchRegex, githubRefMatchRegex } from './modules'; + +describe(getName(__filename), () => { + describe('githubRefMatchRegex', () => { + it('should split project and tag from source', () => { + const { project, tag } = githubRefMatchRegex.exec( + 'github.com/hashicorp/example?ref=v1.0.0' + ).groups; + expect(project).toBe('hashicorp/example'); + expect(tag).toBe('v1.0.0'); + }); + + it('should parse alpha-numeric characters as well as dots, underscores, and dashes in repo names', () => { + const { project } = githubRefMatchRegex.exec( + 'github.com/hashicorp/example.repo-123?ref=v1.0.0' + ).groups; + expect(project).toBe('hashicorp/example.repo-123'); + }); + }); + describe('gitTagsRefMatchRegex', () => { + it('should split project and tag from source', () => { + const http = gitTagsRefMatchRegex.exec( + 'http://github.com/hashicorp/example?ref=v1.0.0' + ).groups; + const https = gitTagsRefMatchRegex.exec( + 'https://github.com/hashicorp/example?ref=v1.0.0' + ).groups; + const ssh = gitTagsRefMatchRegex.exec( + 'ssh://github.com/hashicorp/example?ref=v1.0.0' + ).groups; + + expect(http.project).toBe('hashicorp/example'); + expect(http.tag).toBe('v1.0.0'); + + expect(https.project).toBe('hashicorp/example'); + expect(https.tag).toBe('v1.0.0'); + + expect(ssh.project).toBe('hashicorp/example'); + expect(ssh.tag).toBe('v1.0.0'); + }); + + it('should parse alpha-numeric characters as well as dots, underscores, and dashes in repo names', () => { + const http = gitTagsRefMatchRegex.exec( + 'http://github.com/hashicorp/example.repo-123?ref=v1.0.0' + ).groups; + const https = gitTagsRefMatchRegex.exec( + 'https://github.com/hashicorp/example.repo-123?ref=v1.0.0' + ).groups; + const ssh = gitTagsRefMatchRegex.exec( + 'ssh://github.com/hashicorp/example.repo-123?ref=v1.0.0' + ).groups; + + expect(http.project).toBe('hashicorp/example.repo-123'); + expect(http.tag).toBe('v1.0.0'); + + expect(https.project).toBe('hashicorp/example.repo-123'); + expect(https.tag).toBe('v1.0.0'); + + expect(ssh.project).toBe('hashicorp/example.repo-123'); + expect(ssh.tag).toBe('v1.0.0'); + }); + }); +}); diff --git a/lib/manager/terragrunt/modules.ts b/lib/manager/terragrunt/modules.ts index 77ae489ab3e92b..e11e12e20bf95f 100644 --- a/lib/manager/terragrunt/modules.ts +++ b/lib/manager/terragrunt/modules.ts @@ -7,8 +7,8 @@ import type { PackageDependency } from '../types'; import { extractTerragruntProvider } from './providers'; import { ExtractionResult, TerragruntDependencyTypes } from './util'; -const githubRefMatchRegex = /github.com([/:])(?[^/]+\/[a-z0-9-.]+).*\?ref=(?.*)$/; -const gitTagsRefMatchRegex = /(?:git::)?(?(?:http|https|ssh):\/\/(?:.*@)?(?.*.*\/(?.*\/.*)))\?ref=(?.*)$/; +export const githubRefMatchRegex = /github\.com([/:])(?[^/]+\/[a-z0-9-_.]+).*\?ref=(?.*)$/i; +export const gitTagsRefMatchRegex = /(?:git::)?(?(?:http|https|ssh):\/\/(?:.*@)?(?.*.*\/(?.*\/.*)))\?ref=(?.*)$/; const hostnameMatchRegex = /^(?([\w|\d]+\.)+[\w|\d]+)/; export function extractTerragruntModule( From e366da2ad51a9b43ea55c5bf218a6cf0ae7d861e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 24 Apr 2021 01:18:21 +0000 Subject: [PATCH 46/52] build(deps): update dependency markdown-it to v12.0.6 (#9705) Co-authored-by: Renovate Bot --- package.json | 2 +- yarn.lock | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index a1d6570f3334cf..ae4bd567475823 100644 --- a/package.json +++ b/package.json @@ -160,7 +160,7 @@ "json5": "2.2.0", "linkify-markdown": "1.0.0", "luxon": "1.26.0", - "markdown-it": "12.0.4", + "markdown-it": "12.0.6", "markdown-table": "2.0.0", "minimatch": "3.0.4", "moo": "0.5.1", diff --git a/yarn.lock b/yarn.lock index efd67fcc5f8384..193a71744540ab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6728,6 +6728,17 @@ markdown-it@12.0.4: mdurl "^1.0.1" uc.micro "^1.0.5" +markdown-it@12.0.6: + version "12.0.6" + resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-12.0.6.tgz#adcc8e5fe020af292ccbdf161fe84f1961516138" + integrity sha512-qv3sVLl4lMT96LLtR7xeRJX11OUFjsaD5oVat2/SNBIb21bJXwal2+SklcRbTwGwqWpWH/HRtYavOoJE+seL8w== + dependencies: + argparse "^2.0.1" + entities "~2.1.0" + linkify-it "^3.0.1" + mdurl "^1.0.1" + uc.micro "^1.0.5" + markdown-table@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-2.0.0.tgz#194a90ced26d31fe753d8b9434430214c011865b" From 90e96805e1edfa43a0b4341d551be5c27631eef2 Mon Sep 17 00:00:00 2001 From: Nils Plaschke Date: Sat, 24 Apr 2021 07:54:00 +0200 Subject: [PATCH 47/52] docs: add documentation for forkToken (#9701) --- docs/usage/self-hosted-configuration.md | 8 ++++++++ lib/config/definitions.ts | 9 +++++++++ 2 files changed, 17 insertions(+) diff --git a/docs/usage/self-hosted-configuration.md b/docs/usage/self-hosted-configuration.md index 86c10c63deae4d..4021d45353eb11 100644 --- a/docs/usage/self-hosted-configuration.md +++ b/docs/usage/self-hosted-configuration.md @@ -200,6 +200,14 @@ It will also override any settings in `packageRules`. ## forkMode You probably have no need for this option - it is an experimental setting for the Renovate hosted GitHub App. +If this is set to `true` then Renovate will fork the repository into the personal space of the person owning the Personal Access Token. + +## forkToken + +You probably have no need for this option - it is an experimental setting for the Renovate hosted GitHub App. +This should be set to a Personal Access Token (GitHub only) when `forkMode` is set to `true`. +Renovate will use this token to fork the repository into the personal space of the person owning the Personal Access Token. +Renovate will then create branches on the fork and opens Pull Requests on the parent repository. ## gitAuthor diff --git a/lib/config/definitions.ts b/lib/config/definitions.ts index 3c77b49792aaa2..f03a692e3b37b4 100644 --- a/lib/config/definitions.ts +++ b/lib/config/definitions.ts @@ -340,6 +340,15 @@ const options: RenovateOptions[] = [ default: false, admin: true, }, + { + name: 'forkToken', + description: + 'Will be used on GitHub when `forkMode` is set to `true` to clone the repositories.', + stage: 'repository', + type: 'string', + default: '', + admin: true, + }, { name: 'requireConfig', description: 'Set to true if repositories must have a config to activate.', From 51c01c63c5cdf44ddf30e032066e1f824a0043f0 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Sat, 24 Apr 2021 10:02:55 +0200 Subject: [PATCH 48/52] docs: private modules (#9703) --- docs/usage/private-modules.md | 147 +++++++++++++++++++++++++++++++++- 1 file changed, 145 insertions(+), 2 deletions(-) diff --git a/docs/usage/private-modules.md b/docs/usage/private-modules.md index f64a6dfe4eb656..f58926e4d76769 100644 --- a/docs/usage/private-modules.md +++ b/docs/usage/private-modules.md @@ -5,6 +5,149 @@ description: How to support private modules when using Renovate # Private module support -## npm +It's a very common requirement to be able to support private module/dependency lookups. +This page describes Renovate's approach to authentication. -Please see [Private npm module support](./private-npm-modules) +First, a quick note on terminology: + +- The terms `module`, `package` and `dependency` can mostly be used interchangeably below +- The terms `credentials`, `secrets` and `authentication` are also used interchangeably + +## When does Renovate need credentials? + +By default, the only credentials Renovate has are those for the "platform", i.e. GitHub, GitLab, etc. +If the token used has sufficient permissions, this will enable Renovate to lookup dependencies located in alternative repositories on the same host or any hosted on any embedded package registry on the same host. + +It's also quite common to need to look up packages on other protected hosts, including npmjs, Docker Hub, or private registries like Nexus or Artifactory. +Any time you need Renovate to access such registries with credentials then you will need to provision them as part of your config. + +There are four times in Renovate's behavior when it may need credentials: + +- Resolving private config presets +- Looking up dependency versions +- Looking up release notes +- Passing to package managers when updating lock files or checksums + +Note: if you self-host Renovate, and have a self-hosted registry which _doesn't_ require authentication to access, then such modules/packages are not considered "private" to Renovate. + +## Private Config Presets + +Renovate supports config presets, including those which are private. + +Although npm presets were the first type supported, they are now deprecated and it is recommend that all users migrate to git-hosted "local" presets instead. +However if you do still use them, private modules should work if you configure the `npmrc` file including token credentials in your bot admin config. +Credentials stored on disk (e.g. in `~/.npmrc`) are no longer supported. + +The recommended way of using local presets is to configure then using "local" presets, e.g. like `"extends": ["local>myorg/renovate-config"]`, and ensure that the platform token has access to that repo. + +It's not recommended that you use a private repository to host your config while then extending it from a public repository. +If your preset doesn't contain secrets then you should make it public, while if it does contain secrets then it's better to split your preset between a public one which all repos extend, and a private one with secrets which only other private repos extend. + +In summary, the recommended approach to private presets is: + +- Host the presets on the same server/platform as other repositories +- Make sure you install Renovate into the preset repository so that it has credentials to access it from other private repos +- Use `local>....` syntax to refer to private presets + +## Dependency Version Lookups + +Whenever Renovate detects that a project uses a particular dependency, it attempts to look up that dependency to see if any new versions exist. +If such a package is private, then Renovate will need to be configured with the relevant credentials. +Renovate does not use any package managers for this step and performs all HTTP(S) lookups itself, including insertion of authentication headers. + +Configuring Renovate with credentials requires `hostRules`. +Each host rule consists of a `hostType` value and/or a way to match against hosts using `baseUrl`, `hostName` or `domainName`. + +`hostType` is not particularly important at this step unless you have different credentials for the same host, however it is sometimes useful in later steps so is good to include if you can. +It can be either a "platform" name (e.g. `github`, `azure`, etc) or a "datasource" name (e.g. `npm`, `maven`, `github-tags`, etc). + +`baseUrl` can be used if you want to only apply the credentials for a nested path within the host, e.g. `https://registry.company.com/nested/path/`. +If the same credentials apply to all paths on a host, then use `hostName` instead, e.g. `registry.company.com`. +Finally, to apply credentials to all hosts within the domain, use `domainName`, e.g. `company.com`. +You need to pick only one of these and not try to use multiple at the same time, or it will be a config error. + +In addition to the above options to match against a host, you need to add the credentials. +Typically they are either `token`, or `username` + `password`. +Other credential terms are not supported yet. + +Here is an example of some host rules: + +```json +{ + "hostRules": [ + { + "hostName": "registry.npmjs.org", + "token": "abc123" + }, + { + "baseUrl": "https://registry.company.com/pypi-simple/", + "username": "engineering", + "password": "abc123" + } + ] +} +``` + +Renovate applies theses `hostRules` to every HTTP(s) request which is sent, so they are largely independent of any platform or datasource logic. +With `hostRules` in place, private package lookups should all work. + +## Release Notes + +When Renovate creates Pull Requests, its default behavior is to locate and embed release notes/changelogs of packages. +These release notes are fetched from the source repository of packages and not from the registries themselves, so if they are private then they will require different credentials. + +When it comes to open source, most packages host their source on `github.com` in public repositories. +However, GitHub greatly rate limits unauthenticated API requests so there is a need to configure credentials for github.com as otherwise the bot will get rate limited quickly. +It can be confusing for people who host their own source code privately to be asked to configure a `github.com` token but without it Release Notes for most open source packages will be blocked. + +Currently the preferred way to configure `github.com` credentials for self-hosted Renovate is: + +- Create a read-only Personal Access Token (PAT) for a `github.com` account. It can be any account, and may even be best to be an empty account created just for this purpose. +- Add the PAT to Renovate using the environment variable `GITHUB_COM_TOKEN` + +## Package Manager Credentials for Artifact Updating + +In Renovate terminology, "artifacts" includes lock files, checksum files, and vendored dependencies. +One way of understanding artifacts is: "everything else that needs to be updated when the dependency version changes". + +Not all package managers supported by Renovate require artifact updating, because not all use lock or checksum files. +But when such files need updating, Renovate does so by using the package managers themselves instead of trying to "reverse engineer" each package manager's file formats and behavior. +Importantly, such package managers are run via shell commands and do not understand Renovate's `hostRules` objects, so Renovate needs to reformat the credentials into formats (such as environment variables or configuration files) which the package manager understands. + +Because of this need to convert `hostRules` credentials into a format which package managers understand, sometimes artifact updating can fail due to missing credentials. +Sometimes this can be resolved by changing Renovate configuration, but other times it may be due to a feature gap. +The following details the most common/popular manager artifacts updating and how credentials are passed: + +### bundler + +`hostRules` with `hostType=rubygems` are converted into environment variables which Bundler supports. + +### composer + +Any `hostRules` token for `github.com` or `gitlab.com` are found and written out to `COMPOSER_AUTH` in env for Composer to parse. +Any `hostRules` with `hostType=packagist` are also included. + +### gomod + +If a `github.com` token is found in `hostRules`, then it is written out to local git config prior to running `go` commands. +The command run is `git config --global url."https://${token}@github.com/".insteadOf "https://github.com/"`. + +### npm + +The best way to do this now is using `hostRules` and no longer via `.npmrc` files on disk or in config. +`hostRules` credentials with `hostType=npm` are written to a `.npmrc` file in the same directory as the `package.json` being updated. +See [private npm modules](./private-npm-modules) for more details. + +### nuget + +For each known NuGet registry, Renovate searches for `hostRules` with `hostType=nuget` and matching host. +For those found, a command similar to the following is run: `dotnet nuget add source ${registryInfo.feedUrl} --configfile ${nugetConfigFile} --username ${username} --password ${password} --store-password-in-clear-text` + +### poetry + +For every poetry source, a `hostRules` search is done and then any found credentials are added to env like `POETRY_HTTP_BASIC_X_USERNAME` and `POETRY_HTTP_BASIC_X_PASSWORD`. + + From 6971e41d60992a17ab8a4fbd5aaadd5464381b67 Mon Sep 17 00:00:00 2001 From: Rhys Arkins Date: Sat, 24 Apr 2021 17:46:22 +0200 Subject: [PATCH 49/52] docs: app and self-hosted private modules --- docs/usage/private-modules.md | 68 ++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/docs/usage/private-modules.md b/docs/usage/private-modules.md index f58926e4d76769..3aba9f2421cd43 100644 --- a/docs/usage/private-modules.md +++ b/docs/usage/private-modules.md @@ -147,7 +147,67 @@ For those found, a command similar to the following is run: `dotnet nuget add so For every poetry source, a `hostRules` search is done and then any found credentials are added to env like `POETRY_HTTP_BASIC_X_USERNAME` and `POETRY_HTTP_BASIC_X_PASSWORD`. - +## WhiteSource Renovate Hosted App Encryption + +The popular [Renovate App on GitHub](https://github.com/apps/renovate) is hosted by WhiteSource. +If you are a user of this app, and have private modules, then the following is applicable. + +### Private presets with public repositories + +If you have a preset in a private repo but reference ("extend") it from a public repository then it won't work. +This is because public repositories are provided with a token scoped to only that particular repository, and not for all repositories within the org. +This is a security measure so that if a the token is accidentally leaked publicly, the damage is limited to the public repository it leaked to and not to every repository within the organization. + +The solution to this is that you should break your presets into public and private ones, and reference only the public ones from public repositories. + +### Encrypting secrets + +It is strongly recommended that you don't commit secrets to repositories, including private ones, and this includes secrets needed by Renovate to access private modules. +Therefore the preferred approach to secrets is that the bot administrator configures them as `hostRules` which are then applied to all repositories which the bot accesses. + +If you need to provide credentials to the hosted Renovate App, please do this: + +- Encrypt each secret string using . Note: this encrypts using the app's public key fully in the browser and does not send the original secret to any server. You can download this file and perform the encryption fully offline if you like. +- Wrap each secret field in an [encrypted](https://docs.renovatebot.com/configuration-options/#encrypted) object and paste in the encrypted secret value instead. An example is shown below: + +```json +{ + "hostRules": [ + { + "hostName": "registry.npmjs.org", + "encrypted": { + "token": "3f832f2983yf89hsd98ahadsjfasdfjaslf............" + } + }, + { + "baseUrl": "https://custom.registry.company.com/pypi/", + "username": "bot1", + "encrypted": { + "password": "p278djfdsi9832jnfdshufwji2r389fdskj........." + } + } + ] +} +``` + +### Access to GitHub Actions Secrets + +The WhiteSource Renovate App does not run using GitHub Actions, but such secrets would be a bad fit for the app anyway for the following reasons: + +- The app would be granted access to _all_ the repository/org secrets, not just the ones you want +- If Renovate wants access to such secrets, it would need to ask for them from every user, not just the ones who want to use this approach (GitHub does not support the concept of optional permissions for Apps, so people do not have the option to decline) + +## Admin/Bot config vs User/Repository config for Self-hosted users + +"AdminBot config" refers to the config which the Renovate Bot administrator provides at bot startup, e.g. using environment variables, CLI parameters, or the `config.js` configuration file. User/Repository config refers to the in-repository config file which defaults to `renovate.json` but has a large number of alternative filenames supported. + +If there is a need to supply custom rules for certain repository, it can still be done using the `config.js` file and the `repositories` array. + +If per-repository config must be done within the repository, it is still recommended against committing secrets directly (including e.g. `.npmrc` files with tokens) and instead encrypting them with a custom public key first. +For instructions on this, see the above section on encrypting secrets for the WhiteSource Renovate App but instead: + +- Save a copy of the html file locally, or host it locally +- Generate a public/private key pair for the app using the instructions in [privateKey](https://docs.renovatebot.com/self-hosted-configuration/#privatekey) +- Replace the existing public key in the html with the public key you generated in the step prior +- Use the resulting html encrypt page to encrypt secrets for your app before adding them to user/repository config +- Configure the app to run with `privateKey` set to the private key you generated above From b3431ffb7bf82f369bfd9471f52405ecfb6f7cd5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 24 Apr 2021 20:21:34 +0000 Subject: [PATCH 50/52] chore(deps): update dependency @types/luxon to v1.26.4 (#9706) Co-authored-by: Renovate Bot --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index ae4bd567475823..c81c12efa0d946 100644 --- a/package.json +++ b/package.json @@ -212,7 +212,7 @@ "@types/js-yaml": "3.12.6", "@types/json-dup-key-validator": "1.0.0", "@types/linkify-markdown": "1.0.0", - "@types/luxon": "1.26.3", + "@types/luxon": "1.26.4", "@types/markdown-it": "12.0.1", "@types/markdown-table": "2.0.0", "@types/moo": "0.5.4", diff --git a/yarn.lock b/yarn.lock index 193a71744540ab..48b066ac185d27 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1525,10 +1525,10 @@ resolved "https://registry.yarnpkg.com/@types/linkify-markdown/-/linkify-markdown-1.0.0.tgz#50c357a0a60bb220209f19310a79b939e1b8e2a3" integrity sha512-p3rl2HtugwjkH8qjEjUi5JByoZkVc2lz6E7D96X5/FqNyj2/jlgIrMlyrbck0U+HyjhOIy0XyTwES3RRz+1koQ== -"@types/luxon@1.26.3": - version "1.26.3" - resolved "https://registry.yarnpkg.com/@types/luxon/-/luxon-1.26.3.tgz#3d548f5f6f59723c292a8545da97631a85738b95" - integrity sha512-2TELN+Pd3Ocde87sKJMSQ9Wdj0zc/okHK3/+fOQHr3CaWv4jtVtcMzmt1Foww1+5YvPd9B5vL3XR6u5KF0daEA== +"@types/luxon@1.26.4": + version "1.26.4" + resolved "https://registry.yarnpkg.com/@types/luxon/-/luxon-1.26.4.tgz#77bbd5a1aa74ca31edff2aee4f8313ea0d93ca5c" + integrity sha512-OIvbVLZQUjyZofqSFpre2VsgvKy0V0JQdRgN0k3H1DTGRdxHiaQjT16+H2gyuhAS9r8B2PQEwrSiqP6/Zka3pQ== "@types/markdown-it@12.0.1": version "12.0.1" From a91c85317ab06704d550d34fc0bc297451fab2cd Mon Sep 17 00:00:00 2001 From: Muhammad Rehan Saeed Date: Sat, 24 Apr 2021 21:25:52 +0100 Subject: [PATCH 51/52] Add Open Telemetry Dotnet monorepo (#9710) --- lib/config/presets/internal/monorepo.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/config/presets/internal/monorepo.ts b/lib/config/presets/internal/monorepo.ts index eee396525cad08..bb13b6f8813db1 100644 --- a/lib/config/presets/internal/monorepo.ts +++ b/lib/config/presets/internal/monorepo.ts @@ -119,6 +119,7 @@ const repoGroups = { nuxtjs: 'https://github.com/nuxt/nuxt.js', openfeign: 'https://github.com/OpenFeign/feign', opentelemetry: 'https://github.com/open-telemetry/opentelemetry-js', + OpenTelemetryDotnet: 'https://github.com/open-telemetry/opentelemetry-dotnet', picasso: 'https://github.com/qlik-oss/picasso.js', pnpjs: 'https://github.com/pnp/pnpjs', playwright: 'https://github.com/Microsoft/playwright', From c542cbe7f549e384ee7c64f30285ebc2e40d7ff7 Mon Sep 17 00:00:00 2001 From: HonkingGoose <34918129+HonkingGoose@users.noreply.github.com> Date: Sun, 25 Apr 2021 15:33:11 +0200 Subject: [PATCH 52/52] docs: improve private module support documentation (#9711) --- docs/usage/private-modules.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/docs/usage/private-modules.md b/docs/usage/private-modules.md index 3aba9f2421cd43..b132990ba4d5a8 100644 --- a/docs/usage/private-modules.md +++ b/docs/usage/private-modules.md @@ -38,7 +38,7 @@ Although npm presets were the first type supported, they are now deprecated and However if you do still use them, private modules should work if you configure the `npmrc` file including token credentials in your bot admin config. Credentials stored on disk (e.g. in `~/.npmrc`) are no longer supported. -The recommended way of using local presets is to configure then using "local" presets, e.g. like `"extends": ["local>myorg/renovate-config"]`, and ensure that the platform token has access to that repo. +The recommended way of using local presets is to configure then using "local" presets, e.g. `"extends": ["local>myorg/renovate-config"]`, and ensure that the platform token has access to that repo. It's not recommended that you use a private repository to host your config while then extending it from a public repository. If your preset doesn't contain secrets then you should make it public, while if it does contain secrets then it's better to split your preset between a public one which all repos extend, and a private one with secrets which only other private repos extend. @@ -52,7 +52,7 @@ In summary, the recommended approach to private presets is: ## Dependency Version Lookups Whenever Renovate detects that a project uses a particular dependency, it attempts to look up that dependency to see if any new versions exist. -If such a package is private, then Renovate will need to be configured with the relevant credentials. +If such a package is private, then Renovate must be configured with the relevant credentials. Renovate does not use any package managers for this step and performs all HTTP(S) lookups itself, including insertion of authentication headers. Configuring Renovate with credentials requires `hostRules`. @@ -64,7 +64,7 @@ It can be either a "platform" name (e.g. `github`, `azure`, etc) or a "datasourc `baseUrl` can be used if you want to only apply the credentials for a nested path within the host, e.g. `https://registry.company.com/nested/path/`. If the same credentials apply to all paths on a host, then use `hostName` instead, e.g. `registry.company.com`. Finally, to apply credentials to all hosts within the domain, use `domainName`, e.g. `company.com`. -You need to pick only one of these and not try to use multiple at the same time, or it will be a config error. +You need to pick _only one_ of these and not configure more than one of these fields within the same host rule, otherwise it will error. In addition to the above options to match against a host, you need to add the credentials. Typically they are either `token`, or `username` + `password`. @@ -91,7 +91,7 @@ Here is an example of some host rules: Renovate applies theses `hostRules` to every HTTP(s) request which is sent, so they are largely independent of any platform or datasource logic. With `hostRules` in place, private package lookups should all work. -## Release Notes +## Looking up Release Notes When Renovate creates Pull Requests, its default behavior is to locate and embed release notes/changelogs of packages. These release notes are fetched from the source repository of packages and not from the registries themselves, so if they are private then they will require different credentials. @@ -102,7 +102,7 @@ It can be confusing for people who host their own source code privately to be as Currently the preferred way to configure `github.com` credentials for self-hosted Renovate is: -- Create a read-only Personal Access Token (PAT) for a `github.com` account. It can be any account, and may even be best to be an empty account created just for this purpose. +- Create a read-only Personal Access Token (PAT) for a `github.com` account. This can be any GitHub account, it might be better to create a "empty" account just for this purpose. - Add the PAT to Renovate using the environment variable `GITHUB_COM_TOKEN` ## Package Manager Credentials for Artifact Updating @@ -155,7 +155,7 @@ If you are a user of this app, and have private modules, then the following is a ### Private presets with public repositories If you have a preset in a private repo but reference ("extend") it from a public repository then it won't work. -This is because public repositories are provided with a token scoped to only that particular repository, and not for all repositories within the org. +This is because public repositories are provided with a token scoped to only that particular repository, and not for all repositories within the organization. This is a security measure so that if a the token is accidentally leaked publicly, the damage is limited to the public repository it leaked to and not to every repository within the organization. The solution to this is that you should break your presets into public and private ones, and reference only the public ones from public repositories. @@ -199,15 +199,16 @@ The WhiteSource Renovate App does not run using GitHub Actions, but such secrets ## Admin/Bot config vs User/Repository config for Self-hosted users -"AdminBot config" refers to the config which the Renovate Bot administrator provides at bot startup, e.g. using environment variables, CLI parameters, or the `config.js` configuration file. User/Repository config refers to the in-repository config file which defaults to `renovate.json` but has a large number of alternative filenames supported. +"AdminBot config" refers to the config which the Renovate Bot administrator provides at bot startup, e.g. using environment variables, CLI parameters, or the `config.js` configuration file. +User/Repository config refers to the in-repository config file which defaults to `renovate.json` but has a large number of alternative filenames supported. If there is a need to supply custom rules for certain repository, it can still be done using the `config.js` file and the `repositories` array. If per-repository config must be done within the repository, it is still recommended against committing secrets directly (including e.g. `.npmrc` files with tokens) and instead encrypting them with a custom public key first. For instructions on this, see the above section on encrypting secrets for the WhiteSource Renovate App but instead: -- Save a copy of the html file locally, or host it locally +- Save a copy of the HTML file locally, or host it locally - Generate a public/private key pair for the app using the instructions in [privateKey](https://docs.renovatebot.com/self-hosted-configuration/#privatekey) -- Replace the existing public key in the html with the public key you generated in the step prior -- Use the resulting html encrypt page to encrypt secrets for your app before adding them to user/repository config +- Replace the existing public key in the HTML with the public key you generated in the step prior +- Use the resulting HTML encrypt page to encrypt secrets for your app before adding them to user/repository config - Configure the app to run with `privateKey` set to the private key you generated above