renovate 43.263.1 → 43.263.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/app-strings.js +1 -1
- package/dist/config/app-strings.js.map +1 -1
- package/dist/config/decrypt/bcpgp.js +7 -4
- package/dist/config/decrypt/bcpgp.js.map +1 -1
- package/dist/config/migration.js +4 -6
- package/dist/config/migration.js.map +1 -1
- package/dist/config/options/index.js +1 -1
- package/dist/config/options/index.js.map +1 -1
- package/dist/config/validation-helpers/match-base-branches.js +4 -6
- package/dist/config/validation-helpers/match-base-branches.js.map +1 -1
- package/dist/config/validation-helpers/regex-glob-matchers.js +4 -6
- package/dist/config/validation-helpers/regex-glob-matchers.js.map +1 -1
- package/dist/config/validation-helpers/utils.js +2 -4
- package/dist/config/validation-helpers/utils.js.map +1 -1
- package/dist/config/validation.js +4 -6
- package/dist/config/validation.js.map +1 -1
- package/dist/config-validator.js +1 -3
- package/dist/config-validator.js.map +1 -1
- package/dist/global-config-option-defaults.generated.js +1 -1
- package/dist/global-config-option-defaults.generated.js.map +1 -1
- package/dist/modules/datasource/artifactory/index.js +6 -8
- package/dist/modules/datasource/artifactory/index.js.map +1 -1
- package/dist/modules/datasource/aws-machine-image/index.js +1 -2
- package/dist/modules/datasource/aws-machine-image/index.js.map +1 -1
- package/dist/modules/datasource/azure-pipelines-tasks/index.js +2 -3
- package/dist/modules/datasource/azure-pipelines-tasks/index.js.map +1 -1
- package/dist/modules/datasource/conda/index.js +1 -3
- package/dist/modules/datasource/conda/index.js.map +1 -1
- package/dist/modules/datasource/dart-version/index.js +1 -2
- package/dist/modules/datasource/dart-version/index.js.map +1 -1
- package/dist/modules/datasource/datasource.js +1 -3
- package/dist/modules/datasource/datasource.js.map +1 -1
- package/dist/modules/datasource/devbox/index.js +1 -3
- package/dist/modules/datasource/devbox/index.js.map +1 -1
- package/dist/modules/datasource/docker/ecr.js +2 -1
- package/dist/modules/datasource/docker/ecr.js.map +1 -1
- package/dist/modules/datasource/docker/index.js +1 -1
- package/dist/modules/datasource/docker/index.js.map +1 -1
- package/dist/modules/datasource/galaxy-collection/index.js +1 -1
- package/dist/modules/datasource/galaxy-collection/index.js.map +1 -1
- package/dist/modules/datasource/go/releases-goproxy.js +2 -2
- package/dist/modules/datasource/go/releases-goproxy.js.map +1 -1
- package/dist/modules/datasource/java-version/index.js +1 -3
- package/dist/modules/datasource/java-version/index.js.map +1 -1
- package/dist/modules/datasource/maven/util.js +2 -1
- package/dist/modules/datasource/maven/util.js.map +1 -1
- package/dist/modules/datasource/nuget/common.js +6 -4
- package/dist/modules/datasource/nuget/common.js.map +1 -1
- package/dist/modules/datasource/util.js +3 -2
- package/dist/modules/datasource/util.js.map +1 -1
- package/dist/modules/manager/azure-pipelines/extract.js +1 -1
- package/dist/modules/manager/azure-pipelines/extract.js.map +1 -1
- package/dist/modules/manager/bazel/extract.js +1 -3
- package/dist/modules/manager/bazel/extract.js.map +1 -1
- package/dist/modules/manager/bazel/parser.js +1 -1
- package/dist/modules/manager/bazel/parser.js.map +1 -1
- package/dist/modules/manager/buildpacks/extract.js +1 -1
- package/dist/modules/manager/buildpacks/extract.js.map +1 -1
- package/dist/modules/manager/bundler/common.js +23 -25
- package/dist/modules/manager/bundler/common.js.map +1 -1
- package/dist/modules/manager/bundler/extract.js +2 -6
- package/dist/modules/manager/bundler/extract.js.map +1 -1
- package/dist/modules/manager/cargo/extract.js +4 -6
- package/dist/modules/manager/cargo/extract.js.map +1 -1
- package/dist/modules/manager/dockerfile/extract.js +3 -3
- package/dist/modules/manager/dockerfile/extract.js.map +1 -1
- package/dist/modules/manager/fingerprint.generated.js +11 -11
- package/dist/modules/manager/fingerprint.generated.js.map +1 -1
- package/dist/modules/manager/flux/extract.js +2 -1
- package/dist/modules/manager/flux/extract.js.map +1 -1
- package/dist/modules/manager/github-actions/parse.js +1 -1
- package/dist/modules/manager/github-actions/parse.js.map +1 -1
- package/dist/modules/manager/gradle/extract/catalog.js +4 -3
- package/dist/modules/manager/gradle/extract/catalog.js.map +1 -1
- package/dist/modules/manager/gradle/extract.js +2 -2
- package/dist/modules/manager/gradle/extract.js.map +1 -1
- package/dist/modules/manager/gradle/parser/common.js +1 -1
- package/dist/modules/manager/gradle/parser/common.js.map +1 -1
- package/dist/modules/manager/gradle/parser/handlers.js +1 -1
- package/dist/modules/manager/gradle/parser/handlers.js.map +1 -1
- package/dist/modules/manager/helm-values/extract.js.map +1 -1
- package/dist/modules/manager/helmfile/extract.js +1 -1
- package/dist/modules/manager/helmfile/extract.js.map +1 -1
- package/dist/modules/manager/maven/extract.js.map +1 -1
- package/dist/modules/manager/maven/update.js +2 -1
- package/dist/modules/manager/maven/update.js.map +1 -1
- package/dist/modules/manager/mise/utils.js +5 -7
- package/dist/modules/manager/mise/utils.js.map +1 -1
- package/dist/modules/manager/npm/extract/common/overrides.js +1 -1
- package/dist/modules/manager/npm/extract/common/overrides.js.map +1 -1
- package/dist/modules/manager/npm/extract/yarn.js +1 -1
- package/dist/modules/manager/npm/extract/yarn.js.map +1 -1
- package/dist/modules/manager/npm/npmrc.js +1 -3
- package/dist/modules/manager/npm/npmrc.js.map +1 -1
- package/dist/modules/manager/npm/update/dependency/common.js +2 -3
- package/dist/modules/manager/npm/update/dependency/common.js.map +1 -1
- package/dist/modules/manager/npm/update/dependency/index.js +1 -1
- package/dist/modules/manager/npm/update/dependency/index.js.map +1 -1
- package/dist/modules/manager/npm/update/dependency/pnpm.js +1 -1
- package/dist/modules/manager/npm/update/dependency/pnpm.js.map +1 -1
- package/dist/modules/manager/npm/update/dependency/yarn.js +1 -1
- package/dist/modules/manager/npm/update/dependency/yarn.js.map +1 -1
- package/dist/modules/manager/osgi/extract.js +1 -1
- package/dist/modules/manager/osgi/extract.js.map +1 -1
- package/dist/modules/manager/pep621/processors/uv.js +1 -1
- package/dist/modules/manager/pep621/processors/uv.js.map +1 -1
- package/dist/modules/manager/pep621/schema.js.map +1 -1
- package/dist/modules/manager/pip_setup/extract.js +1 -1
- package/dist/modules/manager/pip_setup/extract.js.map +1 -1
- package/dist/modules/manager/pipenv/artifacts.js.map +1 -1
- package/dist/modules/manager/poetry/schema.js +2 -2
- package/dist/modules/manager/poetry/schema.js.map +1 -1
- package/dist/modules/manager/pub/artifacts.js +4 -6
- package/dist/modules/manager/pub/artifacts.js.map +1 -1
- package/dist/modules/manager/pub/utils.js +2 -2
- package/dist/modules/manager/pub/utils.js.map +1 -1
- package/dist/modules/manager/puppet/common.js +4 -6
- package/dist/modules/manager/puppet/common.js.map +1 -1
- package/dist/modules/manager/sbt/extract.js +1 -1
- package/dist/modules/manager/sbt/extract.js.map +1 -1
- package/dist/modules/manager/sbt/util.js +4 -2
- package/dist/modules/manager/sbt/util.js.map +1 -1
- package/dist/modules/manager/terraform/lockfile/util.js +1 -1
- package/dist/modules/manager/terraform/lockfile/util.js.map +1 -1
- package/dist/modules/platform/azure/index.js +15 -19
- package/dist/modules/platform/azure/index.js.map +1 -1
- package/dist/modules/platform/azure/issue.js +4 -2
- package/dist/modules/platform/azure/issue.js.map +1 -1
- package/dist/modules/platform/bitbucket/index.js +1 -3
- package/dist/modules/platform/bitbucket/index.js.map +1 -1
- package/dist/modules/platform/forgejo/index.js +5 -3
- package/dist/modules/platform/forgejo/index.js.map +1 -1
- package/dist/modules/platform/gerrit/scm.js +5 -7
- package/dist/modules/platform/gerrit/scm.js.map +1 -1
- package/dist/modules/platform/gitea/index.js +5 -3
- package/dist/modules/platform/gitea/index.js.map +1 -1
- package/dist/modules/platform/github/index.js +5 -7
- package/dist/modules/platform/github/index.js.map +1 -1
- package/dist/modules/platform/github/pr.js +1 -1
- package/dist/modules/platform/github/pr.js.map +1 -1
- package/dist/modules/platform/github/schema.d.ts +4 -4
- package/dist/modules/platform/gitlab/index.js +2 -1
- package/dist/modules/platform/gitlab/index.js.map +1 -1
- package/dist/modules/platform/utils/pr-body.js +2 -1
- package/dist/modules/platform/utils/pr-body.js.map +1 -1
- package/dist/modules/versioning/apk/index.js +3 -3
- package/dist/modules/versioning/apk/index.js.map +1 -1
- package/dist/modules/versioning/composer/index.js +4 -7
- package/dist/modules/versioning/composer/index.js.map +1 -1
- package/dist/modules/versioning/conan/common.js +4 -6
- package/dist/modules/versioning/conan/common.js.map +1 -1
- package/dist/modules/versioning/conan/index.js +1 -3
- package/dist/modules/versioning/conan/index.js.map +1 -1
- package/dist/modules/versioning/conan/range.js +4 -5
- package/dist/modules/versioning/conan/range.js.map +1 -1
- package/dist/modules/versioning/conda/index.js +1 -1
- package/dist/modules/versioning/conda/index.js.map +1 -1
- package/dist/modules/versioning/gradle/index.js +7 -3
- package/dist/modules/versioning/gradle/index.js.map +1 -1
- package/dist/modules/versioning/hermit/index.js +2 -2
- package/dist/modules/versioning/hermit/index.js.map +1 -1
- package/dist/modules/versioning/ivy/index.js +1 -1
- package/dist/modules/versioning/ivy/index.js.map +1 -1
- package/dist/modules/versioning/maven/compare.js +4 -6
- package/dist/modules/versioning/maven/compare.js.map +1 -1
- package/dist/modules/versioning/npm/range.js +5 -7
- package/dist/modules/versioning/npm/range.js.map +1 -1
- package/dist/modules/versioning/nuget/version.js +6 -6
- package/dist/modules/versioning/nuget/version.js.map +1 -1
- package/dist/modules/versioning/pep440/index.js +1 -1
- package/dist/modules/versioning/pep440/index.js.map +1 -1
- package/dist/modules/versioning/pep440/range.js +2 -6
- package/dist/modules/versioning/pep440/range.js.map +1 -1
- package/dist/modules/versioning/poetry/index.js +1 -1
- package/dist/modules/versioning/poetry/index.js.map +1 -1
- package/dist/modules/versioning/pvp/index.js +2 -2
- package/dist/modules/versioning/pvp/index.js.map +1 -1
- package/dist/modules/versioning/rpm/index.js +4 -3
- package/dist/modules/versioning/rpm/index.js.map +1 -1
- package/dist/modules/versioning/ruby/range.js +2 -2
- package/dist/modules/versioning/ruby/range.js.map +1 -1
- package/dist/modules/versioning/ruby/strategies/bump.js +1 -1
- package/dist/modules/versioning/ruby/strategies/bump.js.map +1 -1
- package/dist/modules/versioning/ruby/strategies/replace.js +13 -12
- package/dist/modules/versioning/ruby/strategies/replace.js.map +1 -1
- package/dist/modules/versioning/ruby/version.js +1 -1
- package/dist/modules/versioning/ruby/version.js.map +1 -1
- package/dist/modules/versioning/rust-release-channel/index.js +1 -1
- package/dist/modules/versioning/rust-release-channel/index.js.map +1 -1
- package/dist/modules/versioning/rust-release-channel/util.js +4 -4
- package/dist/modules/versioning/rust-release-channel/util.js.map +1 -1
- package/dist/util/common.js +1 -3
- package/dist/util/common.js.map +1 -1
- package/dist/util/exec/common.js +4 -6
- package/dist/util/exec/common.js.map +1 -1
- package/dist/util/exec/containerbase.js +1 -3
- package/dist/util/exec/containerbase.js.map +1 -1
- package/dist/util/git/instrument.js +3 -3
- package/dist/util/git/instrument.js.map +1 -1
- package/dist/util/github/graphql/datasource-fetcher.js +5 -4
- package/dist/util/github/graphql/datasource-fetcher.js.map +1 -1
- package/dist/util/http/cache/package-http-cache-provider.js.map +1 -1
- package/dist/util/http/github.js +3 -2
- package/dist/util/http/github.js.map +1 -1
- package/dist/util/http/http.d.ts +1 -1
- package/dist/util/http/http.js.map +1 -1
- package/dist/util/result.d.ts +8 -8
- package/dist/util/result.js +1 -1
- package/dist/util/result.js.map +1 -1
- package/dist/util/url.js +2 -2
- package/dist/util/url.js.map +1 -1
- package/dist/workers/global/config/parse/cli.js +18 -20
- package/dist/workers/global/config/parse/cli.js.map +1 -1
- package/dist/workers/global/config/parse/env.js +3 -5
- package/dist/workers/global/config/parse/env.js.map +1 -1
- package/dist/workers/repository/config-migration/branch/index.js +3 -5
- package/dist/workers/repository/config-migration/branch/index.js.map +1 -1
- package/dist/workers/repository/init/merge.js +2 -3
- package/dist/workers/repository/init/merge.js.map +1 -1
- package/dist/workers/repository/onboarding/branch/check.js +7 -9
- package/dist/workers/repository/onboarding/branch/check.js.map +1 -1
- package/dist/workers/repository/onboarding/branch/index.js +4 -8
- package/dist/workers/repository/onboarding/branch/index.js.map +1 -1
- package/dist/workers/repository/onboarding/branch/onboarding-branch-cache.js +2 -2
- package/dist/workers/repository/onboarding/branch/onboarding-branch-cache.js.map +1 -1
- package/dist/workers/repository/process/extract-update.js.map +1 -1
- package/dist/workers/repository/process/fetch.js.map +1 -1
- package/dist/workers/repository/process/libyear.js +1 -3
- package/dist/workers/repository/process/libyear.js.map +1 -1
- package/dist/workers/repository/process/lookup/filter-checks.js +9 -11
- package/dist/workers/repository/process/lookup/filter-checks.js.map +1 -1
- package/dist/workers/repository/process/lookup/index.js +5 -8
- package/dist/workers/repository/process/lookup/index.js.map +1 -1
- package/dist/workers/repository/process/vulnerabilities.js +3 -3
- package/dist/workers/repository/process/vulnerabilities.js.map +1 -1
- package/dist/workers/repository/reconfigure/index.js +3 -5
- package/dist/workers/repository/reconfigure/index.js.map +1 -1
- package/dist/workers/repository/update/branch/bump-versions.js +1 -1
- package/dist/workers/repository/update/branch/bump-versions.js.map +1 -1
- package/dist/workers/repository/update/branch/get-updated.js +3 -5
- package/dist/workers/repository/update/branch/get-updated.js.map +1 -1
- package/dist/workers/repository/update/pr/body/updates-table.js +1 -3
- package/dist/workers/repository/update/pr/body/updates-table.js.map +1 -1
- package/dist/workers/repository/update/pr/changelog/common.js +1 -1
- package/dist/workers/repository/update/pr/changelog/common.js.map +1 -1
- package/dist/workers/repository/update/pr/index.js +6 -7
- package/dist/workers/repository/update/pr/index.js.map +1 -1
- package/dist/workers/repository/updates/flatten.js +1 -1
- package/dist/workers/repository/updates/flatten.js.map +1 -1
- package/dist/workers/repository/updates/generate.js +1 -1
- package/dist/workers/repository/updates/generate.js.map +1 -1
- package/package.json +2 -2
- package/renovate-schema.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter-checks.js","names":[],"sources":["../../../../../lib/workers/repository/process/lookup/filter-checks.ts"],"sourcesContent":["import { isNonEmptyString, isNullOrUndefined } from '@sindresorhus/is';\nimport { mergeChildConfig } from '../../../../config/index.ts';\nimport type { MinimumReleaseAgeBehaviour } from '../../../../config/types.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport type { Release } from '../../../../modules/datasource/index.ts';\nimport { postprocessRelease } from '../../../../modules/datasource/postprocess-release.ts';\nimport type { VersioningApi } from '../../../../modules/versioning/index.ts';\nimport { getElapsedMs } from '../../../../util/date.ts';\nimport {\n getMergeConfidenceLevel,\n isActiveConfidenceLevel,\n satisfiesConfidenceLevel,\n} from '../../../../util/merge-confidence/index.ts';\nimport { coerceNumber } from '../../../../util/number.ts';\nimport { applyPackageRules } from '../../../../util/package-rules/index.ts';\nimport { toMs } from '../../../../util/pretty-time.ts';\nimport type { LookupUpdateConfig, UpdateResult } from './types.ts';\nimport { getUpdateType } from './update-type.ts';\n\nexport interface InternalChecksResult {\n release?: Release;\n pendingChecks: boolean;\n pendingReleases: Release[];\n}\n\nexport async function filterInternalChecks(\n config: Partial<LookupUpdateConfig & UpdateResult>,\n versioningApi: VersioningApi,\n bucket: string,\n sortedReleases: Release[],\n): Promise<InternalChecksResult> {\n const {\n currentVersion,\n datasource,\n depName,\n packageName,\n internalChecksFilter,\n } = config;\n let release: Release | undefined = undefined;\n let pendingChecks = false;\n let pendingReleases: Release[] = [];\n if (internalChecksFilter === 'none') {\n // Don't care if minimumReleaseAge or minimumConfidence are unmet\n release = sortedReleases.pop();\n } else {\n const candidateVersionsWithoutReleaseTimestamp: Record<\n MinimumReleaseAgeBehaviour,\n string[]\n > = {\n 'timestamp-required': [],\n 'timestamp-optional': [],\n };\n\n // iterate through releases from highest to lowest, looking for the first which will pass checks if present\n for (let candidateRelease of sortedReleases.reverse()) {\n // merge the release data into dependency config\n let releaseConfig = mergeChildConfig(config, candidateRelease);\n // calculate updateType and then apply it\n releaseConfig.updateType = getUpdateType(\n releaseConfig,\n versioningApi,\n // TODO #22198\n currentVersion!,\n candidateRelease.version,\n );\n releaseConfig = mergeChildConfig(\n releaseConfig,\n releaseConfig[releaseConfig.updateType]!,\n );\n // Apply packageRules in case any apply to updateType\n releaseConfig = await applyPackageRules(releaseConfig, 'update-type');\n\n const updatedCandidateRelease = await postprocessRelease(\n releaseConfig,\n candidateRelease,\n );\n if (!updatedCandidateRelease) {\n continue;\n }\n candidateRelease = updatedCandidateRelease;\n\n // Now check for a minimumReleaseAge config\n const { minimumConfidence, minimumReleaseAge, updateType } =\n releaseConfig;\n\n const minimumReleaseAgeMs = isNonEmptyString(minimumReleaseAge)\n ? coerceNumber(toMs(minimumReleaseAge), 0)\n : 0;\n\n if (minimumReleaseAgeMs) {\n const minimumReleaseAgeBehaviour =\n releaseConfig.minimumReleaseAgeBehaviour;\n\n // if there is a releaseTimestamp, regardless of `minimumReleaseAgeBehaviour`, we should process it\n // v8 ignore else -- TODO: add test #40625\n if (candidateRelease.releaseTimestamp) {\n // we should skip this if we have a timestamp that isn't passing checks:\n if (\n getElapsedMs(candidateRelease.releaseTimestamp) <\n minimumReleaseAgeMs\n ) {\n // Skip it if it doesn't pass checks\n logger.trace(\n { depName, check: 'minimumReleaseAge' },\n `Release ${candidateRelease.version} is pending status checks`,\n );\n pendingReleases.unshift(candidateRelease);\n continue;\n }\n } // or if there is no timestamp, and we're running in `minimumReleaseAgeBehaviour=timestamp-required`\n else if (\n isNullOrUndefined(candidateRelease.releaseTimestamp) &&\n minimumReleaseAgeBehaviour === 'timestamp-required'\n ) {\n // Skip it, as we require a timestamp\n candidateVersionsWithoutReleaseTimestamp[\n minimumReleaseAgeBehaviour\n ].push(candidateRelease.version);\n pendingReleases.unshift(candidateRelease);\n continue;\n } // if there is no timestamp, and we're running in `optional` mode, we can allow it\n else if (\n isNullOrUndefined(candidateRelease.releaseTimestamp) &&\n minimumReleaseAgeBehaviour === 'timestamp-optional'\n ) {\n candidateVersionsWithoutReleaseTimestamp[\n minimumReleaseAgeBehaviour\n ].push(candidateRelease.version);\n }\n }\n\n // TODO #22198\n if (isActiveConfidenceLevel(minimumConfidence!)) {\n const confidenceLevel =\n (await getMergeConfidenceLevel(\n datasource!,\n packageName!,\n currentVersion!,\n candidateRelease.version,\n updateType!,\n )) ?? 'neutral';\n // TODO #22198\n if (!satisfiesConfidenceLevel(confidenceLevel, minimumConfidence!)) {\n logger.trace(\n { depName, check: 'minimumConfidence' },\n `Release ${candidateRelease.version} is pending status checks`,\n );\n pendingReleases.unshift(candidateRelease);\n continue;\n }\n }\n // If we get to here, then the release is OK and we can stop iterating\n release = candidateRelease;\n break;\n }\n\n if (candidateVersionsWithoutReleaseTimestamp['timestamp-required'].length) {\n logger.once.debug(\n {\n depName,\n versions:\n candidateVersionsWithoutReleaseTimestamp['timestamp-required'],\n check: 'minimumReleaseAge',\n },\n `Marking ${candidateVersionsWithoutReleaseTimestamp['timestamp-required'].length} release(s) as pending, as they do not have a releaseTimestamp and we're running with minimumReleaseAgeBehaviour=timestamp-required`,\n );\n }\n\n if (candidateVersionsWithoutReleaseTimestamp['timestamp-optional'].length) {\n logger.once.warn(\n \"Some release(s) did not have a releaseTimestamp, but as we're running with minimumReleaseAgeBehaviour=timestamp-optional, proceeding. See debug logs for more information\",\n );\n logger.once.debug(\n {\n depName,\n versions:\n candidateVersionsWithoutReleaseTimestamp['timestamp-optional'],\n check: 'minimumReleaseAge',\n },\n `${candidateVersionsWithoutReleaseTimestamp['timestamp-optional'].length} release(s) did not have a releaseTimestamp, but as we're running with minimumReleaseAgeBehaviour=timestamp-optional, proceeding`,\n );\n }\n\n
|
|
1
|
+
{"version":3,"file":"filter-checks.js","names":[],"sources":["../../../../../lib/workers/repository/process/lookup/filter-checks.ts"],"sourcesContent":["import { isNonEmptyString, isNullOrUndefined } from '@sindresorhus/is';\nimport { mergeChildConfig } from '../../../../config/index.ts';\nimport type { MinimumReleaseAgeBehaviour } from '../../../../config/types.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport type { Release } from '../../../../modules/datasource/index.ts';\nimport { postprocessRelease } from '../../../../modules/datasource/postprocess-release.ts';\nimport type { VersioningApi } from '../../../../modules/versioning/index.ts';\nimport { getElapsedMs } from '../../../../util/date.ts';\nimport {\n getMergeConfidenceLevel,\n isActiveConfidenceLevel,\n satisfiesConfidenceLevel,\n} from '../../../../util/merge-confidence/index.ts';\nimport { coerceNumber } from '../../../../util/number.ts';\nimport { applyPackageRules } from '../../../../util/package-rules/index.ts';\nimport { toMs } from '../../../../util/pretty-time.ts';\nimport type { LookupUpdateConfig, UpdateResult } from './types.ts';\nimport { getUpdateType } from './update-type.ts';\n\nexport interface InternalChecksResult {\n release?: Release;\n pendingChecks: boolean;\n pendingReleases: Release[];\n}\n\nexport async function filterInternalChecks(\n config: Partial<LookupUpdateConfig & UpdateResult>,\n versioningApi: VersioningApi,\n bucket: string,\n sortedReleases: Release[],\n): Promise<InternalChecksResult> {\n const {\n currentVersion,\n datasource,\n depName,\n packageName,\n internalChecksFilter,\n } = config;\n let release: Release | undefined = undefined;\n let pendingChecks = false;\n let pendingReleases: Release[] = [];\n if (internalChecksFilter === 'none') {\n // Don't care if minimumReleaseAge or minimumConfidence are unmet\n release = sortedReleases.pop();\n } else {\n const candidateVersionsWithoutReleaseTimestamp: Record<\n MinimumReleaseAgeBehaviour,\n string[]\n > = {\n 'timestamp-required': [],\n 'timestamp-optional': [],\n };\n\n // iterate through releases from highest to lowest, looking for the first which will pass checks if present\n for (let candidateRelease of sortedReleases.reverse()) {\n // merge the release data into dependency config\n let releaseConfig = mergeChildConfig(config, candidateRelease);\n // calculate updateType and then apply it\n releaseConfig.updateType = getUpdateType(\n releaseConfig,\n versioningApi,\n // TODO #22198\n currentVersion!,\n candidateRelease.version,\n );\n releaseConfig = mergeChildConfig(\n releaseConfig,\n releaseConfig[releaseConfig.updateType]!,\n );\n // Apply packageRules in case any apply to updateType\n releaseConfig = await applyPackageRules(releaseConfig, 'update-type');\n\n const updatedCandidateRelease = await postprocessRelease(\n releaseConfig,\n candidateRelease,\n );\n if (!updatedCandidateRelease) {\n continue;\n }\n candidateRelease = updatedCandidateRelease;\n\n // Now check for a minimumReleaseAge config\n const { minimumConfidence, minimumReleaseAge, updateType } =\n releaseConfig;\n\n const minimumReleaseAgeMs = isNonEmptyString(minimumReleaseAge)\n ? coerceNumber(toMs(minimumReleaseAge), 0)\n : 0;\n\n if (minimumReleaseAgeMs) {\n const minimumReleaseAgeBehaviour =\n releaseConfig.minimumReleaseAgeBehaviour;\n\n // if there is a releaseTimestamp, regardless of `minimumReleaseAgeBehaviour`, we should process it\n // v8 ignore else -- TODO: add test #40625\n if (candidateRelease.releaseTimestamp) {\n // we should skip this if we have a timestamp that isn't passing checks:\n if (\n getElapsedMs(candidateRelease.releaseTimestamp) <\n minimumReleaseAgeMs\n ) {\n // Skip it if it doesn't pass checks\n logger.trace(\n { depName, check: 'minimumReleaseAge' },\n `Release ${candidateRelease.version} is pending status checks`,\n );\n pendingReleases.unshift(candidateRelease);\n continue;\n }\n } // or if there is no timestamp, and we're running in `minimumReleaseAgeBehaviour=timestamp-required`\n else if (\n isNullOrUndefined(candidateRelease.releaseTimestamp) &&\n minimumReleaseAgeBehaviour === 'timestamp-required'\n ) {\n // Skip it, as we require a timestamp\n candidateVersionsWithoutReleaseTimestamp[\n minimumReleaseAgeBehaviour\n ].push(candidateRelease.version);\n pendingReleases.unshift(candidateRelease);\n continue;\n } // if there is no timestamp, and we're running in `optional` mode, we can allow it\n else if (\n isNullOrUndefined(candidateRelease.releaseTimestamp) &&\n minimumReleaseAgeBehaviour === 'timestamp-optional'\n ) {\n candidateVersionsWithoutReleaseTimestamp[\n minimumReleaseAgeBehaviour\n ].push(candidateRelease.version);\n }\n }\n\n // TODO #22198\n if (isActiveConfidenceLevel(minimumConfidence!)) {\n const confidenceLevel =\n (await getMergeConfidenceLevel(\n datasource!,\n packageName!,\n currentVersion!,\n candidateRelease.version,\n updateType!,\n )) ?? 'neutral';\n // TODO #22198\n if (!satisfiesConfidenceLevel(confidenceLevel, minimumConfidence!)) {\n logger.trace(\n { depName, check: 'minimumConfidence' },\n `Release ${candidateRelease.version} is pending status checks`,\n );\n pendingReleases.unshift(candidateRelease);\n continue;\n }\n }\n // If we get to here, then the release is OK and we can stop iterating\n release = candidateRelease;\n break;\n }\n\n if (candidateVersionsWithoutReleaseTimestamp['timestamp-required'].length) {\n logger.once.debug(\n {\n depName,\n versions:\n candidateVersionsWithoutReleaseTimestamp['timestamp-required'],\n check: 'minimumReleaseAge',\n },\n `Marking ${candidateVersionsWithoutReleaseTimestamp['timestamp-required'].length} release(s) as pending, as they do not have a releaseTimestamp and we're running with minimumReleaseAgeBehaviour=timestamp-required`,\n );\n }\n\n if (candidateVersionsWithoutReleaseTimestamp['timestamp-optional'].length) {\n logger.once.warn(\n \"Some release(s) did not have a releaseTimestamp, but as we're running with minimumReleaseAgeBehaviour=timestamp-optional, proceeding. See debug logs for more information\",\n );\n logger.once.debug(\n {\n depName,\n versions:\n candidateVersionsWithoutReleaseTimestamp['timestamp-optional'],\n check: 'minimumReleaseAge',\n },\n `${candidateVersionsWithoutReleaseTimestamp['timestamp-optional'].length} release(s) did not have a releaseTimestamp, but as we're running with minimumReleaseAgeBehaviour=timestamp-optional, proceeding`,\n );\n }\n\n // v8 ignore else -- TODO: add test #40625\n if (!release && pendingReleases.length) {\n // If all releases were pending then just take the highest\n logger.trace(\n { depName, bucket },\n 'All releases are pending - using latest',\n );\n release = pendingReleases.pop();\n // None are pending anymore because we took the latest, so empty the array\n pendingReleases = [];\n if (internalChecksFilter === 'strict') {\n pendingChecks = true;\n }\n }\n }\n\n return { release, pendingChecks, pendingReleases };\n}\n"],"mappings":";;;;;;;;;;;;AAyBA,eAAsB,qBACpB,QACA,eACA,QACA,gBAC+B;CAC/B,MAAM,EACJ,gBACA,YACA,SACA,aACA,yBACE;CACJ,IAAI,UAA+B,KAAA;CACnC,IAAI,gBAAgB;CACpB,IAAI,kBAA6B,CAAC;CAClC,IAAI,yBAAyB,QAE3B,UAAU,eAAe,IAAI;MACxB;EACL,MAAM,2CAGF;GACF,sBAAsB,CAAC;GACvB,sBAAsB,CAAC;EACzB;EAGA,KAAK,IAAI,oBAAoB,eAAe,QAAQ,GAAG;GAErD,IAAI,gBAAgB,iBAAiB,QAAQ,gBAAgB;GAE7D,cAAc,aAAa,cACzB,eACA,eAEA,gBACA,iBAAiB,OACnB;GACA,gBAAgB,iBACd,eACA,cAAc,cAAc,WAC9B;GAEA,gBAAgB,MAAM,kBAAkB,eAAe,aAAa;GAEpE,MAAM,0BAA0B,MAAM,mBACpC,eACA,gBACF;GACA,IAAI,CAAC,yBACH;GAEF,mBAAmB;GAGnB,MAAM,EAAE,mBAAmB,mBAAmB,eAC5C;GAEF,MAAM,sBAAsB,iBAAiB,iBAAiB,IAC1D,aAAa,KAAK,iBAAiB,GAAG,CAAC,IACvC;GAEJ,IAAI,qBAAqB;IACvB,MAAM,6BACJ,cAAc;;IAIhB,IAAI,iBAAiB;SAGjB,aAAa,iBAAiB,gBAAgB,IAC9C,qBACA;MAEA,OAAO,MACL;OAAE;OAAS,OAAO;MAAoB,GACtC,WAAW,iBAAiB,QAAQ,0BACtC;MACA,gBAAgB,QAAQ,gBAAgB;MACxC;KACF;WAEG,IACH,kBAAkB,iBAAiB,gBAAgB,KACnD,+BAA+B,sBAC/B;KAEA,yCACE,2BACD,CAAC,KAAK,iBAAiB,OAAO;KAC/B,gBAAgB,QAAQ,gBAAgB;KACxC;IACF,OACK,IACH,kBAAkB,iBAAiB,gBAAgB,KACnD,+BAA+B,sBAE/B,yCACE,2BACD,CAAC,KAAK,iBAAiB,OAAO;GAEnC;GAGA,IAAI,wBAAwB,iBAAkB;QAUxC,CAAC,yBARF,MAAM,wBACL,YACA,aACA,gBACA,iBAAiB,SACjB,UACF,KAAM,WAEuC,iBAAkB,GAAG;KAClE,OAAO,MACL;MAAE;MAAS,OAAO;KAAoB,GACtC,WAAW,iBAAiB,QAAQ,0BACtC;KACA,gBAAgB,QAAQ,gBAAgB;KACxC;IACF;;GAGF,UAAU;GACV;EACF;EAEA,IAAI,yCAAyC,qBAAqB,CAAC,QACjE,OAAO,KAAK,MACV;GACE;GACA,UACE,yCAAyC;GAC3C,OAAO;EACT,GACA,WAAW,yCAAyC,qBAAqB,CAAC,OAAO,oIACnF;EAGF,IAAI,yCAAyC,qBAAqB,CAAC,QAAQ;GACzE,OAAO,KAAK,KACV,2KACF;GACA,OAAO,KAAK,MACV;IACE;IACA,UACE,yCAAyC;IAC3C,OAAO;GACT,GACA,GAAG,yCAAyC,qBAAqB,CAAC,OAAO,iIAC3E;EACF;;EAGA,IAAI,CAAC,WAAW,gBAAgB,QAAQ;GAEtC,OAAO,MACL;IAAE;IAAS;GAAO,GAClB,yCACF;GACA,UAAU,gBAAgB,IAAI;GAE9B,kBAAkB,CAAC;GACnB,IAAI,yBAAyB,UAC3B,gBAAgB;EAEpB;CACF;CAEA,OAAO;EAAE;EAAS;EAAe;CAAgB;AACnD"}
|
|
@@ -297,14 +297,11 @@ async function lookupUpdates(inconfig) {
|
|
|
297
297
|
updateType: "digest",
|
|
298
298
|
newValue: config.currentValue
|
|
299
299
|
});
|
|
300
|
-
} else if (config.pinDigests) {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
newValue: config.currentValue
|
|
306
|
-
});
|
|
307
|
-
}
|
|
300
|
+
} else if (config.pinDigests && !res.updates.some((update) => update.updateType === "pin")) res.updates.push({
|
|
301
|
+
isPinDigest: true,
|
|
302
|
+
updateType: "pinDigest",
|
|
303
|
+
newValue: config.currentValue
|
|
304
|
+
});
|
|
308
305
|
if (versioningApi.valueToVersion) {
|
|
309
306
|
res.currentVersion = versioningApi.valueToVersion(res.currentVersion);
|
|
310
307
|
for (const update of res.updates) update.newVersion = versioningApi.valueToVersion(update.newVersion);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["allVersioning.get"],"sources":["../../../../../lib/workers/repository/process/lookup/index.ts"],"sourcesContent":["import { isNonEmptyString, isString, isUndefined } from '@sindresorhus/is';\nimport { mergeChildConfig } from '../../../../config/index.ts';\nimport type { ValidationMessage } from '../../../../config/types.ts';\nimport { CONFIG_VALIDATION } from '../../../../constants/error-messages.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport {\n getDatasourceFor,\n getDefaultVersioning,\n} from '../../../../modules/datasource/common.ts';\nimport type {\n GetDigestInputConfig,\n Release,\n ReleaseResult,\n} from '../../../../modules/datasource/index.ts';\nimport {\n applyDatasourceFilters,\n getDigest,\n getRawPkgReleases,\n isGetPkgReleasesConfig,\n supportsDigests,\n} from '../../../../modules/datasource/index.ts';\nimport { postprocessRelease } from '../../../../modules/datasource/postprocess-release.ts';\nimport { getRangeStrategy } from '../../../../modules/manager/index.ts';\nimport { id as dockerVersioningId } from '../../../../modules/versioning/docker/index.ts';\nimport * as allVersioning from '../../../../modules/versioning/index.ts';\nimport { ExternalHostError } from '../../../../types/errors/external-host-error.ts';\nimport { assignKeys } from '../../../../util/assign-keys.ts';\nimport { getElapsedDays } from '../../../../util/date.ts';\nimport { applyPackageRules } from '../../../../util/package-rules/index.ts';\nimport { regEx } from '../../../../util/regex.ts';\nimport { Result } from '../../../../util/result.ts';\nimport type { Timestamp } from '../../../../util/timestamp.ts';\nimport { calculateAbandonment } from './abandonment.ts';\nimport { getBucket } from './bucket.ts';\nimport { getCurrentVersion } from './current.ts';\nimport { filterVersions } from './filter.ts';\nimport { filterInternalChecks } from './filter-checks.ts';\nimport { generateUpdate } from './generate.ts';\nimport { getRollbackUpdate } from './rollback.ts';\nimport { calculateMostRecentTimestamp } from './timestamps.ts';\nimport type { LookupUpdateConfig, UpdateResult } from './types.ts';\nimport {\n addReplacementUpdateIfValid,\n isReplacementRulesConfigured,\n} from './utils.ts';\n\nasync function getTimestamp(\n config: LookupUpdateConfig,\n versions: Release[],\n version: string,\n versioningApi: allVersioning.VersioningApi,\n): Promise<Timestamp | null | undefined> {\n const currentRelease = versions.find(\n (v) =>\n versioningApi.isValid(v.version) &&\n versioningApi.equals(v.version, version),\n );\n\n if (!currentRelease) {\n return null;\n }\n\n if (currentRelease.releaseTimestamp) {\n return currentRelease.releaseTimestamp;\n }\n\n const remoteRelease = await postprocessRelease(config, currentRelease);\n return remoteRelease?.releaseTimestamp;\n}\n\nexport async function lookupUpdates(\n inconfig: LookupUpdateConfig,\n): Promise<Result<UpdateResult, Error>> {\n let config: LookupUpdateConfig = { ...inconfig };\n config.versioning ??= getDefaultVersioning(config.datasource);\n\n const versioningApi = allVersioning.get(config.versioning);\n\n let dependency: ReleaseResult | null = null;\n const res: UpdateResult = {\n versioning: config.versioning,\n updates: [],\n warnings: [],\n };\n\n try {\n logger.trace(\n {\n dependency: config.packageName,\n currentValue: config.currentValue,\n },\n 'lookupUpdates',\n );\n if (config.currentValue && !isString(config.currentValue)) {\n // If currentValue is not a string, then it's invalid\n // v8 ignore else -- TODO: add test #40625\n if (config.currentValue) {\n logger.debug(\n `Invalid currentValue for ${config.packageName}: ${JSON.stringify(config.currentValue)} (${typeof config.currentValue})`,\n );\n }\n res.skipReason = 'invalid-value';\n return Result.ok(res);\n }\n if (\n !isGetPkgReleasesConfig(config) ||\n !getDatasourceFor(config.datasource)\n ) {\n res.skipReason = 'invalid-config';\n return Result.ok(res);\n }\n let compareValue = config.currentValue;\n if (\n isString(config.currentValue) &&\n isString(config.versionCompatibility)\n ) {\n const versionCompatbilityRegEx = regEx(config.versionCompatibility);\n const regexMatch = versionCompatbilityRegEx.exec(config.currentValue);\n if (regexMatch?.groups) {\n logger.debug(\n {\n versionCompatibility: config.versionCompatibility,\n currentValue: config.currentValue,\n packageName: config.packageName,\n groups: regexMatch.groups,\n },\n 'version compatibility regex match',\n );\n config.currentCompatibility = regexMatch.groups.compatibility;\n compareValue = regexMatch.groups.version;\n } else {\n logger.debug(\n {\n versionCompatibility: config.versionCompatibility,\n currentValue: config.currentValue,\n packageName: config.packageName,\n },\n 'version compatibility regex mismatch',\n );\n }\n }\n\n const isValid =\n isString(compareValue) && versioningApi.isValid(compareValue);\n\n const unconstrainedValue =\n !!config.lockedVersion && isUndefined(config.currentValue);\n\n if (isValid || unconstrainedValue) {\n if (\n !config.updatePinnedDependencies &&\n // TODO #22198\n versioningApi.isSingleVersion(compareValue!)\n ) {\n res.skipReason = 'is-pinned';\n return Result.ok(res);\n }\n\n const { val: releaseResult, err: lookupError } = await getRawPkgReleases(\n config,\n )\n .transform((res) => calculateMostRecentTimestamp(versioningApi, res))\n .transform((res) => calculateAbandonment(res, config))\n .transform((res) => applyDatasourceFilters(res, config))\n .unwrap();\n\n if (lookupError instanceof Error) {\n throw lookupError;\n }\n\n if (lookupError) {\n // If dependency lookup fails then warn and return\n const warning: ValidationMessage = {\n topic: config.packageName,\n message: `Failed to look up ${config.datasource} package ${config.packageName}: ${lookupError}`,\n };\n logger.debug(\n {\n dependency: config.packageName,\n packageFile: config.packageFile,\n },\n warning.message,\n );\n // TODO: return warnings in own field\n res.warnings.push(warning);\n return Result.ok(res);\n }\n\n dependency = releaseResult;\n\n if (dependency.deprecationMessage) {\n logger.debug(\n `Found deprecationMessage for ${config.datasource} package ${config.packageName}`,\n );\n }\n\n assignKeys(res, dependency, [\n 'deprecationMessage',\n 'sourceUrl',\n 'registryUrl',\n 'sourceDirectory',\n 'homepage',\n 'changelogUrl',\n 'dependencyUrl',\n 'lookupName',\n 'packageScope',\n 'mostRecentTimestamp',\n 'isAbandoned',\n 'respectLatest',\n ]);\n\n const latestVersion = dependency.tags?.latest;\n // Filter out any results from datasource that don't comply with our versioning\n let allVersions = dependency.releases.filter((release) =>\n versioningApi.isVersion(release.version),\n );\n const allReleaseVersions = new Set(allVersions.map((r) => r.version));\n // istanbul ignore if\n if (allVersions.length === 0) {\n const message = `Found no results from datasource that look like a version`;\n logger.info(\n {\n dependency: config.packageName,\n result: dependency,\n },\n message,\n );\n if (!config.currentDigest) {\n return Result.ok(res);\n }\n }\n // Reapply package rules in case we missed something from sourceUrl\n config = await applyPackageRules(\n { ...config, sourceUrl: res.sourceUrl },\n 'source-url',\n );\n if (config.followTag) {\n const taggedVersion = dependency.tags?.[config.followTag];\n if (!taggedVersion) {\n res.warnings.push({\n topic: config.packageName,\n message: `Can't find version with tag ${config.followTag} for ${config.datasource} package ${config.packageName}`,\n });\n return Result.ok(res);\n }\n allVersions = allVersions.filter(\n (v) =>\n v.version === taggedVersion ||\n (v.version === compareValue &&\n versioningApi.isGreaterThan(taggedVersion, compareValue)),\n );\n }\n\n const inRangeOnlyStrategy = config.rangeStrategy === 'in-range-only';\n // Check that existing constraint can be satisfied\n const allSatisfyingVersions =\n (inRangeOnlyStrategy || config.rollbackPrs) && !unconstrainedValue\n ? allVersions.filter((v) =>\n // TODO #22198\n versioningApi.matches(v.version, compareValue!),\n )\n : allVersions;\n if (!allSatisfyingVersions.length) {\n logger.debug(\n `Found no satisfying versions with '${config.versioning}' versioning`,\n );\n }\n\n if (config.rollbackPrs && !allSatisfyingVersions.length) {\n const rollback = getRollbackUpdate(config, allVersions, versioningApi);\n // istanbul ignore if\n if (!rollback) {\n res.warnings.push({\n topic: config.packageName,\n // TODO: types (#22198)\n message: `Can't find version matching ${compareValue!} for ${\n config.datasource\n } package ${config.packageName}`,\n });\n return Result.ok(res);\n }\n res.updates.push(rollback);\n }\n let rangeStrategy = getRangeStrategy(config);\n\n // istanbul ignore next\n if (\n config.isVulnerabilityAlert &&\n rangeStrategy === 'update-lockfile' &&\n !config.lockedVersion\n ) {\n rangeStrategy = 'bump';\n }\n // unconstrained deps with lockedVersion\n if (\n config.isVulnerabilityAlert &&\n !config.currentValue &&\n config.lockedVersion\n ) {\n rangeStrategy = 'update-lockfile';\n }\n const nonDeprecatedVersions = dependency.releases\n .filter((release) => !release.isDeprecated)\n .map((release) => release.version);\n let currentVersion: string;\n if (rangeStrategy === 'update-lockfile') {\n currentVersion = config.lockedVersion!;\n } else if (\n compareValue &&\n versioningApi.isSingleVersion(compareValue) &&\n allVersions.find((v) => v.version === compareValue)\n ) {\n currentVersion = compareValue;\n }\n // TODO #22198\n currentVersion ??=\n getCurrentVersion(\n compareValue!,\n config.lockedVersion!,\n versioningApi,\n rangeStrategy!,\n latestVersion!,\n nonDeprecatedVersions,\n ) ??\n getCurrentVersion(\n compareValue!,\n config.lockedVersion!,\n versioningApi,\n rangeStrategy!,\n latestVersion!,\n allVersions.map((v) => v.version),\n )!;\n\n if (!currentVersion) {\n // v8 ignore else -- TODO: add test #40625\n if (!config.lockedVersion) {\n logger.debug(\n `No currentVersion or lockedVersion found for ${config.packageName}`,\n );\n res.skipReason = 'invalid-value';\n }\n return Result.ok(res);\n }\n\n res.currentVersion = currentVersion;\n\n // Use lockedVersion for the timestamp lookup when available, because\n // res.currentVersion is later overwritten to lockedVersion (see below).\n // Without this, strategies like \"replace\" would compute the timestamp\n // for the highest satisfying version (e.g. 1.4.1) while the reported\n // currentVersion ends up being the locked one (e.g. 1.0.0).\n const versionForTimestamp = config.lockedVersion ?? currentVersion;\n const currentVersionTimestamp = await getTimestamp(\n config,\n allVersions,\n versionForTimestamp,\n versioningApi,\n );\n\n if (isNonEmptyString(currentVersionTimestamp)) {\n res.currentVersionTimestamp = currentVersionTimestamp;\n res.currentVersionAgeInDays = getElapsedDays(currentVersionTimestamp);\n\n if (\n config.packageRules?.some((rule) =>\n isNonEmptyString(rule.matchCurrentAge),\n )\n ) {\n // Reapply package rules to check matches for matchCurrentAge\n config = await applyPackageRules(\n { ...config, currentVersionTimestamp },\n 'current-timestamp',\n );\n }\n }\n\n if (\n compareValue &&\n currentVersion &&\n rangeStrategy === 'pin' &&\n !versioningApi.isSingleVersion(compareValue)\n ) {\n const newValue =\n versioningApi.getPinnedValue?.(currentVersion) ?? currentVersion;\n res.updates.push({\n updateType: 'pin',\n isPin: true,\n newValue,\n newVersion: currentVersion,\n newMajor: versioningApi.getMajor(currentVersion)!,\n });\n }\n if (rangeStrategy === 'pin') {\n // Fall back to replace once pinning logic is done\n rangeStrategy = 'replace';\n }\n // istanbul ignore if\n if (!versioningApi.isVersion(currentVersion!)) {\n res.skipReason = 'invalid-version';\n return Result.ok(res);\n }\n // Filter latest, unstable, etc\n // TODO #22198\n let filteredReleases = filterVersions(\n config,\n currentVersion!,\n latestVersion!,\n inRangeOnlyStrategy ? allSatisfyingVersions : allVersions,\n versioningApi,\n ).filter(\n (v) =>\n // Leave only compatible versions\n unconstrainedValue ||\n versioningApi.isCompatible(v.version, compareValue),\n );\n let shrinkedViaVulnerability = false;\n if (config.isVulnerabilityAlert) {\n if (config.vulnerabilityFixVersion) {\n res.vulnerabilityFixVersion = config.vulnerabilityFixVersion;\n res.vulnerabilityFixStrategy = config.vulnerabilityFixStrategy;\n if (versioningApi.isValid(config.vulnerabilityFixVersion)) {\n let fixedFilteredReleases;\n if (versioningApi.isVersion(config.vulnerabilityFixVersion)) {\n // Retain only releases greater than or equal to the fix version\n fixedFilteredReleases = filteredReleases.filter(\n (release) =>\n !versioningApi.isGreaterThan(\n config.vulnerabilityFixVersion!,\n release.version,\n ),\n );\n } else {\n // Retain only releases which max the fix constraint\n fixedFilteredReleases = filteredReleases.filter((release) =>\n versioningApi.matches(\n release.version,\n config.vulnerabilityFixVersion!,\n ),\n );\n }\n // Warn if this filtering results caused zero releases\n if (fixedFilteredReleases.length === 0 && filteredReleases.length) {\n logger.warn(\n {\n releases: filteredReleases,\n vulnerabilityFixVersion: config.vulnerabilityFixVersion,\n packageName: config.packageName,\n },\n 'No releases satisfy vulnerabilityFixVersion',\n );\n }\n // Use the additionally filtered releases\n filteredReleases = fixedFilteredReleases;\n } else {\n logger.warn(\n {\n vulnerabilityFixVersion: config.vulnerabilityFixVersion,\n packageName: config.packageName,\n },\n 'vulnerabilityFixVersion is not valid',\n );\n }\n }\n if (config.vulnerabilityFixStrategy === 'highest') {\n // Don't shrink the list of releases - let Renovate use its normal logic\n logger.once.debug(\n `Using vulnerabilityFixStrategy=highest for ${config.packageName}`,\n );\n } else {\n // Shrink the list of releases to the lowest fixed version\n logger.once.debug(\n `Using vulnerabilityFixStrategy=lowest for ${config.packageName}`,\n );\n filteredReleases = filteredReleases.slice(0, 1);\n shrinkedViaVulnerability = true;\n }\n }\n const buckets: Record<string, [Release]> = {};\n for (const release of filteredReleases) {\n const bucket = getBucket(\n config,\n // TODO #22198\n currentVersion!,\n release.version,\n versioningApi,\n );\n // v8 ignore else -- TODO: add test #40625\n if (isString(bucket)) {\n if (buckets[bucket]) {\n buckets[bucket].push(release);\n } else {\n buckets[bucket] = [release];\n }\n }\n }\n const depResultConfig = mergeChildConfig(config, res);\n for (const [bucket, releases] of Object.entries(buckets)) {\n const sortedReleases = releases.sort((r1, r2) =>\n versioningApi.sortVersions(r1.version, r2.version),\n );\n const { release, pendingChecks, pendingReleases } =\n await filterInternalChecks(\n depResultConfig,\n versioningApi,\n bucket,\n sortedReleases,\n );\n // istanbul ignore next\n if (!release) {\n return Result.ok(res);\n }\n const newVersion = release.version;\n const update = await generateUpdate(\n config,\n compareValue,\n versioningApi,\n // TODO #22198\n\n rangeStrategy!,\n config.lockedVersion ?? currentVersion!,\n bucket,\n release,\n allReleaseVersions,\n );\n\n // #29034\n if (\n config.manager === 'gomod' &&\n compareValue?.startsWith('v0.0.0-') &&\n update.newValue?.startsWith('v0.0.0-') &&\n config.currentDigest !== update.newDigest\n ) {\n update.updateType = 'digest';\n }\n\n if (pendingChecks) {\n update.pendingChecks = pendingChecks;\n }\n\n if (pendingReleases.length) {\n update.pendingVersions = pendingReleases.map((r) => r.version);\n }\n if (!update.newValue || update.newValue === compareValue) {\n if (!config.lockedVersion) {\n continue;\n }\n // istanbul ignore if\n if (rangeStrategy === 'bump') {\n logger.trace(\n {\n packageName: config.packageName,\n currentValue: config.currentValue,\n lockedVersion: config.lockedVersion,\n newVersion,\n },\n 'Skipping bump because newValue is the same',\n );\n continue;\n }\n res.isSingleVersion = true;\n }\n res.isSingleVersion ??=\n isString(update.newValue) &&\n versioningApi.isSingleVersion(update.newValue);\n // istanbul ignore if\n if (\n config.versioning === dockerVersioningId &&\n update.updateType !== 'rollback' &&\n update.newValue &&\n versioningApi.isVersion(update.newValue) &&\n compareValue &&\n versioningApi.isVersion(compareValue) &&\n versioningApi.isGreaterThan(compareValue, update.newValue)\n ) {\n logger.warn(\n {\n packageName: config.packageName,\n currentValue: config.currentValue,\n compareValue,\n currentVersion: config.currentVersion,\n update,\n allVersionsLength: allVersions.length,\n filteredReleaseVersions: filteredReleases.map((r) => r.version),\n shrinkedViaVulnerability,\n },\n 'Unexpected downgrade detected: skipping',\n );\n } else {\n res.updates.push(update);\n }\n }\n } else if (compareValue) {\n logger.debug(\n `Dependency ${config.packageName} has unsupported/unversioned value ${compareValue} (versioning=${config.versioning})`,\n );\n\n if (!config.pinDigests && !config.currentDigest) {\n logger.debug(\n `Skipping ${config.packageName} because no currentDigest or pinDigests`,\n );\n res.skipReason = 'invalid-value';\n } else {\n delete res.skipReason;\n }\n } else {\n res.skipReason = 'invalid-value';\n }\n\n if (isReplacementRulesConfigured(config)) {\n addReplacementUpdateIfValid(res.updates, config);\n } else if (dependency?.replacementName && dependency.replacementVersion) {\n res.updates.push({\n updateType: 'replacement',\n newName: dependency.replacementName,\n newValue: dependency.replacementVersion,\n });\n }\n\n // Record if the dep is fixed to a version\n if (config.lockedVersion) {\n res.currentVersion = config.lockedVersion;\n res.fixedVersion = config.lockedVersion;\n } else if (compareValue && versioningApi.isSingleVersion(compareValue)) {\n res.fixedVersion = compareValue.replace(regEx(/^=+/), '');\n }\n\n // massage versionCompatibility\n if (\n isString(config.currentValue) &&\n isString(compareValue) &&\n isString(config.versionCompatibility)\n ) {\n for (const update of res.updates) {\n logger.debug({ update });\n // v8 ignore else -- TODO: add test #40625\n if (isString(config.currentValue) && isString(update.newValue)) {\n update.newValue = config.currentValue.replace(\n compareValue,\n update.newValue,\n );\n }\n }\n }\n\n // Add digests if necessary\n if (supportsDigests(config.datasource)) {\n if (config.currentDigest) {\n if (!config.digestOneAndOnly || !res.updates.length) {\n // digest update\n res.updates.push({\n updateType: 'digest',\n newValue: config.currentValue,\n });\n }\n } else if (config.pinDigests) {\n // Create a pin only if one doesn't already exists\n // v8 ignore else -- TODO: add test #40625\n if (!res.updates.some((update) => update.updateType === 'pin')) {\n // pin digest\n res.updates.push({\n isPinDigest: true,\n updateType: 'pinDigest',\n newValue: config.currentValue,\n });\n }\n }\n if (versioningApi.valueToVersion) {\n // TODO #22198\n res.currentVersion = versioningApi.valueToVersion(res.currentVersion!);\n for (const update of res.updates) {\n // TODO #22198\n update.newVersion = versioningApi.valueToVersion(update.newVersion!);\n }\n }\n if (res.registryUrl) {\n config.registryUrls = [res.registryUrl];\n }\n\n // update digest for all\n for (const update of res.updates) {\n if (config.pinDigests === true || config.currentDigest) {\n const getDigestConfig: GetDigestInputConfig = {\n ...config,\n registryUrl: update.registryUrl ?? res.registryUrl,\n lookupName: res.lookupName,\n };\n\n // #20304 only pass it for replacement updates, otherwise we get wrong or invalid digest\n if (update.updateType !== 'replacement') {\n delete getDigestConfig.replacementName;\n }\n\n // #20304 don't use lookupName and currentDigest when we replace image name\n if (\n update.updateType === 'replacement' &&\n update.newName !== config.packageName\n ) {\n delete getDigestConfig.lookupName;\n delete getDigestConfig.currentDigest;\n getDigestConfig.replacementName = update.newName;\n }\n\n // Don't use current releases if replacement changes name, otherwise we use the wrong new digest.\n // This happens on datasources which return the digest in release info like `github-tags`.\n // We can still use it when only version is changing.\n if (\n update.updateType !== 'replacement' ||\n update.newName === config.packageName\n ) {\n update.newDigest ??= dependency?.releases.find(\n (r) => r.version === update.newValue,\n )?.newDigest;\n }\n\n update.newDigest ??= await getDigest(\n getDigestConfig,\n update.newValue,\n );\n\n // If the digest could not be determined, report this as otherwise the\n // update will be omitted later on without notice.\n if (update.newDigest === null) {\n logger.debug(\n {\n packageName: config.packageName,\n currentValue: config.currentValue,\n datasource: config.datasource,\n newValue: update.newValue,\n bucket: update.bucket,\n },\n 'Could not determine new digest for update.',\n );\n\n // Only report a warning if there is a current digest.\n // Context: https://github.com/renovatebot/renovate/pull/20175#discussion_r1102615059.\n if (config.currentDigest) {\n res.warnings.push({\n message: `Could not determine new digest for update (${config.datasource} package ${config.packageName})`,\n topic: config.packageName,\n });\n }\n }\n } else {\n delete update.newDigest;\n }\n if (update.newVersion) {\n const registryUrl = dependency?.releases?.find(\n (release) => release.version === update.newVersion,\n )?.registryUrl;\n if (registryUrl && registryUrl !== res.registryUrl) {\n update.registryUrl = registryUrl;\n }\n }\n }\n }\n\n if (res.updates.length) {\n delete res.skipReason;\n }\n // Strip out any non-changed ones\n res.updates = res.updates\n .filter(\n (update) => update.newValue !== null || config.currentValue === null,\n )\n .filter((update) => update.newDigest !== null)\n .filter(\n (update) =>\n (isString(update.newName) && update.newName !== config.packageName) ||\n update.isReplacement === true ||\n update.newValue !== config.currentValue ||\n update.isLockfileUpdate === true ||\n // TODO #22198\n (update.newDigest &&\n !update.newDigest.startsWith(config.currentDigest!)),\n );\n // If range strategy specified in config is 'in-range-only', also strip out updates where currentValue !== newValue\n if (config.rangeStrategy === 'in-range-only') {\n res.updates = res.updates.filter(\n (update) => update.newValue === config.currentValue,\n );\n }\n // Handle a weird edge case involving followTag and fallbacks\n if (config.rollbackPrs && config.followTag) {\n res.updates = res.updates.filter(\n (update) =>\n update.updateType !== 'rollback' || res.updates.length === 1,\n );\n }\n\n const release =\n res.updates.length > 0\n ? (dependency?.releases.find(\n (r) => r.version === res.updates[0].newValue,\n ) ??\n dependency?.releases.find(\n (r) => r.version === res.updates[0].newVersion,\n ))\n : null;\n\n if (release?.changelogContent) {\n res.changelogContent = release.changelogContent;\n res.changelogUrl = release.changelogUrl;\n }\n } catch (err) /* istanbul ignore next */ {\n if (err instanceof ExternalHostError) {\n return Result.err(err);\n }\n\n if (err instanceof Error && err.message === CONFIG_VALIDATION) {\n return Result.err(err);\n }\n\n logger.error(\n {\n currentDigest: config.currentDigest,\n currentValue: config.currentValue,\n datasource: config.datasource,\n packageName: config.packageName,\n digestOneAndOnly: config.digestOneAndOnly,\n followTag: config.followTag,\n lockedVersion: config.lockedVersion,\n packageFile: config.packageFile,\n pinDigests: config.pinDigests,\n rollbackPrs: config.rollbackPrs,\n isVulnerabilityAlert: config.isVulnerabilityAlert,\n updatePinnedDependencies: config.updatePinnedDependencies,\n err,\n },\n 'lookupUpdates error',\n );\n res.skipReason = 'internal-error';\n }\n return Result.ok(res);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["allVersioning.get"],"sources":["../../../../../lib/workers/repository/process/lookup/index.ts"],"sourcesContent":["import { isNonEmptyString, isString, isUndefined } from '@sindresorhus/is';\nimport { mergeChildConfig } from '../../../../config/index.ts';\nimport type { ValidationMessage } from '../../../../config/types.ts';\nimport { CONFIG_VALIDATION } from '../../../../constants/error-messages.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport {\n getDatasourceFor,\n getDefaultVersioning,\n} from '../../../../modules/datasource/common.ts';\nimport type {\n GetDigestInputConfig,\n Release,\n ReleaseResult,\n} from '../../../../modules/datasource/index.ts';\nimport {\n applyDatasourceFilters,\n getDigest,\n getRawPkgReleases,\n isGetPkgReleasesConfig,\n supportsDigests,\n} from '../../../../modules/datasource/index.ts';\nimport { postprocessRelease } from '../../../../modules/datasource/postprocess-release.ts';\nimport { getRangeStrategy } from '../../../../modules/manager/index.ts';\nimport { id as dockerVersioningId } from '../../../../modules/versioning/docker/index.ts';\nimport * as allVersioning from '../../../../modules/versioning/index.ts';\nimport { ExternalHostError } from '../../../../types/errors/external-host-error.ts';\nimport { assignKeys } from '../../../../util/assign-keys.ts';\nimport { getElapsedDays } from '../../../../util/date.ts';\nimport { applyPackageRules } from '../../../../util/package-rules/index.ts';\nimport { regEx } from '../../../../util/regex.ts';\nimport { Result } from '../../../../util/result.ts';\nimport type { Timestamp } from '../../../../util/timestamp.ts';\nimport { calculateAbandonment } from './abandonment.ts';\nimport { getBucket } from './bucket.ts';\nimport { getCurrentVersion } from './current.ts';\nimport { filterVersions } from './filter.ts';\nimport { filterInternalChecks } from './filter-checks.ts';\nimport { generateUpdate } from './generate.ts';\nimport { getRollbackUpdate } from './rollback.ts';\nimport { calculateMostRecentTimestamp } from './timestamps.ts';\nimport type { LookupUpdateConfig, UpdateResult } from './types.ts';\nimport {\n addReplacementUpdateIfValid,\n isReplacementRulesConfigured,\n} from './utils.ts';\n\nasync function getTimestamp(\n config: LookupUpdateConfig,\n versions: Release[],\n version: string,\n versioningApi: allVersioning.VersioningApi,\n): Promise<Timestamp | null | undefined> {\n const currentRelease = versions.find(\n (v) =>\n versioningApi.isValid(v.version) &&\n versioningApi.equals(v.version, version),\n );\n\n if (!currentRelease) {\n return null;\n }\n\n if (currentRelease.releaseTimestamp) {\n return currentRelease.releaseTimestamp;\n }\n\n const remoteRelease = await postprocessRelease(config, currentRelease);\n return remoteRelease?.releaseTimestamp;\n}\n\nexport async function lookupUpdates(\n inconfig: LookupUpdateConfig,\n): Promise<Result<UpdateResult>> {\n let config: LookupUpdateConfig = { ...inconfig };\n config.versioning ??= getDefaultVersioning(config.datasource);\n\n const versioningApi = allVersioning.get(config.versioning);\n\n let dependency: ReleaseResult | null = null;\n const res: UpdateResult = {\n versioning: config.versioning,\n updates: [],\n warnings: [],\n };\n\n try {\n logger.trace(\n {\n dependency: config.packageName,\n currentValue: config.currentValue,\n },\n 'lookupUpdates',\n );\n if (config.currentValue && !isString(config.currentValue)) {\n // If currentValue is not a string, then it's invalid\n // v8 ignore else -- TODO: add test #40625\n if (config.currentValue) {\n logger.debug(\n `Invalid currentValue for ${config.packageName}: ${JSON.stringify(config.currentValue)} (${typeof config.currentValue})`,\n );\n }\n res.skipReason = 'invalid-value';\n return Result.ok(res);\n }\n if (\n !isGetPkgReleasesConfig(config) ||\n !getDatasourceFor(config.datasource)\n ) {\n res.skipReason = 'invalid-config';\n return Result.ok(res);\n }\n let compareValue = config.currentValue;\n if (\n isString(config.currentValue) &&\n isString(config.versionCompatibility)\n ) {\n const versionCompatbilityRegEx = regEx(config.versionCompatibility);\n const regexMatch = versionCompatbilityRegEx.exec(config.currentValue);\n if (regexMatch?.groups) {\n logger.debug(\n {\n versionCompatibility: config.versionCompatibility,\n currentValue: config.currentValue,\n packageName: config.packageName,\n groups: regexMatch.groups,\n },\n 'version compatibility regex match',\n );\n config.currentCompatibility = regexMatch.groups.compatibility;\n compareValue = regexMatch.groups.version;\n } else {\n logger.debug(\n {\n versionCompatibility: config.versionCompatibility,\n currentValue: config.currentValue,\n packageName: config.packageName,\n },\n 'version compatibility regex mismatch',\n );\n }\n }\n\n const isValid =\n isString(compareValue) && versioningApi.isValid(compareValue);\n\n const unconstrainedValue =\n !!config.lockedVersion && isUndefined(config.currentValue);\n\n if (isValid || unconstrainedValue) {\n if (\n !config.updatePinnedDependencies &&\n // TODO #22198\n versioningApi.isSingleVersion(compareValue!)\n ) {\n res.skipReason = 'is-pinned';\n return Result.ok(res);\n }\n\n const { val: releaseResult, err: lookupError } = await getRawPkgReleases(\n config,\n )\n .transform((res) => calculateMostRecentTimestamp(versioningApi, res))\n .transform((res) => calculateAbandonment(res, config))\n .transform((res) => applyDatasourceFilters(res, config))\n .unwrap();\n\n if (lookupError instanceof Error) {\n throw lookupError;\n }\n\n if (lookupError) {\n // If dependency lookup fails then warn and return\n const warning: ValidationMessage = {\n topic: config.packageName,\n message: `Failed to look up ${config.datasource} package ${config.packageName}: ${lookupError}`,\n };\n logger.debug(\n {\n dependency: config.packageName,\n packageFile: config.packageFile,\n },\n warning.message,\n );\n // TODO: return warnings in own field\n res.warnings.push(warning);\n return Result.ok(res);\n }\n\n dependency = releaseResult;\n\n if (dependency.deprecationMessage) {\n logger.debug(\n `Found deprecationMessage for ${config.datasource} package ${config.packageName}`,\n );\n }\n\n assignKeys(res, dependency, [\n 'deprecationMessage',\n 'sourceUrl',\n 'registryUrl',\n 'sourceDirectory',\n 'homepage',\n 'changelogUrl',\n 'dependencyUrl',\n 'lookupName',\n 'packageScope',\n 'mostRecentTimestamp',\n 'isAbandoned',\n 'respectLatest',\n ]);\n\n const latestVersion = dependency.tags?.latest;\n // Filter out any results from datasource that don't comply with our versioning\n let allVersions = dependency.releases.filter((release) =>\n versioningApi.isVersion(release.version),\n );\n const allReleaseVersions = new Set(allVersions.map((r) => r.version));\n // istanbul ignore if\n if (allVersions.length === 0) {\n const message = `Found no results from datasource that look like a version`;\n logger.info(\n {\n dependency: config.packageName,\n result: dependency,\n },\n message,\n );\n if (!config.currentDigest) {\n return Result.ok(res);\n }\n }\n // Reapply package rules in case we missed something from sourceUrl\n config = await applyPackageRules(\n { ...config, sourceUrl: res.sourceUrl },\n 'source-url',\n );\n if (config.followTag) {\n const taggedVersion = dependency.tags?.[config.followTag];\n if (!taggedVersion) {\n res.warnings.push({\n topic: config.packageName,\n message: `Can't find version with tag ${config.followTag} for ${config.datasource} package ${config.packageName}`,\n });\n return Result.ok(res);\n }\n allVersions = allVersions.filter(\n (v) =>\n v.version === taggedVersion ||\n (v.version === compareValue &&\n versioningApi.isGreaterThan(taggedVersion, compareValue)),\n );\n }\n\n const inRangeOnlyStrategy = config.rangeStrategy === 'in-range-only';\n // Check that existing constraint can be satisfied\n const allSatisfyingVersions =\n (inRangeOnlyStrategy || config.rollbackPrs) && !unconstrainedValue\n ? allVersions.filter((v) =>\n // TODO #22198\n versioningApi.matches(v.version, compareValue!),\n )\n : allVersions;\n if (!allSatisfyingVersions.length) {\n logger.debug(\n `Found no satisfying versions with '${config.versioning}' versioning`,\n );\n }\n\n if (config.rollbackPrs && !allSatisfyingVersions.length) {\n const rollback = getRollbackUpdate(config, allVersions, versioningApi);\n // istanbul ignore if\n if (!rollback) {\n res.warnings.push({\n topic: config.packageName,\n // TODO: types (#22198)\n message: `Can't find version matching ${compareValue!} for ${\n config.datasource\n } package ${config.packageName}`,\n });\n return Result.ok(res);\n }\n res.updates.push(rollback);\n }\n let rangeStrategy = getRangeStrategy(config);\n\n // istanbul ignore next\n if (\n config.isVulnerabilityAlert &&\n rangeStrategy === 'update-lockfile' &&\n !config.lockedVersion\n ) {\n rangeStrategy = 'bump';\n }\n // unconstrained deps with lockedVersion\n if (\n config.isVulnerabilityAlert &&\n !config.currentValue &&\n config.lockedVersion\n ) {\n rangeStrategy = 'update-lockfile';\n }\n const nonDeprecatedVersions = dependency.releases\n .filter((release) => !release.isDeprecated)\n .map((release) => release.version);\n let currentVersion: string;\n if (rangeStrategy === 'update-lockfile') {\n currentVersion = config.lockedVersion!;\n } else if (\n compareValue &&\n versioningApi.isSingleVersion(compareValue) &&\n allVersions.find((v) => v.version === compareValue)\n ) {\n currentVersion = compareValue;\n }\n // TODO #22198\n currentVersion ??=\n getCurrentVersion(\n compareValue!,\n config.lockedVersion!,\n versioningApi,\n rangeStrategy!,\n latestVersion!,\n nonDeprecatedVersions,\n ) ??\n getCurrentVersion(\n compareValue!,\n config.lockedVersion!,\n versioningApi,\n rangeStrategy!,\n latestVersion!,\n allVersions.map((v) => v.version),\n )!;\n\n if (!currentVersion) {\n // v8 ignore else -- TODO: add test #40625\n if (!config.lockedVersion) {\n logger.debug(\n `No currentVersion or lockedVersion found for ${config.packageName}`,\n );\n res.skipReason = 'invalid-value';\n }\n return Result.ok(res);\n }\n\n res.currentVersion = currentVersion;\n\n // Use lockedVersion for the timestamp lookup when available, because\n // res.currentVersion is later overwritten to lockedVersion (see below).\n // Without this, strategies like \"replace\" would compute the timestamp\n // for the highest satisfying version (e.g. 1.4.1) while the reported\n // currentVersion ends up being the locked one (e.g. 1.0.0).\n const versionForTimestamp = config.lockedVersion ?? currentVersion;\n const currentVersionTimestamp = await getTimestamp(\n config,\n allVersions,\n versionForTimestamp,\n versioningApi,\n );\n\n if (isNonEmptyString(currentVersionTimestamp)) {\n res.currentVersionTimestamp = currentVersionTimestamp;\n res.currentVersionAgeInDays = getElapsedDays(currentVersionTimestamp);\n\n if (\n config.packageRules?.some((rule) =>\n isNonEmptyString(rule.matchCurrentAge),\n )\n ) {\n // Reapply package rules to check matches for matchCurrentAge\n config = await applyPackageRules(\n { ...config, currentVersionTimestamp },\n 'current-timestamp',\n );\n }\n }\n\n if (\n compareValue &&\n currentVersion &&\n rangeStrategy === 'pin' &&\n !versioningApi.isSingleVersion(compareValue)\n ) {\n const newValue =\n versioningApi.getPinnedValue?.(currentVersion) ?? currentVersion;\n res.updates.push({\n updateType: 'pin',\n isPin: true,\n newValue,\n newVersion: currentVersion,\n newMajor: versioningApi.getMajor(currentVersion)!,\n });\n }\n if (rangeStrategy === 'pin') {\n // Fall back to replace once pinning logic is done\n rangeStrategy = 'replace';\n }\n // istanbul ignore if\n if (!versioningApi.isVersion(currentVersion!)) {\n res.skipReason = 'invalid-version';\n return Result.ok(res);\n }\n // Filter latest, unstable, etc\n // TODO #22198\n let filteredReleases = filterVersions(\n config,\n currentVersion!,\n latestVersion!,\n inRangeOnlyStrategy ? allSatisfyingVersions : allVersions,\n versioningApi,\n ).filter(\n (v) =>\n // Leave only compatible versions\n unconstrainedValue ||\n versioningApi.isCompatible(v.version, compareValue),\n );\n let shrinkedViaVulnerability = false;\n if (config.isVulnerabilityAlert) {\n if (config.vulnerabilityFixVersion) {\n res.vulnerabilityFixVersion = config.vulnerabilityFixVersion;\n res.vulnerabilityFixStrategy = config.vulnerabilityFixStrategy;\n if (versioningApi.isValid(config.vulnerabilityFixVersion)) {\n let fixedFilteredReleases;\n if (versioningApi.isVersion(config.vulnerabilityFixVersion)) {\n // Retain only releases greater than or equal to the fix version\n fixedFilteredReleases = filteredReleases.filter(\n (release) =>\n !versioningApi.isGreaterThan(\n config.vulnerabilityFixVersion!,\n release.version,\n ),\n );\n } else {\n // Retain only releases which max the fix constraint\n fixedFilteredReleases = filteredReleases.filter((release) =>\n versioningApi.matches(\n release.version,\n config.vulnerabilityFixVersion!,\n ),\n );\n }\n // Warn if this filtering results caused zero releases\n if (fixedFilteredReleases.length === 0 && filteredReleases.length) {\n logger.warn(\n {\n releases: filteredReleases,\n vulnerabilityFixVersion: config.vulnerabilityFixVersion,\n packageName: config.packageName,\n },\n 'No releases satisfy vulnerabilityFixVersion',\n );\n }\n // Use the additionally filtered releases\n filteredReleases = fixedFilteredReleases;\n } else {\n logger.warn(\n {\n vulnerabilityFixVersion: config.vulnerabilityFixVersion,\n packageName: config.packageName,\n },\n 'vulnerabilityFixVersion is not valid',\n );\n }\n }\n if (config.vulnerabilityFixStrategy === 'highest') {\n // Don't shrink the list of releases - let Renovate use its normal logic\n logger.once.debug(\n `Using vulnerabilityFixStrategy=highest for ${config.packageName}`,\n );\n } else {\n // Shrink the list of releases to the lowest fixed version\n logger.once.debug(\n `Using vulnerabilityFixStrategy=lowest for ${config.packageName}`,\n );\n filteredReleases = filteredReleases.slice(0, 1);\n shrinkedViaVulnerability = true;\n }\n }\n const buckets: Record<string, [Release]> = {};\n for (const release of filteredReleases) {\n const bucket = getBucket(\n config,\n // TODO #22198\n currentVersion!,\n release.version,\n versioningApi,\n );\n // v8 ignore else -- TODO: add test #40625\n if (isString(bucket)) {\n if (buckets[bucket]) {\n buckets[bucket].push(release);\n } else {\n buckets[bucket] = [release];\n }\n }\n }\n const depResultConfig = mergeChildConfig(config, res);\n for (const [bucket, releases] of Object.entries(buckets)) {\n const sortedReleases = releases.sort((r1, r2) =>\n versioningApi.sortVersions(r1.version, r2.version),\n );\n const { release, pendingChecks, pendingReleases } =\n await filterInternalChecks(\n depResultConfig,\n versioningApi,\n bucket,\n sortedReleases,\n );\n // istanbul ignore next\n if (!release) {\n return Result.ok(res);\n }\n const newVersion = release.version;\n const update = await generateUpdate(\n config,\n compareValue,\n versioningApi,\n // TODO #22198\n\n rangeStrategy!,\n config.lockedVersion ?? currentVersion!,\n bucket,\n release,\n allReleaseVersions,\n );\n\n // #29034\n if (\n config.manager === 'gomod' &&\n compareValue?.startsWith('v0.0.0-') &&\n update.newValue?.startsWith('v0.0.0-') &&\n config.currentDigest !== update.newDigest\n ) {\n update.updateType = 'digest';\n }\n\n if (pendingChecks) {\n update.pendingChecks = pendingChecks;\n }\n\n if (pendingReleases.length) {\n update.pendingVersions = pendingReleases.map((r) => r.version);\n }\n if (!update.newValue || update.newValue === compareValue) {\n if (!config.lockedVersion) {\n continue;\n }\n // istanbul ignore if\n if (rangeStrategy === 'bump') {\n logger.trace(\n {\n packageName: config.packageName,\n currentValue: config.currentValue,\n lockedVersion: config.lockedVersion,\n newVersion,\n },\n 'Skipping bump because newValue is the same',\n );\n continue;\n }\n res.isSingleVersion = true;\n }\n res.isSingleVersion ??=\n isString(update.newValue) &&\n versioningApi.isSingleVersion(update.newValue);\n // istanbul ignore if\n if (\n config.versioning === dockerVersioningId &&\n update.updateType !== 'rollback' &&\n update.newValue &&\n versioningApi.isVersion(update.newValue) &&\n compareValue &&\n versioningApi.isVersion(compareValue) &&\n versioningApi.isGreaterThan(compareValue, update.newValue)\n ) {\n logger.warn(\n {\n packageName: config.packageName,\n currentValue: config.currentValue,\n compareValue,\n currentVersion: config.currentVersion,\n update,\n allVersionsLength: allVersions.length,\n filteredReleaseVersions: filteredReleases.map((r) => r.version),\n shrinkedViaVulnerability,\n },\n 'Unexpected downgrade detected: skipping',\n );\n } else {\n res.updates.push(update);\n }\n }\n } else if (compareValue) {\n logger.debug(\n `Dependency ${config.packageName} has unsupported/unversioned value ${compareValue} (versioning=${config.versioning})`,\n );\n\n if (!config.pinDigests && !config.currentDigest) {\n logger.debug(\n `Skipping ${config.packageName} because no currentDigest or pinDigests`,\n );\n res.skipReason = 'invalid-value';\n } else {\n delete res.skipReason;\n }\n } else {\n res.skipReason = 'invalid-value';\n }\n\n if (isReplacementRulesConfigured(config)) {\n addReplacementUpdateIfValid(res.updates, config);\n } else if (dependency?.replacementName && dependency.replacementVersion) {\n res.updates.push({\n updateType: 'replacement',\n newName: dependency.replacementName,\n newValue: dependency.replacementVersion,\n });\n }\n\n // Record if the dep is fixed to a version\n if (config.lockedVersion) {\n res.currentVersion = config.lockedVersion;\n res.fixedVersion = config.lockedVersion;\n } else if (compareValue && versioningApi.isSingleVersion(compareValue)) {\n res.fixedVersion = compareValue.replace(regEx(/^=+/), '');\n }\n\n // massage versionCompatibility\n if (\n isString(config.currentValue) &&\n isString(compareValue) &&\n isString(config.versionCompatibility)\n ) {\n for (const update of res.updates) {\n logger.debug({ update });\n // v8 ignore else -- TODO: add test #40625\n if (isString(config.currentValue) && isString(update.newValue)) {\n update.newValue = config.currentValue.replace(\n compareValue,\n update.newValue,\n );\n }\n }\n }\n\n // Add digests if necessary\n if (supportsDigests(config.datasource)) {\n if (config.currentDigest) {\n if (!config.digestOneAndOnly || !res.updates.length) {\n // digest update\n res.updates.push({\n updateType: 'digest',\n newValue: config.currentValue,\n });\n }\n } else if (\n config.pinDigests &&\n // Create a pin only if one doesn't already exists\n // v8 ignore else -- TODO: add test #40625\n !res.updates.some((update) => update.updateType === 'pin')\n ) {\n // pin digest\n res.updates.push({\n isPinDigest: true,\n updateType: 'pinDigest',\n newValue: config.currentValue,\n });\n }\n if (versioningApi.valueToVersion) {\n // TODO #22198\n res.currentVersion = versioningApi.valueToVersion(res.currentVersion!);\n for (const update of res.updates) {\n // TODO #22198\n update.newVersion = versioningApi.valueToVersion(update.newVersion!);\n }\n }\n if (res.registryUrl) {\n config.registryUrls = [res.registryUrl];\n }\n\n // update digest for all\n for (const update of res.updates) {\n if (config.pinDigests === true || config.currentDigest) {\n const getDigestConfig: GetDigestInputConfig = {\n ...config,\n registryUrl: update.registryUrl ?? res.registryUrl,\n lookupName: res.lookupName,\n };\n\n // #20304 only pass it for replacement updates, otherwise we get wrong or invalid digest\n if (update.updateType !== 'replacement') {\n delete getDigestConfig.replacementName;\n }\n\n // #20304 don't use lookupName and currentDigest when we replace image name\n if (\n update.updateType === 'replacement' &&\n update.newName !== config.packageName\n ) {\n delete getDigestConfig.lookupName;\n delete getDigestConfig.currentDigest;\n getDigestConfig.replacementName = update.newName;\n }\n\n // Don't use current releases if replacement changes name, otherwise we use the wrong new digest.\n // This happens on datasources which return the digest in release info like `github-tags`.\n // We can still use it when only version is changing.\n if (\n update.updateType !== 'replacement' ||\n update.newName === config.packageName\n ) {\n update.newDigest ??= dependency?.releases.find(\n (r) => r.version === update.newValue,\n )?.newDigest;\n }\n\n update.newDigest ??= await getDigest(\n getDigestConfig,\n update.newValue,\n );\n\n // If the digest could not be determined, report this as otherwise the\n // update will be omitted later on without notice.\n if (update.newDigest === null) {\n logger.debug(\n {\n packageName: config.packageName,\n currentValue: config.currentValue,\n datasource: config.datasource,\n newValue: update.newValue,\n bucket: update.bucket,\n },\n 'Could not determine new digest for update.',\n );\n\n // Only report a warning if there is a current digest.\n // Context: https://github.com/renovatebot/renovate/pull/20175#discussion_r1102615059.\n if (config.currentDigest) {\n res.warnings.push({\n message: `Could not determine new digest for update (${config.datasource} package ${config.packageName})`,\n topic: config.packageName,\n });\n }\n }\n } else {\n delete update.newDigest;\n }\n if (update.newVersion) {\n const registryUrl = dependency?.releases?.find(\n (release) => release.version === update.newVersion,\n )?.registryUrl;\n if (registryUrl && registryUrl !== res.registryUrl) {\n update.registryUrl = registryUrl;\n }\n }\n }\n }\n\n if (res.updates.length) {\n delete res.skipReason;\n }\n // Strip out any non-changed ones\n res.updates = res.updates\n .filter(\n (update) => update.newValue !== null || config.currentValue === null,\n )\n .filter((update) => update.newDigest !== null)\n .filter(\n (update) =>\n (isString(update.newName) && update.newName !== config.packageName) ||\n update.isReplacement === true ||\n update.newValue !== config.currentValue ||\n update.isLockfileUpdate === true ||\n // TODO #22198\n (update.newDigest &&\n !update.newDigest.startsWith(config.currentDigest!)),\n );\n // If range strategy specified in config is 'in-range-only', also strip out updates where currentValue !== newValue\n if (config.rangeStrategy === 'in-range-only') {\n res.updates = res.updates.filter(\n (update) => update.newValue === config.currentValue,\n );\n }\n // Handle a weird edge case involving followTag and fallbacks\n if (config.rollbackPrs && config.followTag) {\n res.updates = res.updates.filter(\n (update) =>\n update.updateType !== 'rollback' || res.updates.length === 1,\n );\n }\n\n const release =\n res.updates.length > 0\n ? (dependency?.releases.find(\n (r) => r.version === res.updates[0].newValue,\n ) ??\n dependency?.releases.find(\n (r) => r.version === res.updates[0].newVersion,\n ))\n : null;\n\n if (release?.changelogContent) {\n res.changelogContent = release.changelogContent;\n res.changelogUrl = release.changelogUrl;\n }\n } catch (err) /* istanbul ignore next */ {\n if (err instanceof ExternalHostError) {\n return Result.err(err);\n }\n\n if (err instanceof Error && err.message === CONFIG_VALIDATION) {\n return Result.err(err);\n }\n\n logger.error(\n {\n currentDigest: config.currentDigest,\n currentValue: config.currentValue,\n datasource: config.datasource,\n packageName: config.packageName,\n digestOneAndOnly: config.digestOneAndOnly,\n followTag: config.followTag,\n lockedVersion: config.lockedVersion,\n packageFile: config.packageFile,\n pinDigests: config.pinDigests,\n rollbackPrs: config.rollbackPrs,\n isVulnerabilityAlert: config.isVulnerabilityAlert,\n updatePinnedDependencies: config.updatePinnedDependencies,\n err,\n },\n 'lookupUpdates error',\n );\n res.skipReason = 'internal-error';\n }\n return Result.ok(res);\n}\n"],"mappings":"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"}
|
|
@@ -280,9 +280,9 @@ var Vulnerabilities = class Vulnerabilities {
|
|
|
280
280
|
let aliases = [vulnerability.id].concat(vulnerability.aliases ?? []).sort();
|
|
281
281
|
aliases = aliases.map((id) => {
|
|
282
282
|
if (id.startsWith("CVE-")) return `[${id}](https://nvd.nist.gov/vuln/detail/${id})`;
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
283
|
+
if (id.startsWith("GHSA-")) return `[${id}](https://github.com/advisories/${id})`;
|
|
284
|
+
if (id.startsWith("GO-")) return `[${id}](https://pkg.go.dev/vuln/${id})`;
|
|
285
|
+
if (id.startsWith("RUSTSEC-")) return `[${id}](https://rustsec.org/advisories/${id}.html)`;
|
|
286
286
|
return id;
|
|
287
287
|
});
|
|
288
288
|
let content = "\n\n---\n\n### ";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vulnerabilities.js","names":["p.all","getVersioning"],"sources":["../../../../lib/workers/repository/process/vulnerabilities.ts"],"sourcesContent":["// TODO #22198\nimport type { Ecosystem, Osv } from '@renovatebot/osv-offline';\nimport { OsvOffline } from '@renovatebot/osv-offline';\nimport {\n isEmptyArray,\n isNonEmptyString,\n isNullOrUndefined,\n isTruthy,\n} from '@sindresorhus/is';\nimport type { CvssVector } from 'ae-cvss-calculator';\nimport * as _aeCvss from 'ae-cvss-calculator';\nimport { z } from 'zod/v4';\nimport { getManagerConfig, mergeChildConfig } from '../../../config/index.ts';\nimport type { PackageRule, RenovateConfig } from '../../../config/types.ts';\nimport { instrument } from '../../../instrumentation/index.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { getDefaultVersioning } from '../../../modules/datasource/common.ts';\nimport type {\n PackageDependency,\n PackageFile,\n} from '../../../modules/manager/types.ts';\nimport type { VersioningApi } from '../../../modules/versioning/index.ts';\nimport { get as getVersioning } from '../../../modules/versioning/index.ts';\nimport { sanitizeMarkdown } from '../../../util/markdown.ts';\nimport * as p from '../../../util/promises.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { titleCase } from '../../../util/string.ts';\nimport { datasourceToOsvEcosystem } from '../../../util/vulnerability/ecosystem.ts';\nimport {\n getFixedVersionConstraint,\n getLastAffectedVersionConstraint,\n} from '../../../util/vulnerability/utils.ts';\nimport type {\n DependencyVulnerabilities,\n SeverityDetails,\n Vulnerability,\n} from './types.ts';\n\nconst { fromVector } = (_aeCvss as unknown as { default: typeof _aeCvss })\n .default;\n\nexport class Vulnerabilities {\n private static osvOffline: Promise<OsvOffline> | undefined;\n\n private osvOffline: OsvOffline;\n\n private static readonly datasourceEcosystemMap = datasourceToOsvEcosystem;\n\n private constructor(osvOffline: OsvOffline) {\n this.osvOffline = osvOffline;\n }\n\n private static initialize(): Promise<OsvOffline> {\n // no async here, so osv promise will only be created once\n Vulnerabilities.osvOffline ??= OsvOffline.create();\n return Vulnerabilities.osvOffline;\n }\n\n static async create(): Promise<Vulnerabilities> {\n // intialize osv only once\n const osvOffline = await Vulnerabilities.initialize();\n\n const instance = new Vulnerabilities(osvOffline);\n return instance;\n }\n\n async appendVulnerabilityPackageRules(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n ): Promise<void> {\n const dependencyVulnerabilities = await this.fetchDependencyVulnerabilities(\n config,\n packageFiles,\n );\n\n config.packageRules ??= [];\n for (const {\n vulnerabilities,\n versioningApi,\n } of dependencyVulnerabilities) {\n const groupPackageRules: PackageRule[] = [];\n for (const vulnerability of vulnerabilities) {\n const rule = this.vulnerabilityToPackageRules(vulnerability);\n if (isNullOrUndefined(rule)) {\n continue;\n }\n groupPackageRules.push(rule);\n }\n this.sortByFixedVersion(groupPackageRules, versioningApi);\n\n config.packageRules.push(...groupPackageRules);\n }\n }\n\n async fetchVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n ): Promise<Vulnerability[]> {\n const groups = await this.fetchDependencyVulnerabilities(\n config,\n packageFiles,\n );\n return groups.flatMap((group) => group.vulnerabilities);\n }\n\n private async fetchDependencyVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n ): Promise<DependencyVulnerabilities[]> {\n const managers = Object.keys(packageFiles);\n const allManagerJobs = managers.map((manager) =>\n this.fetchManagerVulnerabilities(config, packageFiles, manager),\n );\n return (await Promise.all(allManagerJobs)).flat();\n }\n\n private async fetchManagerVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n manager: string,\n ): Promise<DependencyVulnerabilities[]> {\n const managerConfig = getManagerConfig(config, manager);\n const queue = packageFiles[manager].map(\n (pFile) => (): Promise<DependencyVulnerabilities[]> =>\n this.fetchManagerPackageFileVulnerabilities(managerConfig, pFile),\n );\n logger.trace(\n { manager, queueLength: queue.length },\n 'fetchManagerVulnerabilities starting',\n );\n const result = (await p.all(queue)).flat();\n logger.trace({ manager }, 'fetchManagerVulnerabilities finished');\n return result;\n }\n\n private async fetchManagerPackageFileVulnerabilities(\n managerConfig: RenovateConfig,\n pFile: PackageFile,\n ): Promise<DependencyVulnerabilities[]> {\n const { packageFile } = pFile;\n const packageFileConfig = mergeChildConfig(managerConfig, pFile);\n const { manager } = packageFileConfig;\n const queue = pFile.deps.map(\n (dep) => (): Promise<DependencyVulnerabilities | null> =>\n this.fetchDependencyVulnerability(packageFileConfig, dep),\n );\n logger.trace(\n { manager, packageFile, queueLength: queue.length },\n 'fetchManagerPackageFileVulnerabilities starting with concurrency',\n );\n\n const result = await p.all(queue);\n logger.trace(\n { packageFile },\n 'fetchManagerPackageFileVulnerabilities finished',\n );\n\n return result.filter(isTruthy);\n }\n\n private async fetchDependencyVulnerability(\n packageFileConfig: RenovateConfig & PackageFile,\n dep: PackageDependency,\n ): Promise<DependencyVulnerabilities | null> {\n const ecosystem = Vulnerabilities.datasourceEcosystemMap[dep.datasource!];\n if (!ecosystem) {\n logger.trace(`Cannot map datasource ${dep.datasource!} to OSV ecosystem`);\n return null;\n }\n\n const packageName = dep.packageName ?? dep.depName!;\n let osvPackageName = packageName;\n if (ecosystem === 'PyPI') {\n // https://peps.python.org/pep-0503/#normalized-names\n osvPackageName = osvPackageName\n .toLowerCase()\n .replace(regEx(/[_.-]+/g), '-');\n } else if (ecosystem === 'Go' && packageName === 'go') {\n if (dep.depType !== 'toolchain') {\n // The `go` directive is source compatibility, not the build toolchain, so we skip it\n return null;\n }\n osvPackageName = 'stdlib';\n }\n\n try {\n const osvVulnerabilities = await instrument(\n 'get OSV vulnerabilities',\n () => this.osvOffline.getVulnerabilities(ecosystem, osvPackageName),\n {\n attributes: {\n osvPackageName,\n ecosystem,\n },\n },\n );\n if (\n isNullOrUndefined(osvVulnerabilities) ||\n isEmptyArray(osvVulnerabilities)\n ) {\n logger.trace(\n `No vulnerabilities found in OSV database for ${packageName}`,\n );\n return null;\n }\n\n const depVersion =\n dep.lockedVersion ?? dep.currentVersion ?? dep.currentValue!;\n\n const versioning = dep.versioning ?? getDefaultVersioning(dep.datasource);\n const versioningApi = getVersioning(versioning);\n\n if (!versioningApi.isVersion(depVersion)) {\n logger.debug(\n `Skipping vulnerability lookup for package ${packageName} due to unsupported version ${depVersion}`,\n );\n return null;\n }\n\n const vulnerabilities: Vulnerability[] = [];\n for (const osvVulnerability of osvVulnerabilities) {\n if (osvVulnerability.withdrawn) {\n logger.trace(\n `Skipping withdrawn vulnerability ${osvVulnerability.id}`,\n );\n continue;\n }\n\n this.skipMaliciousPackages(\n ecosystem,\n osvPackageName,\n depVersion,\n versioningApi,\n dep,\n packageFileConfig.manager,\n packageFileConfig.packageFile,\n osvVulnerability,\n );\n\n for (const affected of osvVulnerability.affected ?? []) {\n const isVulnerable = this.isPackageVulnerable(\n ecosystem,\n osvPackageName,\n depVersion,\n affected,\n versioningApi,\n );\n if (!isVulnerable) {\n continue;\n }\n\n logger.debug(\n `Vulnerability ${osvVulnerability.id} affects ${packageName} ${depVersion}`,\n );\n const fixedVersion = this.getFixedVersion(\n ecosystem,\n depVersion,\n affected,\n versioningApi,\n );\n\n vulnerabilities.push({\n packageName,\n osvPackageName,\n vulnerability: osvVulnerability,\n affected,\n depVersion,\n fixedVersion,\n datasource: dep.datasource!,\n packageFileConfig,\n });\n }\n }\n\n return { vulnerabilities, versioningApi };\n } catch (err) {\n logger.warn(\n { err, packageName },\n 'Error fetching vulnerability information for package',\n );\n return null;\n }\n }\n\n private skipMaliciousPackages(\n ecosystem: Ecosystem,\n osvPackageName: string,\n depVersion: string,\n versioningApi: VersioningApi,\n dep: PackageDependency,\n manager: string | undefined,\n packageFile: string,\n osvVulnerability: Osv.Vulnerability,\n ): void {\n // the OpenSSF's Malicious Packages (https://github.com/ossf/malicious-packages) is a source of advisories through osv.dev, which takes various sources of advisories, and will re-publish them with more specific information about their malicious usage\n if (osvVulnerability.id.startsWith('MAL-')) {\n // is the current dependency vulnerable?\n for (const affected of osvVulnerability.affected ?? []) {\n // is the current dependency vulnerable?\n const isVulnerable = this.isPackageVulnerable(\n ecosystem,\n osvPackageName,\n depVersion,\n affected,\n versioningApi,\n );\n\n if (isVulnerable) {\n logger.debug(\n {\n packageFile: packageFile,\n depName: dep.depName,\n packageName: dep.packageName,\n manager: manager,\n datasource: dep.datasource,\n currentVersion: depVersion,\n },\n `Marking ${dep.depName} as skipReason=malicious-version-in-use, as it is affected by ${osvVulnerability.id}`,\n );\n dep.skipReason = 'malicious-version-in-use';\n dep.skipStage = 'lookup';\n }\n\n // or are any of the updates vulnerable?\n for (const update of dep.updates ?? []) {\n const newVersion = update.newVersion ?? update.newValue!;\n\n const isUpdateVulnerable = this.isPackageVulnerable(\n ecosystem,\n osvPackageName,\n newVersion,\n affected,\n versioningApi,\n );\n\n if (isUpdateVulnerable) {\n logger.debug(\n {\n packageFile: packageFile,\n depName: dep.depName,\n packageName: dep.packageName,\n manager: manager,\n datasource: dep.datasource,\n currentVersion: depVersion,\n newVersion,\n },\n `Marking ${dep.depName}'s update to ${newVersion} as skipReason=malicious-update-proposed, as it is affected by ${osvVulnerability.id}`,\n );\n dep.skipReason = 'malicious-update-proposed';\n dep.skipStage = 'lookup';\n }\n }\n }\n }\n }\n\n private sortByFixedVersion(\n packageRules: PackageRule[],\n versioningApi: VersioningApi,\n ): void {\n const versionsCleaned: Record<string, string> = {};\n for (const rule of packageRules) {\n const version = rule.allowedVersions!;\n versionsCleaned[version] = version.replace(regEx(/[(),=> ]+/g), '');\n }\n packageRules.sort((a, b) =>\n versioningApi.sortVersions(\n versionsCleaned[a.allowedVersions!],\n versionsCleaned[b.allowedVersions!],\n ),\n );\n }\n\n // https://ossf.github.io/osv-schema/#affectedrangesevents-fields\n private sortEvents(\n events: Osv.Event[],\n versioningApi: VersioningApi,\n ): Osv.Event[] {\n const sortedCopy: Osv.Event[] = [];\n let zeroEvent: Osv.Event | null = null;\n\n for (const event of events) {\n if (event.introduced === '0') {\n zeroEvent = event;\n } else if (versioningApi.isVersion(Object.values(event)[0])) {\n sortedCopy.push(event);\n } else {\n logger.debug({ event }, 'Skipping OSV event with invalid version');\n }\n }\n\n sortedCopy.sort((a, b) =>\n // no pre-processing, as there are only very few values to sort\n versioningApi.sortVersions(Object.values(a)[0], Object.values(b)[0]),\n );\n\n if (zeroEvent) {\n sortedCopy.unshift(zeroEvent);\n }\n\n return sortedCopy;\n }\n\n private isPackageAffected(\n ecosystem: Ecosystem,\n osvPackageName: string,\n affected: Osv.Affected,\n ): boolean {\n return (\n affected.package?.name === osvPackageName &&\n affected.package?.ecosystem === ecosystem\n );\n }\n\n private includedInVersions(\n depVersion: string,\n affected: Osv.Affected,\n ): boolean {\n return !!affected.versions?.includes(depVersion);\n }\n\n private includedInRanges(\n depVersion: string,\n affected: Osv.Affected,\n versioningApi: VersioningApi,\n ): boolean {\n for (const range of affected.ranges ?? []) {\n if (range.type === 'GIT') {\n continue;\n }\n\n let vulnerable = false;\n for (const event of this.sortEvents(range.events, versioningApi)) {\n if (\n isNonEmptyString(event.introduced) &&\n (event.introduced === '0' ||\n this.isVersionGtOrEq(depVersion, event.introduced, versioningApi))\n ) {\n vulnerable = true;\n } else if (\n isNonEmptyString(event.fixed) &&\n this.isVersionGtOrEq(depVersion, event.fixed, versioningApi)\n ) {\n vulnerable = false;\n } else if (\n isNonEmptyString(event.last_affected) &&\n this.isVersionGt(depVersion, event.last_affected, versioningApi)\n ) {\n vulnerable = false;\n }\n }\n\n if (vulnerable) {\n return true;\n }\n }\n\n return false;\n }\n\n // https://ossf.github.io/osv-schema/#evaluation\n private isPackageVulnerable(\n ecosystem: Ecosystem,\n osvPackageName: string,\n depVersion: string,\n affected: Osv.Affected,\n versioningApi: VersioningApi,\n ): boolean {\n return (\n this.isPackageAffected(ecosystem, osvPackageName, affected) &&\n (this.includedInVersions(depVersion, affected) ||\n this.includedInRanges(depVersion, affected, versioningApi))\n );\n }\n\n private getFixedVersion(\n ecosystem: Ecosystem,\n depVersion: string,\n affected: Osv.Affected,\n versioningApi: VersioningApi,\n ): string | null {\n const fixedVersions: string[] = [];\n const lastAffectedVersions: string[] = [];\n\n for (const range of affected.ranges ?? []) {\n if (range.type === 'GIT') {\n continue;\n }\n\n for (const event of range.events) {\n if (\n isNonEmptyString(event.fixed) &&\n versioningApi.isVersion(event.fixed)\n ) {\n fixedVersions.push(event.fixed);\n } else if (\n isNonEmptyString(event.last_affected) &&\n versioningApi.isVersion(event.last_affected)\n ) {\n lastAffectedVersions.push(event.last_affected);\n }\n }\n }\n\n fixedVersions.sort((a, b) => versioningApi.sortVersions(a, b));\n const fixedVersion = fixedVersions.find((version) =>\n this.isVersionGt(version, depVersion, versioningApi),\n );\n if (fixedVersion) {\n return this.getFixedVersionByEcosystem(fixedVersion, ecosystem);\n }\n\n lastAffectedVersions.sort((a, b) => versioningApi.sortVersions(a, b));\n const lastAffected = lastAffectedVersions.find((version) =>\n this.isVersionGtOrEq(version, depVersion, versioningApi),\n );\n if (lastAffected) {\n return this.getLastAffectedByEcosystem(lastAffected, ecosystem);\n }\n\n return null;\n }\n\n private getFixedVersionByEcosystem(\n fixedVersion: string,\n ecosystem: Ecosystem,\n ): string {\n return getFixedVersionConstraint(fixedVersion, ecosystem);\n }\n\n private getLastAffectedByEcosystem(\n lastAffected: string,\n ecosystem: Ecosystem,\n ): string {\n return getLastAffectedVersionConstraint(lastAffected, ecosystem);\n }\n\n private isVersionGt(\n version: string,\n other: string,\n versioningApi: VersioningApi,\n ): boolean {\n return (\n versioningApi.isVersion(version) &&\n versioningApi.isVersion(other) &&\n versioningApi.isGreaterThan(version, other)\n );\n }\n\n private isVersionGtOrEq(\n version: string,\n other: string,\n versioningApi: VersioningApi,\n ): boolean {\n return (\n versioningApi.isVersion(version) &&\n versioningApi.isVersion(other) &&\n (versioningApi.equals(version, other) ||\n versioningApi.isGreaterThan(version, other))\n );\n }\n\n private vulnerabilityToPackageRules(vul: Vulnerability): PackageRule | null {\n const {\n vulnerability,\n affected,\n packageName,\n depVersion,\n fixedVersion,\n datasource,\n packageFileConfig,\n } = vul;\n if (isNullOrUndefined(fixedVersion)) {\n logger.debug(\n `No fixed version available for vulnerability ${vulnerability.id} in ${packageName} ${depVersion}`,\n );\n return null;\n }\n\n // we don't know if the dependency has a `versioning` applied to it already, so we have to use the default for the datasource\n const versioning = getDefaultVersioning(datasource);\n\n logger.debug(\n {\n datasource,\n versioning,\n },\n\n `Setting allowed version ${fixedVersion} to fix vulnerability ${vulnerability.id} in ${packageName} ${depVersion}`,\n );\n\n const severityDetails = this.extractSeverityDetails(\n vulnerability,\n affected,\n );\n\n return {\n matchDatasources: [datasource],\n matchPackageNames: [packageName],\n matchCurrentVersion: depVersion,\n versioning,\n allowedVersions: fixedVersion,\n isVulnerabilityAlert: true,\n vulnerabilitySeverity: severityDetails.severityLevel,\n prBodyNotes: this.generatePrBodyNotes(vulnerability, affected),\n force: {\n ...packageFileConfig.vulnerabilityAlerts,\n },\n };\n }\n\n static evaluateCvssVector(vector: string): [string, string] {\n const CvssJson = z.object({\n baseScore: z.number().default(0.0),\n baseSeverity: z.string().toUpperCase().default('UNKNOWN'),\n });\n\n try {\n const parsedCvssScore: CvssVector<any> | null = fromVector(vector);\n const res = CvssJson.parse(parsedCvssScore?.createJsonSchema());\n\n return [res.baseScore.toFixed(1), res.baseSeverity];\n } catch {\n logger.debug(`Error processing CVSS vector ${vector}`);\n }\n\n return ['', ''];\n }\n\n private generatePrBodyNotes(\n vulnerability: Osv.Vulnerability,\n affected: Osv.Affected,\n ): string[] {\n let aliases = [vulnerability.id].concat(vulnerability.aliases ?? []).sort();\n aliases = aliases.map((id) => {\n if (id.startsWith('CVE-')) {\n return `[${id}](https://nvd.nist.gov/vuln/detail/${id})`;\n } else if (id.startsWith('GHSA-')) {\n return `[${id}](https://github.com/advisories/${id})`;\n } else if (id.startsWith('GO-')) {\n return `[${id}](https://pkg.go.dev/vuln/${id})`;\n } else if (id.startsWith('RUSTSEC-')) {\n return `[${id}](https://rustsec.org/advisories/${id}.html)`;\n }\n\n return id;\n });\n\n let content = '\\n\\n---\\n\\n### ';\n content += vulnerability.summary ? `${vulnerability.summary}\\n` : '';\n content += `${aliases.join(' / ')}\\n`;\n content += `\\n<details>\\n<summary>More information</summary>\\n`;\n\n const details = vulnerability.details?.replace(\n regEx(/^#{1,4} /gm),\n '##### ',\n );\n content += `#### Details\\n${details ?? 'No details.'}\\n`;\n\n content += '#### Severity\\n';\n const severityDetails = this.extractSeverityDetails(\n vulnerability,\n affected,\n );\n\n if (severityDetails.cvssVector) {\n content += `- CVSS Score: ${severityDetails.score}\\n`;\n content += `- Vector String: \\`${severityDetails.cvssVector}\\`\\n`;\n } else {\n content += `${titleCase(severityDetails.severityLevel)}\\n`;\n }\n\n content += `\\n#### References\\n${\n vulnerability.references\n ?.map((ref) => {\n return `- [${ref.url}](${ref.url})`;\n })\n .join('\\n') ?? 'No references.'\n }`;\n\n let attribution = '';\n if (vulnerability.id.startsWith('GHSA-')) {\n attribution = ` and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md))`;\n } else if (vulnerability.id.startsWith('GO-')) {\n attribution = ` and the [Go Vulnerability Database](https://github.com/golang/vulndb) ([CC-BY 4.0](https://github.com/golang/vulndb#license))`;\n } else if (vulnerability.id.startsWith('PYSEC-')) {\n attribution = ` and the [PyPI Advisory Database](https://github.com/pypa/advisory-database) ([CC-BY 4.0](https://github.com/pypa/advisory-database/blob/main/LICENSE))`;\n } else if (vulnerability.id.startsWith('RUSTSEC-')) {\n attribution = ` and the [Rust Advisory Database](https://github.com/RustSec/advisory-db) ([CC0 1.0](https://github.com/rustsec/advisory-db/blob/main/LICENSE.txt))`;\n }\n content += `\\n\\nThis data is provided by [OSV](https://osv.dev/vulnerability/${vulnerability.id})${attribution}.\\n`;\n content += `</details>`;\n\n return [sanitizeMarkdown(content)];\n }\n\n private extractSeverityDetails(\n vulnerability: Osv.Vulnerability,\n affected: Osv.Affected,\n ): SeverityDetails {\n let severityLevel = 'UNKNOWN';\n let score = 'Unknown';\n\n const cvssVector =\n vulnerability.severity?.find((e) => e.type === 'CVSS_V4')?.score ??\n vulnerability.severity?.find((e) => e.type === 'CVSS_V3')?.score ??\n (affected.database_specific?.cvss as string); // RUSTSEC\n\n if (cvssVector) {\n const [baseScore, severity] =\n Vulnerabilities.evaluateCvssVector(cvssVector);\n severityLevel = severity ? severity.toUpperCase() : 'UNKNOWN';\n score = baseScore\n ? `${baseScore} / 10 (${titleCase(severityLevel)})`\n : 'Unknown';\n } else if (\n vulnerability.id.startsWith('GHSA-') &&\n vulnerability.database_specific?.severity\n ) {\n const severity = vulnerability.database_specific.severity as string;\n severityLevel = severity.toUpperCase();\n }\n\n return {\n cvssVector,\n score,\n severityLevel,\n };\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"vulnerabilities.js","names":["p.all","getVersioning"],"sources":["../../../../lib/workers/repository/process/vulnerabilities.ts"],"sourcesContent":["// TODO #22198\nimport type { Ecosystem, Osv } from '@renovatebot/osv-offline';\nimport { OsvOffline } from '@renovatebot/osv-offline';\nimport {\n isEmptyArray,\n isNonEmptyString,\n isNullOrUndefined,\n isTruthy,\n} from '@sindresorhus/is';\nimport type { CvssVector } from 'ae-cvss-calculator';\nimport * as _aeCvss from 'ae-cvss-calculator';\nimport { z } from 'zod/v4';\nimport { getManagerConfig, mergeChildConfig } from '../../../config/index.ts';\nimport type { PackageRule, RenovateConfig } from '../../../config/types.ts';\nimport { instrument } from '../../../instrumentation/index.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { getDefaultVersioning } from '../../../modules/datasource/common.ts';\nimport type {\n PackageDependency,\n PackageFile,\n} from '../../../modules/manager/types.ts';\nimport type { VersioningApi } from '../../../modules/versioning/index.ts';\nimport { get as getVersioning } from '../../../modules/versioning/index.ts';\nimport { sanitizeMarkdown } from '../../../util/markdown.ts';\nimport * as p from '../../../util/promises.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { titleCase } from '../../../util/string.ts';\nimport { datasourceToOsvEcosystem } from '../../../util/vulnerability/ecosystem.ts';\nimport {\n getFixedVersionConstraint,\n getLastAffectedVersionConstraint,\n} from '../../../util/vulnerability/utils.ts';\nimport type {\n DependencyVulnerabilities,\n SeverityDetails,\n Vulnerability,\n} from './types.ts';\n\nconst { fromVector } = (_aeCvss as unknown as { default: typeof _aeCvss })\n .default;\n\nexport class Vulnerabilities {\n private static osvOffline: Promise<OsvOffline> | undefined;\n\n private osvOffline: OsvOffline;\n\n private static readonly datasourceEcosystemMap = datasourceToOsvEcosystem;\n\n private constructor(osvOffline: OsvOffline) {\n this.osvOffline = osvOffline;\n }\n\n private static initialize(): Promise<OsvOffline> {\n // no async here, so osv promise will only be created once\n Vulnerabilities.osvOffline ??= OsvOffline.create();\n return Vulnerabilities.osvOffline;\n }\n\n static async create(): Promise<Vulnerabilities> {\n // intialize osv only once\n const osvOffline = await Vulnerabilities.initialize();\n\n const instance = new Vulnerabilities(osvOffline);\n return instance;\n }\n\n async appendVulnerabilityPackageRules(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n ): Promise<void> {\n const dependencyVulnerabilities = await this.fetchDependencyVulnerabilities(\n config,\n packageFiles,\n );\n\n config.packageRules ??= [];\n for (const {\n vulnerabilities,\n versioningApi,\n } of dependencyVulnerabilities) {\n const groupPackageRules: PackageRule[] = [];\n for (const vulnerability of vulnerabilities) {\n const rule = this.vulnerabilityToPackageRules(vulnerability);\n if (isNullOrUndefined(rule)) {\n continue;\n }\n groupPackageRules.push(rule);\n }\n this.sortByFixedVersion(groupPackageRules, versioningApi);\n\n config.packageRules.push(...groupPackageRules);\n }\n }\n\n async fetchVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n ): Promise<Vulnerability[]> {\n const groups = await this.fetchDependencyVulnerabilities(\n config,\n packageFiles,\n );\n return groups.flatMap((group) => group.vulnerabilities);\n }\n\n private async fetchDependencyVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n ): Promise<DependencyVulnerabilities[]> {\n const managers = Object.keys(packageFiles);\n const allManagerJobs = managers.map((manager) =>\n this.fetchManagerVulnerabilities(config, packageFiles, manager),\n );\n return (await Promise.all(allManagerJobs)).flat();\n }\n\n private async fetchManagerVulnerabilities(\n config: RenovateConfig,\n packageFiles: Record<string, PackageFile[]>,\n manager: string,\n ): Promise<DependencyVulnerabilities[]> {\n const managerConfig = getManagerConfig(config, manager);\n const queue = packageFiles[manager].map(\n (pFile) => (): Promise<DependencyVulnerabilities[]> =>\n this.fetchManagerPackageFileVulnerabilities(managerConfig, pFile),\n );\n logger.trace(\n { manager, queueLength: queue.length },\n 'fetchManagerVulnerabilities starting',\n );\n const result = (await p.all(queue)).flat();\n logger.trace({ manager }, 'fetchManagerVulnerabilities finished');\n return result;\n }\n\n private async fetchManagerPackageFileVulnerabilities(\n managerConfig: RenovateConfig,\n pFile: PackageFile,\n ): Promise<DependencyVulnerabilities[]> {\n const { packageFile } = pFile;\n const packageFileConfig = mergeChildConfig(managerConfig, pFile);\n const { manager } = packageFileConfig;\n const queue = pFile.deps.map(\n (dep) => (): Promise<DependencyVulnerabilities | null> =>\n this.fetchDependencyVulnerability(packageFileConfig, dep),\n );\n logger.trace(\n { manager, packageFile, queueLength: queue.length },\n 'fetchManagerPackageFileVulnerabilities starting with concurrency',\n );\n\n const result = await p.all(queue);\n logger.trace(\n { packageFile },\n 'fetchManagerPackageFileVulnerabilities finished',\n );\n\n return result.filter(isTruthy);\n }\n\n private async fetchDependencyVulnerability(\n packageFileConfig: RenovateConfig & PackageFile,\n dep: PackageDependency,\n ): Promise<DependencyVulnerabilities | null> {\n const ecosystem = Vulnerabilities.datasourceEcosystemMap[dep.datasource!];\n if (!ecosystem) {\n logger.trace(`Cannot map datasource ${dep.datasource!} to OSV ecosystem`);\n return null;\n }\n\n const packageName = dep.packageName ?? dep.depName!;\n let osvPackageName = packageName;\n if (ecosystem === 'PyPI') {\n // https://peps.python.org/pep-0503/#normalized-names\n osvPackageName = osvPackageName\n .toLowerCase()\n .replace(regEx(/[_.-]+/g), '-');\n } else if (ecosystem === 'Go' && packageName === 'go') {\n if (dep.depType !== 'toolchain') {\n // The `go` directive is source compatibility, not the build toolchain, so we skip it\n return null;\n }\n osvPackageName = 'stdlib';\n }\n\n try {\n const osvVulnerabilities = await instrument(\n 'get OSV vulnerabilities',\n () => this.osvOffline.getVulnerabilities(ecosystem, osvPackageName),\n {\n attributes: {\n osvPackageName,\n ecosystem,\n },\n },\n );\n if (\n isNullOrUndefined(osvVulnerabilities) ||\n isEmptyArray(osvVulnerabilities)\n ) {\n logger.trace(\n `No vulnerabilities found in OSV database for ${packageName}`,\n );\n return null;\n }\n\n const depVersion =\n dep.lockedVersion ?? dep.currentVersion ?? dep.currentValue!;\n\n const versioning = dep.versioning ?? getDefaultVersioning(dep.datasource);\n const versioningApi = getVersioning(versioning);\n\n if (!versioningApi.isVersion(depVersion)) {\n logger.debug(\n `Skipping vulnerability lookup for package ${packageName} due to unsupported version ${depVersion}`,\n );\n return null;\n }\n\n const vulnerabilities: Vulnerability[] = [];\n for (const osvVulnerability of osvVulnerabilities) {\n if (osvVulnerability.withdrawn) {\n logger.trace(\n `Skipping withdrawn vulnerability ${osvVulnerability.id}`,\n );\n continue;\n }\n\n this.skipMaliciousPackages(\n ecosystem,\n osvPackageName,\n depVersion,\n versioningApi,\n dep,\n packageFileConfig.manager,\n packageFileConfig.packageFile,\n osvVulnerability,\n );\n\n for (const affected of osvVulnerability.affected ?? []) {\n const isVulnerable = this.isPackageVulnerable(\n ecosystem,\n osvPackageName,\n depVersion,\n affected,\n versioningApi,\n );\n if (!isVulnerable) {\n continue;\n }\n\n logger.debug(\n `Vulnerability ${osvVulnerability.id} affects ${packageName} ${depVersion}`,\n );\n const fixedVersion = this.getFixedVersion(\n ecosystem,\n depVersion,\n affected,\n versioningApi,\n );\n\n vulnerabilities.push({\n packageName,\n osvPackageName,\n vulnerability: osvVulnerability,\n affected,\n depVersion,\n fixedVersion,\n datasource: dep.datasource!,\n packageFileConfig,\n });\n }\n }\n\n return { vulnerabilities, versioningApi };\n } catch (err) {\n logger.warn(\n { err, packageName },\n 'Error fetching vulnerability information for package',\n );\n return null;\n }\n }\n\n private skipMaliciousPackages(\n ecosystem: Ecosystem,\n osvPackageName: string,\n depVersion: string,\n versioningApi: VersioningApi,\n dep: PackageDependency,\n manager: string | undefined,\n packageFile: string,\n osvVulnerability: Osv.Vulnerability,\n ): void {\n // the OpenSSF's Malicious Packages (https://github.com/ossf/malicious-packages) is a source of advisories through osv.dev, which takes various sources of advisories, and will re-publish them with more specific information about their malicious usage\n if (osvVulnerability.id.startsWith('MAL-')) {\n // is the current dependency vulnerable?\n for (const affected of osvVulnerability.affected ?? []) {\n // is the current dependency vulnerable?\n const isVulnerable = this.isPackageVulnerable(\n ecosystem,\n osvPackageName,\n depVersion,\n affected,\n versioningApi,\n );\n\n if (isVulnerable) {\n logger.debug(\n {\n packageFile: packageFile,\n depName: dep.depName,\n packageName: dep.packageName,\n manager: manager,\n datasource: dep.datasource,\n currentVersion: depVersion,\n },\n `Marking ${dep.depName} as skipReason=malicious-version-in-use, as it is affected by ${osvVulnerability.id}`,\n );\n dep.skipReason = 'malicious-version-in-use';\n dep.skipStage = 'lookup';\n }\n\n // or are any of the updates vulnerable?\n for (const update of dep.updates ?? []) {\n const newVersion = update.newVersion ?? update.newValue!;\n\n const isUpdateVulnerable = this.isPackageVulnerable(\n ecosystem,\n osvPackageName,\n newVersion,\n affected,\n versioningApi,\n );\n\n if (isUpdateVulnerable) {\n logger.debug(\n {\n packageFile: packageFile,\n depName: dep.depName,\n packageName: dep.packageName,\n manager: manager,\n datasource: dep.datasource,\n currentVersion: depVersion,\n newVersion,\n },\n `Marking ${dep.depName}'s update to ${newVersion} as skipReason=malicious-update-proposed, as it is affected by ${osvVulnerability.id}`,\n );\n dep.skipReason = 'malicious-update-proposed';\n dep.skipStage = 'lookup';\n }\n }\n }\n }\n }\n\n private sortByFixedVersion(\n packageRules: PackageRule[],\n versioningApi: VersioningApi,\n ): void {\n const versionsCleaned: Record<string, string> = {};\n for (const rule of packageRules) {\n const version = rule.allowedVersions!;\n versionsCleaned[version] = version.replace(regEx(/[(),=> ]+/g), '');\n }\n packageRules.sort((a, b) =>\n versioningApi.sortVersions(\n versionsCleaned[a.allowedVersions!],\n versionsCleaned[b.allowedVersions!],\n ),\n );\n }\n\n // https://ossf.github.io/osv-schema/#affectedrangesevents-fields\n private sortEvents(\n events: Osv.Event[],\n versioningApi: VersioningApi,\n ): Osv.Event[] {\n const sortedCopy: Osv.Event[] = [];\n let zeroEvent: Osv.Event | null = null;\n\n for (const event of events) {\n if (event.introduced === '0') {\n zeroEvent = event;\n } else if (versioningApi.isVersion(Object.values(event)[0])) {\n sortedCopy.push(event);\n } else {\n logger.debug({ event }, 'Skipping OSV event with invalid version');\n }\n }\n\n sortedCopy.sort((a, b) =>\n // no pre-processing, as there are only very few values to sort\n versioningApi.sortVersions(Object.values(a)[0], Object.values(b)[0]),\n );\n\n if (zeroEvent) {\n sortedCopy.unshift(zeroEvent);\n }\n\n return sortedCopy;\n }\n\n private isPackageAffected(\n ecosystem: Ecosystem,\n osvPackageName: string,\n affected: Osv.Affected,\n ): boolean {\n return (\n affected.package?.name === osvPackageName &&\n affected.package?.ecosystem === ecosystem\n );\n }\n\n private includedInVersions(\n depVersion: string,\n affected: Osv.Affected,\n ): boolean {\n return !!affected.versions?.includes(depVersion);\n }\n\n private includedInRanges(\n depVersion: string,\n affected: Osv.Affected,\n versioningApi: VersioningApi,\n ): boolean {\n for (const range of affected.ranges ?? []) {\n if (range.type === 'GIT') {\n continue;\n }\n\n let vulnerable = false;\n for (const event of this.sortEvents(range.events, versioningApi)) {\n if (\n isNonEmptyString(event.introduced) &&\n (event.introduced === '0' ||\n this.isVersionGtOrEq(depVersion, event.introduced, versioningApi))\n ) {\n vulnerable = true;\n } else if (\n isNonEmptyString(event.fixed) &&\n this.isVersionGtOrEq(depVersion, event.fixed, versioningApi)\n ) {\n vulnerable = false;\n } else if (\n isNonEmptyString(event.last_affected) &&\n this.isVersionGt(depVersion, event.last_affected, versioningApi)\n ) {\n vulnerable = false;\n }\n }\n\n if (vulnerable) {\n return true;\n }\n }\n\n return false;\n }\n\n // https://ossf.github.io/osv-schema/#evaluation\n private isPackageVulnerable(\n ecosystem: Ecosystem,\n osvPackageName: string,\n depVersion: string,\n affected: Osv.Affected,\n versioningApi: VersioningApi,\n ): boolean {\n return (\n this.isPackageAffected(ecosystem, osvPackageName, affected) &&\n (this.includedInVersions(depVersion, affected) ||\n this.includedInRanges(depVersion, affected, versioningApi))\n );\n }\n\n private getFixedVersion(\n ecosystem: Ecosystem,\n depVersion: string,\n affected: Osv.Affected,\n versioningApi: VersioningApi,\n ): string | null {\n const fixedVersions: string[] = [];\n const lastAffectedVersions: string[] = [];\n\n for (const range of affected.ranges ?? []) {\n if (range.type === 'GIT') {\n continue;\n }\n\n for (const event of range.events) {\n if (\n isNonEmptyString(event.fixed) &&\n versioningApi.isVersion(event.fixed)\n ) {\n fixedVersions.push(event.fixed);\n } else if (\n isNonEmptyString(event.last_affected) &&\n versioningApi.isVersion(event.last_affected)\n ) {\n lastAffectedVersions.push(event.last_affected);\n }\n }\n }\n\n fixedVersions.sort((a, b) => versioningApi.sortVersions(a, b));\n const fixedVersion = fixedVersions.find((version) =>\n this.isVersionGt(version, depVersion, versioningApi),\n );\n if (fixedVersion) {\n return this.getFixedVersionByEcosystem(fixedVersion, ecosystem);\n }\n\n lastAffectedVersions.sort((a, b) => versioningApi.sortVersions(a, b));\n const lastAffected = lastAffectedVersions.find((version) =>\n this.isVersionGtOrEq(version, depVersion, versioningApi),\n );\n if (lastAffected) {\n return this.getLastAffectedByEcosystem(lastAffected, ecosystem);\n }\n\n return null;\n }\n\n private getFixedVersionByEcosystem(\n fixedVersion: string,\n ecosystem: Ecosystem,\n ): string {\n return getFixedVersionConstraint(fixedVersion, ecosystem);\n }\n\n private getLastAffectedByEcosystem(\n lastAffected: string,\n ecosystem: Ecosystem,\n ): string {\n return getLastAffectedVersionConstraint(lastAffected, ecosystem);\n }\n\n private isVersionGt(\n version: string,\n other: string,\n versioningApi: VersioningApi,\n ): boolean {\n return (\n versioningApi.isVersion(version) &&\n versioningApi.isVersion(other) &&\n versioningApi.isGreaterThan(version, other)\n );\n }\n\n private isVersionGtOrEq(\n version: string,\n other: string,\n versioningApi: VersioningApi,\n ): boolean {\n return (\n versioningApi.isVersion(version) &&\n versioningApi.isVersion(other) &&\n (versioningApi.equals(version, other) ||\n versioningApi.isGreaterThan(version, other))\n );\n }\n\n private vulnerabilityToPackageRules(vul: Vulnerability): PackageRule | null {\n const {\n vulnerability,\n affected,\n packageName,\n depVersion,\n fixedVersion,\n datasource,\n packageFileConfig,\n } = vul;\n if (isNullOrUndefined(fixedVersion)) {\n logger.debug(\n `No fixed version available for vulnerability ${vulnerability.id} in ${packageName} ${depVersion}`,\n );\n return null;\n }\n\n // we don't know if the dependency has a `versioning` applied to it already, so we have to use the default for the datasource\n const versioning = getDefaultVersioning(datasource);\n\n logger.debug(\n {\n datasource,\n versioning,\n },\n\n `Setting allowed version ${fixedVersion} to fix vulnerability ${vulnerability.id} in ${packageName} ${depVersion}`,\n );\n\n const severityDetails = this.extractSeverityDetails(\n vulnerability,\n affected,\n );\n\n return {\n matchDatasources: [datasource],\n matchPackageNames: [packageName],\n matchCurrentVersion: depVersion,\n versioning,\n allowedVersions: fixedVersion,\n isVulnerabilityAlert: true,\n vulnerabilitySeverity: severityDetails.severityLevel,\n prBodyNotes: this.generatePrBodyNotes(vulnerability, affected),\n force: {\n ...packageFileConfig.vulnerabilityAlerts,\n },\n };\n }\n\n static evaluateCvssVector(vector: string): [string, string] {\n const CvssJson = z.object({\n baseScore: z.number().default(0.0),\n baseSeverity: z.string().toUpperCase().default('UNKNOWN'),\n });\n\n try {\n const parsedCvssScore: CvssVector<any> | null = fromVector(vector);\n const res = CvssJson.parse(parsedCvssScore?.createJsonSchema());\n\n return [res.baseScore.toFixed(1), res.baseSeverity];\n } catch {\n logger.debug(`Error processing CVSS vector ${vector}`);\n }\n\n return ['', ''];\n }\n\n private generatePrBodyNotes(\n vulnerability: Osv.Vulnerability,\n affected: Osv.Affected,\n ): string[] {\n let aliases = [vulnerability.id].concat(vulnerability.aliases ?? []).sort();\n aliases = aliases.map((id) => {\n if (id.startsWith('CVE-')) {\n return `[${id}](https://nvd.nist.gov/vuln/detail/${id})`;\n }\n if (id.startsWith('GHSA-')) {\n return `[${id}](https://github.com/advisories/${id})`;\n }\n if (id.startsWith('GO-')) {\n return `[${id}](https://pkg.go.dev/vuln/${id})`;\n }\n if (id.startsWith('RUSTSEC-')) {\n return `[${id}](https://rustsec.org/advisories/${id}.html)`;\n }\n\n return id;\n });\n\n let content = '\\n\\n---\\n\\n### ';\n content += vulnerability.summary ? `${vulnerability.summary}\\n` : '';\n content += `${aliases.join(' / ')}\\n`;\n content += `\\n<details>\\n<summary>More information</summary>\\n`;\n\n const details = vulnerability.details?.replace(\n regEx(/^#{1,4} /gm),\n '##### ',\n );\n content += `#### Details\\n${details ?? 'No details.'}\\n`;\n\n content += '#### Severity\\n';\n const severityDetails = this.extractSeverityDetails(\n vulnerability,\n affected,\n );\n\n if (severityDetails.cvssVector) {\n content += `- CVSS Score: ${severityDetails.score}\\n`;\n content += `- Vector String: \\`${severityDetails.cvssVector}\\`\\n`;\n } else {\n content += `${titleCase(severityDetails.severityLevel)}\\n`;\n }\n\n content += `\\n#### References\\n${\n vulnerability.references\n ?.map((ref) => {\n return `- [${ref.url}](${ref.url})`;\n })\n .join('\\n') ?? 'No references.'\n }`;\n\n let attribution = '';\n if (vulnerability.id.startsWith('GHSA-')) {\n attribution = ` and the [GitHub Advisory Database](https://github.com/github/advisory-database) ([CC-BY 4.0](https://github.com/github/advisory-database/blob/main/LICENSE.md))`;\n } else if (vulnerability.id.startsWith('GO-')) {\n attribution = ` and the [Go Vulnerability Database](https://github.com/golang/vulndb) ([CC-BY 4.0](https://github.com/golang/vulndb#license))`;\n } else if (vulnerability.id.startsWith('PYSEC-')) {\n attribution = ` and the [PyPI Advisory Database](https://github.com/pypa/advisory-database) ([CC-BY 4.0](https://github.com/pypa/advisory-database/blob/main/LICENSE))`;\n } else if (vulnerability.id.startsWith('RUSTSEC-')) {\n attribution = ` and the [Rust Advisory Database](https://github.com/RustSec/advisory-db) ([CC0 1.0](https://github.com/rustsec/advisory-db/blob/main/LICENSE.txt))`;\n }\n content += `\\n\\nThis data is provided by [OSV](https://osv.dev/vulnerability/${vulnerability.id})${attribution}.\\n`;\n content += `</details>`;\n\n return [sanitizeMarkdown(content)];\n }\n\n private extractSeverityDetails(\n vulnerability: Osv.Vulnerability,\n affected: Osv.Affected,\n ): SeverityDetails {\n let severityLevel = 'UNKNOWN';\n let score = 'Unknown';\n\n const cvssVector =\n vulnerability.severity?.find((e) => e.type === 'CVSS_V4')?.score ??\n vulnerability.severity?.find((e) => e.type === 'CVSS_V3')?.score ??\n (affected.database_specific?.cvss as string); // RUSTSEC\n\n if (cvssVector) {\n const [baseScore, severity] =\n Vulnerabilities.evaluateCvssVector(cvssVector);\n severityLevel = severity ? severity.toUpperCase() : 'UNKNOWN';\n score = baseScore\n ? `${baseScore} / 10 (${titleCase(severityLevel)})`\n : 'Unknown';\n } else if (\n vulnerability.id.startsWith('GHSA-') &&\n vulnerability.database_specific?.severity\n ) {\n const severity = vulnerability.database_specific.severity as string;\n severityLevel = severity.toUpperCase();\n }\n\n return {\n cvssVector,\n score,\n severityLevel,\n };\n }\n}\n"],"mappings":"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"}
|
|
@@ -34,11 +34,9 @@ async function checkReconfigureBranch(config, repoConfig) {
|
|
|
34
34
|
});
|
|
35
35
|
const branchSha = getBranchCommit(reconfigureBranch);
|
|
36
36
|
const reconfigureCache = getCache().reconfigureBranchCache;
|
|
37
|
-
if (reconfigureCache?.reconfigureBranchSha === branchSha) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
37
|
+
if (reconfigureCache?.reconfigureBranchSha === branchSha && (!existingPr || reconfigureCache.extractResult)) {
|
|
38
|
+
logger.debug("Skipping validation check as branch sha is unchanged");
|
|
39
|
+
return;
|
|
42
40
|
}
|
|
43
41
|
const result = await getReconfigureConfig(reconfigureBranch);
|
|
44
42
|
if (!result.ok) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../lib/workers/repository/reconfigure/index.ts"],"sourcesContent":["import { GlobalConfig } from '../../../config/global.ts';\nimport { applySecretsAndVariablesToConfig } from '../../../config/secrets.ts';\nimport type { AllConfig, RenovateConfig } from '../../../config/types.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { platform } from '../../../modules/platform/index.ts';\nimport { scm } from '../../../modules/platform/scm.ts';\nimport { getCache } from '../../../util/cache/repository/index.ts';\nimport { getBranchCommit } from '../../../util/git/index.ts';\nimport { mergeInheritedConfig } from '../init/inherited.ts';\nimport { mergeRenovateConfig } from '../init/merge.ts';\nimport type { ExtractResult } from '../process/extract-update.ts';\nimport { extractDependencies } from '../process/index.ts';\nimport { ensureReconfigurePrComment } from './comment.ts';\nimport {\n deleteReconfigureBranchCache,\n setReconfigureBranchCache,\n} from './reconfigure-cache.ts';\nimport {\n getReconfigureBranchName,\n getReconfigureConfig,\n setBranchStatus,\n} from './utils.ts';\nimport { validateReconfigureBranch } from './validate.ts';\n\nexport async function checkReconfigureBranch(\n config: RenovateConfig,\n repoConfig: AllConfig,\n): Promise<void> {\n logger.debug('checkReconfigureBranch()');\n if (GlobalConfig.get('platform') === 'local') {\n logger.debug(\n 'Not attempting to reconfigure when running with local platform',\n );\n return;\n }\n\n const context = config.statusCheckNames?.configValidation;\n const reconfigureBranch = getReconfigureBranchName(config.branchPrefix!);\n const branchExists = await scm.branchExists(reconfigureBranch);\n\n // this is something the user initiates, skip if no branch exists\n if (!branchExists) {\n logger.debug({ reconfigureBranch }, 'No reconfigure branch found');\n deleteReconfigureBranchCache(); // in order to remove cache when the branch has been deleted\n return;\n }\n\n const existingPr = await platform.findPr({\n branchName: reconfigureBranch,\n state: 'open',\n includeOtherAuthors: true,\n targetBranch: config.defaultBranch,\n });\n const branchSha = getBranchCommit(reconfigureBranch)!;\n const cache = getCache();\n const reconfigureCache = cache.reconfigureBranchCache;\n\n // only use valid cached information\n if (reconfigureCache?.reconfigureBranchSha === branchSha
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../lib/workers/repository/reconfigure/index.ts"],"sourcesContent":["import { GlobalConfig } from '../../../config/global.ts';\nimport { applySecretsAndVariablesToConfig } from '../../../config/secrets.ts';\nimport type { AllConfig, RenovateConfig } from '../../../config/types.ts';\nimport { logger } from '../../../logger/index.ts';\nimport { platform } from '../../../modules/platform/index.ts';\nimport { scm } from '../../../modules/platform/scm.ts';\nimport { getCache } from '../../../util/cache/repository/index.ts';\nimport { getBranchCommit } from '../../../util/git/index.ts';\nimport { mergeInheritedConfig } from '../init/inherited.ts';\nimport { mergeRenovateConfig } from '../init/merge.ts';\nimport type { ExtractResult } from '../process/extract-update.ts';\nimport { extractDependencies } from '../process/index.ts';\nimport { ensureReconfigurePrComment } from './comment.ts';\nimport {\n deleteReconfigureBranchCache,\n setReconfigureBranchCache,\n} from './reconfigure-cache.ts';\nimport {\n getReconfigureBranchName,\n getReconfigureConfig,\n setBranchStatus,\n} from './utils.ts';\nimport { validateReconfigureBranch } from './validate.ts';\n\nexport async function checkReconfigureBranch(\n config: RenovateConfig,\n repoConfig: AllConfig,\n): Promise<void> {\n logger.debug('checkReconfigureBranch()');\n if (GlobalConfig.get('platform') === 'local') {\n logger.debug(\n 'Not attempting to reconfigure when running with local platform',\n );\n return;\n }\n\n const context = config.statusCheckNames?.configValidation;\n const reconfigureBranch = getReconfigureBranchName(config.branchPrefix!);\n const branchExists = await scm.branchExists(reconfigureBranch);\n\n // this is something the user initiates, skip if no branch exists\n if (!branchExists) {\n logger.debug({ reconfigureBranch }, 'No reconfigure branch found');\n deleteReconfigureBranchCache(); // in order to remove cache when the branch has been deleted\n return;\n }\n\n const existingPr = await platform.findPr({\n branchName: reconfigureBranch,\n state: 'open',\n includeOtherAuthors: true,\n targetBranch: config.defaultBranch,\n });\n const branchSha = getBranchCommit(reconfigureBranch)!;\n const cache = getCache();\n const reconfigureCache = cache.reconfigureBranchCache;\n\n // only use valid cached information\n if (\n reconfigureCache?.reconfigureBranchSha === branchSha &&\n (!existingPr || reconfigureCache.extractResult)\n ) {\n logger.debug('Skipping validation check as branch sha is unchanged');\n return;\n }\n\n const result = await getReconfigureConfig(reconfigureBranch);\n\n if (!result.ok) {\n await setBranchStatus(reconfigureBranch, result.errMessage, 'red', context);\n setReconfigureBranchCache(branchSha, false);\n await scm.checkoutBranch(config.defaultBranch!);\n return;\n }\n\n const isValidConfig = await validateReconfigureBranch(\n config,\n result.config,\n result.configFileName,\n existingPr,\n );\n\n if (!isValidConfig) {\n logger.debug(\n 'Found errors in reconfigure config. Skipping dependencies extraction',\n );\n await scm.checkoutBranch(config.defaultBranch!);\n return;\n }\n\n if (!existingPr) {\n logger.debug('No reconfigure pr found. Skipping dependencies extraction');\n await scm.checkoutBranch(config.defaultBranch!);\n return;\n }\n\n let extractResult: ExtractResult | undefined;\n // Recompute config similar to repo config processing\n // Get non-global config from file config\n // Merge it with inherited and static repo config\n // Finally, merge the reconfigure config\n let newConfig = GlobalConfig.set(\n applySecretsAndVariablesToConfig({\n config: repoConfig,\n }),\n );\n newConfig.baseBranch = config.defaultBranch;\n newConfig.repoIsOnboarded = true;\n newConfig.errors = [];\n newConfig.warnings = [];\n\n try {\n newConfig = await mergeInheritedConfig(newConfig);\n newConfig = await mergeRenovateConfig(newConfig, reconfigureBranch);\n await scm.checkoutBranch(config.defaultBranch!);\n extractResult = await extractDependencies(newConfig, false);\n } catch (err) {\n logger.debug(\n { err },\n 'Error while extracting dependencies using the reconfigure config',\n );\n setReconfigureBranchCache(branchSha, true);\n await scm.checkoutBranch(config.defaultBranch!); // being cautious\n return;\n }\n\n let commentEnsured = false;\n if (extractResult) {\n commentEnsured = await ensureReconfigurePrComment(\n newConfig,\n extractResult.packageFiles,\n extractResult.branches,\n reconfigureBranch,\n existingPr,\n );\n }\n\n // if comment is not added or updated\n // do not store extractResult in cache so that we re-process the reconfigure branch on next run and do not skip\n // istanbul ignore if: should rarely happen\n if (!commentEnsured) {\n extractResult = undefined;\n }\n await setBranchStatus(\n reconfigureBranch,\n 'Validation Successful',\n 'green',\n context,\n );\n setReconfigureBranchCache(branchSha, true, extractResult);\n await scm.checkoutBranch(config.defaultBranch!); //being cautious\n}\n"],"mappings":";;;;;;;;;;;;;;;AAwBA,eAAsB,uBACpB,QACA,YACe;CACf,OAAO,MAAM,0BAA0B;CACvC,IAAI,aAAa,IAAI,UAAU,MAAM,SAAS;EAC5C,OAAO,MACL,gEACF;EACA;CACF;CAEA,MAAM,UAAU,OAAO,kBAAkB;CACzC,MAAM,oBAAoB,yBAAyB,OAAO,YAAa;CAIvE,IAAI,CAAC,MAHsB,IAAI,aAAa,iBAAiB,GAG1C;EACjB,OAAO,MAAM,EAAE,kBAAkB,GAAG,6BAA6B;EACjE,6BAA6B;EAC7B;CACF;CAEA,MAAM,aAAa,MAAM,SAAS,OAAO;EACvC,YAAY;EACZ,OAAO;EACP,qBAAqB;EACrB,cAAc,OAAO;CACvB,CAAC;CACD,MAAM,YAAY,gBAAgB,iBAAiB;CAEnD,MAAM,mBADQ,SACe,CAAC,CAAC;CAG/B,IACE,kBAAkB,yBAAyB,cAC1C,CAAC,cAAc,iBAAiB,gBACjC;EACA,OAAO,MAAM,sDAAsD;EACnE;CACF;CAEA,MAAM,SAAS,MAAM,qBAAqB,iBAAiB;CAE3D,IAAI,CAAC,OAAO,IAAI;EACd,MAAM,gBAAgB,mBAAmB,OAAO,YAAY,OAAO,OAAO;EAC1E,0BAA0B,WAAW,KAAK;EAC1C,MAAM,IAAI,eAAe,OAAO,aAAc;EAC9C;CACF;CASA,IAAI,CAAC,MAPuB,0BAC1B,QACA,OAAO,QACP,OAAO,gBACP,UACF,GAEoB;EAClB,OAAO,MACL,sEACF;EACA,MAAM,IAAI,eAAe,OAAO,aAAc;EAC9C;CACF;CAEA,IAAI,CAAC,YAAY;EACf,OAAO,MAAM,2DAA2D;EACxE,MAAM,IAAI,eAAe,OAAO,aAAc;EAC9C;CACF;CAEA,IAAI;CAKJ,IAAI,YAAY,aAAa,IAC3B,iCAAiC,EAC/B,QAAQ,WACV,CAAC,CACH;CACA,UAAU,aAAa,OAAO;CAC9B,UAAU,kBAAkB;CAC5B,UAAU,SAAS,CAAC;CACpB,UAAU,WAAW,CAAC;CAEtB,IAAI;EACF,YAAY,MAAM,qBAAqB,SAAS;EAChD,YAAY,MAAM,oBAAoB,WAAW,iBAAiB;EAClE,MAAM,IAAI,eAAe,OAAO,aAAc;EAC9C,gBAAgB,MAAM,oBAAoB,WAAW,KAAK;CAC5D,SAAS,KAAK;EACZ,OAAO,MACL,EAAE,IAAI,GACN,kEACF;EACA,0BAA0B,WAAW,IAAI;EACzC,MAAM,IAAI,eAAe,OAAO,aAAc;EAC9C;CACF;CAEA,IAAI,iBAAiB;CACrB,IAAI,eACF,iBAAiB,MAAM,2BACrB,WACA,cAAc,cACd,cAAc,UACd,mBACA,UACF;;CAMF,IAAI,CAAC,gBACH,gBAAgB,KAAA;CAElB,MAAM,gBACJ,mBACA,yBACA,SACA,OACF;CACA,0BAA0B,WAAW,MAAM,aAAa;CACxD,MAAM,IAAI,eAAe,OAAO,aAAc;AAChD"}
|
|
@@ -162,7 +162,7 @@ async function getFileContent(bumpVersionsDescr, filePath, packageFiles, artifac
|
|
|
162
162
|
function parseFileChanges(filePath, changeRecord) {
|
|
163
163
|
const changes = coerceArray(changeRecord[filePath]);
|
|
164
164
|
if (!changes.length) return { state: "unmodified" };
|
|
165
|
-
const lastChange = changes
|
|
165
|
+
const lastChange = changes.at(-1);
|
|
166
166
|
if (lastChange.type === "deletion") return { state: "deleted" };
|
|
167
167
|
return {
|
|
168
168
|
state: "modified",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bump-versions.js","names":[],"sources":["../../../../../lib/workers/repository/update/branch/bump-versions.ts"],"sourcesContent":["import { type ReleaseType, inc } from 'semver';\nimport type { BumpVersionConfig } from '../../../../config/types.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport { scm } from '../../../../modules/platform/scm.ts';\nimport { coerceArray } from '../../../../util/array.ts';\nimport { readLocalFile } from '../../../../util/fs/index.ts';\nimport type { FileChange } from '../../../../util/git/types.ts';\nimport { regEx } from '../../../../util/regex.ts';\nimport { matchRegexOrGlobList } from '../../../../util/string-match.ts';\nimport { compile } from '../../../../util/template/index.ts';\nimport type { BranchConfig } from '../../../types.ts';\nimport { getFilteredFileList } from '../../extract/file-match.ts';\n\ntype ParseFileChangesResult =\n | { state: 'modified'; content: string | null }\n | { state: 'deleted' }\n | { state: 'unmodified' };\n\nexport async function bumpVersions(config: BranchConfig): Promise<void> {\n const bumpVersions = config.bumpVersions;\n if (!bumpVersions?.length) {\n return;\n }\n\n // skip if no packageFiles or artifacts have been updated\n if (!config.updatedPackageFiles?.length && !config.updatedArtifacts?.length) {\n return;\n }\n\n const allFiles = await scm.getFileList();\n const fileList = getFilteredFileList(config, allFiles);\n\n const packageFileChanges = fileChangeListToMap(config.updatedPackageFiles);\n const artifactFileChanges = fileChangeListToMap(config.updatedArtifacts);\n\n for (const bumpVersionConfig of bumpVersions) {\n await bumpVersion(\n bumpVersionConfig,\n config,\n fileList,\n packageFileChanges,\n artifactFileChanges,\n );\n }\n\n // update the config with the new files\n config.updatedPackageFiles = Object.values(packageFileChanges).flat();\n config.updatedArtifacts = Object.values(artifactFileChanges).flat();\n}\n\nasync function bumpVersion(\n config: BumpVersionConfig,\n branchConfig: BranchConfig,\n fileList: string[],\n packageFiles: Record<string, FileChange[]>,\n artifactFiles: Record<string, FileChange[]>,\n): Promise<void> {\n const rawBumpType = config.bumpType ?? 'patch';\n\n // all log messages should be prefixed with this string to facilitate easier logLevelRemapping\n const bumpVersionsDescr = config.name\n ? `bumpVersions(${config.name})`\n : 'bumpVersions';\n\n const files: string[] = [];\n try {\n files.push(\n ...getMatchedFiles(\n bumpVersionsDescr,\n config.filePatterns,\n branchConfig,\n fileList,\n ),\n );\n } catch (e) {\n addArtifactError(\n branchConfig,\n `Failed to calculate matched files for bumpVersions: ${e.message}`,\n );\n return;\n }\n\n if (!files.length) {\n logger.debug(`${bumpVersionsDescr}: filePatterns did not match any files`);\n return;\n }\n\n logger.trace(\n { files },\n `${bumpVersionsDescr}: Found ${files.length} files to bump versions`,\n );\n\n // keeping this only for logging purposes\n const matchStrings: string[] = [];\n\n // prepare the matchStrings\n const matchStringsRegexes: RegExp[] = [];\n for (const matchString of config.matchStrings) {\n try {\n const templated = compile(matchString, branchConfig);\n matchStrings.push(templated);\n matchStringsRegexes.push(regEx(templated));\n } catch (e) {\n addArtifactError(\n branchConfig,\n `Failed to compile matchString for ${bumpVersionsDescr}: ${e.message}`,\n matchString,\n );\n }\n }\n\n logger.trace({ matchStrings }, `${bumpVersionsDescr}: Compiled matchStrings`);\n\n for (const filePath of files) {\n let fileBumped = false;\n\n const fileContents = await getFileContent(\n bumpVersionsDescr,\n filePath,\n packageFiles,\n artifactFiles,\n );\n if (!fileContents) {\n continue;\n }\n\n for (const matchStringRegex of matchStringsRegexes) {\n // extracting the version from the file\n const regexResult = matchStringRegex.exec(fileContents);\n if (!regexResult) {\n continue;\n }\n const version = regexResult.groups?.version;\n if (!version) {\n logger.debug(\n { file: filePath },\n `${bumpVersionsDescr}: No version found`,\n );\n continue;\n }\n\n // getting new version\n let newVersion: string | null = null;\n try {\n const bumpType = compile(rawBumpType, branchConfig);\n\n // Handle 'sync' type - use version from branch upgrades\n if (bumpType === 'sync') {\n if (branchConfig.upgrades?.length) {\n // Use the newVersion from the first upgrade\n newVersion = branchConfig.upgrades[0].newVersion ?? null;\n if (!newVersion) {\n logger.debug(\n { file: filePath },\n `${bumpVersionsDescr}: No newVersion found in branch upgrades for sync type`,\n );\n continue;\n }\n } else {\n logger.debug(\n { file: filePath },\n `${bumpVersionsDescr}: No upgrades found in branch config for sync type`,\n );\n continue;\n }\n } else {\n // Existing logic for major/minor/patch\n const parts = regEx('^(?<major>\\\\d+)(?:\\\\.(?<minor>\\\\d+))?$').exec(\n version,\n );\n if (parts?.groups) {\n const { major, minor } = parts.groups;\n if (bumpType === 'major') {\n newVersion = `${parseInt(major, 10) + 1}${minor ? `.0` : ''}`;\n } else if (bumpType === 'minor') {\n newVersion = `${major}.${parseInt(minor, 10) + 1}`;\n } else {\n throw new Error(\n `Unsupported bump type for {major}.{minor} version: ${bumpType}`,\n );\n }\n } else {\n newVersion = inc(version, bumpType as ReleaseType);\n }\n }\n } catch (e) {\n addArtifactError(\n branchConfig,\n `Failed to calculate new version for ${bumpVersionsDescr}: ${e.message}`,\n filePath,\n );\n }\n if (!newVersion) {\n logger.debug(\n { file: filePath },\n `${bumpVersionsDescr}: Could not bump version`,\n );\n continue;\n }\n\n // replace the content of the `version` group with newVersion\n const newFileContents: string = fileContents\n .toString()\n .replace(matchStringRegex, (match, ...groups) => {\n const { version } = groups.pop();\n return match.replace(version, newVersion);\n });\n\n // update the file. Add it to the buckets if exists or create a new artifact update\n if (packageFiles[filePath]) {\n packageFiles[filePath].push({\n type: 'addition',\n path: filePath,\n contents: newFileContents,\n });\n } else {\n artifactFiles[filePath] ??= [];\n artifactFiles[filePath].push({\n type: 'addition',\n path: filePath,\n contents: newFileContents,\n });\n }\n\n fileBumped = true;\n }\n\n if (!fileBumped) {\n logger.debug(\n { file: filePath },\n `${bumpVersionsDescr}: No match found for bumping version`,\n );\n }\n }\n}\n\n/**\n * Get files that match ANY of the fileMatches pattern. fileMatches are compiled with the branchConfig.\n * @param bumpVersionsDescr log description for the bump version config\n * @param filePatternTemplates list of regex patterns\n * @param branchConfig compile metadata\n * @param fileList list of files to match against\n */\nfunction getMatchedFiles(\n bumpVersionsDescr: string,\n filePatternTemplates: string[],\n branchConfig: BranchConfig,\n fileList: string[],\n): string[] {\n // prepare file regex\n const filePatterns: string[] = [];\n for (const filePatternTemplateElement of filePatternTemplates) {\n const filePattern = compile(filePatternTemplateElement, branchConfig);\n filePatterns.push(filePattern);\n }\n\n logger.trace({ filePatterns }, `${bumpVersionsDescr}: Compiled filePatterns`);\n\n // get files that match the fileMatch\n const files: string[] = [];\n for (const file of fileList) {\n if (matchRegexOrGlobList(file, filePatterns)) {\n files.push(file);\n }\n }\n return files;\n}\n\nfunction fileChangeListToMap(\n list: FileChange[] | undefined,\n): Record<string, FileChange[]> {\n const record: Record<string, FileChange[]> = {};\n for (const fileChange of coerceArray(list)) {\n record[fileChange.path] ??= [];\n record[fileChange.path].push(fileChange);\n }\n return record;\n}\n\nfunction addArtifactError(\n branchConfig: BranchConfig,\n message: string,\n fileName?: string,\n): void {\n branchConfig.artifactErrors ??= [];\n branchConfig.artifactErrors.push({\n stderr: message,\n fileName,\n });\n}\n\nasync function getFileContent(\n bumpVersionsDescr: string,\n filePath: string,\n packageFiles: Record<string, FileChange[]>,\n artifactFiles: Record<string, FileChange[]>,\n): Promise<string | null> {\n const packageFileChanges = parseFileChanges(filePath, packageFiles);\n const artifactFileChanges = parseFileChanges(filePath, artifactFiles);\n\n // skip if the file is deleted as it virtually doesn't exist\n if (\n packageFileChanges.state === 'deleted' ||\n artifactFileChanges.state === 'deleted'\n ) {\n return null;\n }\n\n if (packageFileChanges.state === 'modified') {\n const lastChange = packageFileChanges.content;\n if (lastChange) {\n return lastChange;\n }\n }\n if (artifactFileChanges.state === 'modified') {\n const lastChange = artifactFileChanges.content;\n if (lastChange) {\n return lastChange;\n }\n }\n\n try {\n return await readLocalFile(filePath, 'utf8');\n } catch (e) {\n logger.warn(\n { file: filePath },\n `${bumpVersionsDescr}: Could not read file: ${e.message}`,\n );\n return null;\n }\n}\n\nfunction parseFileChanges(\n filePath: string,\n changeRecord: Record<string, FileChange[]>,\n): ParseFileChangesResult {\n const changes = coerceArray(changeRecord[filePath]);\n\n // skip if we can fetch from record\n if (!changes.length) {\n return { state: 'unmodified' };\n }\n\n const lastChange = changes[changes.length - 1];\n if (lastChange.type === 'deletion') {\n return { state: 'deleted' };\n }\n return {\n state: 'modified',\n content: lastChange.contents?.toString() ?? null,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bump-versions.js","names":[],"sources":["../../../../../lib/workers/repository/update/branch/bump-versions.ts"],"sourcesContent":["import { type ReleaseType, inc } from 'semver';\nimport type { BumpVersionConfig } from '../../../../config/types.ts';\nimport { logger } from '../../../../logger/index.ts';\nimport { scm } from '../../../../modules/platform/scm.ts';\nimport { coerceArray } from '../../../../util/array.ts';\nimport { readLocalFile } from '../../../../util/fs/index.ts';\nimport type { FileChange } from '../../../../util/git/types.ts';\nimport { regEx } from '../../../../util/regex.ts';\nimport { matchRegexOrGlobList } from '../../../../util/string-match.ts';\nimport { compile } from '../../../../util/template/index.ts';\nimport type { BranchConfig } from '../../../types.ts';\nimport { getFilteredFileList } from '../../extract/file-match.ts';\n\ntype ParseFileChangesResult =\n | { state: 'modified'; content: string | null }\n | { state: 'deleted' }\n | { state: 'unmodified' };\n\nexport async function bumpVersions(config: BranchConfig): Promise<void> {\n const bumpVersions = config.bumpVersions;\n if (!bumpVersions?.length) {\n return;\n }\n\n // skip if no packageFiles or artifacts have been updated\n if (!config.updatedPackageFiles?.length && !config.updatedArtifacts?.length) {\n return;\n }\n\n const allFiles = await scm.getFileList();\n const fileList = getFilteredFileList(config, allFiles);\n\n const packageFileChanges = fileChangeListToMap(config.updatedPackageFiles);\n const artifactFileChanges = fileChangeListToMap(config.updatedArtifacts);\n\n for (const bumpVersionConfig of bumpVersions) {\n await bumpVersion(\n bumpVersionConfig,\n config,\n fileList,\n packageFileChanges,\n artifactFileChanges,\n );\n }\n\n // update the config with the new files\n config.updatedPackageFiles = Object.values(packageFileChanges).flat();\n config.updatedArtifacts = Object.values(artifactFileChanges).flat();\n}\n\nasync function bumpVersion(\n config: BumpVersionConfig,\n branchConfig: BranchConfig,\n fileList: string[],\n packageFiles: Record<string, FileChange[]>,\n artifactFiles: Record<string, FileChange[]>,\n): Promise<void> {\n const rawBumpType = config.bumpType ?? 'patch';\n\n // all log messages should be prefixed with this string to facilitate easier logLevelRemapping\n const bumpVersionsDescr = config.name\n ? `bumpVersions(${config.name})`\n : 'bumpVersions';\n\n const files: string[] = [];\n try {\n files.push(\n ...getMatchedFiles(\n bumpVersionsDescr,\n config.filePatterns,\n branchConfig,\n fileList,\n ),\n );\n } catch (e) {\n addArtifactError(\n branchConfig,\n `Failed to calculate matched files for bumpVersions: ${e.message}`,\n );\n return;\n }\n\n if (!files.length) {\n logger.debug(`${bumpVersionsDescr}: filePatterns did not match any files`);\n return;\n }\n\n logger.trace(\n { files },\n `${bumpVersionsDescr}: Found ${files.length} files to bump versions`,\n );\n\n // keeping this only for logging purposes\n const matchStrings: string[] = [];\n\n // prepare the matchStrings\n const matchStringsRegexes: RegExp[] = [];\n for (const matchString of config.matchStrings) {\n try {\n const templated = compile(matchString, branchConfig);\n matchStrings.push(templated);\n matchStringsRegexes.push(regEx(templated));\n } catch (e) {\n addArtifactError(\n branchConfig,\n `Failed to compile matchString for ${bumpVersionsDescr}: ${e.message}`,\n matchString,\n );\n }\n }\n\n logger.trace({ matchStrings }, `${bumpVersionsDescr}: Compiled matchStrings`);\n\n for (const filePath of files) {\n let fileBumped = false;\n\n const fileContents = await getFileContent(\n bumpVersionsDescr,\n filePath,\n packageFiles,\n artifactFiles,\n );\n if (!fileContents) {\n continue;\n }\n\n for (const matchStringRegex of matchStringsRegexes) {\n // extracting the version from the file\n const regexResult = matchStringRegex.exec(fileContents);\n if (!regexResult) {\n continue;\n }\n const version = regexResult.groups?.version;\n if (!version) {\n logger.debug(\n { file: filePath },\n `${bumpVersionsDescr}: No version found`,\n );\n continue;\n }\n\n // getting new version\n let newVersion: string | null = null;\n try {\n const bumpType = compile(rawBumpType, branchConfig);\n\n // Handle 'sync' type - use version from branch upgrades\n if (bumpType === 'sync') {\n if (branchConfig.upgrades?.length) {\n // Use the newVersion from the first upgrade\n newVersion = branchConfig.upgrades[0].newVersion ?? null;\n if (!newVersion) {\n logger.debug(\n { file: filePath },\n `${bumpVersionsDescr}: No newVersion found in branch upgrades for sync type`,\n );\n continue;\n }\n } else {\n logger.debug(\n { file: filePath },\n `${bumpVersionsDescr}: No upgrades found in branch config for sync type`,\n );\n continue;\n }\n } else {\n // Existing logic for major/minor/patch\n const parts = regEx('^(?<major>\\\\d+)(?:\\\\.(?<minor>\\\\d+))?$').exec(\n version,\n );\n if (parts?.groups) {\n const { major, minor } = parts.groups;\n if (bumpType === 'major') {\n newVersion = `${parseInt(major, 10) + 1}${minor ? `.0` : ''}`;\n } else if (bumpType === 'minor') {\n newVersion = `${major}.${parseInt(minor, 10) + 1}`;\n } else {\n throw new Error(\n `Unsupported bump type for {major}.{minor} version: ${bumpType}`,\n );\n }\n } else {\n newVersion = inc(version, bumpType as ReleaseType);\n }\n }\n } catch (e) {\n addArtifactError(\n branchConfig,\n `Failed to calculate new version for ${bumpVersionsDescr}: ${e.message}`,\n filePath,\n );\n }\n if (!newVersion) {\n logger.debug(\n { file: filePath },\n `${bumpVersionsDescr}: Could not bump version`,\n );\n continue;\n }\n\n // replace the content of the `version` group with newVersion\n const newFileContents: string = fileContents\n .toString()\n .replace(matchStringRegex, (match, ...groups) => {\n const { version } = groups.pop();\n return match.replace(version, newVersion);\n });\n\n // update the file. Add it to the buckets if exists or create a new artifact update\n if (packageFiles[filePath]) {\n packageFiles[filePath].push({\n type: 'addition',\n path: filePath,\n contents: newFileContents,\n });\n } else {\n artifactFiles[filePath] ??= [];\n artifactFiles[filePath].push({\n type: 'addition',\n path: filePath,\n contents: newFileContents,\n });\n }\n\n fileBumped = true;\n }\n\n if (!fileBumped) {\n logger.debug(\n { file: filePath },\n `${bumpVersionsDescr}: No match found for bumping version`,\n );\n }\n }\n}\n\n/**\n * Get files that match ANY of the fileMatches pattern. fileMatches are compiled with the branchConfig.\n * @param bumpVersionsDescr log description for the bump version config\n * @param filePatternTemplates list of regex patterns\n * @param branchConfig compile metadata\n * @param fileList list of files to match against\n */\nfunction getMatchedFiles(\n bumpVersionsDescr: string,\n filePatternTemplates: string[],\n branchConfig: BranchConfig,\n fileList: string[],\n): string[] {\n // prepare file regex\n const filePatterns: string[] = [];\n for (const filePatternTemplateElement of filePatternTemplates) {\n const filePattern = compile(filePatternTemplateElement, branchConfig);\n filePatterns.push(filePattern);\n }\n\n logger.trace({ filePatterns }, `${bumpVersionsDescr}: Compiled filePatterns`);\n\n // get files that match the fileMatch\n const files: string[] = [];\n for (const file of fileList) {\n if (matchRegexOrGlobList(file, filePatterns)) {\n files.push(file);\n }\n }\n return files;\n}\n\nfunction fileChangeListToMap(\n list: FileChange[] | undefined,\n): Record<string, FileChange[]> {\n const record: Record<string, FileChange[]> = {};\n for (const fileChange of coerceArray(list)) {\n record[fileChange.path] ??= [];\n record[fileChange.path].push(fileChange);\n }\n return record;\n}\n\nfunction addArtifactError(\n branchConfig: BranchConfig,\n message: string,\n fileName?: string,\n): void {\n branchConfig.artifactErrors ??= [];\n branchConfig.artifactErrors.push({\n stderr: message,\n fileName,\n });\n}\n\nasync function getFileContent(\n bumpVersionsDescr: string,\n filePath: string,\n packageFiles: Record<string, FileChange[]>,\n artifactFiles: Record<string, FileChange[]>,\n): Promise<string | null> {\n const packageFileChanges = parseFileChanges(filePath, packageFiles);\n const artifactFileChanges = parseFileChanges(filePath, artifactFiles);\n\n // skip if the file is deleted as it virtually doesn't exist\n if (\n packageFileChanges.state === 'deleted' ||\n artifactFileChanges.state === 'deleted'\n ) {\n return null;\n }\n\n if (packageFileChanges.state === 'modified') {\n const lastChange = packageFileChanges.content;\n if (lastChange) {\n return lastChange;\n }\n }\n if (artifactFileChanges.state === 'modified') {\n const lastChange = artifactFileChanges.content;\n if (lastChange) {\n return lastChange;\n }\n }\n\n try {\n return await readLocalFile(filePath, 'utf8');\n } catch (e) {\n logger.warn(\n { file: filePath },\n `${bumpVersionsDescr}: Could not read file: ${e.message}`,\n );\n return null;\n }\n}\n\nfunction parseFileChanges(\n filePath: string,\n changeRecord: Record<string, FileChange[]>,\n): ParseFileChangesResult {\n const changes = coerceArray(changeRecord[filePath]);\n\n // skip if we can fetch from record\n if (!changes.length) {\n return { state: 'unmodified' };\n }\n\n const lastChange = changes.at(-1)!;\n if (lastChange.type === 'deletion') {\n return { state: 'deleted' };\n }\n return {\n state: 'modified',\n content: lastChange.contents?.toString() ?? null,\n };\n}\n"],"mappings":"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"}
|