From d89e3271ab7b5cf3fe48ccb7a29ba922a112631d Mon Sep 17 00:00:00 2001 From: Sergei Zharinov Date: Sat, 11 Feb 2023 14:34:13 +0300 Subject: [PATCH] feat(bazel): Use auto-replace when possible (#20318) --- .../bazel/__snapshots__/extract.spec.ts.snap | 127 +++- lib/modules/manager/bazel/artifacts.spec.ts | 554 +++++++++++++++++ .../manager/bazel/{update.ts => artifacts.ts} | 74 +-- lib/modules/manager/bazel/extract.ts | 1 + lib/modules/manager/bazel/index.ts | 4 +- lib/modules/manager/bazel/rules/go.ts | 6 +- lib/modules/manager/bazel/rules/index.spec.ts | 2 - lib/modules/manager/bazel/update.spec.ts | 572 ------------------ lib/modules/manager/types.ts | 5 +- 9 files changed, 710 insertions(+), 635 deletions(-) create mode 100644 lib/modules/manager/bazel/artifacts.spec.ts rename lib/modules/manager/bazel/{update.ts => artifacts.ts} (70%) delete mode 100644 lib/modules/manager/bazel/update.spec.ts diff --git a/lib/modules/manager/bazel/__snapshots__/extract.spec.ts.snap b/lib/modules/manager/bazel/__snapshots__/extract.spec.ts.snap index 068fe046658f1a..5885d917be2820 100644 --- a/lib/modules/manager/bazel/__snapshots__/extract.spec.ts.snap +++ b/lib/modules/manager/bazel/__snapshots__/extract.spec.ts.snap @@ -11,11 +11,14 @@ exports[`modules/manager/bazel/extract extractPackageFile() extracts multiple ty "idx": 0, }, "packageName": "github.com/bitly/go-nsq", + "replaceString": "go_repository( + name = "com_github_bitly_go-nsq", + importpath = "github.com/bitly/go-nsq", + tag = "v1.0.5" +)", }, { "currentDigest": "dec09d789f3dba190787f8b4454c7d3c936fed9e", - "currentDigestShort": "dec09d7", - "currentValue": "v0.0.0", "datasource": "go", "depName": "com_github_google_uuid", "depType": "go_repository", @@ -24,6 +27,11 @@ exports[`modules/manager/bazel/extract extractPackageFile() extracts multiple ty "idx": 1, }, "packageName": "github.com/google/uuid", + "replaceString": "go_repository( + name = "com_github_google_uuid", + importpath = "github.com/google/uuid", + commit = "dec09d789f3dba190787f8b4454c7d3c936fed9e" +)", }, { "currentValue": "v2", @@ -34,6 +42,11 @@ exports[`modules/manager/bazel/extract extractPackageFile() extracts multiple ty "idx": 2, }, "packageName": "gopkg.in/mgo.v2", + "replaceString": "go_repository( + name = "com_gopkgin_mgo_v2", + importpath = "gopkg.in/mgo.v2", + tag = "v2" +)", }, { "currentValue": "0.3.1", @@ -44,6 +57,11 @@ exports[`modules/manager/bazel/extract extractPackageFile() extracts multiple ty "idx": 3, }, "packageName": "bazelbuild/rules_nodejs", + "replaceString": "git_repository( + name = "build_bazel_rules_nodejs", + remote = "https://github.com/bazelbuild/rules_nodejs.git", + tag = "0.3.1", +)", }, { "currentValue": "0.6.1", @@ -54,6 +72,11 @@ exports[`modules/manager/bazel/extract extractPackageFile() extracts multiple ty "idx": 4, }, "packageName": "bazelbuild/rules_typescript", + "replaceString": "git_repository( + name = "build_bazel_rules_typescript", + remote = "https://github.com/bazelbuild/rules_typescript.git", + tag = "0.6.1", +)", }, { "currentDigest": "446923c3756ceeaa75888f52fcbdd48bb314fbf8", @@ -64,6 +87,12 @@ exports[`modules/manager/bazel/extract extractPackageFile() extracts multiple ty "idx": 5, }, "packageName": "GoogleContainerTools/distroless", + "replaceString": "http_archive( + name="distroless", + sha256="f7a6ecfb8174a1dd4713ea3b21621072996ada7e8f1a69e6ae7581be137c6dd6", + strip_prefix="distroless-446923c3756ceeaa75888f52fcbdd48bb314fbf8", + urls=["https://github.com/GoogleContainerTools/distroless/archive/446923c3756ceeaa75888f52fcbdd48bb314fbf8.tar.gz"] +)", }, { "currentDigest": "d665ccfa3e9c90fa789671bf4ef5f7c19c5715c4", @@ -74,6 +103,15 @@ exports[`modules/manager/bazel/extract extractPackageFile() extracts multiple ty "idx": 6, }, "packageName": "bazelbuild/bazel-toolchains", + "replaceString": "http_archive( + name = "bazel_toolchains", + sha256 = "4b1468b254a572dbe134cc1fd7c6eab1618a72acd339749ea343bd8f55c3b7eb", + strip_prefix = "bazel-toolchains-d665ccfa3e9c90fa789671bf4ef5f7c19c5715c4", + urls = [ + "https://mirror.bazel.build/github.com/bazelbuild/bazel-toolchains/archive/d665ccfa3e9c90fa789671bf4ef5f7c19c5715c4.tar.gz", + "https://github.com/bazelbuild/bazel-toolchains/archive/d665ccfa3e9c90fa789671bf4ef5f7c19c5715c4.tar.gz", + ], +)", }, { "currentValue": "5.5.3", @@ -84,6 +122,13 @@ exports[`modules/manager/bazel/extract extractPackageFile() extracts multiple ty "idx": 7, }, "packageName": "bazelbuild/rules_nodejs", + "replaceString": "http_archive( + name = "rules_nodejs", + sha256 = "5aef09ed3279aa01d5c928e3beb248f9ad32dde6aafe6373a8c994c3ce643064", + urls = [ + "https://github.com/bazelbuild/rules_nodejs/releases/download/5.5.3/rules_nodejs-core-5.5.3.tar.gz" + ], +)", }, { "currentValue": "0.0.3", @@ -94,6 +139,11 @@ exports[`modules/manager/bazel/extract extractPackageFile() extracts multiple ty "idx": 8, }, "packageName": "bazelbuild/rules_sass", + "replaceString": "git_repository( + name = "io_bazel_rules_sass", + remote = "https://github.com/bazelbuild/rules_sass.git", + tag = "0.0.3", +)", }, { "currentDigest": "b3b620e8bcff18ed3378cd3f35ebeb7016d71f71", @@ -104,6 +154,12 @@ exports[`modules/manager/bazel/extract extractPackageFile() extracts multiple ty "idx": 9, }, "packageName": "bazelbuild/buildtools", + "replaceString": "git_repository( + name = "com_github_bazelbuild_buildtools", + remote = "https://github.com/bazelbuild/buildtools.git", + # Note, this commit matches the version of buildifier in angular/ngcontainer + commit = "b3b620e8bcff18ed3378cd3f35ebeb7016d71f71", +)", }, { "currentValue": "0.7.1", @@ -114,6 +170,11 @@ exports[`modules/manager/bazel/extract extractPackageFile() extracts multiple ty "idx": 10, }, "packageName": "bazelbuild/rules_go", + "replaceString": "http_archive( + name = "io_bazel_rules_go", + url = "https://github.com/bazelbuild/rules_go/releases/download/0.7.1/rules_go-0.7.1.tar.gz", + sha256 = "341d5eacef704415386974bc82a1783a8b7ffbff2ab6ba02375e1ca20d9b031c", +)", }, { "currentValue": "0.5.0", @@ -124,6 +185,15 @@ exports[`modules/manager/bazel/extract extractPackageFile() extracts multiple ty "idx": 11, }, "packageName": "bazelbuild/bazel-skylib", + "replaceString": "http_archive( + name = "bazel_skylib", + sha256 = "b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f", + strip_prefix = "bazel-skylib-0.5.0", + urls = [ + "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/archive/0.5.0.tar.gz", + "https://github.com/bazelbuild/bazel-skylib/archive/0.5.0.tar.gz", + ], +)", }, { "currentDigest": "446923c3756ceeaa75888f52fcbdd48bb314fbf8", @@ -134,6 +204,12 @@ exports[`modules/manager/bazel/extract extractPackageFile() extracts multiple ty "idx": 12, }, "packageName": "GoogleContainerTools/distroless", + "replaceString": "http_archive( + name="distroless", + sha256="f7a6ecfb8174a1dd4713ea3b21621072996ada7e8f1a69e6ae7581be137c6dd6", + strip_prefix="distroless-446923c3756ceeaa75888f52fcbdd48bb314fbf8", + urls=["https://github.com/GoogleContainerTools/distroless/archive/446923c3756ceeaa75888f52fcbdd48bb314fbf8.tar.gz"] +)", }, { "currentValue": "v0.29.0", @@ -144,6 +220,12 @@ exports[`modules/manager/bazel/extract extractPackageFile() extracts multiple ty "idx": 13, }, "packageName": "bazelbuild/rules_go", + "replaceString": "maybe( + http_archive, + name = "io_bazel_rules_go", + sha256 = "2b1641428dff9018f9e85c0384f03ec6c10660d935b750e3fa1492a281a53b0f", + url = "https://github.com/bazelbuild/rules_go/releases/download/v0.29.0/rules_go-v0.29.0.zip", +)", }, { "currentValue": "v0.24.0", @@ -154,11 +236,18 @@ exports[`modules/manager/bazel/extract extractPackageFile() extracts multiple ty "idx": 14, }, "packageName": "bazelbuild/bazel-gazelle", + "replaceString": "maybe( + http_archive, + name = "bazel_gazelle", + sha256 = "de69a09dc70417580aabf20a28619bb3ef60d038470c7cf8442fafcf627c21cb", + urls = [ + "https://mirror.bazel.build/github.com/bazelbuild/bazel-gazelle/releases/download/v0.24.0/bazel-gazelle-v0.24.0.tar.gz", + "https://github.com/bazelbuild/bazel-gazelle/releases/download/v0.24.0/bazel-gazelle-v0.24.0.tar.gz", + ], +)", }, { "currentDigest": "816c9085562cd7ee03e7f8188a1cfd942858cded", - "currentDigestShort": "816c908", - "currentValue": "v0.0.0", "datasource": "go", "depName": "com_github_pkg_errors", "depType": "go_repository", @@ -167,6 +256,12 @@ exports[`modules/manager/bazel/extract extractPackageFile() extracts multiple ty "idx": 15, }, "packageName": "github.com/pkg/errors", + "replaceString": "maybe( + go_repository, + name = "com_github_pkg_errors", + commit = "816c9085562cd7ee03e7f8188a1cfd942858cded", + importpath = "github.com/pkg/errors", +)", }, { "currentDigest": "sha256:d5a717649fd93ea5b9c430d7f84e4c37ba219eb53bd73ed1d4a5a98e9edd84a7", @@ -181,6 +276,13 @@ exports[`modules/manager/bazel/extract extractPackageFile() extracts multiple ty "registryUrls": [ "gcr.io", ], + "replaceString": "container_pull( + name = "py3_image_base", + digest = "sha256:d5a717649fd93ea5b9c430d7f84e4c37ba219eb53bd73ed1d4a5a98e9edd84a7", + registry = "gcr.io", + repository = "distroless/python3-debian10", + tag = "latest", +)", "versioning": "docker", }, { @@ -192,6 +294,12 @@ exports[`modules/manager/bazel/extract extractPackageFile() extracts multiple ty "idx": 17, }, "packageName": "GoogleContainerTools/distroless", + "replaceString": "http_file( + name="distroless", + sha256="f7a6ecfb8174a1dd4713ea3b21621072996ada7e8f1a69e6ae7581be137c6dd6", + strip_prefix="distroless-446923c3756ceeaa75888f52fcbdd48bb314fbf8", + urls=["https://github.com/GoogleContainerTools/distroless/archive/446923c3756ceeaa75888f52fcbdd48bb314fbf8.tar.gz"] +)", }, ] `; @@ -207,6 +315,12 @@ exports[`modules/manager/bazel/extract extractPackageFile() sequential http_arch "idx": 0, }, "packageName": "aspect-build/rules_js", + "replaceString": "http_archive( + name = "aspect_rules_js", + sha256 = "db9f446752fe4100320cf8487e8fd476b9af0adf6b99b601bcfd70b289bb0598", + strip_prefix = "rules_js-1.1.2", + url = "https://github.com/aspect-build/rules_js/archive/refs/tags/v1.1.2.tar.gz", +)", }, { "currentValue": "5.5.3", @@ -217,6 +331,11 @@ exports[`modules/manager/bazel/extract extractPackageFile() sequential http_arch "idx": 1, }, "packageName": "bazelbuild/rules_nodejs", + "replaceString": "http_archive( + name = "rules_nodejs", + sha256 = "5aef09ed3279aa01d5c928e3beb248f9ad32dde6aafe6373a8c994c3ce643064", + urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/5.5.3/rules_nodejs-core-5.5.3.tar.gz"], +)", }, ] `; diff --git a/lib/modules/manager/bazel/artifacts.spec.ts b/lib/modules/manager/bazel/artifacts.spec.ts new file mode 100644 index 00000000000000..da400a96c0cd91 --- /dev/null +++ b/lib/modules/manager/bazel/artifacts.spec.ts @@ -0,0 +1,554 @@ +import crypto from 'crypto'; +import { codeBlock } from 'common-tags'; +import * as httpMock from '../../../../test/http-mock'; +import { partial } from '../../../../test/util'; +import type { UpdateArtifact } from '../types'; +import { updateArtifacts } from '.'; + +describe('modules/manager/bazel/artifacts', () => { + it('updates commit-based http archive', async () => { + const inputHash = + 'f7a6ecfb8174a1dd4713ea3b21621072996ada7e8f1a69e6ae7581be137c6dd6'; + const input = codeBlock` + http_archive( + name="distroless", + sha256="${inputHash}", + strip_prefix="distroless-446923c3756ceeaa75888f52fcbdd48bb314fbf8", + urls=["https://github.com/GoogleContainerTools/distroless/archive/446923c3756ceeaa75888f52fcbdd48bb314fbf8.tar.gz"] + ) + `; + + const currentDigest = '446923c3756ceeaa75888f52fcbdd48bb314fbf8'; + const newDigest = '033387ac8853e6cc1cd47df6c346bc53cbc490d8'; + const upgrade = { + depName: 'distroless', + depType: 'http_archive', + repo: 'GoogleContainerTools/distroless', + managerData: { idx: 0 }, + currentDigest, + newDigest, + }; + + const tarContent = Buffer.from('foo'); + const outputHash = crypto + .createHash('sha256') + .update(tarContent) + .digest('hex'); + + const output = input + .replace(currentDigest, newDigest) + .replace(currentDigest, newDigest) + .replace(inputHash, outputHash); + + httpMock + .scope('https://github.com') + .get( + '/GoogleContainerTools/distroless/archive/033387ac8853e6cc1cd47df6c346bc53cbc490d8.tar.gz' + ) + .reply(200, tarContent); + + const res = await updateArtifacts( + partial({ + packageFileName: 'WORKSPACE', + updatedDeps: [upgrade], + newPackageFileContent: input, + }) + ); + + expect(res).toEqual([ + { + file: { + contents: output, + path: 'WORKSPACE', + type: 'addition', + }, + }, + ]); + }); + + it('updates http archive with content other then WORKSPACE', async () => { + const inputHash = + 'eb5c57e4c12e68c0c20bc774bfbc60a568e800d025557bc4ea022c6479acc867'; + const input = codeBlock` + http_archive( + name = "bazel_skylib", + sha256 = "${inputHash}", + strip_prefix = "bazel-skylib-0.6.0", + urls = ["https://github.com/bazelbuild/bazel-skylib/archive/0.6.0.tar.gz"], + ) + `; + + const currentValue = '0.6.0'; + const newValue = '0.8.0'; + const upgrade = { + depName: 'bazel_skylib', + depType: 'http_archive', + repo: 'bazelbuild/bazel-skylib', + managerData: { idx: 0 }, + currentValue, + newValue, + }; + + const tarContent = Buffer.from('foo'); + const outputHash = crypto + .createHash('sha256') + .update(tarContent) + .digest('hex'); + + const output = input + .replace(currentValue, newValue) + .replace(currentValue, newValue) + .replace(inputHash, outputHash); + + httpMock + .scope('https://github.com') + .get('/bazelbuild/bazel-skylib/archive/0.8.0.tar.gz') + .reply(200, tarContent); + + const res = await updateArtifacts( + partial({ + packageFileName: 'WORKSPACE', + updatedDeps: [upgrade], + newPackageFileContent: input, + }) + ); + + expect(res).toEqual([ + { + file: { + contents: output, + path: 'WORKSPACE', + type: 'addition', + }, + }, + ]); + }); + + it('updates finds url instead of urls', async () => { + const inputHash = + 'eb5c57e4c12e68c0c20bc774bfbc60a568e800d025557bc4ea022c6479acc867'; + const input = codeBlock` + http_archive( + name = "bazel_skylib", + sha256 = "${inputHash}", + strip_prefix = "bazel-skylib-0.6.0", + url = "https://github.com/bazelbuild/bazel-skylib/archive/0.6.0.tar.gz", + ) + `; + + const currentValue = '0.6.0'; + const newValue = '0.8.0'; + const upgrade = { + depName: 'bazel_skylib', + depType: 'http_archive', + repo: 'bazelbuild/bazel-skylib', + managerData: { idx: 0 }, + currentValue, + newValue, + }; + + const tarContent = Buffer.from('foo'); + const outputHash = crypto + .createHash('sha256') + .update(tarContent) + .digest('hex'); + + const output = input + .replace(currentValue, newValue) + .replace(currentValue, newValue) + .replace(inputHash, outputHash); + expect(output.indexOf('0.8.0')).not.toBe(-1); + + httpMock + .scope('https://github.com') + .get('/bazelbuild/bazel-skylib/archive/0.8.0.tar.gz') + .reply(200, tarContent); + + const res = await updateArtifacts( + partial({ + packageFileName: 'WORKSPACE', + updatedDeps: [upgrade], + newPackageFileContent: input, + }) + ); + + expect(res).toEqual([ + { + file: { + contents: output, + path: 'WORKSPACE', + type: 'addition', + }, + }, + ]); + }); + + it('returns null if no urls resolve hashes', async () => { + const inputHash = + 'eb5c57e4c12e68c0c20bc774bfbc60a568e800d025557bc4ea022c6479acc867'; + const input = codeBlock` + http_archive( + name = "bazel_skyfoo", + sha256 = "${inputHash}", + strip_prefix = "bazel-skyfoo-0.6.0", + urls = ["https://github.com/bazelbuild/bazel-skyfoo/archive/0.6.0.tar.gz"], + ) + `; + + const currentValue = '0.6.0'; + const newValue = '0.8.0'; + const upgrade = { + depName: 'bazel_skylib', + depType: 'http_archive', + repo: 'bazelbuild/bazel-skyfoo', + managerData: { idx: 0 }, + currentValue, + newValue, + }; + + httpMock + .scope('https://github.com') + .get('/bazelbuild/bazel-skyfoo/archive/0.8.0.tar.gz') + .reply(500); + + const res = await updateArtifacts( + partial({ + packageFileName: 'WORKSPACE', + updatedDeps: [upgrade], + newPackageFileContent: input, + }) + ); + expect(res).toBeNull(); + }); + + it('errors for http_archive without urls', async () => { + const input = codeBlock` + http_archive( + name = "bazel_skylib", + sha256 = "b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f", + strip_prefix = "bazel-skylib-0.5.0", + ) + `; + + const upgrade = { + depName: 'bazel_skylib', + depType: 'http_archive', + repo: 'bazelbuild/bazel-skylib', + managerData: { idx: 0 }, + currentValue: '0.5.0', + newValue: '0.6.2', + }; + const res = await updateArtifacts( + partial({ + packageFileName: 'WORKSPACE', + updatedDeps: [upgrade], + newPackageFileContent: input, + }) + ); + expect(res).toBeNull(); + }); + + it('errors for maybe(http_archive) without urls', async () => { + const input = codeBlock` + maybe( + http_archive, + name = "bazel_skylib", + sha256 = "b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f", + strip_prefix = "bazel-skylib-0.5.0", + ) + `; + + const upgrade = { + depName: 'bazel_skylib', + depType: 'http_archive', + repo: 'bazelbuild/bazel-skylib', + managerData: { idx: 0 }, + currentValue: '0.5.0', + newValue: '0.6.2', + }; + const res = await updateArtifacts( + partial({ + packageFileName: 'WORKSPACE', + updatedDeps: [upgrade], + newPackageFileContent: input, + }) + ); + expect(res).toBeNull(); + }); + + it('updates http_archive with urls array', async () => { + const inputHash = + 'b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f'; + const input = codeBlock` + http_archive( + name = "bazel_skylib", + sha256 = "${inputHash}", + strip_prefix = "bazel-skylib-0.5.0", + urls = [ + "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/archive/0.5.0.tar.gz", + "https://github.com/bazelbuild/bazel-skylib/archive/0.5.0.tar.gz", + ], + ) + `; + + const currentValue = '0.5.0'; + const newValue = '0.6.2'; + const upgrade = { + depName: 'bazel_skylib', + depType: 'http_archive', + repo: 'bazelbuild/bazel-skylib', + managerData: { idx: 0 }, + currentValue, + newValue, + }; + + const tarContent = Buffer.from('foo'); + const outputHash = crypto + .createHash('sha256') + .update(tarContent) + .digest('hex'); + + const output = input + .replace(currentValue, newValue) + .replace(currentValue, newValue) + .replace(currentValue, newValue) + .replace(inputHash, outputHash); + + httpMock + .scope('https://github.com') + .get('/bazelbuild/bazel-skylib/archive/0.6.2.tar.gz') + .reply(200, tarContent); + + httpMock + .scope('https://mirror.bazel.build') + .get('/github.com/bazelbuild/bazel-skylib/archive/0.6.2.tar.gz') + .reply(200, tarContent); + + const res = await updateArtifacts( + partial({ + packageFileName: 'WORKSPACE', + updatedDeps: [upgrade], + newPackageFileContent: input, + }) + ); + + expect(res).toEqual([ + { + file: { + contents: output, + path: 'WORKSPACE', + type: 'addition', + }, + }, + ]); + }); + + it('updates maybe(http_archive) with urls array', async () => { + const inputHash = + 'b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f'; + const input = codeBlock` + maybe( + http_archive, + name = "bazel_skylib", + sha256 = "${inputHash}", + strip_prefix = "bazel-skylib-0.5.0", + urls = [ + "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/archive/0.5.0.tar.gz", + "https://github.com/bazelbuild/bazel-skylib/archive/0.5.0.tar.gz", + ], + ) + `; + + const currentValue = '0.5.0'; + const newValue = '0.6.2'; + const upgrade = { + depName: 'bazel_skylib', + depType: 'http_archive', + repo: 'bazelbuild/bazel-skylib', + managerData: { idx: 0 }, + currentValue, + newValue, + }; + + const tarContent = Buffer.from('foo'); + const outputHash = crypto + .createHash('sha256') + .update(tarContent) + .digest('hex'); + + const output = input + .replace(currentValue, newValue) + .replace(currentValue, newValue) + .replace(currentValue, newValue) + .replace(inputHash, outputHash); + + httpMock + .scope('https://github.com') + .get('/bazelbuild/bazel-skylib/archive/0.6.2.tar.gz') + .reply(200, tarContent); + httpMock + .scope('https://mirror.bazel.build') + .get('/github.com/bazelbuild/bazel-skylib/archive/0.6.2.tar.gz') + .reply(200, tarContent); + + const res = await updateArtifacts( + partial({ + packageFileName: 'WORKSPACE', + updatedDeps: [upgrade], + newPackageFileContent: input, + }) + ); + + expect(res).toEqual([ + { + file: { + contents: output, + path: 'WORKSPACE', + type: 'addition', + }, + }, + ]); + }); + + it('updates one http_archive alongside others', async () => { + const inputHash = + '5aef09ed3279aa01d5c928e3beb248f9ad32dde6aafe6373a8c994c3ce643064'; + const other_http_archive = codeBlock` + http_archive( + name = "aspect_rules_js", + sha256 = "db9f446752fe4100320cf8487e8fd476b9af0adf6b99b601bcfd70b289bb0598", + strip_prefix = "rules_js-1.1.2", + url = "https://github.com/aspect-build/rules_js/archive/refs/tags/v1.1.2.tar.gz", + ) + `; + const upgraded_http_archive = codeBlock` + http_archive( + name = "rules_nodejs", + sha256 = "${inputHash}", + urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/5.5.3/rules_nodejs-core-5.5.3.tar.gz"], + ) + `; + + const input = `${other_http_archive}\n${upgraded_http_archive}`; + + const currentValue = '5.5.3'; + const newValue = '5.5.4'; + const upgrade = { + depName: 'rules_nodejs', + depType: 'http_archive', + repo: 'bazelbuild/rules_nodejs', + managerData: { idx: 1 }, + currentValue, + newValue, + }; + + const tarContent = Buffer.from('foo'); + const outputHash = crypto + .createHash('sha256') + .update(tarContent) + .digest('hex'); + + httpMock + .scope('https://github.com') + .get( + '/bazelbuild/rules_nodejs/releases/download/5.5.4/rules_nodejs-core-5.5.4.tar.gz' + ) + .reply(200, tarContent); + + const output = input + .replace(currentValue, newValue) + .replace(currentValue, newValue) + .replace(currentValue, newValue) + .replace(inputHash, outputHash); + + const res = await updateArtifacts( + partial({ + packageFileName: 'WORKSPACE', + updatedDeps: [upgrade], + newPackageFileContent: input, + }) + ); + + expect(res).toEqual([ + { + file: { + contents: output, + path: 'WORKSPACE', + type: 'addition', + }, + }, + ]); + }); + + it('updates one http_archive alongside others with matching versions', async () => { + const inputHash = + '5aef09ed3279aa01d5c928e3beb248f9ad32dde6aafe6373a8c994c3ce643064'; + + const other_http_archive = codeBlock` + http_archive( + name = "aspect_rules_js", + sha256 = "db9f446752fe4100320cf8487e8fd476b9af0adf6b99b601bcfd70b289bb0598", + strip_prefix = "rules_js-1.1.2", + url = "https://github.com/aspect-build/rules_js/archive/refs/tags/v1.1.2.tar.gz", + )`; + + const upgraded_http_archive = codeBlock` + http_archive( + name = "rules_nodejs", + sha256 = "${inputHash}", + urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/1.1.2/rules_nodejs-core-1.1.2.tar.gz"], + ) + `; + + const input = `${other_http_archive}\n${upgraded_http_archive}`; + + const currentValue = '1.1.2'; + const newValue = '1.2.3'; + const upgrade = { + depName: 'rules_nodejs', + depType: 'http_archive', + repo: 'bazelbuild/rules_nodejs', + managerData: { idx: 1 }, + currentValue, + newValue, + }; + + const tarContent = Buffer.from('foo'); + const outputHash = crypto + .createHash('sha256') + .update(tarContent) + .digest('hex'); + + httpMock + .scope('https://github.com') + .get( + '/bazelbuild/rules_nodejs/releases/download/1.2.3/rules_nodejs-core-1.2.3.tar.gz' + ) + .reply(200, tarContent); + + const output = input + .replace( + `${currentValue}/rules_nodejs-core-${currentValue}`, + `${newValue}/rules_nodejs-core-${newValue}` + ) + .replace(inputHash, outputHash); + + const res = await updateArtifacts( + partial({ + packageFileName: 'WORKSPACE', + updatedDeps: [upgrade], + newPackageFileContent: input, + }) + ); + + expect(res).toEqual([ + { + file: { + contents: output, + path: 'WORKSPACE', + type: 'addition', + }, + }, + ]); + }); +}); diff --git a/lib/modules/manager/bazel/update.ts b/lib/modules/manager/bazel/artifacts.ts similarity index 70% rename from lib/modules/manager/bazel/update.ts rename to lib/modules/manager/bazel/artifacts.ts index 3bf0bb4890ebe7..194f929f3d570c 100644 --- a/lib/modules/manager/bazel/update.ts +++ b/lib/modules/manager/bazel/artifacts.ts @@ -5,9 +5,9 @@ import * as packageCache from '../../../util/cache/package'; import { Http } from '../../../util/http'; import { map as pMap } from '../../../util/promises'; import { regEx } from '../../../util/regex'; -import type { UpdateDependencyConfig } from '../types'; +import type { UpdateArtifact, UpdateArtifactsResult } from '../types'; import { findCodeFragment, patchCodeAtFragments, updateCode } from './common'; -import type { BazelManagerData, RecordFragment, StringFragment } from './types'; +import type { RecordFragment, StringFragment } from './types'; const http = new Http('bazel'); @@ -105,48 +105,17 @@ async function getHashFromUrls(urls: string[]): Promise { return hashes[0]; } -export async function updateDependency({ - fileContent, - upgrade, -}: UpdateDependencyConfig): Promise { - try { - const { newValue, newDigest } = upgrade; - logger.debug({ newValue, newDigest }, `bazel.updateDependency()`); - const idx = upgrade.managerData!.idx; - - if (upgrade.depType === 'container_pull') { - let result = fileContent; - - if (newValue) { - result = updateCode(result, [idx, 'tag'], newValue); - } - - if (newDigest) { - result = updateCode(result, [idx, 'digest'], newDigest); - } - - return result; - } - - if ( - upgrade.depType === 'git_repository' || - upgrade.depType === 'go_repository' - ) { - let result = fileContent; - - if (newValue) { - result = updateCode(result, [idx, 'tag'], newValue); - } - - if (newDigest) { - result = updateCode(result, [idx, 'commit'], newDigest); - } - - return result; - } +export async function updateArtifacts( + updateArtifact: UpdateArtifact +): Promise { + const { packageFileName: path, updatedDeps: upgrades } = updateArtifact; + let { newPackageFileContent: contents } = updateArtifact; + for (const upgrade of upgrades) { + const { managerData } = upgrade; + const idx = managerData?.idx as number; if (upgrade.depType === 'http_file' || upgrade.depType === 'http_archive') { - const rule = findCodeFragment(fileContent, [idx]); + const rule = findCodeFragment(contents, [idx]); // istanbul ignore if if (rule?.type !== 'record') { return null; @@ -171,16 +140,19 @@ export async function updateDependency({ return null; } - let result = fileContent; - result = patchCodeAtFragments(result, urlFragments, updateValues); - result = updateCode(result, [idx, 'strip_prefix'], updateValues); - result = updateCode(result, [idx, 'sha256'], hash); - return result; + contents = patchCodeAtFragments(contents, urlFragments, updateValues); + contents = updateCode(contents, [idx, 'strip_prefix'], updateValues); + contents = updateCode(contents, [idx, 'sha256'], hash); } - } catch (err) /* istanbul ignore next */ { - logger.debug({ err }, 'Error setting new bazel WORKSPACE version'); } - // istanbul ignore next - return null; + return [ + { + file: { + type: 'addition', + path, + contents, + }, + }, + ]; } diff --git a/lib/modules/manager/bazel/extract.ts b/lib/modules/manager/bazel/extract.ts index 072c632a181298..aca6894f193630 100644 --- a/lib/modules/manager/bazel/extract.ts +++ b/lib/modules/manager/bazel/extract.ts @@ -22,6 +22,7 @@ export function extractPackageFile( continue; } + dep.replaceString = fragment.value; dep.managerData = { idx }; deps.push(dep); } diff --git a/lib/modules/manager/bazel/index.ts b/lib/modules/manager/bazel/index.ts index 0c6d3294611ff8..3ff48cfeab9e4a 100644 --- a/lib/modules/manager/bazel/index.ts +++ b/lib/modules/manager/bazel/index.ts @@ -2,10 +2,10 @@ import { DockerDatasource } from '../../datasource/docker'; import { GithubReleasesDatasource } from '../../datasource/github-releases'; import { GithubTagsDatasource } from '../../datasource/github-tags'; import { GoDatasource } from '../../datasource/go'; +import { updateArtifacts } from './artifacts'; import { extractPackageFile } from './extract'; -import { updateDependency } from './update'; -export { extractPackageFile, updateDependency }; +export { extractPackageFile, updateArtifacts }; export const defaultConfig = { fileMatch: ['(^|/)WORKSPACE(|\\.bazel)$', '\\.bzl$'], diff --git a/lib/modules/manager/bazel/rules/go.ts b/lib/modules/manager/bazel/rules/go.ts index ff6f4398003b7a..ef68c1c93194f0 100644 --- a/lib/modules/manager/bazel/rules/go.ts +++ b/lib/modules/manager/bazel/rules/go.ts @@ -29,10 +29,10 @@ export const GoTarget = z } if (commit) { - dep.currentValue = 'v0.0.0'; dep.currentDigest = commit; - dep.currentDigestShort = commit.substring(0, 7); - dep.digestOneAndOnly = true; + if (!tag) { + dep.digestOneAndOnly = true; + } } if (remote) { diff --git a/lib/modules/manager/bazel/rules/index.spec.ts b/lib/modules/manager/bazel/rules/index.spec.ts index 4a01c579767cc3..df3043127b550e 100644 --- a/lib/modules/manager/bazel/rules/index.spec.ts +++ b/lib/modules/manager/bazel/rules/index.spec.ts @@ -152,9 +152,7 @@ describe('modules/manager/bazel/rules/index', () => { depType: 'go_repository', depName: 'foo_bar', packageName: 'foo/bar/baz', - currentValue: 'v0.0.0', currentDigest: 'abcdef0123abcdef0123abcdef0123abcdef0123', - currentDigestShort: 'abcdef0', digestOneAndOnly: true, }); diff --git a/lib/modules/manager/bazel/update.spec.ts b/lib/modules/manager/bazel/update.spec.ts deleted file mode 100644 index f336e00445006d..00000000000000 --- a/lib/modules/manager/bazel/update.spec.ts +++ /dev/null @@ -1,572 +0,0 @@ -import crypto from 'crypto'; -import * as httpMock from '../../../../test/http-mock'; -import type { UpdateType } from '../../../config/types'; -import { updateDependency } from '.'; - -describe('modules/manager/bazel/update', () => { - describe('updateDependency', () => { - beforeEach(() => { - jest.resetAllMocks(); - }); - - it('updates git_repository tag', async () => { - const input = ` - git_repository( - name = "build_bazel_rules_nodejs", - remote = "https://github.com/bazelbuild/rules_nodejs.git", - tag = "0.1.8", - ) - `.trim(); - - const upgrade = { - depName: 'build_bazel_rules_nodejs', - depType: 'git_repository', - managerData: { idx: 0 }, - currentValue: '0.1.8', - newValue: '0.2.0', - }; - const output = input.replace('0.1.8', '0.2.0'); - - const res = await updateDependency({ - fileContent: input, - upgrade, - }); - - expect(res).toEqual(output); - }); - - it('updates maybe(git_repository) tag', async () => { - const input = - ` - maybe( - git_repository, - name = "build_bazel_rules_nodejs", - remote = "https://github.com/bazelbuild/rules_nodejs.git", - tag = "0.1.8", - ) - `.trim() + '\n'; - - const upgrade = { - depName: 'build_bazel_rules_nodejs', - depType: 'git_repository', - managerData: { idx: 0 }, - currentValue: '0.1.8', - newValue: '0.2.0', - }; - const output = input.replace('0.1.8', '0.2.0'); - - const res = await updateDependency({ - fileContent: input, - upgrade, - }); - - expect(res).toEqual(output); - }); - - it('updates container_pull deptype and preserves comment', async () => { - const input = ` - container_pull( - name="hasura", - registry="index.docker.io", - repository="hasura/graphql-engine", - # v1.0.0-alpha31.cli-migrations 11/28 - digest="sha256:a4e8d8c444ca04fe706649e82263c9f4c2a4229bc30d2a64561b5e1d20cc8548", - tag="v1.0.0-alpha31.cli-migrations" - ) - `.trim(); - - const currentValue = 'v1.0.0-alpha31.cli-migrations'; - const newValue = 'v1.0.0-alpha42.cli-migrations'; - - const currentDigest = - 'sha256:a4e8d8c444ca04fe706649e82263c9f4c2a4229bc30d2a64561b5e1d20cc8548'; - const newDigest = - 'sha256:2c29ba015faef92a3f55b37632fc373a7fbc2c9fddd31e317bf07113391c640b'; - - const upgrade = { - depName: 'hasura', - depType: 'container_pull', - managerData: { idx: 0 }, - currentValue, - newValue, - currentDigest, - newDigest, - }; - - const output = input - .replace(`tag="${currentValue}"`, `tag="${newValue}"`) - .replace(currentDigest, newDigest); - - const res = await updateDependency({ fileContent: input, upgrade }); - - expect(res).toEqual(output); - expect(res).toContain('# v1.0.0-alpha31.cli-migrations 11/28'); - }); - - it('updates commit to tag', async () => { - const input = ` - go_repository( - name = "com_github_google_uuid", - importpath = "github.com/google/uuid", - commit = "dec09d789f3dba190787f8b4454c7d3c936fed9e" - ) - `.trim(); - - const currentDigest = 'dec09d789f3dba190787f8b4454c7d3c936fed9e'; - const newDigest = 'aaa09d789f3dba190787f8b4454c7d3c936fe123'; - const newValue = 'v1.0.3'; - - const upgrade = { - depName: 'com_github_google_uuid', - depType: 'go_repository', - managerData: { idx: 0 }, - currentValue: 'v0.0.0', - currentDigest, - newDigest, - newValue, - updateType: 'major' as UpdateType, - }; - - const output = input.replace(`"${currentDigest}"`, `"${newDigest}"`); - - const res = await updateDependency({ fileContent: input, upgrade }); - - expect(res).toEqual(output); - expect(res).toContain('"aaa09d789f3dba190787f8b4454c7d3c936fe123"'); - }); - - it('updates commit-based http archive', async () => { - const inputHash = - 'f7a6ecfb8174a1dd4713ea3b21621072996ada7e8f1a69e6ae7581be137c6dd6'; - const input = ` - http_archive( - name="distroless", - sha256="${inputHash}", - strip_prefix="distroless-446923c3756ceeaa75888f52fcbdd48bb314fbf8", - urls=["https://github.com/GoogleContainerTools/distroless/archive/446923c3756ceeaa75888f52fcbdd48bb314fbf8.tar.gz"] - ) - `.trim(); - - const currentDigest = '446923c3756ceeaa75888f52fcbdd48bb314fbf8'; - const newDigest = '033387ac8853e6cc1cd47df6c346bc53cbc490d8'; - const upgrade = { - depName: 'distroless', - depType: 'http_archive', - repo: 'GoogleContainerTools/distroless', - managerData: { idx: 0 }, - currentDigest, - newDigest, - }; - - const tarContent = Buffer.from('foo'); - const outputHash = crypto - .createHash('sha256') - .update(tarContent) - .digest('hex'); - - const output = input - .replace(currentDigest, newDigest) - .replace(currentDigest, newDigest) - .replace(inputHash, outputHash); - - httpMock - .scope('https://github.com') - .get( - '/GoogleContainerTools/distroless/archive/033387ac8853e6cc1cd47df6c346bc53cbc490d8.tar.gz' - ) - .reply(200, tarContent); - - const res = await updateDependency({ fileContent: input, upgrade }); - - expect(res).toEqual(output); - }); - - it('updates http archive with content other then WORKSPACE', async () => { - const inputHash = - 'eb5c57e4c12e68c0c20bc774bfbc60a568e800d025557bc4ea022c6479acc867'; - const input = ` - http_archive( - name = "bazel_skylib", - sha256 = "${inputHash}", - strip_prefix = "bazel-skylib-0.6.0", - urls = ["https://github.com/bazelbuild/bazel-skylib/archive/0.6.0.tar.gz"], - ) - `.trim(); - - const currentValue = '0.6.0'; - const newValue = '0.8.0'; - const upgrade = { - depName: 'bazel_skylib', - depType: 'http_archive', - repo: 'bazelbuild/bazel-skylib', - managerData: { idx: 0 }, - currentValue, - newValue, - }; - - const tarContent = Buffer.from('foo'); - const outputHash = crypto - .createHash('sha256') - .update(tarContent) - .digest('hex'); - - const output = input - .replace(currentValue, newValue) - .replace(currentValue, newValue) - .replace(inputHash, outputHash); - - httpMock - .scope('https://github.com') - .get('/bazelbuild/bazel-skylib/archive/0.8.0.tar.gz') - .reply(200, tarContent); - - const res = await updateDependency({ fileContent: input, upgrade }); - - expect(res).toEqual(output); - }); - - it('updates finds url instead of urls', async () => { - const inputHash = - 'eb5c57e4c12e68c0c20bc774bfbc60a568e800d025557bc4ea022c6479acc867'; - const input = ` - http_archive( - name = "bazel_skylib", - sha256 = "${inputHash}", - strip_prefix = "bazel-skylib-0.6.0", - url = "https://github.com/bazelbuild/bazel-skylib/archive/0.6.0.tar.gz", - ) - `.trim(); - - const currentValue = '0.6.0'; - const newValue = '0.8.0'; - const upgrade = { - depName: 'bazel_skylib', - depType: 'http_archive', - repo: 'bazelbuild/bazel-skylib', - managerData: { idx: 0 }, - currentValue, - newValue, - }; - - const tarContent = Buffer.from('foo'); - const outputHash = crypto - .createHash('sha256') - .update(tarContent) - .digest('hex'); - - const output = input - .replace(currentValue, newValue) - .replace(currentValue, newValue) - .replace(inputHash, outputHash); - - httpMock - .scope('https://github.com') - .get('/bazelbuild/bazel-skylib/archive/0.8.0.tar.gz') - .reply(200, tarContent); - - const res = await updateDependency({ fileContent: input, upgrade }); - - expect(res).toEqual(output); - expect(res?.indexOf('0.8.0')).not.toBe(-1); - }); - - it('returns null if no urls resolve hashes', async () => { - const inputHash = - 'eb5c57e4c12e68c0c20bc774bfbc60a568e800d025557bc4ea022c6479acc867'; - const input = ` - http_archive( - name = "bazel_skyfoo", - sha256 = "${inputHash}", - strip_prefix = "bazel-skyfoo-0.6.0", - urls = ["https://github.com/bazelbuild/bazel-skyfoo/archive/0.6.0.tar.gz"], - ) - `.trim(); - - const currentValue = '0.6.0'; - const newValue = '0.8.0'; - const upgrade = { - depName: 'bazel_skylib', - depType: 'http_archive', - repo: 'bazelbuild/bazel-skyfoo', - managerData: { idx: 0 }, - currentValue, - newValue, - }; - - httpMock - .scope('https://github.com') - .get('/bazelbuild/bazel-skyfoo/archive/0.8.0.tar.gz') - .reply(500); - - const res = await updateDependency({ fileContent: input, upgrade }); - - expect(res).toBeNull(); - }); - - it('errors for http_archive without urls', async () => { - const input = ` - http_archive( - name = "bazel_skylib", - sha256 = "b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f", - strip_prefix = "bazel-skylib-0.5.0", - ) - `.trim(); - - const upgrade = { - depName: 'bazel_skylib', - depType: 'http_archive', - repo: 'bazelbuild/bazel-skylib', - managerData: { idx: 0 }, - currentValue: '0.5.0', - newValue: '0.6.2', - }; - const res = await updateDependency({ fileContent: input, upgrade }); - expect(res).toBeNull(); - }); - - it('errors for maybe(http_archive) without urls', async () => { - const input = ` - maybe( - http_archive, - name = "bazel_skylib", - sha256 = "b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f", - strip_prefix = "bazel-skylib-0.5.0", - ) - `.trim(); - - const upgrade = { - depName: 'bazel_skylib', - depType: 'http_archive', - repo: 'bazelbuild/bazel-skylib', - managerData: { idx: 0 }, - currentValue: '0.5.0', - newValue: '0.6.2', - }; - const res = await updateDependency({ fileContent: input, upgrade }); - expect(res).toBeNull(); - }); - - it('updates http_archive with urls array', async () => { - const inputHash = - 'b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f'; - const input = ` - http_archive( - name = "bazel_skylib", - sha256 = "${inputHash}", - strip_prefix = "bazel-skylib-0.5.0", - urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/archive/0.5.0.tar.gz", - "https://github.com/bazelbuild/bazel-skylib/archive/0.5.0.tar.gz", - ], - ) - `.trim(); - - const currentValue = '0.5.0'; - const newValue = '0.6.2'; - const upgrade = { - depName: 'bazel_skylib', - depType: 'http_archive', - repo: 'bazelbuild/bazel-skylib', - managerData: { idx: 0 }, - currentValue, - newValue, - }; - - const tarContent = Buffer.from('foo'); - const outputHash = crypto - .createHash('sha256') - .update(tarContent) - .digest('hex'); - - const output = input - .replace(currentValue, newValue) - .replace(currentValue, newValue) - .replace(currentValue, newValue) - .replace(inputHash, outputHash); - - httpMock - .scope('https://github.com') - .get('/bazelbuild/bazel-skylib/archive/0.6.2.tar.gz') - .reply(200, tarContent); - - httpMock - .scope('https://mirror.bazel.build') - .get('/github.com/bazelbuild/bazel-skylib/archive/0.6.2.tar.gz') - .reply(200, tarContent); - - const res = await updateDependency({ fileContent: input, upgrade }); - - expect(res).toEqual(output); - }); - - it('updates maybe(http_archive) with urls array', async () => { - const inputHash = - 'b5f6abe419da897b7901f90cbab08af958b97a8f3575b0d3dd062ac7ce78541f'; - const input = ` - maybe( - http_archive, - name = "bazel_skylib", - sha256 = "${inputHash}", - strip_prefix = "bazel-skylib-0.5.0", - urls = [ - "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/archive/0.5.0.tar.gz", - "https://github.com/bazelbuild/bazel-skylib/archive/0.5.0.tar.gz", - ], - ) - `.trim(); - - const currentValue = '0.5.0'; - const newValue = '0.6.2'; - const upgrade = { - depName: 'bazel_skylib', - depType: 'http_archive', - repo: 'bazelbuild/bazel-skylib', - managerData: { idx: 0 }, - currentValue, - newValue, - }; - - const tarContent = Buffer.from('foo'); - const outputHash = crypto - .createHash('sha256') - .update(tarContent) - .digest('hex'); - - const output = input - .replace(currentValue, newValue) - .replace(currentValue, newValue) - .replace(currentValue, newValue) - .replace(inputHash, outputHash); - - httpMock - .scope('https://github.com') - .get('/bazelbuild/bazel-skylib/archive/0.6.2.tar.gz') - .reply(200, tarContent); - httpMock - .scope('https://mirror.bazel.build') - .get('/github.com/bazelbuild/bazel-skylib/archive/0.6.2.tar.gz') - .reply(200, tarContent); - - const res = await updateDependency({ fileContent: input, upgrade }); - expect(res).toEqual(output); - }); - }); - - it('updates one http_archive alongside others', async () => { - const inputHash1 = - '5aef09ed3279aa01d5c928e3beb248f9ad32dde6aafe6373a8c994c3ce643064'; - const other_http_archive = ` - http_archive( - name = "aspect_rules_js", - sha256 = "db9f446752fe4100320cf8487e8fd476b9af0adf6b99b601bcfd70b289bb0598", - strip_prefix = "rules_js-1.1.2", - url = "https://github.com/aspect-build/rules_js/archive/refs/tags/v1.1.2.tar.gz", - ) - `.trim(); - const upgraded_http_archive = ` - http_archive( - name = "rules_nodejs", - sha256 = "${inputHash1}", - urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/5.5.3/rules_nodejs-core-5.5.3.tar.gz"], - ) - `.trim(); - - const input = `${other_http_archive}\n${upgraded_http_archive}`; - - const currentValue1 = '5.5.3'; - const newValue1 = '5.5.4'; - const upgrade1 = { - depName: 'rules_nodejs', - depType: 'http_archive', - repo: 'bazelbuild/rules_nodejs', - managerData: { idx: 1 }, - currentValue: currentValue1, - newValue: newValue1, - }; - - const tarContent1 = Buffer.from('foo'); - const outputHash1 = crypto - .createHash('sha256') - .update(tarContent1) - .digest('hex'); - - httpMock - .scope('https://github.com') - .get( - '/bazelbuild/rules_nodejs/releases/download/5.5.4/rules_nodejs-core-5.5.4.tar.gz' - ) - .reply(200, tarContent1); - - const output1 = input - .replace(currentValue1, newValue1) - .replace(currentValue1, newValue1) - .replace(currentValue1, newValue1) - .replace(inputHash1, outputHash1); - - const res = await updateDependency({ - fileContent: input, - upgrade: upgrade1, - }); - expect(res).toEqual(output1); - }); - - it('updates one http_archive alongside others with matching versions', async () => { - const inputHash1 = - '5aef09ed3279aa01d5c928e3beb248f9ad32dde6aafe6373a8c994c3ce643064'; - - const other_http_archive = ` - http_archive( - name = "aspect_rules_js", - sha256 = "db9f446752fe4100320cf8487e8fd476b9af0adf6b99b601bcfd70b289bb0598", - strip_prefix = "rules_js-1.1.2", - url = "https://github.com/aspect-build/rules_js/archive/refs/tags/v1.1.2.tar.gz", - )`.trim(); - - const upgraded_http_archive = ` - http_archive( - name = "rules_nodejs", - sha256 = "${inputHash1}", - urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/1.1.2/rules_nodejs-core-1.1.2.tar.gz"], - ) - `.trim(); - - const input = `${other_http_archive}\n${upgraded_http_archive}`; - - const currentValue1 = '1.1.2'; - const newValue1 = '1.2.3'; - const upgrade1 = { - depName: 'rules_nodejs', - depType: 'http_archive', - repo: 'bazelbuild/rules_nodejs', - managerData: { idx: 1 }, - currentValue: currentValue1, - newValue: newValue1, - }; - - const tarContent1 = Buffer.from('foo'); - const outputHash1 = crypto - .createHash('sha256') - .update(tarContent1) - .digest('hex'); - - httpMock - .scope('https://github.com') - .get( - '/bazelbuild/rules_nodejs/releases/download/1.2.3/rules_nodejs-core-1.2.3.tar.gz' - ) - .reply(200, tarContent1); - - const output1 = input - .replace( - `${currentValue1}/rules_nodejs-core-${currentValue1}`, - `${newValue1}/rules_nodejs-core-${newValue1}` - ) - .replace(inputHash1, outputHash1); - - const res = await updateDependency({ - fileContent: input, - upgrade: upgrade1, - }); - expect(res).toEqual(output1); - }); -}); diff --git a/lib/modules/manager/types.ts b/lib/modules/manager/types.ts index c3a93d8f9b6a4c..d3d897ff7e22bd 100644 --- a/lib/modules/manager/types.ts +++ b/lib/modules/manager/types.ts @@ -187,6 +187,9 @@ export interface Upgrade> isLockFileMaintenance?: boolean; isRemediation?: boolean; isVulnerabilityAlert?: boolean; + registryUrls?: string[] | null; + currentVersion?: string; + replaceString?: string; } export interface ArtifactError { @@ -201,7 +204,7 @@ export interface UpdateArtifactsResult { export interface UpdateArtifact> { packageFileName: string; - updatedDeps: PackageDependency[]; + updatedDeps: Upgrade[]; newPackageFileContent: string; config: UpdateArtifactsConfig; }