renovate 44.210.2 → 44.211.0
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/options/index.js +1 -1
- package/dist/config/options/index.js.map +1 -1
- package/dist/config/utils.js +2 -1
- package/dist/config/utils.js.map +1 -1
- package/dist/config/validation-helpers/regex-glob-matchers.js.map +1 -1
- package/dist/config/validation-helpers/utils.js +5 -1
- package/dist/config/validation-helpers/utils.js.map +1 -1
- package/dist/config/validation.js +8 -2
- package/dist/config/validation.js.map +1 -1
- package/dist/config-validator.js +1 -1
- 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/instrumentation/index.js +3 -2
- package/dist/instrumentation/index.js.map +1 -1
- package/dist/logger/bunyan.js +3 -2
- package/dist/logger/bunyan.js.map +1 -1
- package/dist/logger/pretty-stdout.js +2 -1
- package/dist/logger/pretty-stdout.js.map +1 -1
- package/dist/modules/datasource/apk/index.js +2 -2
- package/dist/modules/datasource/apk/index.js.map +1 -1
- package/dist/modules/datasource/artifactory/index.js +2 -3
- package/dist/modules/datasource/artifactory/index.js.map +1 -1
- package/dist/modules/datasource/bazel/index.js +2 -1
- package/dist/modules/datasource/bazel/index.js.map +1 -1
- package/dist/modules/datasource/cdnjs/index.js +2 -1
- package/dist/modules/datasource/cdnjs/index.js.map +1 -1
- package/dist/modules/datasource/conda/index.js +2 -1
- package/dist/modules/datasource/conda/index.js.map +1 -1
- package/dist/modules/datasource/crate/index.js +2 -1
- package/dist/modules/datasource/crate/index.js.map +1 -1
- package/dist/modules/datasource/dart-version/index.js +2 -1
- package/dist/modules/datasource/dart-version/index.js.map +1 -1
- package/dist/modules/datasource/datasource.js +2 -2
- package/dist/modules/datasource/datasource.js.map +1 -1
- package/dist/modules/datasource/deb/url.js +3 -1
- package/dist/modules/datasource/deb/url.js.map +1 -1
- package/dist/modules/datasource/devbox/index.js +2 -1
- package/dist/modules/datasource/devbox/index.js.map +1 -1
- package/dist/modules/datasource/docker/common.js +10 -8
- package/dist/modules/datasource/docker/common.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 +20 -17
- package/dist/modules/datasource/docker/index.js.map +1 -1
- package/dist/modules/datasource/gitea-tags/base.js +2 -3
- package/dist/modules/datasource/gitea-tags/base.js.map +1 -1
- package/dist/modules/datasource/github-tags/index.js +2 -1
- package/dist/modules/datasource/github-tags/index.js.map +1 -1
- package/dist/modules/datasource/gitlab-tags/index.js +2 -3
- package/dist/modules/datasource/gitlab-tags/index.js.map +1 -1
- package/dist/modules/datasource/go/base.js +1 -1
- package/dist/modules/datasource/go/base.js.map +1 -1
- package/dist/modules/datasource/go/common.js +8 -2
- package/dist/modules/datasource/go/common.js.map +1 -1
- package/dist/modules/datasource/go/env.js +2 -1
- package/dist/modules/datasource/go/env.js.map +1 -1
- package/dist/modules/datasource/go/releases-goproxy.js +7 -5
- package/dist/modules/datasource/go/releases-goproxy.js.map +1 -1
- package/dist/modules/datasource/helm/index.js +2 -1
- package/dist/modules/datasource/helm/index.js.map +1 -1
- package/dist/modules/datasource/hexpm-bob/index.js +2 -1
- package/dist/modules/datasource/hexpm-bob/index.js.map +1 -1
- package/dist/modules/datasource/index.js +4 -3
- package/dist/modules/datasource/index.js.map +1 -1
- package/dist/modules/datasource/java-version/adoptium.js +3 -2
- package/dist/modules/datasource/java-version/adoptium.js.map +1 -1
- package/dist/modules/datasource/java-version/graalvm.js +2 -1
- package/dist/modules/datasource/java-version/graalvm.js.map +1 -1
- package/dist/modules/datasource/maven/index.js.map +1 -1
- package/dist/modules/datasource/maven/util.js +7 -10
- package/dist/modules/datasource/maven/util.js.map +1 -1
- package/dist/modules/datasource/npm/npmrc.js +2 -2
- package/dist/modules/datasource/npm/npmrc.js.map +1 -1
- package/dist/modules/datasource/nuget/v3.js +3 -5
- package/dist/modules/datasource/nuget/v3.js.map +1 -1
- package/dist/modules/datasource/packagist/index.js +4 -5
- package/dist/modules/datasource/packagist/index.js.map +1 -1
- package/dist/modules/datasource/pod/index.js +4 -4
- package/dist/modules/datasource/pod/index.js.map +1 -1
- package/dist/modules/datasource/pypi/index.js +19 -11
- package/dist/modules/datasource/pypi/index.js.map +1 -1
- package/dist/modules/datasource/python-version/index.js +2 -3
- package/dist/modules/datasource/python-version/index.js.map +1 -1
- package/dist/modules/datasource/repology/index.js +4 -3
- package/dist/modules/datasource/repology/index.js.map +1 -1
- package/dist/modules/datasource/rpm/providers/common.js +3 -1
- package/dist/modules/datasource/rpm/providers/common.js.map +1 -1
- package/dist/modules/datasource/rubygems/index.js +2 -5
- package/dist/modules/datasource/rubygems/index.js.map +1 -1
- package/dist/modules/datasource/rubygems/versions-endpoint-cache.js +13 -18
- package/dist/modules/datasource/rubygems/versions-endpoint-cache.js.map +1 -1
- package/dist/modules/datasource/terraform-module/base.js +2 -1
- package/dist/modules/datasource/terraform-module/base.js.map +1 -1
- package/dist/modules/datasource/terraform-provider/index.js +2 -3
- package/dist/modules/datasource/terraform-provider/index.js.map +1 -1
- package/dist/modules/manager/bazel-module/parser/context.js +0 -1
- package/dist/modules/manager/bazel-module/parser/context.js.map +1 -1
- package/dist/modules/manager/bundler/host-rules.js +4 -1
- package/dist/modules/manager/bundler/host-rules.js.map +1 -1
- package/dist/modules/manager/composer/range.js +1 -1
- package/dist/modules/manager/composer/range.js.map +1 -1
- package/dist/modules/manager/custom/utils.js +3 -1
- package/dist/modules/manager/custom/utils.js.map +1 -1
- package/dist/modules/manager/devbox/schema.js +2 -1
- package/dist/modules/manager/devbox/schema.js.map +1 -1
- package/dist/modules/manager/dockerfile/extract.js +10 -2
- package/dist/modules/manager/dockerfile/extract.js.map +1 -1
- package/dist/modules/manager/fingerprint.generated.js +1 -1
- package/dist/modules/manager/fingerprint.generated.js.map +1 -1
- package/dist/modules/manager/github-actions/parse.js +2 -1
- package/dist/modules/manager/github-actions/parse.js.map +1 -1
- package/dist/modules/manager/gomod/artifacts.js +5 -2
- package/dist/modules/manager/gomod/artifacts.js.map +1 -1
- package/dist/modules/manager/gradle/artifacts.js +5 -2
- package/dist/modules/manager/gradle/artifacts.js.map +1 -1
- package/dist/modules/manager/gradle/utils.js +2 -1
- package/dist/modules/manager/gradle/utils.js.map +1 -1
- package/dist/modules/manager/gradle-wrapper/utils.js +9 -5
- package/dist/modules/manager/gradle-wrapper/utils.js.map +1 -1
- package/dist/modules/manager/helm-values/util.js +1 -1
- package/dist/modules/manager/helm-values/util.js.map +1 -1
- package/dist/modules/manager/helmfile/artifacts.js +1 -1
- package/dist/modules/manager/helmfile/artifacts.js.map +1 -1
- package/dist/modules/manager/helmv3/artifacts.js +1 -1
- package/dist/modules/manager/helmv3/artifacts.js.map +1 -1
- package/dist/modules/manager/maven/extract.js +5 -2
- package/dist/modules/manager/maven/extract.js.map +1 -1
- package/dist/modules/manager/maven-wrapper/artifacts.js +3 -2
- package/dist/modules/manager/maven-wrapper/artifacts.js.map +1 -1
- package/dist/modules/manager/mise/artifacts.js +2 -1
- package/dist/modules/manager/mise/artifacts.js.map +1 -1
- package/dist/modules/manager/mise/extract.js.map +1 -1
- package/dist/modules/manager/npm/artifacts.js +3 -1
- package/dist/modules/manager/npm/artifacts.js.map +1 -1
- package/dist/modules/manager/npm/extract/common/dependency.js +4 -1
- package/dist/modules/manager/npm/extract/common/dependency.js.map +1 -1
- package/dist/modules/manager/npm/extract/common/package-file.js +2 -1
- package/dist/modules/manager/npm/extract/common/package-file.js.map +1 -1
- package/dist/modules/manager/npm/extract/index.js.map +1 -1
- package/dist/modules/manager/npm/extract/post/locked-versions.js.map +1 -1
- package/dist/modules/manager/npm/npmrc.js +2 -1
- package/dist/modules/manager/npm/npmrc.js.map +1 -1
- package/dist/modules/manager/npm/post-update/index.js +2 -1
- package/dist/modules/manager/npm/post-update/index.js.map +1 -1
- package/dist/modules/manager/npm/post-update/npm.js +2 -3
- package/dist/modules/manager/npm/post-update/npm.js.map +1 -1
- package/dist/modules/manager/npm/post-update/yarn.js.map +1 -1
- package/dist/modules/manager/npm/schema.js +6 -2
- package/dist/modules/manager/npm/schema.js.map +1 -1
- package/dist/modules/manager/npm/update/dependency/index.js +3 -2
- package/dist/modules/manager/npm/update/dependency/index.js.map +1 -1
- package/dist/modules/manager/npm/update/locked-dependency/common/parent-version.js +6 -2
- package/dist/modules/manager/npm/update/locked-dependency/common/parent-version.js.map +1 -1
- package/dist/modules/manager/npm/update/locked-dependency/package-lock/get-locked.js +2 -1
- package/dist/modules/manager/npm/update/locked-dependency/package-lock/get-locked.js.map +1 -1
- package/dist/modules/manager/nuget/package-tree.js +2 -1
- package/dist/modules/manager/nuget/package-tree.js.map +1 -1
- package/dist/modules/manager/paket/update-locked.js +4 -1
- package/dist/modules/manager/paket/update-locked.js.map +1 -1
- package/dist/modules/manager/pipenv/extract.js +4 -1
- package/dist/modules/manager/pipenv/extract.js.map +1 -1
- package/dist/modules/platform/azure/azure-helper.js +2 -1
- package/dist/modules/platform/azure/azure-helper.js.map +1 -1
- package/dist/modules/platform/azure/index.js +7 -3
- package/dist/modules/platform/azure/index.js.map +1 -1
- package/dist/modules/platform/bitbucket/index.js +13 -6
- package/dist/modules/platform/bitbucket/index.js.map +1 -1
- package/dist/modules/platform/bitbucket-server/index.js +13 -9
- package/dist/modules/platform/bitbucket-server/index.js.map +1 -1
- package/dist/modules/platform/codecommit/index.js +2 -2
- package/dist/modules/platform/codecommit/index.js.map +1 -1
- package/dist/modules/platform/gerrit/client.js +4 -1
- package/dist/modules/platform/gerrit/client.js.map +1 -1
- package/dist/modules/platform/gerrit/index.js +3 -2
- package/dist/modules/platform/gerrit/index.js.map +1 -1
- package/dist/modules/platform/gitea/gitea-helper.js +5 -4
- package/dist/modules/platform/gitea/gitea-helper.js.map +1 -1
- package/dist/modules/platform/gitea/index.js +11 -4
- package/dist/modules/platform/gitea/index.js.map +1 -1
- package/dist/modules/platform/github/index.js +36 -23
- package/dist/modules/platform/github/index.js.map +1 -1
- package/dist/modules/platform/gitlab/index.js +16 -9
- package/dist/modules/platform/gitlab/index.js.map +1 -1
- package/dist/modules/platform/scm-manager/index.js +4 -1
- package/dist/modules/platform/scm-manager/index.js.map +1 -1
- package/dist/modules/platform/scm-manager/utils.js +2 -1
- package/dist/modules/platform/scm-manager/utils.js.map +1 -1
- package/dist/modules/versioning/cargo/index.js.map +1 -1
- package/dist/modules/versioning/composer/index.js +2 -1
- package/dist/modules/versioning/composer/index.js.map +1 -1
- package/dist/modules/versioning/conan/common.js +4 -1
- package/dist/modules/versioning/conan/common.js.map +1 -1
- package/dist/modules/versioning/debian/index.js +2 -1
- package/dist/modules/versioning/debian/index.js.map +1 -1
- package/dist/modules/versioning/gradle/compare.js +2 -1
- package/dist/modules/versioning/gradle/compare.js.map +1 -1
- package/dist/modules/versioning/hex/index.js +2 -1
- package/dist/modules/versioning/hex/index.js.map +1 -1
- package/dist/modules/versioning/julia/index.js.map +1 -1
- package/dist/modules/versioning/maven/compare.js +17 -7
- package/dist/modules/versioning/maven/compare.js.map +1 -1
- package/dist/modules/versioning/npm/index.js +2 -1
- package/dist/modules/versioning/npm/index.js.map +1 -1
- package/dist/modules/versioning/npm/range.js.map +1 -1
- package/dist/modules/versioning/paket/index.js +2 -1
- package/dist/modules/versioning/paket/index.js.map +1 -1
- package/dist/modules/versioning/paket/range.js +7 -3
- package/dist/modules/versioning/paket/range.js.map +1 -1
- package/dist/modules/versioning/pep440/index.js +2 -1
- package/dist/modules/versioning/pep440/index.js.map +1 -1
- package/dist/modules/versioning/poetry/index.js +2 -1
- package/dist/modules/versioning/poetry/index.js.map +1 -1
- package/dist/modules/versioning/regex/index.js +1 -1
- package/dist/modules/versioning/regex/index.js.map +1 -1
- package/dist/modules/versioning/rez/index.js +2 -1
- package/dist/modules/versioning/rez/index.js.map +1 -1
- package/dist/modules/versioning/vcpkg/index.js +2 -1
- package/dist/modules/versioning/vcpkg/index.js.map +1 -1
- package/dist/util/cache/package/impl/base.js +2 -1
- package/dist/util/cache/package/impl/base.js.map +1 -1
- package/dist/util/cache/package/with-cache.js +2 -1
- package/dist/util/cache/package/with-cache.js.map +1 -1
- package/dist/util/check-token.js +7 -4
- package/dist/util/check-token.js.map +1 -1
- package/dist/util/exec/utils.js +4 -1
- package/dist/util/exec/utils.js.map +1 -1
- package/dist/util/git/auth.js +5 -1
- package/dist/util/git/auth.js.map +1 -1
- package/dist/util/git/error.js.map +1 -1
- package/dist/util/host-rules.js +5 -3
- package/dist/util/host-rules.js.map +1 -1
- package/dist/util/http/cache/abstract-http-cache-provider.js +3 -2
- package/dist/util/http/cache/abstract-http-cache-provider.js.map +1 -1
- package/dist/util/http/cache/package-http-cache-provider.js +2 -1
- package/dist/util/http/cache/package-http-cache-provider.js.map +1 -1
- package/dist/util/http/github.js +15 -11
- package/dist/util/http/github.js.map +1 -1
- package/dist/util/http/gitlab.js +5 -4
- package/dist/util/http/gitlab.js.map +1 -1
- package/dist/util/http/http.js +2 -1
- package/dist/util/http/http.js.map +1 -1
- package/dist/util/http/jwt.js +2 -1
- package/dist/util/http/jwt.js.map +1 -1
- package/dist/util/http/retry-after.js +2 -1
- package/dist/util/http/retry-after.js.map +1 -1
- package/dist/util/http/status.js +95 -0
- package/dist/util/http/status.js.map +1 -0
- package/dist/util/merge-confidence/index.js +3 -2
- package/dist/util/merge-confidence/index.js.map +1 -1
- package/dist/util/package-rules/current-version.js +4 -1
- package/dist/util/package-rules/current-version.js.map +1 -1
- package/dist/util/package-rules/index.js +7 -3
- package/dist/util/package-rules/index.js.map +1 -1
- package/dist/util/schema-utils/index.js +5 -0
- package/dist/util/schema-utils/index.js.map +1 -1
- package/dist/workers/global/config/parse/host-rules-from-env.js +2 -1
- package/dist/workers/global/config/parse/host-rules-from-env.js.map +1 -1
- package/dist/workers/repository/common.js +4 -1
- package/dist/workers/repository/common.js.map +1 -1
- package/dist/workers/repository/config-migration/branch/index.js +2 -1
- package/dist/workers/repository/config-migration/branch/index.js.map +1 -1
- package/dist/workers/repository/dependency-dashboard.js +6 -2
- package/dist/workers/repository/dependency-dashboard.js.map +1 -1
- package/dist/workers/repository/finalize/repository-statistics.js +4 -1
- package/dist/workers/repository/finalize/repository-statistics.js.map +1 -1
- package/dist/workers/repository/init/merge.js +13 -3
- package/dist/workers/repository/init/merge.js.map +1 -1
- package/dist/workers/repository/onboarding/branch/check.js +2 -1
- package/dist/workers/repository/onboarding/branch/check.js.map +1 -1
- package/dist/workers/repository/onboarding/pr/pr-list.js +4 -2
- package/dist/workers/repository/onboarding/pr/pr-list.js.map +1 -1
- package/dist/workers/repository/process/extract-update.js +4 -1
- package/dist/workers/repository/process/extract-update.js.map +1 -1
- package/dist/workers/repository/process/lookup/digest.js +2 -1
- package/dist/workers/repository/process/lookup/digest.js.map +1 -1
- package/dist/workers/repository/process/lookup/generate.js +1 -1
- package/dist/workers/repository/process/lookup/generate.js.map +1 -1
- package/dist/workers/repository/process/lookup/index.js +4 -1
- package/dist/workers/repository/process/lookup/index.js.map +1 -1
- package/dist/workers/repository/process/lookup/utils.js +7 -1
- package/dist/workers/repository/process/lookup/utils.js.map +1 -1
- package/dist/workers/repository/process/vulnerabilities.js +10 -3
- package/dist/workers/repository/process/vulnerabilities.js.map +1 -1
- package/dist/workers/repository/reconfigure/index.js +2 -1
- package/dist/workers/repository/reconfigure/index.js.map +1 -1
- package/dist/workers/repository/update/branch/auto-replace.js +6 -2
- package/dist/workers/repository/update/branch/auto-replace.js.map +1 -1
- package/dist/workers/repository/update/branch/errors.js +2 -1
- package/dist/workers/repository/update/branch/errors.js.map +1 -1
- package/dist/workers/repository/update/branch/execute-post-upgrade-commands.js +2 -2
- package/dist/workers/repository/update/branch/execute-post-upgrade-commands.js.map +1 -1
- package/dist/workers/repository/update/branch/get-updated.js +1 -2
- package/dist/workers/repository/update/branch/get-updated.js.map +1 -1
- package/dist/workers/repository/update/branch/index.js +2 -1
- package/dist/workers/repository/update/branch/index.js.map +1 -1
- package/dist/workers/repository/update/branch/status-checks.js +2 -1
- package/dist/workers/repository/update/branch/status-checks.js.map +1 -1
- package/dist/workers/repository/update/pr/body/index.js.map +1 -1
- package/dist/workers/repository/update/pr/changelog/release-notes.js +3 -2
- package/dist/workers/repository/update/pr/changelog/release-notes.js.map +1 -1
- package/dist/workers/repository/update/pr/index.js +7 -3
- package/dist/workers/repository/update/pr/index.js.map +1 -1
- package/dist/workers/repository/updates/generate.js +6 -3
- package/dist/workers/repository/updates/generate.js.map +1 -1
- package/package.json +2 -2
- package/renovate-schema.json +2 -2
|
@@ -6,6 +6,7 @@ import { GlobalConfig } from "../../../config/global.js";
|
|
|
6
6
|
import { sanitize } from "../../../util/sanitize.js";
|
|
7
7
|
import { logger } from "../../../logger/index.js";
|
|
8
8
|
import { ensureTrailingSlash, getQueryString } from "../../../util/url.js";
|
|
9
|
+
import { isConflict, isNoContent, isNotFound } from "../../../util/http/status.js";
|
|
9
10
|
import { find } from "../../../util/host-rules.js";
|
|
10
11
|
import { parseJson } from "../../../util/common.js";
|
|
11
12
|
import { isEmailAdress } from "../../../util/schema-utils/index.js";
|
|
@@ -154,7 +155,7 @@ async function initRepo({ repository, cloneSubmodules, cloneSubmodulesFilter, gi
|
|
|
154
155
|
config.owner = info.project.key;
|
|
155
156
|
logger.debug(`${repository} owner = ${config.owner}`);
|
|
156
157
|
const branchRes = await bitbucketServerHttp.getJsonUnchecked(`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/branches/default`);
|
|
157
|
-
if (
|
|
158
|
+
if (isNoContent(branchRes) || isNotFound(branchRes)) throw new Error(REPOSITORY_EMPTY);
|
|
158
159
|
const url = getRepoGitUrl(config.repositorySlug, defaults.endpoint, gitUrl, info, opts);
|
|
159
160
|
await initRepo$1({
|
|
160
161
|
...config,
|
|
@@ -171,7 +172,7 @@ async function initRepo({ repository, cloneSubmodules, cloneSubmodulesFilter, gi
|
|
|
171
172
|
repoFingerprint: repoFingerprint(info.id, defaults.endpoint)
|
|
172
173
|
};
|
|
173
174
|
} catch (err) /* v8 ignore next -- initRepo error mapping (404, empty repo) is not mocked in specs */ {
|
|
174
|
-
if (err
|
|
175
|
+
if (isNotFound(err)) throw new Error(REPOSITORY_NOT_FOUND);
|
|
175
176
|
if (err.message === "empty") throw err;
|
|
176
177
|
logger.debug({ err }, "Unknown Bitbucket initRepo error");
|
|
177
178
|
throw err;
|
|
@@ -202,7 +203,10 @@ function matchesState(state, desiredState) {
|
|
|
202
203
|
}
|
|
203
204
|
/* v8 ignore next -- covered only through findPr callers, direct coverage tracked in #40625 */
|
|
204
205
|
function isRelevantPr(branchName, prTitle, state) {
|
|
205
|
-
return (p) =>
|
|
206
|
+
return (p) => {
|
|
207
|
+
if (p.sourceBranch !== branchName || !matchesState(p.state, state)) return false;
|
|
208
|
+
return !prTitle || p.title.toUpperCase() === prTitle.toUpperCase();
|
|
209
|
+
};
|
|
206
210
|
}
|
|
207
211
|
async function getPrList() {
|
|
208
212
|
logger.debug(`getPrList()`);
|
|
@@ -395,8 +399,8 @@ async function updatePRAndAddReviewers(prNo, reviewers) {
|
|
|
395
399
|
reviewers,
|
|
396
400
|
prNo
|
|
397
401
|
}, `Failed to add reviewers`);
|
|
398
|
-
if (err
|
|
399
|
-
else if (err
|
|
402
|
+
if (isNotFound(err)) throw new Error(REPOSITORY_NOT_FOUND);
|
|
403
|
+
else if (isConflict(err)) {
|
|
400
404
|
if (isInvalidReviewersResponse(err)) {
|
|
401
405
|
const invalidReviewers = getInvalidReviewers(err);
|
|
402
406
|
const filteredReviewers = reviewers.filter((name) => !invalidReviewers.includes(name));
|
|
@@ -614,8 +618,8 @@ async function updatePr({ number: prNo, prTitle: title, prBody: rawDescription,
|
|
|
614
618
|
err,
|
|
615
619
|
prNo
|
|
616
620
|
}, `Failed to update PR`);
|
|
617
|
-
if (err
|
|
618
|
-
else if (err
|
|
621
|
+
if (isNotFound(err)) throw new Error(REPOSITORY_NOT_FOUND);
|
|
622
|
+
else if (isConflict(err)) {
|
|
619
623
|
if (isInvalidReviewersResponse(err) && !bitbucketInvalidReviewers) await updatePr({
|
|
620
624
|
number: prNo,
|
|
621
625
|
prTitle: title,
|
|
@@ -635,8 +639,8 @@ async function mergePr({ branchName, id: prNo }) {
|
|
|
635
639
|
const { body } = await bitbucketServerHttp.postJson(`./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/merge?version=${pr.version}`);
|
|
636
640
|
updatePrVersion(prNo, body.version);
|
|
637
641
|
} catch (err) {
|
|
638
|
-
if (err
|
|
639
|
-
else if (err
|
|
642
|
+
if (isNotFound(err)) throw new Error(REPOSITORY_NOT_FOUND);
|
|
643
|
+
else if (isConflict(err)) {
|
|
640
644
|
logger.warn({ err }, `Failed to merge PR`);
|
|
641
645
|
return false;
|
|
642
646
|
} else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["hostRules.find","utils.getRepoGitUrl","git.initRepo","utils.prInfo","git.getBranchCommit","git.branchExists","utils.isInvalidReviewersResponse","utils.getInvalidReviewers"],"sources":["../../../../lib/modules/platform/bitbucket-server/index.ts"],"sourcesContent":["import { setTimeout } from 'node:timers/promises';\nimport { isNonEmptyStringAndNotWhitespace } from '@sindresorhus/is';\nimport ignore from 'ignore';\nimport semver from 'semver';\nimport type { PartialDeep } from 'type-fest';\nimport { GlobalConfig } from '../../../config/global.ts';\nimport {\n REPOSITORY_CHANGED,\n REPOSITORY_EMPTY,\n REPOSITORY_NOT_FOUND,\n} from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport type { BranchStatus } from '../../../types/index.ts';\nimport type { FileData } from '../../../types/platform/bitbucket-server/index.ts';\nimport { parseJson } from '../../../util/common.ts';\nimport { getEnv } from '../../../util/env.ts';\nimport * as git from '../../../util/git/index.ts';\nimport { deleteBranch } from '../../../util/git/index.ts';\nimport * as hostRules from '../../../util/host-rules.ts';\nimport {\n BitbucketServerHttp,\n type BitbucketServerHttpOptions,\n setBaseUrl,\n} from '../../../util/http/bitbucket-server.ts';\nimport { memCacheProvider } from '../../../util/http/cache/memory-http-cache-provider.ts';\nimport type { HttpOptions, HttpResponse } from '../../../util/http/types.ts';\nimport { newlineRegex, regEx } from '../../../util/regex.ts';\nimport { sampleSize } from '../../../util/sample.ts';\nimport { sanitize } from '../../../util/sanitize.ts';\nimport { isEmailAdress } from '../../../util/schema-utils/index.ts';\nimport { ensureTrailingSlash, getQueryString } from '../../../util/url.ts';\nimport type {\n BranchStatusConfig,\n CreatePRConfig,\n EnsureCommentConfig,\n EnsureCommentRemovalConfig,\n EnsureIssueConfig,\n EnsureIssueResult,\n FileOwnerRule,\n FindPRConfig,\n Issue,\n MergePRConfig,\n PlatformParams,\n PlatformPrOptions,\n PlatformResult,\n Pr,\n ReattemptPlatformAutomergeConfig,\n RepoParams,\n RepoResult,\n UpdatePrConfig,\n} from '../types.ts';\nimport { getNewBranchName, repoFingerprint } from '../util.ts';\nimport { smartTruncate } from '../utils/pr-body.ts';\nimport { BbsPrCache } from './pr-cache.ts';\nimport type {\n Comment,\n PullRequestActivity,\n PullRequestCommentActivity,\n PullRequestMerge,\n} from './schema.ts';\nimport { ReviewerGroups, User, Users } from './schema.ts';\nimport type {\n BbsConfig,\n BbsPr,\n BbsRestBranch,\n BbsRestPr,\n BbsRestRepo,\n BbsRestUserRef,\n BitbucketCommitStatus,\n BitbucketStatus,\n} from './types.ts';\nimport * as utils from './utils.ts';\nimport {\n getExtraCloneOpts,\n parseModifier,\n splitEscapedSpaces,\n} from './utils.ts';\n\n/*\n * Version: 5.3 (EOL Date: 15 Aug 2019)\n * See following docs for api information:\n * https://docs.atlassian.com/bitbucket-server/rest/5.3.0/bitbucket-rest.html\n * https://docs.atlassian.com/bitbucket-server/rest/5.3.0/bitbucket-build-rest.html\n *\n * See following page for uptodate supported versions\n * https://confluence.atlassian.com/support/atlassian-support-end-of-life-policy-201851003.html#AtlassianSupportEndofLifePolicy-BitbucketServer\n */\n\nexport const id = 'bitbucket-server';\n\nlet config: BbsConfig = {} as any;\n\nconst bitbucketServerHttp = new BitbucketServerHttp();\n\nconst defaults: {\n endpoint?: string;\n hostType: string;\n version: string;\n} = {\n hostType: 'bitbucket-server',\n version: '0.0.0',\n};\n\n/* v8 ignore next -- exercised only via mocked call sites, direct coverage tracked in #40625 */\nfunction updatePrVersion(pr: number, version: number): number {\n const res = Math.max(config.prVersions.get(pr) ?? 0, version);\n config.prVersions.set(pr, res);\n return res;\n}\n\nexport async function initPlatform({\n endpoint,\n token,\n username,\n password,\n gitAuthor,\n}: PlatformParams): Promise<PlatformResult> {\n if (!endpoint) {\n throw new Error('Init: You must configure a Bitbucket Server endpoint');\n }\n if (!(username && password) && !token) {\n throw new Error(\n 'Init: You must either configure a Bitbucket Server username/password or a HTTP access token',\n );\n } else if (password && token) {\n throw new Error(\n 'Init: You must configure either a Bitbucket Server password or a HTTP access token, not both',\n );\n }\n // TODO: Add a connection check that endpoint/username/password combination are valid (#9595)\n defaults.endpoint = ensureTrailingSlash(endpoint);\n setBaseUrl(defaults.endpoint);\n const platformConfig: PlatformResult = {\n endpoint: defaults.endpoint,\n };\n try {\n const env = getEnv();\n let bitbucketServerVersion = env.RENOVATE_X_PLATFORM_VERSION;\n const { body, headers } = await bitbucketServerHttp.getJsonUnchecked<{\n version: string;\n }>(`./rest/api/1.0/application-properties`, { ...(token && { token }) });\n\n bitbucketServerVersion ??= body.version;\n if (isNonEmptyStringAndNotWhitespace(headers['x-ausername']) && !username) {\n logger.debug(\n { 'x-ausername': headers['x-ausername'] },\n 'Platform: No username configured using headers[\"x-ausername\"]',\n );\n config.username = headers['x-ausername'];\n }\n logger.debug(`Bitbucket Server version is: ${bitbucketServerVersion}`);\n\n // v8 ignore else -- TODO: add test #40625\n if (semver.valid(bitbucketServerVersion)) {\n defaults.version = bitbucketServerVersion;\n }\n } catch (err) {\n logger.debug(\n { err },\n 'Error authenticating with Bitbucket. Check that your token includes \"api\" permissions',\n );\n }\n\n if (!gitAuthor && username) {\n logger.debug(`Attempting to confirm gitAuthor from username`);\n const options: HttpOptions = {\n memCache: false,\n };\n\n if (token) {\n options.token = token;\n } else {\n options.username = username;\n options.password = password;\n }\n\n try {\n const { displayName, emailAddress } = (\n await bitbucketServerHttp.getJson(\n `./rest/api/1.0/users/${username}`,\n options,\n User,\n )\n ).body;\n\n if (!emailAddress?.length) {\n throw new Error(`No email address configured for username ${username}`);\n }\n\n platformConfig.gitAuthor = `${displayName} <${emailAddress}>`;\n\n logger.debug(`Detected gitAuthor: ${platformConfig.gitAuthor}`);\n } catch (err) {\n logger.debug(\n { err },\n 'Failed to get user info, fallback gitAuthor will be used',\n );\n }\n }\n\n return platformConfig;\n}\n\n// Get all repositories that the user has access to\nexport async function getRepos(): Promise<string[]> {\n logger.debug('Autodiscovering Bitbucket Server repositories');\n try {\n const repos = (\n await bitbucketServerHttp.getJsonUnchecked<BbsRestRepo[]>(\n `./rest/api/1.0/repos?permission=REPO_WRITE&state=AVAILABLE`,\n { paginate: true },\n )\n ).body;\n\n const result = repos.map((repo) => `${repo.project.key}/${repo.slug}`);\n logger.debug({ result }, 'result of getRepos()');\n return result;\n } catch (err) /* v8 ignore next -- defensive: repo listing failures are logged and rethrown, not simulated in specs */ {\n logger.error({ err }, `bitbucket getRepos error`);\n throw err;\n }\n}\n\nexport async function getRawFile(\n fileName: string,\n repoName?: string,\n branchOrTag?: string,\n): Promise<string | null> {\n const repo = repoName ?? config.repository;\n const [project, slug] = repo.split('/');\n const fileUrl = `./rest/api/1.0/projects/${project}/repos/${slug}/browse/${fileName}?limit=20000${branchOrTag ? `&at=${branchOrTag}` : ''}`;\n const res = await bitbucketServerHttp.getJsonUnchecked<FileData>(fileUrl);\n const { isLastPage, lines, size } = res.body;\n if (isLastPage) {\n return lines.map(({ text }) => text).join('\\n');\n }\n logger.warn({ size }, 'The file is too big');\n throw new Error(`The file is too big (${size}B)`);\n}\n\nexport async function getJsonFile(\n fileName: string,\n repoName?: string,\n branchOrTag?: string,\n): Promise<any> {\n // TODO #22198\n const raw = await getRawFile(fileName, repoName, branchOrTag);\n return parseJson(raw, fileName);\n}\n\n// Initialize Bitbucket Server by getting base branch\nexport async function initRepo({\n repository,\n cloneSubmodules,\n cloneSubmodulesFilter,\n gitUrl,\n}: RepoParams): Promise<RepoResult> {\n logger.debug(`initRepo(\"${JSON.stringify({ repository }, null, 2)}\")`);\n const opts = hostRules.find({\n hostType: defaults.hostType,\n url: defaults.endpoint,\n });\n\n const [projectKey, repositorySlug] = repository.split('/');\n\n config = {\n projectKey,\n repositorySlug,\n repository,\n prVersions: new Map<number, number>(),\n username: opts.username,\n ignorePrAuthor: GlobalConfig.get('ignorePrAuthor'),\n } as any;\n\n try {\n const info = (\n await bitbucketServerHttp.getJsonUnchecked<BbsRestRepo>(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}`,\n )\n ).body;\n config.owner = info.project.key;\n logger.debug(`${repository} owner = ${config.owner}`);\n const branchRes = await bitbucketServerHttp.getJsonUnchecked<BbsRestBranch>(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/branches/default`,\n );\n\n // 204 means empty, 404 means repo not found or missing default branch. repo must exist here.\n if ([204, 404].includes(branchRes.statusCode)) {\n throw new Error(REPOSITORY_EMPTY);\n }\n\n const url = utils.getRepoGitUrl(\n config.repositorySlug,\n // TODO #22198\n defaults.endpoint!,\n gitUrl,\n info,\n opts,\n );\n\n await git.initRepo({\n ...config,\n url,\n extraCloneOpts: getExtraCloneOpts(opts),\n cloneSubmodules,\n cloneSubmodulesFilter,\n fullClone: semver.lte(defaults.version, '8.0.0'),\n });\n\n config.mergeMethod = 'merge';\n const repoConfig: RepoResult = {\n defaultBranch: branchRes.body.displayId,\n isFork: !!info.origin,\n repoFingerprint: repoFingerprint(info.id, defaults.endpoint),\n };\n\n return repoConfig;\n } catch (err) /* v8 ignore next -- initRepo error mapping (404, empty repo) is not mocked in specs */ {\n if (err.statusCode === 404) {\n throw new Error(REPOSITORY_NOT_FOUND);\n }\n if (err.message === REPOSITORY_EMPTY) {\n throw err;\n }\n\n logger.debug({ err }, 'Unknown Bitbucket initRepo error');\n throw err;\n }\n}\n\nexport async function getBranchForceRebase(\n _branchName: string,\n): Promise<boolean> {\n // https://docs.atlassian.com/bitbucket-server/rest/7.0.1/bitbucket-rest.html#idp342\n const res = await bitbucketServerHttp.getJsonUnchecked<{\n mergeConfig: { defaultStrategy: { id: string } };\n }>(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/settings/pull-requests`,\n );\n\n // If the default merge strategy contains `ff-only` the PR can only be merged\n // if it is up to date with the base branch.\n // The current options for id are:\n // no-ff, ff, ff-only, rebase-no-ff, rebase-ff-only, squash, squash-ff-only\n return Boolean(\n res.body?.mergeConfig?.defaultStrategy?.id.includes('ff-only'),\n );\n}\n\n// Gets details for a PR\nexport async function getPr(\n prNo: number,\n refreshCache?: boolean,\n): Promise<BbsPr | null> {\n logger.debug(`getPr(${prNo})`);\n if (!prNo) {\n return null;\n }\n\n // Disables memCache (which is enabled by default) to be replaced by\n // memCacheProvider.\n const opts: HttpOptions = { memCache: false };\n // TODO: should refresh the cache rather than just ignore it\n if (!refreshCache) {\n opts.cacheProvider = memCacheProvider;\n }\n\n const res = await bitbucketServerHttp.getJsonUnchecked<BbsRestPr>(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}`,\n opts,\n );\n\n const pr: BbsPr = {\n ...utils.prInfo(res.body),\n reviewers: res.body.reviewers.map((r) => r.user.name),\n };\n // TODO #22198\n pr.version = updatePrVersion(pr.number, pr.version!);\n\n return pr;\n}\n\n// TODO: coverage (#40625)\n/* v8 ignore next -- covered only through findPr callers, direct coverage tracked in #40625 */\nfunction matchesState(state: string, desiredState: string): boolean {\n if (desiredState === 'all') {\n return true;\n }\n if (desiredState.startsWith('!')) {\n return state !== desiredState.substring(1);\n }\n return state === desiredState;\n}\n\n// TODO: coverage (#40625)\n/* v8 ignore next -- covered only through findPr callers, direct coverage tracked in #40625 */\nfunction isRelevantPr(\n branchName: string,\n prTitle: string | null | undefined,\n state: string,\n) {\n return (p: Pr): boolean =>\n p.sourceBranch === branchName &&\n (!prTitle || p.title.toUpperCase() === prTitle.toUpperCase()) &&\n matchesState(p.state, state);\n}\n\n// TODO: coverage (#40625)\nexport async function getPrList(): Promise<Pr[]> {\n logger.debug(`getPrList()`);\n return await BbsPrCache.getPrs(\n bitbucketServerHttp,\n config.projectKey,\n config.repositorySlug,\n config.ignorePrAuthor,\n config.username,\n );\n}\n\n// TODO: coverage (#40625)\n/* v8 ignore next -- pr-cache-backed lookup paths lack direct specs, tracked in #40625 */\nexport async function findPr({\n branchName,\n prTitle,\n state = 'all',\n includeOtherAuthors,\n}: FindPRConfig): Promise<Pr | null> {\n logger.debug(`findPr(${branchName}, \"${prTitle!}\", \"${state}\")`);\n\n if (includeOtherAuthors) {\n // PR might have been created by anyone, so don't use the cached Renovate PR list\n const searchParams: Record<string, string> = {\n state: 'OPEN',\n };\n searchParams.direction = 'outgoing';\n searchParams.at = `refs/heads/${branchName}`;\n\n const query = getQueryString(searchParams);\n const prs = (\n await bitbucketServerHttp.getJsonUnchecked<BbsRestPr[]>(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests?${query}`,\n {\n paginate: true,\n limit: 1, // only fetch the latest pr\n },\n )\n ).body;\n\n if (!prs.length) {\n logger.debug(`No PR found for branch ${branchName}`);\n return null;\n }\n\n return utils.prInfo(prs[0]);\n }\n\n const prList = await getPrList();\n const pr = prList.find(isRelevantPr(branchName, prTitle, state));\n if (pr) {\n logger.debug(`Found PR #${pr.number}`);\n } else {\n logger.debug(`Renovate did not find a PR for branch ${branchName}`);\n }\n return pr ?? null;\n}\n\n// Returns the Pull Request for a branch. Null if not exists.\nexport async function getBranchPr(branchName: string): Promise<BbsPr | null> {\n logger.debug(`getBranchPr(${branchName})`);\n const existingPr = await findPr({\n branchName,\n state: 'open',\n });\n return existingPr ? getPr(existingPr.number) : null;\n}\n\n/* v8 ignore next -- real-time propagation delay helper, sleeping 1s in specs is not worthwhile */\nexport async function refreshPr(number: number): Promise<void> {\n // wait for pr change propagation\n await setTimeout(1000);\n // refresh cache\n await getPr(number, true);\n}\n\nasync function getStatus(\n branchName: string,\n memCache = true,\n): Promise<BitbucketCommitStatus> {\n const branchCommit = git.getBranchCommit(branchName);\n\n /* v8 ignore next: temporary code */\n const opts: HttpOptions = memCache\n ? { cacheProvider: memCacheProvider }\n : { memCache: false };\n\n return (\n await bitbucketServerHttp.getJsonUnchecked<BitbucketCommitStatus>(\n // TODO: types (#22198)\n `./rest/build-status/1.0/commits/stats/${branchCommit!}`,\n opts,\n )\n ).body;\n}\n\n// Returns the combined status for a branch.\n// umbrella for status checks\n// https://docs.atlassian.com/bitbucket-server/rest/6.0.0/bitbucket-build-rest.html#idp2\nexport async function getBranchStatus(\n branchName: string,\n): Promise<BranchStatus> {\n logger.debug(`getBranchStatus(${branchName})`);\n\n if (!git.branchExists(branchName)) {\n logger.debug('Branch does not exist - cannot fetch status');\n throw new Error(REPOSITORY_CHANGED);\n }\n\n try {\n const commitStatus = await getStatus(branchName);\n\n logger.debug({ commitStatus }, 'branch status check result');\n\n if (commitStatus.failed > 0) {\n return 'red';\n }\n if (commitStatus.inProgress > 0) {\n return 'yellow';\n }\n return commitStatus.successful > 0 ? 'green' : 'yellow';\n } catch (err) {\n logger.warn({ err }, `Failed to get branch status`);\n return 'red';\n }\n}\n\nasync function getStatusCheck(\n branchName: string,\n memCache = true,\n): Promise<BitbucketStatus[]> {\n const branchCommit = git.getBranchCommit(branchName);\n\n const opts: BitbucketServerHttpOptions = { paginate: true };\n /* v8 ignore next: temporary code */\n if (memCache) {\n opts.cacheProvider = memCacheProvider;\n } else {\n opts.memCache = false;\n }\n\n return (\n await bitbucketServerHttp.getJsonUnchecked<BitbucketStatus[]>(\n `./rest/build-status/1.0/commits/${branchCommit!}`,\n opts,\n )\n ).body;\n}\n\n// https://docs.atlassian.com/bitbucket-server/rest/6.0.0/bitbucket-build-rest.html#idp2\nexport async function getBranchStatusCheck(\n branchName: string,\n context: string,\n): Promise<BranchStatus | null> {\n logger.debug(`getBranchStatusCheck(${branchName}, context=${context})`);\n\n try {\n const states = await getStatusCheck(branchName);\n\n for (const state of states) {\n if (state.key === context) {\n switch (state.state) {\n case 'SUCCESSFUL':\n return 'green';\n case 'INPROGRESS':\n return 'yellow';\n case 'FAILED':\n default:\n return 'red';\n }\n }\n }\n } catch (err) {\n logger.warn({ err }, `Failed to check branch status`);\n }\n return null;\n}\n\nexport async function setBranchStatus({\n branchName,\n context,\n description,\n state,\n url: targetUrl,\n}: BranchStatusConfig): Promise<void> {\n logger.debug(`setBranchStatus(${branchName})`);\n\n const existingStatus = await getBranchStatusCheck(branchName, context);\n if (existingStatus === state) {\n return;\n }\n logger.debug({ branch: branchName, context, state }, 'Setting branch status');\n\n const branchCommit = git.getBranchCommit(branchName);\n\n try {\n const body: any = {\n key: context,\n description,\n url: targetUrl ?? 'https://renovatebot.com',\n };\n\n switch (state) {\n case 'green':\n body.state = 'SUCCESSFUL';\n break;\n case 'yellow':\n body.state = 'INPROGRESS';\n break;\n case 'red':\n default:\n body.state = 'FAILED';\n break;\n }\n\n await bitbucketServerHttp.postJson(\n // TODO: types (#22198)\n `./rest/build-status/1.0/commits/${branchCommit!}`,\n { body },\n );\n\n // update status cache\n await getStatus(branchName, false);\n await getStatusCheck(branchName, false);\n } catch (err) {\n logger.warn({ err }, `Failed to set branch status`);\n }\n}\n\n// Issue\n\n/* v8 ignore next -- no-op stub: Bitbucket Server has no issues */\nexport function findIssue(title: string): Promise<Issue | null> {\n logger.debug(`findIssue(${title})`);\n // This is used by Renovate when creating its own issues,\n // e.g. for deprecated package warnings,\n // config error notifications, or \"dependencyDashboard\"\n //\n // Bitbucket Server does not have issues\n return Promise.resolve(null);\n}\n\n/* v8 ignore next -- no-op stub: Bitbucket Server has no issues */\nexport function ensureIssue({\n title,\n}: EnsureIssueConfig): Promise<EnsureIssueResult | null> {\n logger.warn({ title }, 'Cannot ensure issue');\n // This is used by Renovate when creating its own issues,\n // e.g. for deprecated package warnings,\n // config error notifications, or \"dependencyDashboard\"\n //\n // Bitbucket Server does not have issues\n return Promise.resolve(null);\n}\n\n/* v8 ignore next -- no-op stub: Bitbucket Server has no issues */\nexport function getIssueList(): Promise<Issue[]> {\n logger.debug(`getIssueList()`);\n // This is used by Renovate when creating its own issues,\n // e.g. for deprecated package warnings,\n // config error notifications, or \"dependencyDashboard\"\n //\n // Bitbucket Server does not have issues\n return Promise.resolve([]);\n}\n\n/* v8 ignore next -- no-op stub: Bitbucket Server has no issues */\nexport function ensureIssueClosing(title: string): Promise<void> {\n logger.debug(`ensureIssueClosing(${title})`);\n // This is used by Renovate when creating its own issues,\n // e.g. for deprecated package warnings,\n // config error notifications, or \"dependencyDashboard\"\n //\n // Bitbucket Server does not have issues\n return Promise.resolve();\n}\n\nexport function addAssignees(iid: number, assignees: string[]): Promise<void> {\n logger.debug(`addAssignees(${iid}, [${assignees.join(', ')}])`);\n // This is used by Renovate when creating its own issues,\n // e.g. for deprecated package warnings,\n // config error notifications, or \"dependencyDashboard\"\n //\n // Bitbucket Server does not have issues\n return Promise.resolve();\n}\n\nexport async function addReviewers(\n prNo: number,\n reviewers: string[],\n): Promise<void> {\n logger.debug(`Adding reviewers '${reviewers.join(', ')}' to #${prNo}`);\n\n const reviewerNames = new Set<string>();\n\n for (const entry of reviewers) {\n // If entry is an email address, resolve username\n if (isEmailAdress(entry)) {\n const names = await getUsernamesByEmail(entry);\n for (const name of names) {\n reviewerNames.add(name);\n }\n } else {\n reviewerNames.add(entry);\n }\n }\n\n await retry(updatePRAndAddReviewers, [prNo, Array.from(reviewerNames)], 3, [\n REPOSITORY_CHANGED,\n ]);\n}\n\n/**\n * Resolves Bitbucket users by email address,\n * restricted to users who have REPO_READ permission on the target repository.\n *\n * @param emailAddress - A string that could be the user's email address.\n * @returns List of usernames for active, matched users.\n */\nexport async function getUsernamesByEmail(\n emailAddress: string,\n): Promise<string[]> {\n try {\n const filterUrl =\n `./rest/api/1.0/users?filter=${emailAddress}` +\n `&permission.1=REPO_READ` +\n `&permission.1.projectKey=${config.projectKey}` +\n `&permission.1.repositorySlug=${config.repositorySlug}`;\n\n const users = await bitbucketServerHttp.getJson(\n filterUrl,\n { paginate: true, limit: 100 },\n Users,\n );\n\n if (users.body.length) {\n return users.body\n .filter((u) => u.active && u.emailAddress === emailAddress)\n .map((u) => u.name);\n }\n } catch (err) {\n logger.warn(\n { err, emailAddress },\n `Failed to resolve email address to username`,\n );\n throw err;\n }\n logger.debug({ userinfo: emailAddress }, 'No users found for email-address');\n return [];\n}\n\nasync function updatePRAndAddReviewers(\n prNo: number,\n reviewers: string[],\n): Promise<void> {\n try {\n const pr = await getPr(prNo);\n if (!pr) {\n throw new Error(REPOSITORY_NOT_FOUND);\n }\n\n // TODO: can `reviewers` be undefined? (#40625)\n const reviewersSet = new Set([...pr.reviewers!, ...reviewers]);\n\n await bitbucketServerHttp.putJson(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}`,\n {\n body: {\n title: pr.title,\n version: pr.version,\n reviewers: Array.from(reviewersSet).map((name) => ({\n user: { name },\n })),\n },\n },\n );\n await getPr(prNo, true);\n } catch (err) {\n logger.warn({ err, reviewers, prNo }, `Failed to add reviewers`);\n if (err.statusCode === 404) {\n throw new Error(REPOSITORY_NOT_FOUND);\n } else if (err.statusCode === 409) {\n if (utils.isInvalidReviewersResponse(err)) {\n // Retry again with invalid reviewers being removed\n const invalidReviewers = utils.getInvalidReviewers(err);\n const filteredReviewers = reviewers.filter(\n (name) => !invalidReviewers.includes(name),\n );\n if (filteredReviewers.length < reviewers.length) {\n await updatePRAndAddReviewers(prNo, filteredReviewers);\n } else {\n logger.warn(\n { invalidReviewers, reviewers },\n 'Could not filter invalid reviewers from list, aborting to prevent infinite recursion',\n );\n throw err;\n }\n } else {\n logger.debug(\n '409 response to adding reviewers - has repository changed?',\n );\n throw new Error(REPOSITORY_CHANGED);\n }\n } else {\n throw err;\n }\n }\n}\n\nasync function retry<T extends (...arg0: any[]) => Promise<any>>(\n fn: T,\n args: Parameters<T>,\n maxTries: number,\n retryErrorMessages: string[],\n): Promise<Awaited<ReturnType<T>>> {\n const maxAttempts = Math.max(maxTries, 1);\n let lastError: Error | undefined;\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n return await fn(...args);\n } catch (e) {\n lastError = e;\n if (\n retryErrorMessages.length !== 0 &&\n !retryErrorMessages.includes(e.message)\n ) {\n logger.debug(`Error not marked for retry`);\n throw e;\n }\n }\n }\n\n logger.debug(`All ${maxAttempts} retry attempts exhausted`);\n throw lastError!;\n}\n\nexport function deleteLabel(issueNo: number, label: string): Promise<void> {\n logger.debug(`deleteLabel(${issueNo}, ${label})`);\n // Only used for the \"request Renovate to rebase a PR using a label\" feature\n //\n // Bitbucket Server does not have issues\n return Promise.resolve();\n}\n\nasync function getComments(prNo: number): Promise<Comment[]> {\n // GET /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/activities\n const activities = (\n await bitbucketServerHttp.getJsonUnchecked<PullRequestActivity[]>(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/activities`,\n { paginate: true },\n )\n ).body;\n\n const comments = activities\n .filter(\n (a): a is PullRequestCommentActivity =>\n a.action === 'COMMENTED' && 'comment' in a && 'commentAction' in a,\n )\n .filter((a) => a.commentAction === 'ADDED')\n .map((a) => a.comment);\n\n logger.debug(`Found ${comments.length} comments`);\n\n return comments;\n}\n\nasync function addComment(prNo: number, text: string): Promise<void> {\n // POST /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments\n await bitbucketServerHttp.postJson(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/comments`,\n {\n body: { text },\n },\n );\n}\n\nasync function getCommentVersion(\n prNo: number,\n commentId: number,\n): Promise<number> {\n // GET /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments/{commentId}\n const { version } = (\n await bitbucketServerHttp.getJsonUnchecked<{ version: number }>(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/comments/${commentId}`,\n )\n ).body;\n\n return version;\n}\n\nasync function editComment(\n prNo: number,\n commentId: number,\n text: string,\n): Promise<void> {\n const version = await getCommentVersion(prNo, commentId);\n\n // PUT /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments/{commentId}\n await bitbucketServerHttp.putJson(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/comments/${commentId}`,\n {\n body: { text, version },\n },\n );\n}\n\nasync function deleteComment(prNo: number, commentId: number): Promise<void> {\n const version = await getCommentVersion(prNo, commentId);\n\n // DELETE /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments/{commentId}\n await bitbucketServerHttp.deleteJson(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/comments/${commentId}?version=${version}`,\n );\n}\n\nexport async function ensureComment({\n number,\n topic,\n content,\n}: EnsureCommentConfig): Promise<boolean> {\n const sanitizedContent = sanitize(content);\n try {\n const comments = await getComments(number);\n let body: string;\n let commentId: number | undefined;\n let commentNeedsUpdating: boolean | undefined;\n if (topic) {\n logger.debug(`Ensuring comment \"${topic}\" in #${number}`);\n body = `### ${topic}\\n\\n${sanitizedContent}`;\n comments.forEach((comment) => {\n if (comment.text.startsWith(`### ${topic}\\n\\n`)) {\n commentId = comment.id;\n commentNeedsUpdating = comment.text !== body;\n }\n });\n } else {\n logger.debug(`Ensuring content-only comment in #${number}`);\n body = `${sanitizedContent}`;\n comments.forEach((comment) => {\n if (comment.text === body) {\n commentId = comment.id;\n commentNeedsUpdating = false;\n }\n });\n }\n if (!commentId) {\n await addComment(number, body);\n logger.info(\n { repository: config.repository, prNo: number, topic },\n 'Comment added',\n );\n } else if (commentNeedsUpdating) {\n await editComment(number, commentId, body);\n logger.debug(\n { repository: config.repository, prNo: number },\n 'Comment updated',\n );\n } else {\n logger.debug('Comment is already up-to-date');\n }\n return true;\n } catch (err) /* v8 ignore next -- defensive: comment API failures are logged and swallowed, not simulated in specs */ {\n logger.warn({ err }, 'Error ensuring comment');\n return false;\n }\n}\n\nfunction byTopic(comment: Comment, topic: string): boolean {\n return comment.text.startsWith(`### ${topic}\\n\\n`);\n}\n\nfunction byContent(comment: Comment, content: string): boolean {\n return comment.text.trim() === content;\n}\n\nexport async function ensureCommentRemoval(\n deleteConfig: EnsureCommentRemovalConfig,\n): Promise<void> {\n try {\n const { number: prNo } = deleteConfig;\n const key =\n deleteConfig.type === 'by-topic'\n ? deleteConfig.topic\n : deleteConfig.content;\n logger.debug(`Ensuring comment \"${key}\" in #${prNo} is removed`);\n const comments = await getComments(prNo);\n\n let commentId: number | null | undefined = null;\n // v8 ignore else -- TODO: add test #40625\n if (deleteConfig.type === 'by-topic') {\n const topic = deleteConfig.topic;\n commentId = comments.find((comment) => byTopic(comment, topic))?.id;\n } else if (deleteConfig.type === 'by-content') {\n const content = deleteConfig.content;\n commentId = comments.find((comment) => byContent(comment, content))?.id;\n }\n\n if (commentId) {\n await deleteComment(prNo, commentId);\n }\n } catch (err) /* v8 ignore next -- defensive: comment API failures are logged and swallowed, not simulated in specs */ {\n logger.warn({ err }, 'Error ensuring comment removal');\n }\n}\n\n// Pull Request\n\nfunction escapeHash(input: string): string {\n return input?.replace(regEx(/#/g), '%23');\n}\n\nexport async function createPr({\n sourceBranch,\n targetBranch,\n prTitle: title,\n prBody: rawDescription,\n platformPrOptions,\n}: CreatePRConfig): Promise<Pr> {\n const description = sanitize(rawDescription);\n logger.debug(`createPr(${sourceBranch}, title=${title})`);\n const base = targetBranch;\n let reviewers: BbsRestUserRef[] = [];\n\n if (platformPrOptions?.bbUseDefaultReviewers) {\n logger.debug(`fetching default reviewers`);\n const { id } = (\n await bitbucketServerHttp.getJsonUnchecked<{ id: number }>(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}`,\n )\n ).body;\n\n const defReviewers = (\n await bitbucketServerHttp.getJsonUnchecked<{ name: string }[]>(\n `./rest/default-reviewers/1.0/projects/${config.projectKey}/repos/${\n config.repositorySlug\n }/reviewers?sourceRefId=refs/heads/${escapeHash(\n sourceBranch,\n )}&targetRefId=refs/heads/${base}&sourceRepoId=${id}&targetRepoId=${id}`,\n )\n ).body;\n\n reviewers = defReviewers.map((u) => ({\n user: { name: u.name },\n }));\n }\n\n const body: PartialDeep<BbsRestPr> = {\n title,\n description,\n fromRef: {\n id: `refs/heads/${sourceBranch}`,\n },\n toRef: {\n id: `refs/heads/${base}`,\n },\n reviewers,\n };\n let prInfoRes: HttpResponse<BbsRestPr>;\n try {\n prInfoRes = await bitbucketServerHttp.postJson<BbsRestPr>(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests`,\n { body },\n );\n } catch (err) /* v8 ignore next -- EmptyPullRequestException handling is not mocked in specs */ {\n if (\n err.body?.errors?.[0]?.exceptionName ===\n 'com.atlassian.bitbucket.pull.EmptyPullRequestException'\n ) {\n logger.debug(\n 'Empty pull request - deleting branch so it can be recreated next run',\n );\n await deleteBranch(sourceBranch);\n throw new Error(REPOSITORY_CHANGED);\n }\n throw err;\n }\n\n const pr: BbsPr = {\n ...utils.prInfo(prInfoRes.body),\n };\n\n // TODO #22198\n updatePrVersion(pr.number, pr.version!);\n await BbsPrCache.setPr(\n bitbucketServerHttp,\n config.projectKey,\n config.repositorySlug,\n config.ignorePrAuthor,\n config.username,\n pr,\n );\n\n await tryPrAutomerge(pr.number, pr.version!, platformPrOptions);\n\n return pr;\n}\n\nexport async function reattemptPlatformAutomerge({\n number,\n platformPrOptions,\n}: ReattemptPlatformAutomergeConfig): Promise<void> {\n logger.debug(`reattemptPlatformAutomerge(${number})`);\n\n try {\n const pr = await getPr(number, true);\n if (!pr) {\n throw new Error(REPOSITORY_NOT_FOUND);\n }\n await tryPrAutomerge(pr.number, pr.version!, platformPrOptions);\n\n logger.debug(`PR platform automerge re-attempted...prNo: ${number}`);\n } catch (err) {\n logger.warn({ err }, 'Error re-attempting PR platform automerge');\n }\n}\n\nexport async function updatePr({\n number: prNo,\n prTitle: title,\n prBody: rawDescription,\n state,\n bitbucketInvalidReviewers,\n targetBranch,\n}: UpdatePrConfig & {\n bitbucketInvalidReviewers?: string[] | undefined;\n}): Promise<void> {\n const description = sanitize(rawDescription);\n logger.debug(`updatePr(${prNo}, title=${title})`);\n\n try {\n const pr = await getPr(prNo);\n if (!pr) {\n throw Object.assign(new Error(REPOSITORY_NOT_FOUND), { statusCode: 404 });\n }\n\n const body: any = {\n title,\n description,\n version: pr.version,\n reviewers: pr.reviewers\n ?.filter((name: string) => !bitbucketInvalidReviewers?.includes(name))\n .map((name: string) => ({ user: { name } })),\n };\n if (targetBranch) {\n body.toRef = {\n id: getNewBranchName(targetBranch),\n };\n }\n\n const { body: updatedPr } = await bitbucketServerHttp.putJson<\n BbsRestPr & {\n version: number;\n }\n >(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}`,\n { body },\n );\n\n updatePrVersion(prNo, updatedPr.version);\n\n const currentState = updatedPr.state;\n // TODO #22198\n const newState = {\n ['open']: 'OPEN',\n ['closed']: 'DECLINED',\n }[state!];\n\n let finalState: 'open' | 'closed' =\n currentState === 'OPEN' ? 'open' : 'closed';\n\n if (\n newState &&\n ['OPEN', 'DECLINED'].includes(currentState) &&\n currentState !== newState\n ) {\n const command = state === 'open' ? 'reopen' : 'decline';\n const { body: updatedStatePr } = await bitbucketServerHttp.postJson<{\n version: number;\n }>(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${pr.number}/${command}?version=${updatedPr.version}`,\n );\n\n finalState = state!;\n\n updatePrVersion(pr.number, updatedStatePr.version);\n }\n\n const bbsPr = utils.prInfo(updatedPr);\n await BbsPrCache.setPr(\n bitbucketServerHttp,\n config.projectKey,\n config.repositorySlug,\n config.ignorePrAuthor,\n config.username,\n { ...bbsPr, state: finalState },\n );\n } catch (err) {\n logger.debug({ err, prNo }, `Failed to update PR`);\n if (err.statusCode === 404) {\n throw new Error(REPOSITORY_NOT_FOUND);\n } else if (err.statusCode === 409) {\n if (utils.isInvalidReviewersResponse(err) && !bitbucketInvalidReviewers) {\n // Retry again with invalid reviewers being removed\n const invalidReviewers = utils.getInvalidReviewers(err);\n await updatePr({\n number: prNo,\n prTitle: title,\n prBody: rawDescription,\n state,\n bitbucketInvalidReviewers: invalidReviewers,\n });\n } else {\n throw new Error(REPOSITORY_CHANGED);\n }\n } else {\n throw err;\n }\n }\n}\n\n// https://docs.atlassian.com/bitbucket-server/rest/6.0.0/bitbucket-rest.html#idp261\nexport async function mergePr({\n branchName,\n id: prNo,\n}: MergePRConfig): Promise<boolean> {\n logger.debug(`mergePr(${prNo}, ${branchName!})`);\n // Used for \"automerge\" feature\n try {\n const pr = await getPr(prNo);\n if (!pr) {\n throw Object.assign(new Error(REPOSITORY_NOT_FOUND), { statusCode: 404 });\n }\n const { body } = await bitbucketServerHttp.postJson<{ version: number }>(\n // TODO: types (#22198)\n `./rest/api/1.0/projects/${config.projectKey}/repos/${\n config.repositorySlug\n }/pull-requests/${prNo}/merge?version=${pr.version!}`,\n );\n updatePrVersion(prNo, body.version);\n } catch (err) {\n if (err.statusCode === 404) {\n throw new Error(REPOSITORY_NOT_FOUND);\n } else if (err.statusCode === 409) {\n logger.warn({ err }, `Failed to merge PR`);\n return false;\n } else {\n logger.warn({ err }, `Failed to merge PR`);\n return false;\n }\n }\n\n logger.debug(`PR merged, PrNo:${prNo}`);\n return true;\n}\n\n/**\n * Enables Bitbucket Server-native automerge for the given PR.\n * https://confluence.atlassian.com/bitbucketserver094/merge-a-pull-request-1489802114.html#Mergeapullrequest-Auto-mergeapullrequest\n */\nasync function tryPrAutomerge(\n prNumber: number,\n prVersion: number,\n platformPrOptions?: PlatformPrOptions,\n): Promise<void> {\n if (!platformPrOptions?.usePlatformAutomerge) {\n return;\n }\n\n logger.debug(`tryPrAutomerge(${prNumber})`);\n\n if (semver.lt(defaults.version, '8.15.0')) {\n logger.debug(\n { prNumber },\n 'Bitbucket Server-native automerge: not supported on this version of Bitbucket. Use 8.15.0 or newer.',\n );\n return;\n }\n\n try {\n const body: PullRequestMerge = { autoMerge: true };\n await bitbucketServerHttp.postJson(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNumber}/merge?version=${prVersion}`,\n { body },\n );\n\n // enabling auto-merge doesn't increase PR version, so we omit updating the cache\n logger.debug({ prNumber }, 'Bitbucket Server-native automerge: success');\n } catch (err) {\n logger.warn({ err, prNumber }, 'Bitbucket Server-native automerge: fail');\n }\n}\n\nexport async function expandGroupMembers(\n reviewers: string[],\n): Promise<string[]> {\n logger.debug(`expandGroupMembers(${reviewers.join(', ')})`);\n const expandedUsers: string[] = [];\n const reviewerGroupPrefix = '@reviewer-group/';\n\n for (const reviewer of reviewers) {\n const [baseEntry, modifier] = reviewer.split(':');\n\n if (baseEntry.startsWith(reviewerGroupPrefix)) {\n const groupName = baseEntry.replace(reviewerGroupPrefix, '');\n const groupUsers = await getUsersFromReviewerGroup(groupName);\n if (!groupUsers.length) {\n continue;\n }\n\n if (modifier) {\n const randomCount = parseModifier(modifier);\n if (randomCount) {\n expandedUsers.push(...sampleSize(groupUsers, randomCount));\n continue;\n }\n }\n\n expandedUsers.push(...groupUsers);\n } else {\n expandedUsers.push(baseEntry); // Add the user entry\n }\n }\n\n return [...new Set(expandedUsers)];\n}\n\nexport function extractRulesFromCodeOwnersLines(\n cleanedLines: string[],\n): FileOwnerRule[] {\n const results: FileOwnerRule[] = [];\n\n const reversedLines = cleanedLines\n .filter((line) => line.trim() !== '' && !line.trim().startsWith('#'))\n .reverse();\n\n for (const line of reversedLines) {\n const [pattern, ...entries] = splitEscapedSpaces(line);\n const matcher = ignore().add(pattern);\n results.push({\n pattern,\n usernames: [...new Set(entries)],\n score: pattern.length,\n match: (path: string) => matcher.ignores(path),\n });\n }\n\n return results;\n}\n\n// Gets active users by name, from a reviewer group\n// Returns an empty array if the group is not found or has no active users\n// As there is no direct API to get group by name, we get all reviewer groups per repo and filter them\n// This is not efficient, but it is the only way to get users from a group by name\n// Supports both repository-scoped and project-scoped groups following the BitBucket server logic described here:\n// https://confluence.atlassian.com/bitbucketserver/code-owners-1296171116.html#Codeowners-Whatifaprojectandrepositorycontainareviewergroupwiththesamename?\nasync function getUsersFromReviewerGroup(groupName: string): Promise<string[]> {\n const allGroups = [];\n\n try {\n const reviewerGroups = await bitbucketServerHttp.getJson(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/settings/reviewer-groups`,\n { paginate: true },\n ReviewerGroups,\n );\n\n allGroups.push(...reviewerGroups.body);\n } catch (err) {\n logger.debug({ err, groupName }, 'Failed to get reviewer groups for repo');\n return [];\n }\n\n // First, try to find a repo-scoped group with this name\n const repoGroup = allGroups.find(\n (group) => group.name === groupName && group.scope?.type === 'REPOSITORY',\n );\n\n if (repoGroup) {\n return repoGroup.users\n .filter((user) => user.active)\n .map((user) => user.name);\n }\n\n // If no repo-level group, fall back to project-level group\n const projectGroup = allGroups.find(\n (group) => group.name === groupName && group.scope?.type === 'PROJECT',\n );\n\n if (projectGroup) {\n return projectGroup.users\n .filter((user) => user.active)\n .map((user) => user.name);\n }\n\n // Group not found at either level\n logger.warn(\n { groupName },\n 'Reviewer group not found at repo or project level',\n );\n return [];\n}\n\nexport function massageMarkdown(input: string): string {\n logger.debug(`massageMarkdown(${input.split(newlineRegex)[0]})`);\n // Remove any HTML we use\n return smartTruncate(input, maxBodyLength())\n .replace(\n 'you tick the rebase/retry checkbox',\n 'PR is renamed to start with \"rebase!\"',\n )\n .replace(\n 'checking the rebase/retry box above',\n 'renaming the PR to start with \"rebase!\"',\n )\n .replace(regEx(/<\\/?summary>/g), '**')\n .replace(regEx(/<\\/?details>/g), '')\n .replace(regEx(`\\n---\\n\\n.*?<!-- rebase-check -->.*?(\\n|$)`), '')\n .replace(regEx(/<!--.*?-->/gs), '')\n .replace(\n regEx(\n /(?<badge>!\\[.+?\\]\\(https:\\/\\/developer\\.mend\\.io\\/api\\/mc\\/badges\\/.+?\\))/g,\n ),\n '$<badge>{height=20}',\n );\n}\n\nexport function maxBodyLength(): number {\n return 30000;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["hostRules.find","utils.getRepoGitUrl","git.initRepo","utils.prInfo","git.getBranchCommit","git.branchExists","utils.isInvalidReviewersResponse","utils.getInvalidReviewers"],"sources":["../../../../lib/modules/platform/bitbucket-server/index.ts"],"sourcesContent":["import { setTimeout } from 'node:timers/promises';\nimport { isNonEmptyStringAndNotWhitespace } from '@sindresorhus/is';\nimport ignore from 'ignore';\nimport semver from 'semver';\nimport type { PartialDeep } from 'type-fest';\nimport { GlobalConfig } from '../../../config/global.ts';\nimport {\n REPOSITORY_CHANGED,\n REPOSITORY_EMPTY,\n REPOSITORY_NOT_FOUND,\n} from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport type { BranchStatus } from '../../../types/index.ts';\nimport type { FileData } from '../../../types/platform/bitbucket-server/index.ts';\nimport { parseJson } from '../../../util/common.ts';\nimport { getEnv } from '../../../util/env.ts';\nimport * as git from '../../../util/git/index.ts';\nimport { deleteBranch } from '../../../util/git/index.ts';\nimport * as hostRules from '../../../util/host-rules.ts';\nimport {\n BitbucketServerHttp,\n type BitbucketServerHttpOptions,\n setBaseUrl,\n} from '../../../util/http/bitbucket-server.ts';\nimport { memCacheProvider } from '../../../util/http/cache/memory-http-cache-provider.ts';\nimport {\n isConflict,\n isNoContent,\n isNotFound,\n} from '../../../util/http/status.ts';\nimport type { HttpOptions, HttpResponse } from '../../../util/http/types.ts';\nimport { newlineRegex, regEx } from '../../../util/regex.ts';\nimport { sampleSize } from '../../../util/sample.ts';\nimport { sanitize } from '../../../util/sanitize.ts';\nimport { isEmailAdress } from '../../../util/schema-utils/index.ts';\nimport { ensureTrailingSlash, getQueryString } from '../../../util/url.ts';\nimport type {\n BranchStatusConfig,\n CreatePRConfig,\n EnsureCommentConfig,\n EnsureCommentRemovalConfig,\n EnsureIssueConfig,\n EnsureIssueResult,\n FileOwnerRule,\n FindPRConfig,\n Issue,\n MergePRConfig,\n PlatformParams,\n PlatformPrOptions,\n PlatformResult,\n Pr,\n ReattemptPlatformAutomergeConfig,\n RepoParams,\n RepoResult,\n UpdatePrConfig,\n} from '../types.ts';\nimport { getNewBranchName, repoFingerprint } from '../util.ts';\nimport { smartTruncate } from '../utils/pr-body.ts';\nimport { BbsPrCache } from './pr-cache.ts';\nimport type {\n Comment,\n PullRequestActivity,\n PullRequestCommentActivity,\n PullRequestMerge,\n} from './schema.ts';\nimport { ReviewerGroups, User, Users } from './schema.ts';\nimport type {\n BbsConfig,\n BbsPr,\n BbsRestBranch,\n BbsRestPr,\n BbsRestRepo,\n BbsRestUserRef,\n BitbucketCommitStatus,\n BitbucketStatus,\n} from './types.ts';\nimport * as utils from './utils.ts';\nimport {\n getExtraCloneOpts,\n parseModifier,\n splitEscapedSpaces,\n} from './utils.ts';\n\n/*\n * Version: 5.3 (EOL Date: 15 Aug 2019)\n * See following docs for api information:\n * https://docs.atlassian.com/bitbucket-server/rest/5.3.0/bitbucket-rest.html\n * https://docs.atlassian.com/bitbucket-server/rest/5.3.0/bitbucket-build-rest.html\n *\n * See following page for uptodate supported versions\n * https://confluence.atlassian.com/support/atlassian-support-end-of-life-policy-201851003.html#AtlassianSupportEndofLifePolicy-BitbucketServer\n */\n\nexport const id = 'bitbucket-server';\n\nlet config: BbsConfig = {} as any;\n\nconst bitbucketServerHttp = new BitbucketServerHttp();\n\nconst defaults: {\n endpoint?: string;\n hostType: string;\n version: string;\n} = {\n hostType: 'bitbucket-server',\n version: '0.0.0',\n};\n\n/* v8 ignore next -- exercised only via mocked call sites, direct coverage tracked in #40625 */\nfunction updatePrVersion(pr: number, version: number): number {\n const res = Math.max(config.prVersions.get(pr) ?? 0, version);\n config.prVersions.set(pr, res);\n return res;\n}\n\nexport async function initPlatform({\n endpoint,\n token,\n username,\n password,\n gitAuthor,\n}: PlatformParams): Promise<PlatformResult> {\n if (!endpoint) {\n throw new Error('Init: You must configure a Bitbucket Server endpoint');\n }\n if (!(username && password) && !token) {\n throw new Error(\n 'Init: You must either configure a Bitbucket Server username/password or a HTTP access token',\n );\n } else if (password && token) {\n throw new Error(\n 'Init: You must configure either a Bitbucket Server password or a HTTP access token, not both',\n );\n }\n // TODO: Add a connection check that endpoint/username/password combination are valid (#9595)\n defaults.endpoint = ensureTrailingSlash(endpoint);\n setBaseUrl(defaults.endpoint);\n const platformConfig: PlatformResult = {\n endpoint: defaults.endpoint,\n };\n try {\n const env = getEnv();\n let bitbucketServerVersion = env.RENOVATE_X_PLATFORM_VERSION;\n const { body, headers } = await bitbucketServerHttp.getJsonUnchecked<{\n version: string;\n }>(`./rest/api/1.0/application-properties`, { ...(token && { token }) });\n\n bitbucketServerVersion ??= body.version;\n if (isNonEmptyStringAndNotWhitespace(headers['x-ausername']) && !username) {\n logger.debug(\n { 'x-ausername': headers['x-ausername'] },\n 'Platform: No username configured using headers[\"x-ausername\"]',\n );\n config.username = headers['x-ausername'];\n }\n logger.debug(`Bitbucket Server version is: ${bitbucketServerVersion}`);\n\n // v8 ignore else -- TODO: add test #40625\n if (semver.valid(bitbucketServerVersion)) {\n defaults.version = bitbucketServerVersion;\n }\n } catch (err) {\n logger.debug(\n { err },\n 'Error authenticating with Bitbucket. Check that your token includes \"api\" permissions',\n );\n }\n\n if (!gitAuthor && username) {\n logger.debug(`Attempting to confirm gitAuthor from username`);\n const options: HttpOptions = {\n memCache: false,\n };\n\n if (token) {\n options.token = token;\n } else {\n options.username = username;\n options.password = password;\n }\n\n try {\n const { displayName, emailAddress } = (\n await bitbucketServerHttp.getJson(\n `./rest/api/1.0/users/${username}`,\n options,\n User,\n )\n ).body;\n\n if (!emailAddress?.length) {\n throw new Error(`No email address configured for username ${username}`);\n }\n\n platformConfig.gitAuthor = `${displayName} <${emailAddress}>`;\n\n logger.debug(`Detected gitAuthor: ${platformConfig.gitAuthor}`);\n } catch (err) {\n logger.debug(\n { err },\n 'Failed to get user info, fallback gitAuthor will be used',\n );\n }\n }\n\n return platformConfig;\n}\n\n// Get all repositories that the user has access to\nexport async function getRepos(): Promise<string[]> {\n logger.debug('Autodiscovering Bitbucket Server repositories');\n try {\n const repos = (\n await bitbucketServerHttp.getJsonUnchecked<BbsRestRepo[]>(\n `./rest/api/1.0/repos?permission=REPO_WRITE&state=AVAILABLE`,\n { paginate: true },\n )\n ).body;\n\n const result = repos.map((repo) => `${repo.project.key}/${repo.slug}`);\n logger.debug({ result }, 'result of getRepos()');\n return result;\n } catch (err) /* v8 ignore next -- defensive: repo listing failures are logged and rethrown, not simulated in specs */ {\n logger.error({ err }, `bitbucket getRepos error`);\n throw err;\n }\n}\n\nexport async function getRawFile(\n fileName: string,\n repoName?: string,\n branchOrTag?: string,\n): Promise<string | null> {\n const repo = repoName ?? config.repository;\n const [project, slug] = repo.split('/');\n const fileUrl = `./rest/api/1.0/projects/${project}/repos/${slug}/browse/${fileName}?limit=20000${branchOrTag ? `&at=${branchOrTag}` : ''}`;\n const res = await bitbucketServerHttp.getJsonUnchecked<FileData>(fileUrl);\n const { isLastPage, lines, size } = res.body;\n if (isLastPage) {\n return lines.map(({ text }) => text).join('\\n');\n }\n logger.warn({ size }, 'The file is too big');\n throw new Error(`The file is too big (${size}B)`);\n}\n\nexport async function getJsonFile(\n fileName: string,\n repoName?: string,\n branchOrTag?: string,\n): Promise<any> {\n // TODO #22198\n const raw = await getRawFile(fileName, repoName, branchOrTag);\n return parseJson(raw, fileName);\n}\n\n// Initialize Bitbucket Server by getting base branch\nexport async function initRepo({\n repository,\n cloneSubmodules,\n cloneSubmodulesFilter,\n gitUrl,\n}: RepoParams): Promise<RepoResult> {\n logger.debug(`initRepo(\"${JSON.stringify({ repository }, null, 2)}\")`);\n const opts = hostRules.find({\n hostType: defaults.hostType,\n url: defaults.endpoint,\n });\n\n const [projectKey, repositorySlug] = repository.split('/');\n\n config = {\n projectKey,\n repositorySlug,\n repository,\n prVersions: new Map<number, number>(),\n username: opts.username,\n ignorePrAuthor: GlobalConfig.get('ignorePrAuthor'),\n } as any;\n\n try {\n const info = (\n await bitbucketServerHttp.getJsonUnchecked<BbsRestRepo>(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}`,\n )\n ).body;\n config.owner = info.project.key;\n logger.debug(`${repository} owner = ${config.owner}`);\n const branchRes = await bitbucketServerHttp.getJsonUnchecked<BbsRestBranch>(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/branches/default`,\n );\n\n // 204 means empty, 404 means repo not found or missing default branch. repo must exist here.\n if (isNoContent(branchRes) || isNotFound(branchRes)) {\n throw new Error(REPOSITORY_EMPTY);\n }\n\n const url = utils.getRepoGitUrl(\n config.repositorySlug,\n // TODO #22198\n defaults.endpoint!,\n gitUrl,\n info,\n opts,\n );\n\n await git.initRepo({\n ...config,\n url,\n extraCloneOpts: getExtraCloneOpts(opts),\n cloneSubmodules,\n cloneSubmodulesFilter,\n fullClone: semver.lte(defaults.version, '8.0.0'),\n });\n\n config.mergeMethod = 'merge';\n const repoConfig: RepoResult = {\n defaultBranch: branchRes.body.displayId,\n isFork: !!info.origin,\n repoFingerprint: repoFingerprint(info.id, defaults.endpoint),\n };\n\n return repoConfig;\n } catch (err) /* v8 ignore next -- initRepo error mapping (404, empty repo) is not mocked in specs */ {\n if (isNotFound(err)) {\n throw new Error(REPOSITORY_NOT_FOUND);\n }\n if (err.message === REPOSITORY_EMPTY) {\n throw err;\n }\n\n logger.debug({ err }, 'Unknown Bitbucket initRepo error');\n throw err;\n }\n}\n\nexport async function getBranchForceRebase(\n _branchName: string,\n): Promise<boolean> {\n // https://docs.atlassian.com/bitbucket-server/rest/7.0.1/bitbucket-rest.html#idp342\n const res = await bitbucketServerHttp.getJsonUnchecked<{\n mergeConfig: { defaultStrategy: { id: string } };\n }>(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/settings/pull-requests`,\n );\n\n // If the default merge strategy contains `ff-only` the PR can only be merged\n // if it is up to date with the base branch.\n // The current options for id are:\n // no-ff, ff, ff-only, rebase-no-ff, rebase-ff-only, squash, squash-ff-only\n return Boolean(\n res.body?.mergeConfig?.defaultStrategy?.id.includes('ff-only'),\n );\n}\n\n// Gets details for a PR\nexport async function getPr(\n prNo: number,\n refreshCache?: boolean,\n): Promise<BbsPr | null> {\n logger.debug(`getPr(${prNo})`);\n if (!prNo) {\n return null;\n }\n\n // Disables memCache (which is enabled by default) to be replaced by\n // memCacheProvider.\n const opts: HttpOptions = { memCache: false };\n // TODO: should refresh the cache rather than just ignore it\n if (!refreshCache) {\n opts.cacheProvider = memCacheProvider;\n }\n\n const res = await bitbucketServerHttp.getJsonUnchecked<BbsRestPr>(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}`,\n opts,\n );\n\n const pr: BbsPr = {\n ...utils.prInfo(res.body),\n reviewers: res.body.reviewers.map((r) => r.user.name),\n };\n // TODO #22198\n pr.version = updatePrVersion(pr.number, pr.version!);\n\n return pr;\n}\n\n// TODO: coverage (#40625)\n/* v8 ignore next -- covered only through findPr callers, direct coverage tracked in #40625 */\nfunction matchesState(state: string, desiredState: string): boolean {\n if (desiredState === 'all') {\n return true;\n }\n if (desiredState.startsWith('!')) {\n return state !== desiredState.substring(1);\n }\n return state === desiredState;\n}\n\n// TODO: coverage (#40625)\n/* v8 ignore next -- covered only through findPr callers, direct coverage tracked in #40625 */\nfunction isRelevantPr(\n branchName: string,\n prTitle: string | null | undefined,\n state: string,\n) {\n return (p: Pr): boolean => {\n if (p.sourceBranch !== branchName || !matchesState(p.state, state)) {\n return false;\n }\n return !prTitle || p.title.toUpperCase() === prTitle.toUpperCase();\n };\n}\n\n// TODO: coverage (#40625)\nexport async function getPrList(): Promise<Pr[]> {\n logger.debug(`getPrList()`);\n return await BbsPrCache.getPrs(\n bitbucketServerHttp,\n config.projectKey,\n config.repositorySlug,\n config.ignorePrAuthor,\n config.username,\n );\n}\n\n// TODO: coverage (#40625)\n/* v8 ignore next -- pr-cache-backed lookup paths lack direct specs, tracked in #40625 */\nexport async function findPr({\n branchName,\n prTitle,\n state = 'all',\n includeOtherAuthors,\n}: FindPRConfig): Promise<Pr | null> {\n logger.debug(`findPr(${branchName}, \"${prTitle!}\", \"${state}\")`);\n\n if (includeOtherAuthors) {\n // PR might have been created by anyone, so don't use the cached Renovate PR list\n const searchParams: Record<string, string> = {\n state: 'OPEN',\n };\n searchParams.direction = 'outgoing';\n searchParams.at = `refs/heads/${branchName}`;\n\n const query = getQueryString(searchParams);\n const prs = (\n await bitbucketServerHttp.getJsonUnchecked<BbsRestPr[]>(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests?${query}`,\n {\n paginate: true,\n limit: 1, // only fetch the latest pr\n },\n )\n ).body;\n\n if (!prs.length) {\n logger.debug(`No PR found for branch ${branchName}`);\n return null;\n }\n\n return utils.prInfo(prs[0]);\n }\n\n const prList = await getPrList();\n const pr = prList.find(isRelevantPr(branchName, prTitle, state));\n if (pr) {\n logger.debug(`Found PR #${pr.number}`);\n } else {\n logger.debug(`Renovate did not find a PR for branch ${branchName}`);\n }\n return pr ?? null;\n}\n\n// Returns the Pull Request for a branch. Null if not exists.\nexport async function getBranchPr(branchName: string): Promise<BbsPr | null> {\n logger.debug(`getBranchPr(${branchName})`);\n const existingPr = await findPr({\n branchName,\n state: 'open',\n });\n return existingPr ? getPr(existingPr.number) : null;\n}\n\n/* v8 ignore next -- real-time propagation delay helper, sleeping 1s in specs is not worthwhile */\nexport async function refreshPr(number: number): Promise<void> {\n // wait for pr change propagation\n await setTimeout(1000);\n // refresh cache\n await getPr(number, true);\n}\n\nasync function getStatus(\n branchName: string,\n memCache = true,\n): Promise<BitbucketCommitStatus> {\n const branchCommit = git.getBranchCommit(branchName);\n\n /* v8 ignore next: temporary code */\n const opts: HttpOptions = memCache\n ? { cacheProvider: memCacheProvider }\n : { memCache: false };\n\n return (\n await bitbucketServerHttp.getJsonUnchecked<BitbucketCommitStatus>(\n // TODO: types (#22198)\n `./rest/build-status/1.0/commits/stats/${branchCommit!}`,\n opts,\n )\n ).body;\n}\n\n// Returns the combined status for a branch.\n// umbrella for status checks\n// https://docs.atlassian.com/bitbucket-server/rest/6.0.0/bitbucket-build-rest.html#idp2\nexport async function getBranchStatus(\n branchName: string,\n): Promise<BranchStatus> {\n logger.debug(`getBranchStatus(${branchName})`);\n\n if (!git.branchExists(branchName)) {\n logger.debug('Branch does not exist - cannot fetch status');\n throw new Error(REPOSITORY_CHANGED);\n }\n\n try {\n const commitStatus = await getStatus(branchName);\n\n logger.debug({ commitStatus }, 'branch status check result');\n\n if (commitStatus.failed > 0) {\n return 'red';\n }\n if (commitStatus.inProgress > 0) {\n return 'yellow';\n }\n return commitStatus.successful > 0 ? 'green' : 'yellow';\n } catch (err) {\n logger.warn({ err }, `Failed to get branch status`);\n return 'red';\n }\n}\n\nasync function getStatusCheck(\n branchName: string,\n memCache = true,\n): Promise<BitbucketStatus[]> {\n const branchCommit = git.getBranchCommit(branchName);\n\n const opts: BitbucketServerHttpOptions = { paginate: true };\n /* v8 ignore next: temporary code */\n if (memCache) {\n opts.cacheProvider = memCacheProvider;\n } else {\n opts.memCache = false;\n }\n\n return (\n await bitbucketServerHttp.getJsonUnchecked<BitbucketStatus[]>(\n `./rest/build-status/1.0/commits/${branchCommit!}`,\n opts,\n )\n ).body;\n}\n\n// https://docs.atlassian.com/bitbucket-server/rest/6.0.0/bitbucket-build-rest.html#idp2\nexport async function getBranchStatusCheck(\n branchName: string,\n context: string,\n): Promise<BranchStatus | null> {\n logger.debug(`getBranchStatusCheck(${branchName}, context=${context})`);\n\n try {\n const states = await getStatusCheck(branchName);\n\n for (const state of states) {\n if (state.key === context) {\n switch (state.state) {\n case 'SUCCESSFUL':\n return 'green';\n case 'INPROGRESS':\n return 'yellow';\n case 'FAILED':\n default:\n return 'red';\n }\n }\n }\n } catch (err) {\n logger.warn({ err }, `Failed to check branch status`);\n }\n return null;\n}\n\nexport async function setBranchStatus({\n branchName,\n context,\n description,\n state,\n url: targetUrl,\n}: BranchStatusConfig): Promise<void> {\n logger.debug(`setBranchStatus(${branchName})`);\n\n const existingStatus = await getBranchStatusCheck(branchName, context);\n if (existingStatus === state) {\n return;\n }\n logger.debug({ branch: branchName, context, state }, 'Setting branch status');\n\n const branchCommit = git.getBranchCommit(branchName);\n\n try {\n const body: any = {\n key: context,\n description,\n url: targetUrl ?? 'https://renovatebot.com',\n };\n\n switch (state) {\n case 'green':\n body.state = 'SUCCESSFUL';\n break;\n case 'yellow':\n body.state = 'INPROGRESS';\n break;\n case 'red':\n default:\n body.state = 'FAILED';\n break;\n }\n\n await bitbucketServerHttp.postJson(\n // TODO: types (#22198)\n `./rest/build-status/1.0/commits/${branchCommit!}`,\n { body },\n );\n\n // update status cache\n await getStatus(branchName, false);\n await getStatusCheck(branchName, false);\n } catch (err) {\n logger.warn({ err }, `Failed to set branch status`);\n }\n}\n\n// Issue\n\n/* v8 ignore next -- no-op stub: Bitbucket Server has no issues */\nexport function findIssue(title: string): Promise<Issue | null> {\n logger.debug(`findIssue(${title})`);\n // This is used by Renovate when creating its own issues,\n // e.g. for deprecated package warnings,\n // config error notifications, or \"dependencyDashboard\"\n //\n // Bitbucket Server does not have issues\n return Promise.resolve(null);\n}\n\n/* v8 ignore next -- no-op stub: Bitbucket Server has no issues */\nexport function ensureIssue({\n title,\n}: EnsureIssueConfig): Promise<EnsureIssueResult | null> {\n logger.warn({ title }, 'Cannot ensure issue');\n // This is used by Renovate when creating its own issues,\n // e.g. for deprecated package warnings,\n // config error notifications, or \"dependencyDashboard\"\n //\n // Bitbucket Server does not have issues\n return Promise.resolve(null);\n}\n\n/* v8 ignore next -- no-op stub: Bitbucket Server has no issues */\nexport function getIssueList(): Promise<Issue[]> {\n logger.debug(`getIssueList()`);\n // This is used by Renovate when creating its own issues,\n // e.g. for deprecated package warnings,\n // config error notifications, or \"dependencyDashboard\"\n //\n // Bitbucket Server does not have issues\n return Promise.resolve([]);\n}\n\n/* v8 ignore next -- no-op stub: Bitbucket Server has no issues */\nexport function ensureIssueClosing(title: string): Promise<void> {\n logger.debug(`ensureIssueClosing(${title})`);\n // This is used by Renovate when creating its own issues,\n // e.g. for deprecated package warnings,\n // config error notifications, or \"dependencyDashboard\"\n //\n // Bitbucket Server does not have issues\n return Promise.resolve();\n}\n\nexport function addAssignees(iid: number, assignees: string[]): Promise<void> {\n logger.debug(`addAssignees(${iid}, [${assignees.join(', ')}])`);\n // This is used by Renovate when creating its own issues,\n // e.g. for deprecated package warnings,\n // config error notifications, or \"dependencyDashboard\"\n //\n // Bitbucket Server does not have issues\n return Promise.resolve();\n}\n\nexport async function addReviewers(\n prNo: number,\n reviewers: string[],\n): Promise<void> {\n logger.debug(`Adding reviewers '${reviewers.join(', ')}' to #${prNo}`);\n\n const reviewerNames = new Set<string>();\n\n for (const entry of reviewers) {\n // If entry is an email address, resolve username\n if (isEmailAdress(entry)) {\n const names = await getUsernamesByEmail(entry);\n for (const name of names) {\n reviewerNames.add(name);\n }\n } else {\n reviewerNames.add(entry);\n }\n }\n\n await retry(updatePRAndAddReviewers, [prNo, Array.from(reviewerNames)], 3, [\n REPOSITORY_CHANGED,\n ]);\n}\n\n/**\n * Resolves Bitbucket users by email address,\n * restricted to users who have REPO_READ permission on the target repository.\n *\n * @param emailAddress - A string that could be the user's email address.\n * @returns List of usernames for active, matched users.\n */\nexport async function getUsernamesByEmail(\n emailAddress: string,\n): Promise<string[]> {\n try {\n const filterUrl =\n `./rest/api/1.0/users?filter=${emailAddress}` +\n `&permission.1=REPO_READ` +\n `&permission.1.projectKey=${config.projectKey}` +\n `&permission.1.repositorySlug=${config.repositorySlug}`;\n\n const users = await bitbucketServerHttp.getJson(\n filterUrl,\n { paginate: true, limit: 100 },\n Users,\n );\n\n if (users.body.length) {\n return users.body\n .filter((u) => u.active && u.emailAddress === emailAddress)\n .map((u) => u.name);\n }\n } catch (err) {\n logger.warn(\n { err, emailAddress },\n `Failed to resolve email address to username`,\n );\n throw err;\n }\n logger.debug({ userinfo: emailAddress }, 'No users found for email-address');\n return [];\n}\n\nasync function updatePRAndAddReviewers(\n prNo: number,\n reviewers: string[],\n): Promise<void> {\n try {\n const pr = await getPr(prNo);\n if (!pr) {\n throw new Error(REPOSITORY_NOT_FOUND);\n }\n\n // TODO: can `reviewers` be undefined? (#40625)\n const reviewersSet = new Set([...pr.reviewers!, ...reviewers]);\n\n await bitbucketServerHttp.putJson(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}`,\n {\n body: {\n title: pr.title,\n version: pr.version,\n reviewers: Array.from(reviewersSet).map((name) => ({\n user: { name },\n })),\n },\n },\n );\n await getPr(prNo, true);\n } catch (err) {\n logger.warn({ err, reviewers, prNo }, `Failed to add reviewers`);\n if (isNotFound(err)) {\n throw new Error(REPOSITORY_NOT_FOUND);\n } else if (isConflict(err)) {\n if (utils.isInvalidReviewersResponse(err)) {\n // Retry again with invalid reviewers being removed\n const invalidReviewers = utils.getInvalidReviewers(err);\n const filteredReviewers = reviewers.filter(\n (name) => !invalidReviewers.includes(name),\n );\n if (filteredReviewers.length < reviewers.length) {\n await updatePRAndAddReviewers(prNo, filteredReviewers);\n } else {\n logger.warn(\n { invalidReviewers, reviewers },\n 'Could not filter invalid reviewers from list, aborting to prevent infinite recursion',\n );\n throw err;\n }\n } else {\n logger.debug(\n '409 response to adding reviewers - has repository changed?',\n );\n throw new Error(REPOSITORY_CHANGED);\n }\n } else {\n throw err;\n }\n }\n}\n\nasync function retry<T extends (...arg0: any[]) => Promise<any>>(\n fn: T,\n args: Parameters<T>,\n maxTries: number,\n retryErrorMessages: string[],\n): Promise<Awaited<ReturnType<T>>> {\n const maxAttempts = Math.max(maxTries, 1);\n let lastError: Error | undefined;\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n try {\n return await fn(...args);\n } catch (e) {\n lastError = e;\n if (\n retryErrorMessages.length !== 0 &&\n !retryErrorMessages.includes(e.message)\n ) {\n logger.debug(`Error not marked for retry`);\n throw e;\n }\n }\n }\n\n logger.debug(`All ${maxAttempts} retry attempts exhausted`);\n throw lastError!;\n}\n\nexport function deleteLabel(issueNo: number, label: string): Promise<void> {\n logger.debug(`deleteLabel(${issueNo}, ${label})`);\n // Only used for the \"request Renovate to rebase a PR using a label\" feature\n //\n // Bitbucket Server does not have issues\n return Promise.resolve();\n}\n\nasync function getComments(prNo: number): Promise<Comment[]> {\n // GET /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/activities\n const activities = (\n await bitbucketServerHttp.getJsonUnchecked<PullRequestActivity[]>(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/activities`,\n { paginate: true },\n )\n ).body;\n\n const comments = activities\n .filter(\n (a): a is PullRequestCommentActivity =>\n a.action === 'COMMENTED' && 'comment' in a && 'commentAction' in a,\n )\n .filter((a) => a.commentAction === 'ADDED')\n .map((a) => a.comment);\n\n logger.debug(`Found ${comments.length} comments`);\n\n return comments;\n}\n\nasync function addComment(prNo: number, text: string): Promise<void> {\n // POST /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments\n await bitbucketServerHttp.postJson(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/comments`,\n {\n body: { text },\n },\n );\n}\n\nasync function getCommentVersion(\n prNo: number,\n commentId: number,\n): Promise<number> {\n // GET /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments/{commentId}\n const { version } = (\n await bitbucketServerHttp.getJsonUnchecked<{ version: number }>(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/comments/${commentId}`,\n )\n ).body;\n\n return version;\n}\n\nasync function editComment(\n prNo: number,\n commentId: number,\n text: string,\n): Promise<void> {\n const version = await getCommentVersion(prNo, commentId);\n\n // PUT /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments/{commentId}\n await bitbucketServerHttp.putJson(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/comments/${commentId}`,\n {\n body: { text, version },\n },\n );\n}\n\nasync function deleteComment(prNo: number, commentId: number): Promise<void> {\n const version = await getCommentVersion(prNo, commentId);\n\n // DELETE /rest/api/1.0/projects/{projectKey}/repos/{repositorySlug}/pull-requests/{pullRequestId}/comments/{commentId}\n await bitbucketServerHttp.deleteJson(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}/comments/${commentId}?version=${version}`,\n );\n}\n\nexport async function ensureComment({\n number,\n topic,\n content,\n}: EnsureCommentConfig): Promise<boolean> {\n const sanitizedContent = sanitize(content);\n try {\n const comments = await getComments(number);\n let body: string;\n let commentId: number | undefined;\n let commentNeedsUpdating: boolean | undefined;\n if (topic) {\n logger.debug(`Ensuring comment \"${topic}\" in #${number}`);\n body = `### ${topic}\\n\\n${sanitizedContent}`;\n comments.forEach((comment) => {\n if (comment.text.startsWith(`### ${topic}\\n\\n`)) {\n commentId = comment.id;\n commentNeedsUpdating = comment.text !== body;\n }\n });\n } else {\n logger.debug(`Ensuring content-only comment in #${number}`);\n body = `${sanitizedContent}`;\n comments.forEach((comment) => {\n if (comment.text === body) {\n commentId = comment.id;\n commentNeedsUpdating = false;\n }\n });\n }\n if (!commentId) {\n await addComment(number, body);\n logger.info(\n { repository: config.repository, prNo: number, topic },\n 'Comment added',\n );\n } else if (commentNeedsUpdating) {\n await editComment(number, commentId, body);\n logger.debug(\n { repository: config.repository, prNo: number },\n 'Comment updated',\n );\n } else {\n logger.debug('Comment is already up-to-date');\n }\n return true;\n } catch (err) /* v8 ignore next -- defensive: comment API failures are logged and swallowed, not simulated in specs */ {\n logger.warn({ err }, 'Error ensuring comment');\n return false;\n }\n}\n\nfunction byTopic(comment: Comment, topic: string): boolean {\n return comment.text.startsWith(`### ${topic}\\n\\n`);\n}\n\nfunction byContent(comment: Comment, content: string): boolean {\n return comment.text.trim() === content;\n}\n\nexport async function ensureCommentRemoval(\n deleteConfig: EnsureCommentRemovalConfig,\n): Promise<void> {\n try {\n const { number: prNo } = deleteConfig;\n const key =\n deleteConfig.type === 'by-topic'\n ? deleteConfig.topic\n : deleteConfig.content;\n logger.debug(`Ensuring comment \"${key}\" in #${prNo} is removed`);\n const comments = await getComments(prNo);\n\n let commentId: number | null | undefined = null;\n // v8 ignore else -- TODO: add test #40625\n if (deleteConfig.type === 'by-topic') {\n const topic = deleteConfig.topic;\n commentId = comments.find((comment) => byTopic(comment, topic))?.id;\n } else if (deleteConfig.type === 'by-content') {\n const content = deleteConfig.content;\n commentId = comments.find((comment) => byContent(comment, content))?.id;\n }\n\n if (commentId) {\n await deleteComment(prNo, commentId);\n }\n } catch (err) /* v8 ignore next -- defensive: comment API failures are logged and swallowed, not simulated in specs */ {\n logger.warn({ err }, 'Error ensuring comment removal');\n }\n}\n\n// Pull Request\n\nfunction escapeHash(input: string): string {\n return input?.replace(regEx(/#/g), '%23');\n}\n\nexport async function createPr({\n sourceBranch,\n targetBranch,\n prTitle: title,\n prBody: rawDescription,\n platformPrOptions,\n}: CreatePRConfig): Promise<Pr> {\n const description = sanitize(rawDescription);\n logger.debug(`createPr(${sourceBranch}, title=${title})`);\n const base = targetBranch;\n let reviewers: BbsRestUserRef[] = [];\n\n if (platformPrOptions?.bbUseDefaultReviewers) {\n logger.debug(`fetching default reviewers`);\n const { id } = (\n await bitbucketServerHttp.getJsonUnchecked<{ id: number }>(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}`,\n )\n ).body;\n\n const defReviewers = (\n await bitbucketServerHttp.getJsonUnchecked<{ name: string }[]>(\n `./rest/default-reviewers/1.0/projects/${config.projectKey}/repos/${\n config.repositorySlug\n }/reviewers?sourceRefId=refs/heads/${escapeHash(\n sourceBranch,\n )}&targetRefId=refs/heads/${base}&sourceRepoId=${id}&targetRepoId=${id}`,\n )\n ).body;\n\n reviewers = defReviewers.map((u) => ({\n user: { name: u.name },\n }));\n }\n\n const body: PartialDeep<BbsRestPr> = {\n title,\n description,\n fromRef: {\n id: `refs/heads/${sourceBranch}`,\n },\n toRef: {\n id: `refs/heads/${base}`,\n },\n reviewers,\n };\n let prInfoRes: HttpResponse<BbsRestPr>;\n try {\n prInfoRes = await bitbucketServerHttp.postJson<BbsRestPr>(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests`,\n { body },\n );\n } catch (err) /* v8 ignore next -- EmptyPullRequestException handling is not mocked in specs */ {\n if (\n err.body?.errors?.[0]?.exceptionName ===\n 'com.atlassian.bitbucket.pull.EmptyPullRequestException'\n ) {\n logger.debug(\n 'Empty pull request - deleting branch so it can be recreated next run',\n );\n await deleteBranch(sourceBranch);\n throw new Error(REPOSITORY_CHANGED);\n }\n throw err;\n }\n\n const pr: BbsPr = {\n ...utils.prInfo(prInfoRes.body),\n };\n\n // TODO #22198\n updatePrVersion(pr.number, pr.version!);\n await BbsPrCache.setPr(\n bitbucketServerHttp,\n config.projectKey,\n config.repositorySlug,\n config.ignorePrAuthor,\n config.username,\n pr,\n );\n\n await tryPrAutomerge(pr.number, pr.version!, platformPrOptions);\n\n return pr;\n}\n\nexport async function reattemptPlatformAutomerge({\n number,\n platformPrOptions,\n}: ReattemptPlatformAutomergeConfig): Promise<void> {\n logger.debug(`reattemptPlatformAutomerge(${number})`);\n\n try {\n const pr = await getPr(number, true);\n if (!pr) {\n throw new Error(REPOSITORY_NOT_FOUND);\n }\n await tryPrAutomerge(pr.number, pr.version!, platformPrOptions);\n\n logger.debug(`PR platform automerge re-attempted...prNo: ${number}`);\n } catch (err) {\n logger.warn({ err }, 'Error re-attempting PR platform automerge');\n }\n}\n\nexport async function updatePr({\n number: prNo,\n prTitle: title,\n prBody: rawDescription,\n state,\n bitbucketInvalidReviewers,\n targetBranch,\n}: UpdatePrConfig & {\n bitbucketInvalidReviewers?: string[] | undefined;\n}): Promise<void> {\n const description = sanitize(rawDescription);\n logger.debug(`updatePr(${prNo}, title=${title})`);\n\n try {\n const pr = await getPr(prNo);\n if (!pr) {\n throw Object.assign(new Error(REPOSITORY_NOT_FOUND), { statusCode: 404 });\n }\n\n const body: any = {\n title,\n description,\n version: pr.version,\n reviewers: pr.reviewers\n ?.filter((name: string) => !bitbucketInvalidReviewers?.includes(name))\n .map((name: string) => ({ user: { name } })),\n };\n if (targetBranch) {\n body.toRef = {\n id: getNewBranchName(targetBranch),\n };\n }\n\n const { body: updatedPr } = await bitbucketServerHttp.putJson<\n BbsRestPr & {\n version: number;\n }\n >(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNo}`,\n { body },\n );\n\n updatePrVersion(prNo, updatedPr.version);\n\n const currentState = updatedPr.state;\n // TODO #22198\n const newState = {\n ['open']: 'OPEN',\n ['closed']: 'DECLINED',\n }[state!];\n\n let finalState: 'open' | 'closed' =\n currentState === 'OPEN' ? 'open' : 'closed';\n\n if (\n newState &&\n ['OPEN', 'DECLINED'].includes(currentState) &&\n currentState !== newState\n ) {\n const command = state === 'open' ? 'reopen' : 'decline';\n const { body: updatedStatePr } = await bitbucketServerHttp.postJson<{\n version: number;\n }>(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${pr.number}/${command}?version=${updatedPr.version}`,\n );\n\n finalState = state!;\n\n updatePrVersion(pr.number, updatedStatePr.version);\n }\n\n const bbsPr = utils.prInfo(updatedPr);\n await BbsPrCache.setPr(\n bitbucketServerHttp,\n config.projectKey,\n config.repositorySlug,\n config.ignorePrAuthor,\n config.username,\n { ...bbsPr, state: finalState },\n );\n } catch (err) {\n logger.debug({ err, prNo }, `Failed to update PR`);\n if (isNotFound(err)) {\n throw new Error(REPOSITORY_NOT_FOUND);\n } else if (isConflict(err)) {\n if (utils.isInvalidReviewersResponse(err) && !bitbucketInvalidReviewers) {\n // Retry again with invalid reviewers being removed\n const invalidReviewers = utils.getInvalidReviewers(err);\n await updatePr({\n number: prNo,\n prTitle: title,\n prBody: rawDescription,\n state,\n bitbucketInvalidReviewers: invalidReviewers,\n });\n } else {\n throw new Error(REPOSITORY_CHANGED);\n }\n } else {\n throw err;\n }\n }\n}\n\n// https://docs.atlassian.com/bitbucket-server/rest/6.0.0/bitbucket-rest.html#idp261\nexport async function mergePr({\n branchName,\n id: prNo,\n}: MergePRConfig): Promise<boolean> {\n logger.debug(`mergePr(${prNo}, ${branchName!})`);\n // Used for \"automerge\" feature\n try {\n const pr = await getPr(prNo);\n if (!pr) {\n throw Object.assign(new Error(REPOSITORY_NOT_FOUND), { statusCode: 404 });\n }\n const { body } = await bitbucketServerHttp.postJson<{ version: number }>(\n // TODO: types (#22198)\n `./rest/api/1.0/projects/${config.projectKey}/repos/${\n config.repositorySlug\n }/pull-requests/${prNo}/merge?version=${pr.version!}`,\n );\n updatePrVersion(prNo, body.version);\n } catch (err) {\n if (isNotFound(err)) {\n throw new Error(REPOSITORY_NOT_FOUND);\n } else if (isConflict(err)) {\n logger.warn({ err }, `Failed to merge PR`);\n return false;\n } else {\n logger.warn({ err }, `Failed to merge PR`);\n return false;\n }\n }\n\n logger.debug(`PR merged, PrNo:${prNo}`);\n return true;\n}\n\n/**\n * Enables Bitbucket Server-native automerge for the given PR.\n * https://confluence.atlassian.com/bitbucketserver094/merge-a-pull-request-1489802114.html#Mergeapullrequest-Auto-mergeapullrequest\n */\nasync function tryPrAutomerge(\n prNumber: number,\n prVersion: number,\n platformPrOptions?: PlatformPrOptions,\n): Promise<void> {\n if (!platformPrOptions?.usePlatformAutomerge) {\n return;\n }\n\n logger.debug(`tryPrAutomerge(${prNumber})`);\n\n if (semver.lt(defaults.version, '8.15.0')) {\n logger.debug(\n { prNumber },\n 'Bitbucket Server-native automerge: not supported on this version of Bitbucket. Use 8.15.0 or newer.',\n );\n return;\n }\n\n try {\n const body: PullRequestMerge = { autoMerge: true };\n await bitbucketServerHttp.postJson(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/pull-requests/${prNumber}/merge?version=${prVersion}`,\n { body },\n );\n\n // enabling auto-merge doesn't increase PR version, so we omit updating the cache\n logger.debug({ prNumber }, 'Bitbucket Server-native automerge: success');\n } catch (err) {\n logger.warn({ err, prNumber }, 'Bitbucket Server-native automerge: fail');\n }\n}\n\nexport async function expandGroupMembers(\n reviewers: string[],\n): Promise<string[]> {\n logger.debug(`expandGroupMembers(${reviewers.join(', ')})`);\n const expandedUsers: string[] = [];\n const reviewerGroupPrefix = '@reviewer-group/';\n\n for (const reviewer of reviewers) {\n const [baseEntry, modifier] = reviewer.split(':');\n\n if (baseEntry.startsWith(reviewerGroupPrefix)) {\n const groupName = baseEntry.replace(reviewerGroupPrefix, '');\n const groupUsers = await getUsersFromReviewerGroup(groupName);\n if (!groupUsers.length) {\n continue;\n }\n\n if (modifier) {\n const randomCount = parseModifier(modifier);\n if (randomCount) {\n expandedUsers.push(...sampleSize(groupUsers, randomCount));\n continue;\n }\n }\n\n expandedUsers.push(...groupUsers);\n } else {\n expandedUsers.push(baseEntry); // Add the user entry\n }\n }\n\n return [...new Set(expandedUsers)];\n}\n\nexport function extractRulesFromCodeOwnersLines(\n cleanedLines: string[],\n): FileOwnerRule[] {\n const results: FileOwnerRule[] = [];\n\n const reversedLines = cleanedLines\n .filter((line) => line.trim() !== '' && !line.trim().startsWith('#'))\n .reverse();\n\n for (const line of reversedLines) {\n const [pattern, ...entries] = splitEscapedSpaces(line);\n const matcher = ignore().add(pattern);\n results.push({\n pattern,\n usernames: [...new Set(entries)],\n score: pattern.length,\n match: (path: string) => matcher.ignores(path),\n });\n }\n\n return results;\n}\n\n// Gets active users by name, from a reviewer group\n// Returns an empty array if the group is not found or has no active users\n// As there is no direct API to get group by name, we get all reviewer groups per repo and filter them\n// This is not efficient, but it is the only way to get users from a group by name\n// Supports both repository-scoped and project-scoped groups following the BitBucket server logic described here:\n// https://confluence.atlassian.com/bitbucketserver/code-owners-1296171116.html#Codeowners-Whatifaprojectandrepositorycontainareviewergroupwiththesamename?\nasync function getUsersFromReviewerGroup(groupName: string): Promise<string[]> {\n const allGroups = [];\n\n try {\n const reviewerGroups = await bitbucketServerHttp.getJson(\n `./rest/api/1.0/projects/${config.projectKey}/repos/${config.repositorySlug}/settings/reviewer-groups`,\n { paginate: true },\n ReviewerGroups,\n );\n\n allGroups.push(...reviewerGroups.body);\n } catch (err) {\n logger.debug({ err, groupName }, 'Failed to get reviewer groups for repo');\n return [];\n }\n\n // First, try to find a repo-scoped group with this name\n const repoGroup = allGroups.find(\n (group) => group.name === groupName && group.scope?.type === 'REPOSITORY',\n );\n\n if (repoGroup) {\n return repoGroup.users\n .filter((user) => user.active)\n .map((user) => user.name);\n }\n\n // If no repo-level group, fall back to project-level group\n const projectGroup = allGroups.find(\n (group) => group.name === groupName && group.scope?.type === 'PROJECT',\n );\n\n if (projectGroup) {\n return projectGroup.users\n .filter((user) => user.active)\n .map((user) => user.name);\n }\n\n // Group not found at either level\n logger.warn(\n { groupName },\n 'Reviewer group not found at repo or project level',\n );\n return [];\n}\n\nexport function massageMarkdown(input: string): string {\n logger.debug(`massageMarkdown(${input.split(newlineRegex)[0]})`);\n // Remove any HTML we use\n return smartTruncate(input, maxBodyLength())\n .replace(\n 'you tick the rebase/retry checkbox',\n 'PR is renamed to start with \"rebase!\"',\n )\n .replace(\n 'checking the rebase/retry box above',\n 'renaming the PR to start with \"rebase!\"',\n )\n .replace(regEx(/<\\/?summary>/g), '**')\n .replace(regEx(/<\\/?details>/g), '')\n .replace(regEx(`\\n---\\n\\n.*?<!-- rebase-check -->.*?(\\n|$)`), '')\n .replace(regEx(/<!--.*?-->/gs), '')\n .replace(\n regEx(\n /(?<badge>!\\[.+?\\]\\(https:\\/\\/developer\\.mend\\.io\\/api\\/mc\\/badges\\/.+?\\))/g,\n ),\n '$<badge>{height=20}',\n );\n}\n\nexport function maxBodyLength(): number {\n return 30000;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6FA,MAAa,KAAK;AAElB,IAAI,SAAoB,CAAC;AAEzB,MAAM,sBAAsB,IAAI,oBAAoB;AAEpD,MAAM,WAIF;CACF,UAAU;CACV,SAAS;AACX;;AAGA,SAAS,gBAAgB,IAAY,SAAyB;CAC5D,MAAM,MAAM,KAAK,IAAI,OAAO,WAAW,IAAI,EAAE,KAAK,GAAG,OAAO;CAC5D,OAAO,WAAW,IAAI,IAAI,GAAG;CAC7B,OAAO;AACT;AAEA,eAAsB,aAAa,EACjC,UACA,OACA,UACA,UACA,aAC0C;CAC1C,IAAI,CAAC,UACH,MAAM,IAAI,MAAM,sDAAsD;CAExE,IAAI,EAAE,YAAY,aAAa,CAAC,OAC9B,MAAM,IAAI,MACR,6FACF;MACK,IAAI,YAAY,OACrB,MAAM,IAAI,MACR,8FACF;CAGF,SAAS,WAAW,oBAAoB,QAAQ;CAChD,WAAW,SAAS,QAAQ;CAC5B,MAAM,iBAAiC,EACrC,UAAU,SAAS,SACrB;CACA,IAAI;EAEF,IAAI,yBADQ,OACmB,CAAC,CAAC;EACjC,MAAM,EAAE,MAAM,YAAY,MAAM,oBAAoB,iBAEjD,yCAAyC,EAAE,GAAI,SAAS,EAAE,MAAM,EAAG,CAAC;EAEvE,2BAA2B,KAAK;EAChC,IAAI,iCAAiC,QAAQ,cAAc,KAAK,CAAC,UAAU;GACzE,OAAO,MACL,EAAE,eAAe,QAAQ,eAAe,GACxC,iEACF;GACA,OAAO,WAAW,QAAQ;EAC5B;EACA,OAAO,MAAM,gCAAgC,wBAAwB;;EAGrE,IAAI,OAAO,MAAM,sBAAsB,GACrC,SAAS,UAAU;CAEvB,SAAS,KAAK;EACZ,OAAO,MACL,EAAE,IAAI,GACN,yFACF;CACF;CAEA,IAAI,CAAC,aAAa,UAAU;EAC1B,OAAO,MAAM,+CAA+C;EAC5D,MAAM,UAAuB,EAC3B,UAAU,MACZ;EAEA,IAAI,OACF,QAAQ,QAAQ;OACX;GACL,QAAQ,WAAW;GACnB,QAAQ,WAAW;EACrB;EAEA,IAAI;GACF,MAAM,EAAE,aAAa,kBACnB,MAAM,oBAAoB,QACxB,wBAAwB,YACxB,SACA,IACF,EAAA,CACA;GAEF,IAAI,CAAC,cAAc,QACjB,MAAM,IAAI,MAAM,4CAA4C,UAAU;GAGxE,eAAe,YAAY,GAAG,YAAY,IAAI,aAAa;GAE3D,OAAO,MAAM,uBAAuB,eAAe,WAAW;EAChE,SAAS,KAAK;GACZ,OAAO,MACL,EAAE,IAAI,GACN,0DACF;EACF;CACF;CAEA,OAAO;AACT;AAGA,eAAsB,WAA8B;CAClD,OAAO,MAAM,+CAA+C;CAC5D,IAAI;EAQF,MAAM,UANJ,MAAM,oBAAoB,iBACxB,8DACA,EAAE,UAAU,KAAK,CACnB,EAAA,CACA,KAEmB,KAAK,SAAS,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,MAAM;EACrE,OAAO,MAAM,EAAE,OAAO,GAAG,sBAAsB;EAC/C,OAAO;CACT,SAAS,8GAA8G;EACrH,OAAO,MAAM,EAAE,IAAI,GAAG,0BAA0B;EAChD,MAAM;CACR;AACF;AAEA,eAAsB,WACpB,UACA,UACA,aACwB;CAExB,MAAM,CAAC,SAAS,SADH,YAAY,OAAO,WAAA,CACH,MAAM,GAAG;CACtC,MAAM,UAAU,2BAA2B,QAAQ,SAAS,KAAK,UAAU,SAAS,cAAc,cAAc,OAAO,gBAAgB;CAEvI,MAAM,EAAE,YAAY,OAAO,UAAS,MADlB,oBAAoB,iBAA2B,OAAO,EAAA,CAChC;CACxC,IAAI,YACF,OAAO,MAAM,KAAK,EAAE,WAAW,IAAI,CAAC,CAAC,KAAK,IAAI;CAEhD,OAAO,KAAK,EAAE,KAAK,GAAG,qBAAqB;CAC3C,MAAM,IAAI,MAAM,wBAAwB,KAAK,GAAG;AAClD;AAEA,eAAsB,YACpB,UACA,UACA,aACc;CAEd,MAAM,MAAM,MAAM,WAAW,UAAU,UAAU,WAAW;CAC5D,OAAO,UAAU,KAAK,QAAQ;AAChC;AAGA,eAAsB,SAAS,EAC7B,YACA,iBACA,uBACA,UACkC;CAClC,OAAO,MAAM,aAAa,KAAK,UAAU,EAAE,WAAW,GAAG,MAAM,CAAC,EAAE,GAAG;CACrE,MAAM,OAAOA,KAAe;EAC1B,UAAU,SAAS;EACnB,KAAK,SAAS;CAChB,CAAC;CAED,MAAM,CAAC,YAAY,kBAAkB,WAAW,MAAM,GAAG;CAEzD,SAAS;EACP;EACA;EACA;EACA,4BAAY,IAAI,IAAoB;EACpC,UAAU,KAAK;EACf,gBAAgB,aAAa,IAAI,gBAAgB;CACnD;CAEA,IAAI;EACF,MAAM,QACJ,MAAM,oBAAoB,iBACxB,2BAA2B,OAAO,WAAW,SAAS,OAAO,gBAC/D,EAAA,CACA;EACF,OAAO,QAAQ,KAAK,QAAQ;EAC5B,OAAO,MAAM,GAAG,WAAW,WAAW,OAAO,OAAO;EACpD,MAAM,YAAY,MAAM,oBAAoB,iBAC1C,2BAA2B,OAAO,WAAW,SAAS,OAAO,eAAe,kBAC9E;EAGA,IAAI,YAAY,SAAS,KAAK,WAAW,SAAS,GAChD,MAAM,IAAI,MAAM,gBAAgB;EAGlC,MAAM,MAAMC,cACV,OAAO,gBAEP,SAAS,UACT,QACA,MACA,IACF;EAEA,MAAMC,WAAa;GACjB,GAAG;GACH;GACA,gBAAgB,kBAAkB,IAAI;GACtC;GACA;GACA,WAAW,OAAO,IAAI,SAAS,SAAS,OAAO;EACjD,CAAC;EAED,OAAO,cAAc;EAOrB,OAAO;GALL,eAAe,UAAU,KAAK;GAC9B,QAAQ,CAAC,CAAC,KAAK;GACf,iBAAiB,gBAAgB,KAAK,IAAI,SAAS,QAAQ;EAG7C;CAClB,SAAS,6FAA6F;EACpG,IAAI,WAAW,GAAG,GAChB,MAAM,IAAI,MAAM,oBAAoB;EAEtC,IAAI,IAAI,YAAA,SACN,MAAM;EAGR,OAAO,MAAM,EAAE,IAAI,GAAG,kCAAkC;EACxD,MAAM;CACR;AACF;AAEA,eAAsB,qBACpB,aACkB;CAElB,MAAM,MAAM,MAAM,oBAAoB,iBAGpC,2BAA2B,OAAO,WAAW,SAAS,OAAO,eAAe,wBAC9E;CAMA,OAAO,QACL,IAAI,MAAM,aAAa,iBAAiB,GAAG,SAAS,SAAS,CAC/D;AACF;AAGA,eAAsB,MACpB,MACA,cACuB;CACvB,OAAO,MAAM,SAAS,KAAK,EAAE;CAC7B,IAAI,CAAC,MACH,OAAO;CAKT,MAAM,OAAoB,EAAE,UAAU,MAAM;CAE5C,IAAI,CAAC,cACH,KAAK,gBAAgB;CAGvB,MAAM,MAAM,MAAM,oBAAoB,iBACpC,2BAA2B,OAAO,WAAW,SAAS,OAAO,eAAe,iBAAiB,QAC7F,IACF;CAEA,MAAM,KAAY;EAChB,GAAGC,OAAa,IAAI,IAAI;EACxB,WAAW,IAAI,KAAK,UAAU,KAAK,MAAM,EAAE,KAAK,IAAI;CACtD;CAEA,GAAG,UAAU,gBAAgB,GAAG,QAAQ,GAAG,OAAQ;CAEnD,OAAO;AACT;;AAIA,SAAS,aAAa,OAAe,cAA+B;CAClE,IAAI,iBAAiB,OACnB,OAAO;CAET,IAAI,aAAa,WAAW,GAAG,GAC7B,OAAO,UAAU,aAAa,UAAU,CAAC;CAE3C,OAAO,UAAU;AACnB;;AAIA,SAAS,aACP,YACA,SACA,OACA;CACA,QAAQ,MAAmB;EACzB,IAAI,EAAE,iBAAiB,cAAc,CAAC,aAAa,EAAE,OAAO,KAAK,GAC/D,OAAO;EAET,OAAO,CAAC,WAAW,EAAE,MAAM,YAAY,MAAM,QAAQ,YAAY;CACnE;AACF;AAGA,eAAsB,YAA2B;CAC/C,OAAO,MAAM,aAAa;CAC1B,OAAO,MAAM,WAAW,OACtB,qBACA,OAAO,YACP,OAAO,gBACP,OAAO,gBACP,OAAO,QACT;AACF;;AAIA,eAAsB,OAAO,EAC3B,YACA,SACA,QAAQ,OACR,uBACmC;CACnC,OAAO,MAAM,UAAU,WAAW,KAAK,QAAS,MAAM,MAAM,GAAG;CAE/D,IAAI,qBAAqB;EAEvB,MAAM,eAAuC,EAC3C,OAAO,OACT;EACA,aAAa,YAAY;EACzB,aAAa,KAAK,cAAc;EAEhC,MAAM,QAAQ,eAAe,YAAY;EACzC,MAAM,OACJ,MAAM,oBAAoB,iBACxB,2BAA2B,OAAO,WAAW,SAAS,OAAO,eAAe,iBAAiB,SAC7F;GACE,UAAU;GACV,OAAO;EACT,CACF,EAAA,CACA;EAEF,IAAI,CAAC,IAAI,QAAQ;GACf,OAAO,MAAM,0BAA0B,YAAY;GACnD,OAAO;EACT;EAEA,OAAOA,OAAa,IAAI,EAAE;CAC5B;CAGA,MAAM,MAAK,MADU,UAAU,EAAA,CACb,KAAK,aAAa,YAAY,SAAS,KAAK,CAAC;CAC/D,IAAI,IACF,OAAO,MAAM,aAAa,GAAG,QAAQ;MAErC,OAAO,MAAM,yCAAyC,YAAY;CAEpE,OAAO,MAAM;AACf;AAGA,eAAsB,YAAY,YAA2C;CAC3E,OAAO,MAAM,eAAe,WAAW,EAAE;CACzC,MAAM,aAAa,MAAM,OAAO;EAC9B;EACA,OAAO;CACT,CAAC;CACD,OAAO,aAAa,MAAM,WAAW,MAAM,IAAI;AACjD;;AAGA,eAAsB,UAAU,QAA+B;CAE7D,MAAM,WAAW,GAAI;CAErB,MAAM,MAAM,QAAQ,IAAI;AAC1B;AAEA,eAAe,UACb,YACA,WAAW,MACqB;CAChC,MAAM,eAAeC,gBAAoB,UAAU;;CAGnD,MAAM,OAAoB,WACtB,EAAE,eAAe,iBAAiB,IAClC,EAAE,UAAU,MAAM;CAEtB,QACE,MAAM,oBAAoB,iBAExB,yCAAyC,gBACzC,IACF,EAAA,CACA;AACJ;AAKA,eAAsB,gBACpB,YACuB;CACvB,OAAO,MAAM,mBAAmB,WAAW,EAAE;CAE7C,IAAI,CAACC,aAAiB,UAAU,GAAG;EACjC,OAAO,MAAM,6CAA6C;EAC1D,MAAM,IAAI,MAAM,kBAAkB;CACpC;CAEA,IAAI;EACF,MAAM,eAAe,MAAM,UAAU,UAAU;EAE/C,OAAO,MAAM,EAAE,aAAa,GAAG,4BAA4B;EAE3D,IAAI,aAAa,SAAS,GACxB,OAAO;EAET,IAAI,aAAa,aAAa,GAC5B,OAAO;EAET,OAAO,aAAa,aAAa,IAAI,UAAU;CACjD,SAAS,KAAK;EACZ,OAAO,KAAK,EAAE,IAAI,GAAG,6BAA6B;EAClD,OAAO;CACT;AACF;AAEA,eAAe,eACb,YACA,WAAW,MACiB;CAC5B,MAAM,eAAeD,gBAAoB,UAAU;CAEnD,MAAM,OAAmC,EAAE,UAAU,KAAK;;CAE1D,IAAI,UACF,KAAK,gBAAgB;MAErB,KAAK,WAAW;CAGlB,QACE,MAAM,oBAAoB,iBACxB,mCAAmC,gBACnC,IACF,EAAA,CACA;AACJ;AAGA,eAAsB,qBACpB,YACA,SAC8B;CAC9B,OAAO,MAAM,wBAAwB,WAAW,YAAY,QAAQ,EAAE;CAEtE,IAAI;EACF,MAAM,SAAS,MAAM,eAAe,UAAU;EAE9C,KAAK,MAAM,SAAS,QAClB,IAAI,MAAM,QAAQ,SAChB,QAAQ,MAAM,OAAd;GACE,KAAK,cACH,OAAO;GACT,KAAK,cACH,OAAO;GAET,SACE,OAAO;EACX;CAGN,SAAS,KAAK;EACZ,OAAO,KAAK,EAAE,IAAI,GAAG,+BAA+B;CACtD;CACA,OAAO;AACT;AAEA,eAAsB,gBAAgB,EACpC,YACA,SACA,aACA,OACA,KAAK,aAC+B;CACpC,OAAO,MAAM,mBAAmB,WAAW,EAAE;CAG7C,IAAI,MADyB,qBAAqB,YAAY,OAAO,MAC9C,OACrB;CAEF,OAAO,MAAM;EAAE,QAAQ;EAAY;EAAS;CAAM,GAAG,uBAAuB;CAE5E,MAAM,eAAeA,gBAAoB,UAAU;CAEnD,IAAI;EACF,MAAM,OAAY;GAChB,KAAK;GACL;GACA,KAAK,aAAa;EACpB;EAEA,QAAQ,OAAR;GACE,KAAK;IACH,KAAK,QAAQ;IACb;GACF,KAAK;IACH,KAAK,QAAQ;IACb;GAEF,SACE,KAAK,QAAQ;EAEjB;EAEA,MAAM,oBAAoB,SAExB,mCAAmC,gBACnC,EAAE,KAAK,CACT;EAGA,MAAM,UAAU,YAAY,KAAK;EACjC,MAAM,eAAe,YAAY,KAAK;CACxC,SAAS,KAAK;EACZ,OAAO,KAAK,EAAE,IAAI,GAAG,6BAA6B;CACpD;AACF;;AAKA,SAAgB,UAAU,OAAsC;CAC9D,OAAO,MAAM,aAAa,MAAM,EAAE;CAMlC,OAAO,QAAQ,QAAQ,IAAI;AAC7B;;AAGA,SAAgB,YAAY,EAC1B,SACuD;CACvD,OAAO,KAAK,EAAE,MAAM,GAAG,qBAAqB;CAM5C,OAAO,QAAQ,QAAQ,IAAI;AAC7B;;AAGA,SAAgB,eAAiC;CAC/C,OAAO,MAAM,gBAAgB;CAM7B,OAAO,QAAQ,QAAQ,CAAC,CAAC;AAC3B;;AAGA,SAAgB,mBAAmB,OAA8B;CAC/D,OAAO,MAAM,sBAAsB,MAAM,EAAE;CAM3C,OAAO,QAAQ,QAAQ;AACzB;AAEA,SAAgB,aAAa,KAAa,WAAoC;CAC5E,OAAO,MAAM,gBAAgB,IAAI,KAAK,UAAU,KAAK,IAAI,EAAE,GAAG;CAM9D,OAAO,QAAQ,QAAQ;AACzB;AAEA,eAAsB,aACpB,MACA,WACe;CACf,OAAO,MAAM,qBAAqB,UAAU,KAAK,IAAI,EAAE,QAAQ,MAAM;CAErE,MAAM,gCAAgB,IAAI,IAAY;CAEtC,KAAK,MAAM,SAAS,WAElB,IAAI,cAAc,KAAK,GAAG;EACxB,MAAM,QAAQ,MAAM,oBAAoB,KAAK;EAC7C,KAAK,MAAM,QAAQ,OACjB,cAAc,IAAI,IAAI;CAE1B,OACE,cAAc,IAAI,KAAK;CAI3B,MAAM,MAAM,yBAAyB,CAAC,MAAM,MAAM,KAAK,aAAa,CAAC,GAAG,GAAG,CACzE,kBACF,CAAC;AACH;;;;;;;;AASA,eAAsB,oBACpB,cACmB;CACnB,IAAI;EACF,MAAM,YACJ,+BAA+B,aAAA,kDAEH,OAAO,WAAA,+BACH,OAAO;EAEzC,MAAM,QAAQ,MAAM,oBAAoB,QACtC,WACA;GAAE,UAAU;GAAM,OAAO;EAAI,GAC7B,KACF;EAEA,IAAI,MAAM,KAAK,QACb,OAAO,MAAM,KACV,QAAQ,MAAM,EAAE,UAAU,EAAE,iBAAiB,YAAY,CAAC,CAC1D,KAAK,MAAM,EAAE,IAAI;CAExB,SAAS,KAAK;EACZ,OAAO,KACL;GAAE;GAAK;EAAa,GACpB,6CACF;EACA,MAAM;CACR;CACA,OAAO,MAAM,EAAE,UAAU,aAAa,GAAG,kCAAkC;CAC3E,OAAO,CAAC;AACV;AAEA,eAAe,wBACb,MACA,WACe;CACf,IAAI;EACF,MAAM,KAAK,MAAM,MAAM,IAAI;EAC3B,IAAI,CAAC,IACH,MAAM,IAAI,MAAM,oBAAoB;EAItC,MAAM,+BAAe,IAAI,IAAI,CAAC,GAAG,GAAG,WAAY,GAAG,SAAS,CAAC;EAE7D,MAAM,oBAAoB,QACxB,2BAA2B,OAAO,WAAW,SAAS,OAAO,eAAe,iBAAiB,QAC7F,EACE,MAAM;GACJ,OAAO,GAAG;GACV,SAAS,GAAG;GACZ,WAAW,MAAM,KAAK,YAAY,CAAC,CAAC,KAAK,UAAU,EACjD,MAAM,EAAE,KAAK,EACf,EAAE;EACJ,EACF,CACF;EACA,MAAM,MAAM,MAAM,IAAI;CACxB,SAAS,KAAK;EACZ,OAAO,KAAK;GAAE;GAAK;GAAW;EAAK,GAAG,yBAAyB;EAC/D,IAAI,WAAW,GAAG,GAChB,MAAM,IAAI,MAAM,oBAAoB;OAC/B,IAAI,WAAW,GAAG,GAAG;GAC1B,IAAIE,2BAAiC,GAAG,GAAG;IAEzC,MAAM,mBAAmBC,oBAA0B,GAAG;IACtD,MAAM,oBAAoB,UAAU,QACjC,SAAS,CAAC,iBAAiB,SAAS,IAAI,CAC3C;IACA,IAAI,kBAAkB,SAAS,UAAU,QACvC,MAAM,wBAAwB,MAAM,iBAAiB;SAChD;KACL,OAAO,KACL;MAAE;MAAkB;KAAU,GAC9B,sFACF;KACA,MAAM;IACR;GACF,OAAO;IACL,OAAO,MACL,4DACF;IACA,MAAM,IAAI,MAAM,kBAAkB;GACpC;EACF,OACE,MAAM;CAEV;AACF;AAEA,eAAe,MACb,IACA,MACA,UACA,oBACiC;CACjC,MAAM,cAAc,KAAK,IAAI,UAAU,CAAC;CACxC,IAAI;CACJ,KAAK,IAAI,UAAU,GAAG,UAAU,aAAa,WAC3C,IAAI;EACF,OAAO,MAAM,GAAG,GAAG,IAAI;CACzB,SAAS,GAAG;EACV,YAAY;EACZ,IACE,mBAAmB,WAAW,KAC9B,CAAC,mBAAmB,SAAS,EAAE,OAAO,GACtC;GACA,OAAO,MAAM,4BAA4B;GACzC,MAAM;EACR;CACF;CAGF,OAAO,MAAM,OAAO,YAAY,0BAA0B;CAC1D,MAAM;AACR;AAEA,SAAgB,YAAY,SAAiB,OAA8B;CACzE,OAAO,MAAM,eAAe,QAAQ,IAAI,MAAM,EAAE;CAIhD,OAAO,QAAQ,QAAQ;AACzB;AAEA,eAAe,YAAY,MAAkC;CAS3D,MAAM,YANJ,MAAM,oBAAoB,iBACxB,2BAA2B,OAAO,WAAW,SAAS,OAAO,eAAe,iBAAiB,KAAK,cAClG,EAAE,UAAU,KAAK,CACnB,EAAA,CACA,KAGC,QACE,MACC,EAAE,WAAW,eAAe,aAAa,KAAK,mBAAmB,CACrE,CAAC,CACA,QAAQ,MAAM,EAAE,kBAAkB,OAAO,CAAC,CAC1C,KAAK,MAAM,EAAE,OAAO;CAEvB,OAAO,MAAM,SAAS,SAAS,OAAO,UAAU;CAEhD,OAAO;AACT;AAEA,eAAe,WAAW,MAAc,MAA6B;CAEnE,MAAM,oBAAoB,SACxB,2BAA2B,OAAO,WAAW,SAAS,OAAO,eAAe,iBAAiB,KAAK,YAClG,EACE,MAAM,EAAE,KAAK,EACf,CACF;AACF;AAEA,eAAe,kBACb,MACA,WACiB;CAEjB,MAAM,EAAE,aACN,MAAM,oBAAoB,iBACxB,2BAA2B,OAAO,WAAW,SAAS,OAAO,eAAe,iBAAiB,KAAK,YAAY,WAChH,EAAA,CACA;CAEF,OAAO;AACT;AAEA,eAAe,YACb,MACA,WACA,MACe;CACf,MAAM,UAAU,MAAM,kBAAkB,MAAM,SAAS;CAGvD,MAAM,oBAAoB,QACxB,2BAA2B,OAAO,WAAW,SAAS,OAAO,eAAe,iBAAiB,KAAK,YAAY,aAC9G,EACE,MAAM;EAAE;EAAM;CAAQ,EACxB,CACF;AACF;AAEA,eAAe,cAAc,MAAc,WAAkC;CAC3E,MAAM,UAAU,MAAM,kBAAkB,MAAM,SAAS;CAGvD,MAAM,oBAAoB,WACxB,2BAA2B,OAAO,WAAW,SAAS,OAAO,eAAe,iBAAiB,KAAK,YAAY,UAAU,WAAW,SACrI;AACF;AAEA,eAAsB,cAAc,EAClC,QACA,OACA,WACwC;CACxC,MAAM,mBAAmB,SAAS,OAAO;CACzC,IAAI;EACF,MAAM,WAAW,MAAM,YAAY,MAAM;EACzC,IAAI;EACJ,IAAI;EACJ,IAAI;EACJ,IAAI,OAAO;GACT,OAAO,MAAM,qBAAqB,MAAM,QAAQ,QAAQ;GACxD,OAAO,OAAO,MAAM,MAAM;GAC1B,SAAS,SAAS,YAAY;IAC5B,IAAI,QAAQ,KAAK,WAAW,OAAO,MAAM,KAAK,GAAG;KAC/C,YAAY,QAAQ;KACpB,uBAAuB,QAAQ,SAAS;IAC1C;GACF,CAAC;EACH,OAAO;GACL,OAAO,MAAM,qCAAqC,QAAQ;GAC1D,OAAO,GAAG;GACV,SAAS,SAAS,YAAY;IAC5B,IAAI,QAAQ,SAAS,MAAM;KACzB,YAAY,QAAQ;KACpB,uBAAuB;IACzB;GACF,CAAC;EACH;EACA,IAAI,CAAC,WAAW;GACd,MAAM,WAAW,QAAQ,IAAI;GAC7B,OAAO,KACL;IAAE,YAAY,OAAO;IAAY,MAAM;IAAQ;GAAM,GACrD,eACF;EACF,OAAO,IAAI,sBAAsB;GAC/B,MAAM,YAAY,QAAQ,WAAW,IAAI;GACzC,OAAO,MACL;IAAE,YAAY,OAAO;IAAY,MAAM;GAAO,GAC9C,iBACF;EACF,OACE,OAAO,MAAM,+BAA+B;EAE9C,OAAO;CACT,SAAS,8GAA8G;EACrH,OAAO,KAAK,EAAE,IAAI,GAAG,wBAAwB;EAC7C,OAAO;CACT;AACF;AAEA,SAAS,QAAQ,SAAkB,OAAwB;CACzD,OAAO,QAAQ,KAAK,WAAW,OAAO,MAAM,KAAK;AACnD;AAEA,SAAS,UAAU,SAAkB,SAA0B;CAC7D,OAAO,QAAQ,KAAK,KAAK,MAAM;AACjC;AAEA,eAAsB,qBACpB,cACe;CACf,IAAI;EACF,MAAM,EAAE,QAAQ,SAAS;EACzB,MAAM,MACJ,aAAa,SAAS,aAClB,aAAa,QACb,aAAa;EACnB,OAAO,MAAM,qBAAqB,IAAI,QAAQ,KAAK,YAAY;EAC/D,MAAM,WAAW,MAAM,YAAY,IAAI;EAEvC,IAAI,YAAuC;;EAE3C,IAAI,aAAa,SAAS,YAAY;GACpC,MAAM,QAAQ,aAAa;GAC3B,YAAY,SAAS,MAAM,YAAY,QAAQ,SAAS,KAAK,CAAC,CAAC,EAAE;EACnE,OAAO,IAAI,aAAa,SAAS,cAAc;GAC7C,MAAM,UAAU,aAAa;GAC7B,YAAY,SAAS,MAAM,YAAY,UAAU,SAAS,OAAO,CAAC,CAAC,EAAE;EACvE;EAEA,IAAI,WACF,MAAM,cAAc,MAAM,SAAS;CAEvC,SAAS,8GAA8G;EACrH,OAAO,KAAK,EAAE,IAAI,GAAG,gCAAgC;CACvD;AACF;AAIA,SAAS,WAAW,OAAuB;CACzC,OAAO,OAAO,QAAQ,MAAM,IAAI,GAAG,KAAK;AAC1C;AAEA,eAAsB,SAAS,EAC7B,cACA,cACA,SAAS,OACT,QAAQ,gBACR,qBAC8B;CAC9B,MAAM,cAAc,SAAS,cAAc;CAC3C,OAAO,MAAM,YAAY,aAAa,UAAU,MAAM,EAAE;CACxD,MAAM,OAAO;CACb,IAAI,YAA8B,CAAC;CAEnC,IAAI,mBAAmB,uBAAuB;EAC5C,OAAO,MAAM,4BAA4B;EACzC,MAAM,EAAE,QACN,MAAM,oBAAoB,iBACxB,2BAA2B,OAAO,WAAW,SAAS,OAAO,gBAC/D,EAAA,CACA;EAYF,aATE,MAAM,oBAAoB,iBACxB,yCAAyC,OAAO,WAAW,SACzD,OAAO,eACR,oCAAoC,WACnC,YACF,EAAE,0BAA0B,KAAK,gBAAgB,GAAG,gBAAgB,IACtE,EAAA,CACA,KAEuB,KAAK,OAAO,EACnC,MAAM,EAAE,MAAM,EAAE,KAAK,EACvB,EAAE;CACJ;CAEA,MAAM,OAA+B;EACnC;EACA;EACA,SAAS,EACP,IAAI,cAAc,eACpB;EACA,OAAO,EACL,IAAI,cAAc,OACpB;EACA;CACF;CACA,IAAI;CACJ,IAAI;EACF,YAAY,MAAM,oBAAoB,SACpC,2BAA2B,OAAO,WAAW,SAAS,OAAO,eAAe,iBAC5E,EAAE,KAAK,CACT;CACF,SAAS,uFAAuF;EAC9F,IACE,IAAI,MAAM,SAAS,EAAE,EAAE,kBACvB,0DACA;GACA,OAAO,MACL,sEACF;GACA,MAAM,aAAa,YAAY;GAC/B,MAAM,IAAI,MAAM,kBAAkB;EACpC;EACA,MAAM;CACR;CAEA,MAAM,KAAY,EAChB,GAAGJ,OAAa,UAAU,IAAI,EAChC;CAGA,gBAAgB,GAAG,QAAQ,GAAG,OAAQ;CACtC,MAAM,WAAW,MACf,qBACA,OAAO,YACP,OAAO,gBACP,OAAO,gBACP,OAAO,UACP,EACF;CAEA,MAAM,eAAe,GAAG,QAAQ,GAAG,SAAU,iBAAiB;CAE9D,OAAO;AACT;AAEA,eAAsB,2BAA2B,EAC/C,QACA,qBACkD;CAClD,OAAO,MAAM,8BAA8B,OAAO,EAAE;CAEpD,IAAI;EACF,MAAM,KAAK,MAAM,MAAM,QAAQ,IAAI;EACnC,IAAI,CAAC,IACH,MAAM,IAAI,MAAM,oBAAoB;EAEtC,MAAM,eAAe,GAAG,QAAQ,GAAG,SAAU,iBAAiB;EAE9D,OAAO,MAAM,8CAA8C,QAAQ;CACrE,SAAS,KAAK;EACZ,OAAO,KAAK,EAAE,IAAI,GAAG,2CAA2C;CAClE;AACF;AAEA,eAAsB,SAAS,EAC7B,QAAQ,MACR,SAAS,OACT,QAAQ,gBACR,OACA,2BACA,gBAGgB;CAChB,MAAM,cAAc,SAAS,cAAc;CAC3C,OAAO,MAAM,YAAY,KAAK,UAAU,MAAM,EAAE;CAEhD,IAAI;EACF,MAAM,KAAK,MAAM,MAAM,IAAI;EAC3B,IAAI,CAAC,IACH,MAAM,OAAO,OAAO,IAAI,MAAM,oBAAoB,GAAG,EAAE,YAAY,IAAI,CAAC;EAG1E,MAAM,OAAY;GAChB;GACA;GACA,SAAS,GAAG;GACZ,WAAW,GAAG,WACV,QAAQ,SAAiB,CAAC,2BAA2B,SAAS,IAAI,CAAC,CAAC,CACrE,KAAK,UAAkB,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;EAC/C;EACA,IAAI,cACF,KAAK,QAAQ,EACX,IAAI,iBAAiB,YAAY,EACnC;EAGF,MAAM,EAAE,MAAM,cAAc,MAAM,oBAAoB,QAKpD,2BAA2B,OAAO,WAAW,SAAS,OAAO,eAAe,iBAAiB,QAC7F,EAAE,KAAK,CACT;EAEA,gBAAgB,MAAM,UAAU,OAAO;EAEvC,MAAM,eAAe,UAAU;EAE/B,MAAM,WAAW;IACd,SAAS;IACT,WAAW;EACd,EAAE;EAEF,IAAI,aACF,iBAAiB,SAAS,SAAS;EAErC,IACE,YACA,CAAC,QAAQ,UAAU,CAAC,CAAC,SAAS,YAAY,KAC1C,iBAAiB,UACjB;GACA,MAAM,UAAU,UAAU,SAAS,WAAW;GAC9C,MAAM,EAAE,MAAM,mBAAmB,MAAM,oBAAoB,SAGzD,2BAA2B,OAAO,WAAW,SAAS,OAAO,eAAe,iBAAiB,GAAG,OAAO,GAAG,QAAQ,WAAW,UAAU,SACzI;GAEA,aAAa;GAEb,gBAAgB,GAAG,QAAQ,eAAe,OAAO;EACnD;EAEA,MAAM,QAAQA,OAAa,SAAS;EACpC,MAAM,WAAW,MACf,qBACA,OAAO,YACP,OAAO,gBACP,OAAO,gBACP,OAAO,UACP;GAAE,GAAG;GAAO,OAAO;EAAW,CAChC;CACF,SAAS,KAAK;EACZ,OAAO,MAAM;GAAE;GAAK;EAAK,GAAG,qBAAqB;EACjD,IAAI,WAAW,GAAG,GAChB,MAAM,IAAI,MAAM,oBAAoB;OAC/B,IAAI,WAAW,GAAG,GAAG;GAC1B,IAAIG,2BAAiC,GAAG,KAAK,CAAC,2BAG5C,MAAM,SAAS;IACb,QAAQ;IACR,SAAS;IACT,QAAQ;IACR;IACA,2BANuBC,oBAA0B,GAMP;GAC5C,CAAC;QAED,MAAM,IAAI,MAAM,kBAAkB;EAEtC,OACE,MAAM;CAEV;AACF;AAGA,eAAsB,QAAQ,EAC5B,YACA,IAAI,QAC8B;CAClC,OAAO,MAAM,WAAW,KAAK,IAAI,WAAY,EAAE;CAE/C,IAAI;EACF,MAAM,KAAK,MAAM,MAAM,IAAI;EAC3B,IAAI,CAAC,IACH,MAAM,OAAO,OAAO,IAAI,MAAM,oBAAoB,GAAG,EAAE,YAAY,IAAI,CAAC;EAE1E,MAAM,EAAE,SAAS,MAAM,oBAAoB,SAEzC,2BAA2B,OAAO,WAAW,SAC3C,OAAO,eACR,iBAAiB,KAAK,iBAAiB,GAAG,SAC7C;EACA,gBAAgB,MAAM,KAAK,OAAO;CACpC,SAAS,KAAK;EACZ,IAAI,WAAW,GAAG,GAChB,MAAM,IAAI,MAAM,oBAAoB;OAC/B,IAAI,WAAW,GAAG,GAAG;GAC1B,OAAO,KAAK,EAAE,IAAI,GAAG,oBAAoB;GACzC,OAAO;EACT,OAAO;GACL,OAAO,KAAK,EAAE,IAAI,GAAG,oBAAoB;GACzC,OAAO;EACT;CACF;CAEA,OAAO,MAAM,mBAAmB,MAAM;CACtC,OAAO;AACT;;;;;AAMA,eAAe,eACb,UACA,WACA,mBACe;CACf,IAAI,CAAC,mBAAmB,sBACtB;CAGF,OAAO,MAAM,kBAAkB,SAAS,EAAE;CAE1C,IAAI,OAAO,GAAG,SAAS,SAAS,QAAQ,GAAG;EACzC,OAAO,MACL,EAAE,SAAS,GACX,qGACF;EACA;CACF;CAEA,IAAI;EAEF,MAAM,oBAAoB,SACxB,2BAA2B,OAAO,WAAW,SAAS,OAAO,eAAe,iBAAiB,SAAS,iBAAiB,aACvH,EAAE,MAAA,EAH6B,WAAW,KAGrC,EAAE,CACT;EAGA,OAAO,MAAM,EAAE,SAAS,GAAG,4CAA4C;CACzE,SAAS,KAAK;EACZ,OAAO,KAAK;GAAE;GAAK;EAAS,GAAG,yCAAyC;CAC1E;AACF;AAEA,eAAsB,mBACpB,WACmB;CACnB,OAAO,MAAM,sBAAsB,UAAU,KAAK,IAAI,EAAE,EAAE;CAC1D,MAAM,gBAA0B,CAAC;CACjC,MAAM,sBAAsB;CAE5B,KAAK,MAAM,YAAY,WAAW;EAChC,MAAM,CAAC,WAAW,YAAY,SAAS,MAAM,GAAG;EAEhD,IAAI,UAAU,WAAW,mBAAmB,GAAG;GAE7C,MAAM,aAAa,MAAM,0BADP,UAAU,QAAQ,qBAAqB,EACE,CAAC;GAC5D,IAAI,CAAC,WAAW,QACd;GAGF,IAAI,UAAU;IACZ,MAAM,cAAc,cAAc,QAAQ;IAC1C,IAAI,aAAa;KACf,cAAc,KAAK,GAAG,WAAW,YAAY,WAAW,CAAC;KACzD;IACF;GACF;GAEA,cAAc,KAAK,GAAG,UAAU;EAClC,OACE,cAAc,KAAK,SAAS;CAEhC;CAEA,OAAO,CAAC,GAAG,IAAI,IAAI,aAAa,CAAC;AACnC;AAEA,SAAgB,gCACd,cACiB;CACjB,MAAM,UAA2B,CAAC;CAElC,MAAM,gBAAgB,aACnB,QAAQ,SAAS,KAAK,KAAK,MAAM,MAAM,CAAC,KAAK,KAAK,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CACpE,QAAQ;CAEX,KAAK,MAAM,QAAQ,eAAe;EAChC,MAAM,CAAC,SAAS,GAAG,WAAW,mBAAmB,IAAI;EACrD,MAAM,UAAU,OAAO,CAAC,CAAC,IAAI,OAAO;EACpC,QAAQ,KAAK;GACX;GACA,WAAW,CAAC,GAAG,IAAI,IAAI,OAAO,CAAC;GAC/B,OAAO,QAAQ;GACf,QAAQ,SAAiB,QAAQ,QAAQ,IAAI;EAC/C,CAAC;CACH;CAEA,OAAO;AACT;AAQA,eAAe,0BAA0B,WAAsC;CAC7E,MAAM,YAAY,CAAC;CAEnB,IAAI;EACF,MAAM,iBAAiB,MAAM,oBAAoB,QAC/C,2BAA2B,OAAO,WAAW,SAAS,OAAO,eAAe,4BAC5E,EAAE,UAAU,KAAK,GACjB,cACF;EAEA,UAAU,KAAK,GAAG,eAAe,IAAI;CACvC,SAAS,KAAK;EACZ,OAAO,MAAM;GAAE;GAAK;EAAU,GAAG,wCAAwC;EACzE,OAAO,CAAC;CACV;CAGA,MAAM,YAAY,UAAU,MACzB,UAAU,MAAM,SAAS,aAAa,MAAM,OAAO,SAAS,YAC/D;CAEA,IAAI,WACF,OAAO,UAAU,MACd,QAAQ,SAAS,KAAK,MAAM,CAAC,CAC7B,KAAK,SAAS,KAAK,IAAI;CAI5B,MAAM,eAAe,UAAU,MAC5B,UAAU,MAAM,SAAS,aAAa,MAAM,OAAO,SAAS,SAC/D;CAEA,IAAI,cACF,OAAO,aAAa,MACjB,QAAQ,SAAS,KAAK,MAAM,CAAC,CAC7B,KAAK,SAAS,KAAK,IAAI;CAI5B,OAAO,KACL,EAAE,UAAU,GACZ,mDACF;CACA,OAAO,CAAC;AACV;AAEA,SAAgB,gBAAgB,OAAuB;CACrD,OAAO,MAAM,mBAAmB,MAAM,MAAM,YAAY,CAAC,CAAC,GAAG,EAAE;CAE/D,OAAO,cAAc,OAAO,cAAc,CAAC,CAAC,CACzC,QACC,sCACA,yCACF,CAAC,CACA,QACC,uCACA,2CACF,CAAC,CACA,QAAQ,MAAM,eAAe,GAAG,IAAI,CAAC,CACrC,QAAQ,MAAM,eAAe,GAAG,EAAE,CAAC,CACnC,QAAQ,MAAM,4CAA4C,GAAG,EAAE,CAAC,CAChE,QAAQ,MAAM,cAAc,GAAG,EAAE,CAAC,CAClC,QACC,MACE,4EACF,GACA,qBACF;AACJ;AAEA,SAAgB,gBAAwB;CACtC,OAAO;AACT"}
|
|
@@ -314,7 +314,7 @@ async function ensureComment({ number, topic, content }) {
|
|
|
314
314
|
for (const commentObj of prCommentsResponse.commentsForPullRequestData) {
|
|
315
315
|
if (!commentObj?.comments) continue;
|
|
316
316
|
const firstCommentContent = commentObj.comments[0].content;
|
|
317
|
-
if (
|
|
317
|
+
if (topic ? firstCommentContent?.startsWith(header) === true : firstCommentContent === body) {
|
|
318
318
|
commentId = commentObj.comments[0].commentId;
|
|
319
319
|
commentNeedsUpdating = firstCommentContent !== body;
|
|
320
320
|
break;
|
|
@@ -366,7 +366,7 @@ async function ensureCommentRemoval(removeConfig) {
|
|
|
366
366
|
}
|
|
367
367
|
for (const comment of commentObj.comments)
|
|
368
368
|
// v8 ignore else -- TODO: add test #40625
|
|
369
|
-
if (
|
|
369
|
+
if (removeConfig.type === "by-topic" ? comment.content?.startsWith(`### ${removeConfig.topic}\n\n`) === true : removeConfig.content === comment.content?.trim()) {
|
|
370
370
|
commentIdToRemove = comment.commentId;
|
|
371
371
|
break;
|
|
372
372
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["client.listRepositories","client.getRepositoryInfo","client.getCodeCommitUrl","git.initRepo","client.listPullRequests","client.getPr","client.getFile","client.createPr","client.updatePrDescription","client.updatePrTitle","client.updatePrStatus","client.createPrApprovalRule","client.getPrComments","client.createPrComment","client.updateComment","client.deleteComment"],"sources":["../../../../lib/modules/platform/codecommit/index.ts"],"sourcesContent":["import { Buffer } from 'node:buffer';\nimport type {\n GetCommentsForPullRequestOutput,\n ListRepositoriesOutput,\n} from '@aws-sdk/client-codecommit';\nimport { PullRequestStatusEnum } from '@aws-sdk/client-codecommit';\nimport {\n PLATFORM_BAD_CREDENTIALS,\n REPOSITORY_EMPTY,\n REPOSITORY_NOT_FOUND,\n} from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport type { BranchStatus, PrState } from '../../../types/index.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport { parseJson } from '../../../util/common.ts';\nimport * as git from '../../../util/git/index.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { sanitize } from '../../../util/sanitize.ts';\nimport type {\n BranchStatusConfig,\n CreatePRConfig,\n EnsureCommentConfig,\n EnsureCommentRemovalConfig,\n EnsureIssueConfig,\n EnsureIssueResult,\n FindPRConfig,\n Issue,\n MergePRConfig,\n PlatformParams,\n PlatformResult,\n RepoParams,\n RepoResult,\n UpdatePrConfig,\n} from '../types.ts';\nimport { getNewBranchName, repoFingerprint } from '../util.ts';\nimport { smartTruncate } from '../utils/pr-body.ts';\nimport * as client from './codecommit-client.ts';\nimport type { CodeCommitPr } from './types.ts';\n\ninterface Config {\n repository?: string;\n defaultBranch?: string;\n region?: string;\n prList?: CodeCommitPr[];\n}\n\nexport const id = 'codecommit';\nexport const experimental = true;\n\nconst platformConfig = {\n endpoint: 'https://git-codecommit.us-east-1.amazonaws.com',\n};\n\nlet config: Config = {};\n\nexport async function initPlatform({\n endpoint,\n username,\n password,\n token: awsToken,\n}: PlatformParams): Promise<PlatformResult> {\n const accessKeyId = username;\n const secretAccessKey = password;\n const env = process.env;\n let region: string | undefined;\n\n if (accessKeyId) {\n env.AWS_ACCESS_KEY_ID = accessKeyId;\n }\n if (secretAccessKey) {\n env.AWS_SECRET_ACCESS_KEY = secretAccessKey;\n }\n if (awsToken) {\n env.AWS_SESSION_TOKEN = awsToken;\n }\n\n if (endpoint) {\n const regionReg = regEx(/.*codecommit\\.(?<region>.+)\\.amazonaws\\.com/);\n const codeCommitMatch = regionReg.exec(endpoint);\n region = codeCommitMatch?.groups?.region;\n if (region) {\n env.AWS_REGION = region;\n } else {\n logger.warn(\"Can't parse region, make sure your endpoint is correct\");\n }\n }\n\n // If any of the below fails, it will throw an exception stopping the program.\n client.buildCodeCommitClient();\n // To check if we have permission to codecommit, throws exception if failed.\n await client.listRepositories();\n\n platformConfig.endpoint =\n endpoint ??\n `https://git-codecommit.${env.AWS_REGION ?? 'us-east-1'}.amazonaws.com/`;\n\n const platformResult: PlatformResult = {\n endpoint: platformConfig.endpoint,\n };\n return platformResult;\n}\n\nexport async function initRepo({\n repository,\n}: RepoParams): Promise<RepoResult> {\n logger.debug(`initRepo(\"${repository}\")`);\n\n config = { repository };\n\n let repo;\n try {\n repo = await client.getRepositoryInfo(repository);\n } catch (err) {\n logger.error({ err }, 'Could not find repository');\n throw new Error(REPOSITORY_NOT_FOUND);\n }\n\n if (!repo?.repositoryMetadata) {\n logger.error({ repository }, 'Could not find repository');\n throw new Error(REPOSITORY_NOT_FOUND);\n }\n logger.debug({ repositoryDetails: repo }, 'Repository details');\n const metadata = repo.repositoryMetadata;\n\n const url = client.getCodeCommitUrl(metadata, repository);\n try {\n await git.initRepo({\n url,\n });\n } catch (err) {\n logger.debug({ err }, 'Failed to git init');\n throw new Error(PLATFORM_BAD_CREDENTIALS);\n }\n\n if (!metadata.defaultBranch || !metadata.repositoryId) {\n logger.debug('Repo is empty');\n throw new Error(REPOSITORY_EMPTY);\n }\n\n const defaultBranch = metadata.defaultBranch;\n config.defaultBranch = defaultBranch;\n logger.debug(`${repository} default branch = ${defaultBranch}`);\n\n return {\n repoFingerprint: repoFingerprint(\n metadata.repositoryId,\n platformConfig.endpoint,\n ),\n defaultBranch,\n isFork: false,\n };\n}\n\nexport async function getPrList(): Promise<CodeCommitPr[]> {\n logger.debug('getPrList()');\n\n if (config.prList) {\n return config.prList;\n }\n\n const listPrsResponse = await client.listPullRequests(config.repository!);\n const fetchedPrs: CodeCommitPr[] = [];\n\n if (listPrsResponse && !listPrsResponse.pullRequestIds) {\n return fetchedPrs;\n }\n\n const prIds = coerceArray(listPrsResponse.pullRequestIds);\n\n for (const prId of prIds) {\n const prRes = await client.getPr(prId);\n\n if (!prRes?.pullRequest) {\n continue;\n }\n const prInfo = prRes.pullRequest;\n const pr: CodeCommitPr = {\n targetBranch: prInfo.pullRequestTargets![0].destinationReference!,\n sourceBranch: prInfo.pullRequestTargets![0].sourceReference!,\n destinationCommit: prInfo.pullRequestTargets![0].destinationCommit!,\n sourceCommit: prInfo.pullRequestTargets![0].sourceCommit!,\n state:\n prInfo.pullRequestStatus === PullRequestStatusEnum.OPEN\n ? 'open'\n : 'closed',\n number: Number.parseInt(prId, 10),\n title: prInfo.title!,\n body: prInfo.description!,\n createdAt: prInfo.creationDate?.toISOString(),\n };\n fetchedPrs.push(pr);\n }\n\n config.prList = fetchedPrs;\n\n logger.debug(`Retrieved Pull Requests, count: ${fetchedPrs.length}`);\n return fetchedPrs;\n}\n\nexport async function findPr({\n branchName,\n prTitle,\n state = 'all',\n}: FindPRConfig): Promise<CodeCommitPr | null> {\n let prsFiltered: CodeCommitPr[] = [];\n try {\n const prs = await getPrList();\n const refsHeadBranchName = getNewBranchName(branchName);\n prsFiltered = prs.filter(\n (item) => item.sourceBranch === refsHeadBranchName,\n );\n\n if (prTitle) {\n prsFiltered = prsFiltered.filter(\n (item) => item.title.toUpperCase() === prTitle.toUpperCase(),\n );\n }\n\n switch (state) {\n case 'all':\n break;\n case '!open':\n prsFiltered = prsFiltered.filter((item) => item.state !== 'open');\n break;\n default:\n prsFiltered = prsFiltered.filter((item) => item.state === 'open');\n break;\n }\n } catch (err) {\n logger.error({ err }, 'findPr error');\n }\n if (prsFiltered.length === 0) {\n return null;\n }\n return prsFiltered[0];\n}\n\nexport async function getBranchPr(\n branchName: string,\n): Promise<CodeCommitPr | null> {\n logger.debug(`getBranchPr(${branchName})`);\n const existingPr = await findPr({\n branchName,\n state: 'open',\n });\n return existingPr ? getPr(existingPr.number) : null;\n}\n\nexport async function getPr(\n pullRequestId: number,\n): Promise<CodeCommitPr | null> {\n logger.debug(`getPr(${pullRequestId})`);\n const prRes = await client.getPr(`${pullRequestId}`);\n\n if (!prRes?.pullRequest) {\n return null;\n }\n\n const prInfo = prRes.pullRequest;\n let prState: PrState;\n if (prInfo.pullRequestTargets![0].mergeMetadata?.isMerged) {\n prState = 'merged';\n } else {\n prState =\n prInfo.pullRequestStatus === PullRequestStatusEnum.OPEN\n ? 'open'\n : 'closed';\n }\n\n return {\n sourceBranch: prInfo.pullRequestTargets![0].sourceReference!,\n sourceCommit: prInfo.pullRequestTargets![0].sourceCommit!,\n state: prState,\n number: pullRequestId,\n title: prInfo.title!,\n targetBranch: prInfo.pullRequestTargets![0].destinationReference!,\n destinationCommit: prInfo.pullRequestTargets![0].destinationCommit!,\n body: prInfo.description!,\n };\n}\n\nexport async function getRepos(): Promise<string[]> {\n logger.debug('Autodiscovering AWS CodeCommit repositories');\n\n let reposRes: ListRepositoriesOutput;\n try {\n reposRes = await client.listRepositories();\n //todo do we need pagination? maximum number of repos is 1000 without pagination, also the same for free account\n } catch (err) {\n logger.error({ err }, 'Could not retrieve repositories');\n return [];\n }\n\n const res: string[] = [];\n\n const repoNames = coerceArray(reposRes?.repositories);\n\n for (const repo of repoNames) {\n // v8 ignore else -- TODO: add test #40625\n if (repo.repositoryName) {\n res.push(repo.repositoryName);\n }\n }\n\n return res;\n}\n\nexport function massageMarkdown(input: string): string {\n // Remove any HTML we use\n return input\n .replace(\n 'you tick the rebase/retry checkbox',\n 'PR is renamed to start with \"rebase!\"',\n )\n .replace(\n 'checking the rebase/retry box above',\n 'renaming the PR to start with \"rebase!\"',\n )\n .replace(regEx(/<\\/?summary>/g), '**')\n .replace(regEx(/<\\/?details>/g), '')\n .replace(regEx(`\\n---\\n\\n.*?<!-- rebase-check -->.*?\\n`), '')\n .replace(regEx(/\\]\\(\\.\\.\\/issues\\//g), '](#')\n .replace(regEx(/\\]\\(\\.\\.\\/pull\\//g), '](../../pull-requests/')\n .replace(\n regEx(/(?<hiddenComment><!--renovate-(?:debug|config-hash):.*?-->)/g),\n '[//]: # ($<hiddenComment>)',\n );\n}\n\n/**\n * Unsed, no Dashboard\n */\nexport function maxBodyLength(): number {\n return Infinity;\n}\n\nexport async function getJsonFile(\n fileName: string,\n repoName?: string,\n branchOrTag?: string,\n): Promise<any> {\n const raw = await getRawFile(fileName, repoName, branchOrTag);\n return parseJson(raw, fileName);\n}\n\nexport async function getRawFile(\n fileName: string,\n repoName?: string,\n branchOrTag?: string,\n): Promise<string | null> {\n const fileRes = await client.getFile(\n repoName ?? config.repository,\n fileName,\n branchOrTag,\n );\n if (!fileRes?.fileContent) {\n return null;\n }\n const buf = Buffer.from(fileRes.fileContent);\n return buf.toString();\n}\n\nconst AMAZON_MAX_BODY_LENGTH = 10239;\n\nexport async function createPr({\n sourceBranch,\n targetBranch,\n prTitle: title,\n prBody: body,\n}: CreatePRConfig): Promise<CodeCommitPr> {\n const description = smartTruncate(sanitize(body), AMAZON_MAX_BODY_LENGTH);\n\n const prCreateRes = await client.createPr(\n title,\n sanitize(description),\n sourceBranch,\n targetBranch,\n config.repository,\n );\n\n if (\n !prCreateRes.pullRequest?.title ||\n !prCreateRes.pullRequest?.pullRequestId ||\n !prCreateRes.pullRequest?.description ||\n !prCreateRes.pullRequest?.pullRequestTargets?.length\n ) {\n throw new Error('Could not create pr, missing PR info');\n }\n\n return {\n number: Number.parseInt(prCreateRes.pullRequest.pullRequestId, 10),\n state: 'open',\n title: prCreateRes.pullRequest.title,\n sourceBranch,\n targetBranch,\n sourceCommit: prCreateRes.pullRequest.pullRequestTargets[0].sourceCommit!,\n destinationCommit:\n prCreateRes.pullRequest.pullRequestTargets[0].destinationCommit!,\n sourceRepo: config.repository,\n body: prCreateRes.pullRequest.description,\n };\n}\n\nexport async function updatePr({\n number: prNo,\n prTitle: title,\n prBody: body,\n state,\n}: UpdatePrConfig): Promise<void> {\n logger.debug(`updatePr(${prNo}, ${title}, body)`);\n\n let cachedPr: CodeCommitPr | undefined = undefined;\n const cachedPrs = coerceArray(config.prList);\n for (const p of cachedPrs) {\n // v8 ignore else -- TODO: add test #40625\n if (p.number === prNo) {\n cachedPr = p;\n }\n }\n\n // v8 ignore else -- TODO: add test #40625\n if (body && cachedPr?.body !== body) {\n await client.updatePrDescription(\n `${prNo}`,\n smartTruncate(sanitize(body), AMAZON_MAX_BODY_LENGTH),\n );\n }\n\n // v8 ignore else -- TODO: add test #40625\n if (title && cachedPr?.title !== title) {\n await client.updatePrTitle(`${prNo}`, title);\n }\n\n const prStatusInput =\n state === 'closed'\n ? PullRequestStatusEnum.CLOSED\n : PullRequestStatusEnum.OPEN;\n // v8 ignore else -- TODO: add test #40625\n if (cachedPr?.state !== prStatusInput) {\n try {\n await client.updatePrStatus(`${prNo}`, prStatusInput);\n } catch {\n // safety check\n // do nothing, it's ok to fail sometimes when trying to update from open to open or from closed to closed.\n }\n }\n}\n\n// Auto-Merge not supported currently.\n/* v8 ignore next -- auto-merge is not supported on CodeCommit, so this stub is unexercised */\nexport async function mergePr({\n branchName,\n id: prNo,\n}: MergePRConfig): Promise<boolean> {\n logger.debug(`mergePr(${prNo}, ${branchName!})`);\n await client.getPr(`${prNo}`);\n return Promise.resolve(false);\n //\n // if (!prOut) {\n // return false;\n // }\n // const pReq = prOut.pullRequest;\n // const targets = pReq?.pullRequestTargets;\n //\n // if (!targets) {\n // return false;\n // }\n //\n // if (strategy === 'rebase') {\n // logger.warn('CodeCommit does not support a \"rebase\" strategy.');\n // return false;\n // }\n //\n // try {\n // if (strategy === 'auto' || strategy === 'squash') {\n // await client.squashMerge(\n // targets[0].repositoryName!,\n // targets[0].sourceReference!,\n // targets[0].destinationReference!,\n // pReq?.title\n // );\n // } else if (strategy === 'fast-forward') {\n // await client.fastForwardMerge(\n // targets[0].repositoryName!,\n // targets[0].sourceReference!,\n // targets[0].destinationReference!\n // );\n // } else {\n // logger.debug(`unsupported strategy`);\n // return false;\n // }\n // } catch (err) {\n // logger.debug({ err }, `PR merge error`);\n // logger.info({ pr: prNo }, 'PR automerge failed');\n // return false;\n // }\n //\n // logger.trace(`Updating PR ${prNo} to status ${PullRequestStatusEnum.CLOSED}`);\n //\n // try {\n // const response = await client.updatePrStatus(\n // `${prNo}`,\n // PullRequestStatusEnum.CLOSED\n // );\n // const isClosed =\n // response.pullRequest?.pullRequestStatus === PullRequestStatusEnum.CLOSED;\n //\n // if (!isClosed) {\n // logger.warn(\n // {\n // pullRequestId: prNo,\n // status: response.pullRequest?.pullRequestStatus,\n // },\n // `Expected PR to have status`\n // );\n // }\n // return true;\n // } catch (err) {\n // logger.debug({ err }, 'Failed to set the PR as Closed.');\n // return false;\n // }\n}\n\nexport async function addReviewers(\n prNo: number,\n reviewers: string[],\n): Promise<void> {\n const numberOfApprovers = reviewers.length;\n const approvalRuleContents = `{\"Version\":\"2018-11-08\",\"Statements\": [{\"Type\": \"Approvers\",\"NumberOfApprovalsNeeded\":${numberOfApprovers},\"ApprovalPoolMembers\": ${JSON.stringify(\n reviewers,\n )}}]}`;\n const res = await client.createPrApprovalRule(\n `${prNo}`,\n approvalRuleContents,\n );\n // v8 ignore else -- TODO: add test #40625\n if (res) {\n const approvalRule = res.approvalRule;\n logger.debug({ approvalRule }, `Approval Rule Added to PR #${prNo}:`);\n }\n}\n\n/* v8 ignore next -- no-op stub: CodeCommit does not support adding assignees */\nexport function addAssignees(\n _iid: number,\n _assignees: string[],\n): Promise<void> {\n // CodeCommit does not support adding reviewers\n return Promise.resolve();\n}\n\n/* v8 ignore next -- no-op stub: CodeCommit has no issues */\nexport function findIssue(_title: string): Promise<Issue | null> {\n // CodeCommit does not have issues\n return Promise.resolve(null);\n}\n\n/* v8 ignore next -- no-op stub: CodeCommit has no issues */\nexport function ensureIssue(\n _cfg: EnsureIssueConfig,\n): Promise<EnsureIssueResult | null> {\n // CodeCommit does not have issues\n return Promise.resolve(null);\n}\n\n/* v8 ignore next -- no-op stub: CodeCommit has no issues */\nexport function getIssueList(): Promise<Issue[]> {\n // CodeCommit does not have issues\n return Promise.resolve([]);\n}\n\n/* v8 ignore next -- no-op stub: CodeCommit has no issues */\nexport function ensureIssueClosing(_title: string): Promise<void> {\n // CodeCommit does not have issues\n return Promise.resolve();\n}\n\n/* v8 ignore next -- no-op stub: label deletion is not implemented for CodeCommit */\nexport function deleteLabel(_prNumber: number, _label: string): Promise<void> {\n return Promise.resolve();\n}\n\n// Returns the combined status for a branch.\n/* v8 ignore next -- stub: branch statuses are not supported on CodeCommit yet, always yellow */\nexport function getBranchStatus(branchName: string): Promise<BranchStatus> {\n logger.debug(`getBranchStatus(${branchName})`);\n logger.debug(\n 'returning branch status yellow, because getBranchStatus isnt supported on aws yet',\n );\n return Promise.resolve('yellow');\n}\n\n/* v8 ignore next -- stub: branch status checks are not supported on CodeCommit yet, always null */\nexport function getBranchStatusCheck(\n branchName: string,\n context: string,\n): Promise<BranchStatus | null> {\n logger.debug(`getBranchStatusCheck(${branchName}, context=${context})`);\n logger.debug(\n 'returning null, because getBranchStatusCheck is not supported on aws yet',\n );\n return Promise.resolve(null);\n}\n\n/* v8 ignore next -- no-op stub: setting branch status is not supported on CodeCommit */\nexport function setBranchStatus(_cfg: BranchStatusConfig): Promise<void> {\n return Promise.resolve();\n}\n\nexport async function ensureComment({\n number,\n topic,\n content,\n}: EnsureCommentConfig): Promise<boolean> {\n logger.debug(`ensureComment(${number}, ${topic!}, content)`);\n const header = topic ? `### ${topic}\\n\\n` : '';\n const body = `${header}${sanitize(content)}`;\n let prCommentsResponse: GetCommentsForPullRequestOutput;\n try {\n prCommentsResponse = await client.getPrComments(`${number}`);\n } catch (err) {\n logger.debug({ err }, 'Unable to retrieve pr comments');\n return false;\n }\n\n let commentId: string | undefined = undefined;\n let commentNeedsUpdating = false;\n\n if (!prCommentsResponse?.commentsForPullRequestData) {\n return false;\n }\n\n for (const commentObj of prCommentsResponse.commentsForPullRequestData) {\n if (!commentObj?.comments) {\n continue;\n }\n const firstCommentContent = commentObj.comments[0].content;\n if (\n (topic && firstCommentContent?.startsWith(header)) === true ||\n (!topic && firstCommentContent === body)\n ) {\n commentId = commentObj.comments[0].commentId;\n commentNeedsUpdating = firstCommentContent !== body;\n break;\n }\n }\n\n if (!commentId) {\n const prs = await getPrList();\n const thisPr = prs.filter((item) => item.number === number);\n\n if (!thisPr[0].sourceCommit || !thisPr[0].destinationCommit) {\n return false;\n }\n\n await client.createPrComment(\n `${number}`,\n config.repository,\n body,\n thisPr[0].destinationCommit,\n thisPr[0].sourceCommit,\n );\n logger.info(\n { repository: config.repository, prNo: number, topic },\n 'Comment added',\n );\n } else if (commentNeedsUpdating && commentId) {\n await client.updateComment(commentId, body);\n\n logger.debug(\n { repository: config.repository, prNo: number, topic },\n 'Comment updated',\n );\n } else {\n logger.debug(\n { repository: config.repository, prNo: number, topic },\n 'Comment is already up-to-date',\n );\n }\n\n return true;\n}\n\nexport async function ensureCommentRemoval(\n removeConfig: EnsureCommentRemovalConfig,\n): Promise<void> {\n const { number: prNo } = removeConfig;\n const key =\n removeConfig.type === 'by-topic'\n ? removeConfig.topic\n : removeConfig.content;\n logger.debug(`Ensuring comment \"${key}\" in #${prNo} is removed`);\n\n let prCommentsResponse: GetCommentsForPullRequestOutput;\n try {\n prCommentsResponse = await client.getPrComments(`${prNo}`);\n } catch (err) {\n logger.debug({ err }, 'Unable to retrieve pr comments');\n return;\n }\n\n if (!prCommentsResponse?.commentsForPullRequestData) {\n logger.debug('commentsForPullRequestData not found');\n return;\n }\n\n let commentIdToRemove: string | undefined;\n for (const commentObj of prCommentsResponse.commentsForPullRequestData) {\n if (!commentObj?.comments) {\n logger.debug(\n 'comments object not found under commentsForPullRequestData',\n );\n continue;\n }\n\n for (const comment of commentObj.comments) {\n // v8 ignore else -- TODO: add test #40625\n if (\n (removeConfig.type === 'by-topic' &&\n comment.content?.startsWith(`### ${removeConfig.topic}\\n\\n`)) ===\n true ||\n (removeConfig.type === 'by-content' &&\n removeConfig.content === comment.content?.trim())\n ) {\n commentIdToRemove = comment.commentId;\n break;\n }\n }\n // v8 ignore else -- TODO: add test #40625\n if (commentIdToRemove) {\n await client.deleteComment(commentIdToRemove);\n logger.debug(`comment \"${key}\" in PR #${prNo} was removed`);\n break;\n }\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["client.listRepositories","client.getRepositoryInfo","client.getCodeCommitUrl","git.initRepo","client.listPullRequests","client.getPr","client.getFile","client.createPr","client.updatePrDescription","client.updatePrTitle","client.updatePrStatus","client.createPrApprovalRule","client.getPrComments","client.createPrComment","client.updateComment","client.deleteComment"],"sources":["../../../../lib/modules/platform/codecommit/index.ts"],"sourcesContent":["import { Buffer } from 'node:buffer';\nimport type {\n GetCommentsForPullRequestOutput,\n ListRepositoriesOutput,\n} from '@aws-sdk/client-codecommit';\nimport { PullRequestStatusEnum } from '@aws-sdk/client-codecommit';\nimport {\n PLATFORM_BAD_CREDENTIALS,\n REPOSITORY_EMPTY,\n REPOSITORY_NOT_FOUND,\n} from '../../../constants/error-messages.ts';\nimport { logger } from '../../../logger/index.ts';\nimport type { BranchStatus, PrState } from '../../../types/index.ts';\nimport { coerceArray } from '../../../util/array.ts';\nimport { parseJson } from '../../../util/common.ts';\nimport * as git from '../../../util/git/index.ts';\nimport { regEx } from '../../../util/regex.ts';\nimport { sanitize } from '../../../util/sanitize.ts';\nimport type {\n BranchStatusConfig,\n CreatePRConfig,\n EnsureCommentConfig,\n EnsureCommentRemovalConfig,\n EnsureIssueConfig,\n EnsureIssueResult,\n FindPRConfig,\n Issue,\n MergePRConfig,\n PlatformParams,\n PlatformResult,\n RepoParams,\n RepoResult,\n UpdatePrConfig,\n} from '../types.ts';\nimport { getNewBranchName, repoFingerprint } from '../util.ts';\nimport { smartTruncate } from '../utils/pr-body.ts';\nimport * as client from './codecommit-client.ts';\nimport type { CodeCommitPr } from './types.ts';\n\ninterface Config {\n repository?: string;\n defaultBranch?: string;\n region?: string;\n prList?: CodeCommitPr[];\n}\n\nexport const id = 'codecommit';\nexport const experimental = true;\n\nconst platformConfig = {\n endpoint: 'https://git-codecommit.us-east-1.amazonaws.com',\n};\n\nlet config: Config = {};\n\nexport async function initPlatform({\n endpoint,\n username,\n password,\n token: awsToken,\n}: PlatformParams): Promise<PlatformResult> {\n const accessKeyId = username;\n const secretAccessKey = password;\n const env = process.env;\n let region: string | undefined;\n\n if (accessKeyId) {\n env.AWS_ACCESS_KEY_ID = accessKeyId;\n }\n if (secretAccessKey) {\n env.AWS_SECRET_ACCESS_KEY = secretAccessKey;\n }\n if (awsToken) {\n env.AWS_SESSION_TOKEN = awsToken;\n }\n\n if (endpoint) {\n const regionReg = regEx(/.*codecommit\\.(?<region>.+)\\.amazonaws\\.com/);\n const codeCommitMatch = regionReg.exec(endpoint);\n region = codeCommitMatch?.groups?.region;\n if (region) {\n env.AWS_REGION = region;\n } else {\n logger.warn(\"Can't parse region, make sure your endpoint is correct\");\n }\n }\n\n // If any of the below fails, it will throw an exception stopping the program.\n client.buildCodeCommitClient();\n // To check if we have permission to codecommit, throws exception if failed.\n await client.listRepositories();\n\n platformConfig.endpoint =\n endpoint ??\n `https://git-codecommit.${env.AWS_REGION ?? 'us-east-1'}.amazonaws.com/`;\n\n const platformResult: PlatformResult = {\n endpoint: platformConfig.endpoint,\n };\n return platformResult;\n}\n\nexport async function initRepo({\n repository,\n}: RepoParams): Promise<RepoResult> {\n logger.debug(`initRepo(\"${repository}\")`);\n\n config = { repository };\n\n let repo;\n try {\n repo = await client.getRepositoryInfo(repository);\n } catch (err) {\n logger.error({ err }, 'Could not find repository');\n throw new Error(REPOSITORY_NOT_FOUND);\n }\n\n if (!repo?.repositoryMetadata) {\n logger.error({ repository }, 'Could not find repository');\n throw new Error(REPOSITORY_NOT_FOUND);\n }\n logger.debug({ repositoryDetails: repo }, 'Repository details');\n const metadata = repo.repositoryMetadata;\n\n const url = client.getCodeCommitUrl(metadata, repository);\n try {\n await git.initRepo({\n url,\n });\n } catch (err) {\n logger.debug({ err }, 'Failed to git init');\n throw new Error(PLATFORM_BAD_CREDENTIALS);\n }\n\n if (!metadata.defaultBranch || !metadata.repositoryId) {\n logger.debug('Repo is empty');\n throw new Error(REPOSITORY_EMPTY);\n }\n\n const defaultBranch = metadata.defaultBranch;\n config.defaultBranch = defaultBranch;\n logger.debug(`${repository} default branch = ${defaultBranch}`);\n\n return {\n repoFingerprint: repoFingerprint(\n metadata.repositoryId,\n platformConfig.endpoint,\n ),\n defaultBranch,\n isFork: false,\n };\n}\n\nexport async function getPrList(): Promise<CodeCommitPr[]> {\n logger.debug('getPrList()');\n\n if (config.prList) {\n return config.prList;\n }\n\n const listPrsResponse = await client.listPullRequests(config.repository!);\n const fetchedPrs: CodeCommitPr[] = [];\n\n if (listPrsResponse && !listPrsResponse.pullRequestIds) {\n return fetchedPrs;\n }\n\n const prIds = coerceArray(listPrsResponse.pullRequestIds);\n\n for (const prId of prIds) {\n const prRes = await client.getPr(prId);\n\n if (!prRes?.pullRequest) {\n continue;\n }\n const prInfo = prRes.pullRequest;\n const pr: CodeCommitPr = {\n targetBranch: prInfo.pullRequestTargets![0].destinationReference!,\n sourceBranch: prInfo.pullRequestTargets![0].sourceReference!,\n destinationCommit: prInfo.pullRequestTargets![0].destinationCommit!,\n sourceCommit: prInfo.pullRequestTargets![0].sourceCommit!,\n state:\n prInfo.pullRequestStatus === PullRequestStatusEnum.OPEN\n ? 'open'\n : 'closed',\n number: Number.parseInt(prId, 10),\n title: prInfo.title!,\n body: prInfo.description!,\n createdAt: prInfo.creationDate?.toISOString(),\n };\n fetchedPrs.push(pr);\n }\n\n config.prList = fetchedPrs;\n\n logger.debug(`Retrieved Pull Requests, count: ${fetchedPrs.length}`);\n return fetchedPrs;\n}\n\nexport async function findPr({\n branchName,\n prTitle,\n state = 'all',\n}: FindPRConfig): Promise<CodeCommitPr | null> {\n let prsFiltered: CodeCommitPr[] = [];\n try {\n const prs = await getPrList();\n const refsHeadBranchName = getNewBranchName(branchName);\n prsFiltered = prs.filter(\n (item) => item.sourceBranch === refsHeadBranchName,\n );\n\n if (prTitle) {\n prsFiltered = prsFiltered.filter(\n (item) => item.title.toUpperCase() === prTitle.toUpperCase(),\n );\n }\n\n switch (state) {\n case 'all':\n break;\n case '!open':\n prsFiltered = prsFiltered.filter((item) => item.state !== 'open');\n break;\n default:\n prsFiltered = prsFiltered.filter((item) => item.state === 'open');\n break;\n }\n } catch (err) {\n logger.error({ err }, 'findPr error');\n }\n if (prsFiltered.length === 0) {\n return null;\n }\n return prsFiltered[0];\n}\n\nexport async function getBranchPr(\n branchName: string,\n): Promise<CodeCommitPr | null> {\n logger.debug(`getBranchPr(${branchName})`);\n const existingPr = await findPr({\n branchName,\n state: 'open',\n });\n return existingPr ? getPr(existingPr.number) : null;\n}\n\nexport async function getPr(\n pullRequestId: number,\n): Promise<CodeCommitPr | null> {\n logger.debug(`getPr(${pullRequestId})`);\n const prRes = await client.getPr(`${pullRequestId}`);\n\n if (!prRes?.pullRequest) {\n return null;\n }\n\n const prInfo = prRes.pullRequest;\n let prState: PrState;\n if (prInfo.pullRequestTargets![0].mergeMetadata?.isMerged) {\n prState = 'merged';\n } else {\n prState =\n prInfo.pullRequestStatus === PullRequestStatusEnum.OPEN\n ? 'open'\n : 'closed';\n }\n\n return {\n sourceBranch: prInfo.pullRequestTargets![0].sourceReference!,\n sourceCommit: prInfo.pullRequestTargets![0].sourceCommit!,\n state: prState,\n number: pullRequestId,\n title: prInfo.title!,\n targetBranch: prInfo.pullRequestTargets![0].destinationReference!,\n destinationCommit: prInfo.pullRequestTargets![0].destinationCommit!,\n body: prInfo.description!,\n };\n}\n\nexport async function getRepos(): Promise<string[]> {\n logger.debug('Autodiscovering AWS CodeCommit repositories');\n\n let reposRes: ListRepositoriesOutput;\n try {\n reposRes = await client.listRepositories();\n //todo do we need pagination? maximum number of repos is 1000 without pagination, also the same for free account\n } catch (err) {\n logger.error({ err }, 'Could not retrieve repositories');\n return [];\n }\n\n const res: string[] = [];\n\n const repoNames = coerceArray(reposRes?.repositories);\n\n for (const repo of repoNames) {\n // v8 ignore else -- TODO: add test #40625\n if (repo.repositoryName) {\n res.push(repo.repositoryName);\n }\n }\n\n return res;\n}\n\nexport function massageMarkdown(input: string): string {\n // Remove any HTML we use\n return input\n .replace(\n 'you tick the rebase/retry checkbox',\n 'PR is renamed to start with \"rebase!\"',\n )\n .replace(\n 'checking the rebase/retry box above',\n 'renaming the PR to start with \"rebase!\"',\n )\n .replace(regEx(/<\\/?summary>/g), '**')\n .replace(regEx(/<\\/?details>/g), '')\n .replace(regEx(`\\n---\\n\\n.*?<!-- rebase-check -->.*?\\n`), '')\n .replace(regEx(/\\]\\(\\.\\.\\/issues\\//g), '](#')\n .replace(regEx(/\\]\\(\\.\\.\\/pull\\//g), '](../../pull-requests/')\n .replace(\n regEx(/(?<hiddenComment><!--renovate-(?:debug|config-hash):.*?-->)/g),\n '[//]: # ($<hiddenComment>)',\n );\n}\n\n/**\n * Unsed, no Dashboard\n */\nexport function maxBodyLength(): number {\n return Infinity;\n}\n\nexport async function getJsonFile(\n fileName: string,\n repoName?: string,\n branchOrTag?: string,\n): Promise<any> {\n const raw = await getRawFile(fileName, repoName, branchOrTag);\n return parseJson(raw, fileName);\n}\n\nexport async function getRawFile(\n fileName: string,\n repoName?: string,\n branchOrTag?: string,\n): Promise<string | null> {\n const fileRes = await client.getFile(\n repoName ?? config.repository,\n fileName,\n branchOrTag,\n );\n if (!fileRes?.fileContent) {\n return null;\n }\n const buf = Buffer.from(fileRes.fileContent);\n return buf.toString();\n}\n\nconst AMAZON_MAX_BODY_LENGTH = 10239;\n\nexport async function createPr({\n sourceBranch,\n targetBranch,\n prTitle: title,\n prBody: body,\n}: CreatePRConfig): Promise<CodeCommitPr> {\n const description = smartTruncate(sanitize(body), AMAZON_MAX_BODY_LENGTH);\n\n const prCreateRes = await client.createPr(\n title,\n sanitize(description),\n sourceBranch,\n targetBranch,\n config.repository,\n );\n\n if (\n !prCreateRes.pullRequest?.title ||\n !prCreateRes.pullRequest?.pullRequestId ||\n !prCreateRes.pullRequest?.description ||\n !prCreateRes.pullRequest?.pullRequestTargets?.length\n ) {\n throw new Error('Could not create pr, missing PR info');\n }\n\n return {\n number: Number.parseInt(prCreateRes.pullRequest.pullRequestId, 10),\n state: 'open',\n title: prCreateRes.pullRequest.title,\n sourceBranch,\n targetBranch,\n sourceCommit: prCreateRes.pullRequest.pullRequestTargets[0].sourceCommit!,\n destinationCommit:\n prCreateRes.pullRequest.pullRequestTargets[0].destinationCommit!,\n sourceRepo: config.repository,\n body: prCreateRes.pullRequest.description,\n };\n}\n\nexport async function updatePr({\n number: prNo,\n prTitle: title,\n prBody: body,\n state,\n}: UpdatePrConfig): Promise<void> {\n logger.debug(`updatePr(${prNo}, ${title}, body)`);\n\n let cachedPr: CodeCommitPr | undefined = undefined;\n const cachedPrs = coerceArray(config.prList);\n for (const p of cachedPrs) {\n // v8 ignore else -- TODO: add test #40625\n if (p.number === prNo) {\n cachedPr = p;\n }\n }\n\n // v8 ignore else -- TODO: add test #40625\n if (body && cachedPr?.body !== body) {\n await client.updatePrDescription(\n `${prNo}`,\n smartTruncate(sanitize(body), AMAZON_MAX_BODY_LENGTH),\n );\n }\n\n // v8 ignore else -- TODO: add test #40625\n if (title && cachedPr?.title !== title) {\n await client.updatePrTitle(`${prNo}`, title);\n }\n\n const prStatusInput =\n state === 'closed'\n ? PullRequestStatusEnum.CLOSED\n : PullRequestStatusEnum.OPEN;\n // v8 ignore else -- TODO: add test #40625\n if (cachedPr?.state !== prStatusInput) {\n try {\n await client.updatePrStatus(`${prNo}`, prStatusInput);\n } catch {\n // safety check\n // do nothing, it's ok to fail sometimes when trying to update from open to open or from closed to closed.\n }\n }\n}\n\n// Auto-Merge not supported currently.\n/* v8 ignore next -- auto-merge is not supported on CodeCommit, so this stub is unexercised */\nexport async function mergePr({\n branchName,\n id: prNo,\n}: MergePRConfig): Promise<boolean> {\n logger.debug(`mergePr(${prNo}, ${branchName!})`);\n await client.getPr(`${prNo}`);\n return Promise.resolve(false);\n //\n // if (!prOut) {\n // return false;\n // }\n // const pReq = prOut.pullRequest;\n // const targets = pReq?.pullRequestTargets;\n //\n // if (!targets) {\n // return false;\n // }\n //\n // if (strategy === 'rebase') {\n // logger.warn('CodeCommit does not support a \"rebase\" strategy.');\n // return false;\n // }\n //\n // try {\n // if (strategy === 'auto' || strategy === 'squash') {\n // await client.squashMerge(\n // targets[0].repositoryName!,\n // targets[0].sourceReference!,\n // targets[0].destinationReference!,\n // pReq?.title\n // );\n // } else if (strategy === 'fast-forward') {\n // await client.fastForwardMerge(\n // targets[0].repositoryName!,\n // targets[0].sourceReference!,\n // targets[0].destinationReference!\n // );\n // } else {\n // logger.debug(`unsupported strategy`);\n // return false;\n // }\n // } catch (err) {\n // logger.debug({ err }, `PR merge error`);\n // logger.info({ pr: prNo }, 'PR automerge failed');\n // return false;\n // }\n //\n // logger.trace(`Updating PR ${prNo} to status ${PullRequestStatusEnum.CLOSED}`);\n //\n // try {\n // const response = await client.updatePrStatus(\n // `${prNo}`,\n // PullRequestStatusEnum.CLOSED\n // );\n // const isClosed =\n // response.pullRequest?.pullRequestStatus === PullRequestStatusEnum.CLOSED;\n //\n // if (!isClosed) {\n // logger.warn(\n // {\n // pullRequestId: prNo,\n // status: response.pullRequest?.pullRequestStatus,\n // },\n // `Expected PR to have status`\n // );\n // }\n // return true;\n // } catch (err) {\n // logger.debug({ err }, 'Failed to set the PR as Closed.');\n // return false;\n // }\n}\n\nexport async function addReviewers(\n prNo: number,\n reviewers: string[],\n): Promise<void> {\n const numberOfApprovers = reviewers.length;\n const approvalRuleContents = `{\"Version\":\"2018-11-08\",\"Statements\": [{\"Type\": \"Approvers\",\"NumberOfApprovalsNeeded\":${numberOfApprovers},\"ApprovalPoolMembers\": ${JSON.stringify(\n reviewers,\n )}}]}`;\n const res = await client.createPrApprovalRule(\n `${prNo}`,\n approvalRuleContents,\n );\n // v8 ignore else -- TODO: add test #40625\n if (res) {\n const approvalRule = res.approvalRule;\n logger.debug({ approvalRule }, `Approval Rule Added to PR #${prNo}:`);\n }\n}\n\n/* v8 ignore next -- no-op stub: CodeCommit does not support adding assignees */\nexport function addAssignees(\n _iid: number,\n _assignees: string[],\n): Promise<void> {\n // CodeCommit does not support adding reviewers\n return Promise.resolve();\n}\n\n/* v8 ignore next -- no-op stub: CodeCommit has no issues */\nexport function findIssue(_title: string): Promise<Issue | null> {\n // CodeCommit does not have issues\n return Promise.resolve(null);\n}\n\n/* v8 ignore next -- no-op stub: CodeCommit has no issues */\nexport function ensureIssue(\n _cfg: EnsureIssueConfig,\n): Promise<EnsureIssueResult | null> {\n // CodeCommit does not have issues\n return Promise.resolve(null);\n}\n\n/* v8 ignore next -- no-op stub: CodeCommit has no issues */\nexport function getIssueList(): Promise<Issue[]> {\n // CodeCommit does not have issues\n return Promise.resolve([]);\n}\n\n/* v8 ignore next -- no-op stub: CodeCommit has no issues */\nexport function ensureIssueClosing(_title: string): Promise<void> {\n // CodeCommit does not have issues\n return Promise.resolve();\n}\n\n/* v8 ignore next -- no-op stub: label deletion is not implemented for CodeCommit */\nexport function deleteLabel(_prNumber: number, _label: string): Promise<void> {\n return Promise.resolve();\n}\n\n// Returns the combined status for a branch.\n/* v8 ignore next -- stub: branch statuses are not supported on CodeCommit yet, always yellow */\nexport function getBranchStatus(branchName: string): Promise<BranchStatus> {\n logger.debug(`getBranchStatus(${branchName})`);\n logger.debug(\n 'returning branch status yellow, because getBranchStatus isnt supported on aws yet',\n );\n return Promise.resolve('yellow');\n}\n\n/* v8 ignore next -- stub: branch status checks are not supported on CodeCommit yet, always null */\nexport function getBranchStatusCheck(\n branchName: string,\n context: string,\n): Promise<BranchStatus | null> {\n logger.debug(`getBranchStatusCheck(${branchName}, context=${context})`);\n logger.debug(\n 'returning null, because getBranchStatusCheck is not supported on aws yet',\n );\n return Promise.resolve(null);\n}\n\n/* v8 ignore next -- no-op stub: setting branch status is not supported on CodeCommit */\nexport function setBranchStatus(_cfg: BranchStatusConfig): Promise<void> {\n return Promise.resolve();\n}\n\nexport async function ensureComment({\n number,\n topic,\n content,\n}: EnsureCommentConfig): Promise<boolean> {\n logger.debug(`ensureComment(${number}, ${topic!}, content)`);\n const header = topic ? `### ${topic}\\n\\n` : '';\n const body = `${header}${sanitize(content)}`;\n let prCommentsResponse: GetCommentsForPullRequestOutput;\n try {\n prCommentsResponse = await client.getPrComments(`${number}`);\n } catch (err) {\n logger.debug({ err }, 'Unable to retrieve pr comments');\n return false;\n }\n\n let commentId: string | undefined = undefined;\n let commentNeedsUpdating = false;\n\n if (!prCommentsResponse?.commentsForPullRequestData) {\n return false;\n }\n\n for (const commentObj of prCommentsResponse.commentsForPullRequestData) {\n if (!commentObj?.comments) {\n continue;\n }\n const firstCommentContent = commentObj.comments[0].content;\n const isMatchingComment = topic\n ? firstCommentContent?.startsWith(header) === true\n : firstCommentContent === body;\n if (isMatchingComment) {\n commentId = commentObj.comments[0].commentId;\n commentNeedsUpdating = firstCommentContent !== body;\n break;\n }\n }\n\n if (!commentId) {\n const prs = await getPrList();\n const thisPr = prs.filter((item) => item.number === number);\n\n if (!thisPr[0].sourceCommit || !thisPr[0].destinationCommit) {\n return false;\n }\n\n await client.createPrComment(\n `${number}`,\n config.repository,\n body,\n thisPr[0].destinationCommit,\n thisPr[0].sourceCommit,\n );\n logger.info(\n { repository: config.repository, prNo: number, topic },\n 'Comment added',\n );\n } else if (commentNeedsUpdating && commentId) {\n await client.updateComment(commentId, body);\n\n logger.debug(\n { repository: config.repository, prNo: number, topic },\n 'Comment updated',\n );\n } else {\n logger.debug(\n { repository: config.repository, prNo: number, topic },\n 'Comment is already up-to-date',\n );\n }\n\n return true;\n}\n\nexport async function ensureCommentRemoval(\n removeConfig: EnsureCommentRemovalConfig,\n): Promise<void> {\n const { number: prNo } = removeConfig;\n const key =\n removeConfig.type === 'by-topic'\n ? removeConfig.topic\n : removeConfig.content;\n logger.debug(`Ensuring comment \"${key}\" in #${prNo} is removed`);\n\n let prCommentsResponse: GetCommentsForPullRequestOutput;\n try {\n prCommentsResponse = await client.getPrComments(`${prNo}`);\n } catch (err) {\n logger.debug({ err }, 'Unable to retrieve pr comments');\n return;\n }\n\n if (!prCommentsResponse?.commentsForPullRequestData) {\n logger.debug('commentsForPullRequestData not found');\n return;\n }\n\n let commentIdToRemove: string | undefined;\n for (const commentObj of prCommentsResponse.commentsForPullRequestData) {\n if (!commentObj?.comments) {\n logger.debug(\n 'comments object not found under commentsForPullRequestData',\n );\n continue;\n }\n\n for (const comment of commentObj.comments) {\n const isMatchingComment =\n removeConfig.type === 'by-topic'\n ? comment.content?.startsWith(`### ${removeConfig.topic}\\n\\n`) ===\n true\n : removeConfig.content === comment.content?.trim();\n // v8 ignore else -- TODO: add test #40625\n if (isMatchingComment) {\n commentIdToRemove = comment.commentId;\n break;\n }\n }\n // v8 ignore else -- TODO: add test #40625\n if (commentIdToRemove) {\n await client.deleteComment(commentIdToRemove);\n logger.debug(`comment \"${key}\" in PR #${prNo} was removed`);\n break;\n }\n }\n}\n"],"mappings":"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"}
|
|
@@ -97,7 +97,10 @@ var GerritClient = class {
|
|
|
97
97
|
} })).body.change_info?.updated ?? currentGerritTimestamp();
|
|
98
98
|
}
|
|
99
99
|
async checkForExistingMessage(changeNumber, newMessage, msgType) {
|
|
100
|
-
return (await this.getMessages(changeNumber)).some((existingMsg) =>
|
|
100
|
+
return (await this.getMessages(changeNumber)).some((existingMsg) => {
|
|
101
|
+
if (msgType !== void 0 && msgType !== existingMsg.tag) return false;
|
|
102
|
+
return existingMsg.message.includes(newMessage);
|
|
103
|
+
});
|
|
101
104
|
}
|
|
102
105
|
async addMessageIfNotAlreadyExists(changeNumber, message, tag) {
|
|
103
106
|
const newMsg = this.normalizeMessage(message);
|