@paklo/runner 0.6.0 → 0.7.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.
@@ -1,5 +1,5 @@
1
+ import { KyInstance } from "ky";
1
2
  import { DependabotCredential, DependabotJobConfig, DependabotMetric, DependabotRecordUpdateJobError } from "@paklo/core/dependabot";
2
- import { InnerApiClient } from "@paklo/core/http";
3
3
 
4
4
  //#region src/params.d.ts
5
5
  declare class JobParameters {
@@ -29,8 +29,9 @@ declare class ApiClient {
29
29
  readonly params: JobParameters;
30
30
  private readonly credentialsToken;
31
31
  private readonly secretMasker;
32
+ private dependabotApiUrl;
32
33
  private jobToken;
33
- constructor(client: InnerApiClient, params: JobParameters, jobToken: string, credentialsToken: string, secretMasker: SecretMasker);
34
+ constructor(client: KyInstance, params: JobParameters, jobToken: string, credentialsToken: string, secretMasker: SecretMasker);
34
35
  UnknownSha: {
35
36
  'base-commit-sha': string;
36
37
  };
@@ -45,4 +46,4 @@ declare class ApiClient {
45
46
  }
46
47
  //#endregion
47
48
  export { JobParameters as a, SecretMasker as i, CredentialFetchingError as n, getJobParameters as o, JobDetailsFetchingError as r, ApiClient as t };
48
- //# sourceMappingURL=api-client-M8F9t7II.d.mts.map
49
+ //# sourceMappingURL=api-client-BoQ6jjRB.d.mts.map
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
- import { a as JobParameters, i as SecretMasker, n as CredentialFetchingError, o as getJobParameters, r as JobDetailsFetchingError, t as ApiClient } from "./api-client-M8F9t7II.mjs";
2
- import { DependabotCredential, DependabotJobConfig, DependabotProxyConfig, FileFetcherInput, FileUpdaterInput } from "@paklo/core/dependabot";
1
+ import { a as JobParameters, i as SecretMasker, n as CredentialFetchingError, o as getJobParameters, r as JobDetailsFetchingError, t as ApiClient } from "./api-client-BoQ6jjRB.mjs";
3
2
  import Docker, { Container, Network } from "dockerode";
3
+ import { CertificateAuthority, DependabotCredential, DependabotJobConfig, DependabotProxyConfig, FileFetcherInput, FileUpdaterInput } from "@paklo/core/dependabot";
4
4
  import { UsageTelemetryRequestData } from "@paklo/core/usage";
5
5
 
6
6
  //#region src/cleanup.d.ts
@@ -42,6 +42,7 @@ type Proxy = {
42
42
  cert: string;
43
43
  shutdown: () => Promise<void>;
44
44
  };
45
+ declare const CONFIG_FILE_NAME = "config.json";
45
46
  declare class ProxyBuilder {
46
47
  private readonly docker;
47
48
  private readonly proxyImage;
@@ -50,7 +51,7 @@ declare class ProxyBuilder {
50
51
  run(jobId: string, jobToken: string, dependabotApiUrl: string, credentials: DependabotCredential[]): Promise<Proxy>;
51
52
  private ensureNetwork;
52
53
  private buildProxyConfig;
53
- private generateCertificateAuthority;
54
+ static generateCertificateAuthority(): Promise<CertificateAuthority>;
54
55
  private createContainer;
55
56
  private customCAPath;
56
57
  }
@@ -103,6 +104,13 @@ declare class Updater {
103
104
  }
104
105
  //#endregion
105
106
  //#region src/updater-builder.d.ts
107
+ declare const JOB_OUTPUT_FILENAME = "output.json";
108
+ declare const JOB_OUTPUT_PATH = "/home/dependabot/dependabot-updater/output";
109
+ declare const JOB_INPUT_FILENAME = "job.json";
110
+ declare const JOB_INPUT_PATH = "/home/dependabot/dependabot-updater";
111
+ declare const REPO_CONTENTS_PATH = "/home/dependabot/dependabot-updater/repo";
112
+ declare const CA_CERT_INPUT_PATH = "/usr/local/share/ca-certificates";
113
+ declare const CA_CERT_FILENAME = "dbot-ca.crt";
106
114
  declare class UpdaterBuilder {
107
115
  private readonly docker;
108
116
  private readonly jobParams;
@@ -113,5 +121,13 @@ declare class UpdaterBuilder {
113
121
  run(containerName: string): Promise<Container>;
114
122
  }
115
123
  //#endregion
116
- export { ApiClient, ContainerRuntimeError, ContainerService, CredentialFetchingError, ImageService, JobDetailsFetchingError, JobParameters, JobRunnerImagingError, JobRunnerUpdaterError, MetricReporter, PROXY_IMAGE_NAME, Proxy, ProxyBuilder, RunJobOptions, RunJobResult, SecretMasker, Updater, UpdaterBuilder, cleanup, cleanupOldImageVersions, digestName, getJobParameters, getOrgFromImage, hasDigest, isRunningInDocker, repositoryName, runJob, updaterImageName, updaterImages };
124
+ //#region src/utils.d.ts
125
+ /**
126
+ * Extracts the SHA from an updater image string.
127
+ * @param updaterImage - Image string in the format "image:sha" or "registry/image:sha"
128
+ * @returns The SHA part after the last colon, or null if no colon is found
129
+ */
130
+ declare const extractUpdaterSha: (updaterImage: string) => string | null;
131
+ //#endregion
132
+ export { ApiClient, CA_CERT_FILENAME, CA_CERT_INPUT_PATH, CONFIG_FILE_NAME, ContainerRuntimeError, ContainerService, CredentialFetchingError, ImageService, JOB_INPUT_FILENAME, JOB_INPUT_PATH, JOB_OUTPUT_FILENAME, JOB_OUTPUT_PATH, JobDetailsFetchingError, JobParameters, JobRunnerImagingError, JobRunnerUpdaterError, MetricReporter, PROXY_IMAGE_NAME, Proxy, ProxyBuilder, REPO_CONTENTS_PATH, RunJobOptions, RunJobResult, SecretMasker, Updater, UpdaterBuilder, cleanup, cleanupOldImageVersions, digestName, extractUpdaterSha, getJobParameters, getOrgFromImage, hasDigest, isRunningInDocker, repositoryName, runJob, updaterImageName, updaterImages };
117
133
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { S as JobDetailsFetchingError, _ as repositoryName, a as Updater, b as ApiClient, c as JobParameters, d as getOrgFromImage, f as ContainerRuntimeError, g as hasDigest, h as digestName, i as runJob, l as getJobParameters, m as PROXY_IMAGE_NAME, n as JobRunnerUpdaterError, o as UpdaterBuilder, p as ContainerService, r as isRunningInDocker, s as ProxyBuilder, t as JobRunnerImagingError, u as ImageService, v as updaterImageName, x as CredentialFetchingError, y as updaterImages } from "./run-DBD6Hefl.mjs";
1
+ import { A as CredentialFetchingError, C as PROXY_IMAGE_NAME, D as updaterImageName, E as repositoryName, O as updaterImages, S as extractUpdaterSha, T as hasDigest, _ as getJobParameters, a as Updater, b as ContainerRuntimeError, c as JOB_INPUT_FILENAME, d as JOB_OUTPUT_PATH, f as REPO_CONTENTS_PATH, g as JobParameters, h as ProxyBuilder, i as runJob, j as JobDetailsFetchingError, k as ApiClient, l as JOB_INPUT_PATH, m as CONFIG_FILE_NAME, n as JobRunnerUpdaterError, o as CA_CERT_FILENAME, p as UpdaterBuilder, r as isRunningInDocker, s as CA_CERT_INPUT_PATH, t as JobRunnerImagingError, u as JOB_OUTPUT_FILENAME, v as ImageService, w as digestName, x as ContainerService, y as getOrgFromImage } from "./run-CJUFvK8K.mjs";
2
2
  import { logger } from "@paklo/core/logger";
3
3
  import Docker from "dockerode";
4
4
 
@@ -45,5 +45,5 @@ function imageMatches(imageInfo, imageName) {
45
45
  }
46
46
 
47
47
  //#endregion
48
- export { ApiClient, ContainerRuntimeError, ContainerService, CredentialFetchingError, ImageService, JobDetailsFetchingError, JobParameters, JobRunnerImagingError, JobRunnerUpdaterError, PROXY_IMAGE_NAME, ProxyBuilder, Updater, UpdaterBuilder, cleanup, cleanupOldImageVersions, digestName, getJobParameters, getOrgFromImage, hasDigest, isRunningInDocker, repositoryName, runJob, updaterImageName, updaterImages };
48
+ export { ApiClient, CA_CERT_FILENAME, CA_CERT_INPUT_PATH, CONFIG_FILE_NAME, ContainerRuntimeError, ContainerService, CredentialFetchingError, ImageService, JOB_INPUT_FILENAME, JOB_INPUT_PATH, JOB_OUTPUT_FILENAME, JOB_OUTPUT_PATH, JobDetailsFetchingError, JobParameters, JobRunnerImagingError, JobRunnerUpdaterError, PROXY_IMAGE_NAME, ProxyBuilder, REPO_CONTENTS_PATH, Updater, UpdaterBuilder, cleanup, cleanupOldImageVersions, digestName, extractUpdaterSha, getJobParameters, getOrgFromImage, hasDigest, isRunningInDocker, repositoryName, runJob, updaterImageName, updaterImages };
49
49
  //# sourceMappingURL=index.mjs.map
@@ -1,7 +1,7 @@
1
- import "../../api-client-M8F9t7II.mjs";
2
- import { a as LocalJobsRunner, i as LocalDependabotServerOptions, n as LocalDependabotServer, o as LocalJobsRunnerOptions, s as RunJobsResult } from "../../server-DTAFwSrb.mjs";
1
+ import "../../api-client-BoQ6jjRB.mjs";
2
+ import { a as LocalJobsRunner, i as LocalDependabotServerOptions, n as LocalDependabotServer, o as LocalJobsRunnerOptions, s as RunJobsResult } from "../../server-89g3AXRY.mjs";
3
3
  import { DependabotRequest } from "@paklo/core/dependabot";
4
- import { AzureDevOpsRepositoryUrl, AzureDevOpsWebApiClient, IPullRequestProperties } from "@paklo/core/azure";
4
+ import { AzdoPullRequestMergeStrategy, AzureDevOpsRepositoryUrl, AzureDevOpsWebApiClient, IPullRequestProperties } from "@paklo/core/azure";
5
5
 
6
6
  //#region src/local/azure/server.d.ts
7
7
  type AzureLocalDependabotServerOptions = LocalDependabotServerOptions & {
@@ -10,7 +10,7 @@ type AzureLocalDependabotServerOptions = LocalDependabotServerOptions & {
10
10
  autoApprove: boolean;
11
11
  approverClient?: AzureDevOpsWebApiClient;
12
12
  setAutoComplete: boolean;
13
- mergeStrategy?: string;
13
+ mergeStrategy?: AzdoPullRequestMergeStrategy;
14
14
  autoCompleteIgnoreConfigIds: number[];
15
15
  existingBranchNames: string[] | undefined;
16
16
  existingPullRequests: IPullRequestProperties[];
@@ -1,10 +1,10 @@
1
- import { i as runJob } from "../../run-DBD6Hefl.mjs";
2
- import { n as LocalJobsRunner, t as LocalDependabotServer } from "../../server-M1ps5BVd.mjs";
3
- import { DependabotJobBuilder, getBranchNameForUpdate, mapPackageEcosystemToPackageManager } from "@paklo/core/dependabot";
1
+ import { i as runJob } from "../../run-CJUFvK8K.mjs";
2
+ import { n as LocalJobsRunner, t as LocalDependabotServer } from "../../server-BxUu1gGo.mjs";
4
3
  import { logger } from "@paklo/core/logger";
5
4
  import { readFile } from "node:fs/promises";
6
5
  import { existsSync } from "node:fs";
7
- import { AzureDevOpsWebApiClient, DEVOPS_PR_PROPERTY_MICROSOFT_GIT_SOURCE_REF_NAME, GitPullRequestMergeStrategy, buildPullRequestProperties, getPullRequestChangedFilesForOutputData, getPullRequestCloseReasonForOutputData, getPullRequestDependenciesPropertyValueForOutputData, getPullRequestDescription, getPullRequestForDependencyNames, normalizeBranchName, parsePullRequestProperties } from "@paklo/core/azure";
6
+ import { DependabotJobBuilder, getBranchNameForUpdate, mapPackageEcosystemToPackageManager } from "@paklo/core/dependabot";
7
+ import { AzureDevOpsWebApiClient, DEVOPS_PR_PROPERTY_MICROSOFT_GIT_SOURCE_REF_NAME, buildPullRequestProperties, getPullRequestChangedFilesForOutputData, getPullRequestCloseReasonForOutputData, getPullRequestDependenciesPropertyValueForOutputData, getPullRequestDescription, getPullRequestForDependencyNames, normalizeBranchName, parsePullRequestProperties } from "@paklo/core/azure";
8
8
  import { GitHubSecurityAdvisoryClient, SecurityVulnerabilitySchema, filterVulnerabilities, getGhsaPackageEcosystemFromDependabotPackageManager } from "@paklo/core/github";
9
9
 
10
10
  //#region src/local/azure/server.ts
@@ -70,15 +70,7 @@ var AzureLocalDependabotServer = class extends LocalDependabotServer {
70
70
  commitMessage: data["commit-message"],
71
71
  autoComplete: setAutoComplete ? {
72
72
  ignorePolicyConfigIds: autoCompleteIgnoreConfigIds,
73
- mergeStrategy: (() => {
74
- switch (mergeStrategy) {
75
- case "noFastForward": return GitPullRequestMergeStrategy.NoFastForward;
76
- case "squash": return GitPullRequestMergeStrategy.Squash;
77
- case "rebase": return GitPullRequestMergeStrategy.Rebase;
78
- case "rebaseMerge": return GitPullRequestMergeStrategy.RebaseMerge;
79
- default: return GitPullRequestMergeStrategy.Squash;
80
- }
81
- })()
73
+ mergeStrategy: mergeStrategy ?? "squash"
82
74
  } : void 0,
83
75
  assignees: update.assignees,
84
76
  labels: update.labels?.map((label) => label?.trim()) || [],
@@ -268,6 +260,11 @@ var AzureLocalJobsRunner = class extends LocalJobsRunner {
268
260
  async performUpdates(server, updates, existingPullRequests, dependabotApiUrl, dependabotApiDockerUrl, command) {
269
261
  const { options: { url, gitToken, githubToken, experiments, config, dryRun, securityAdvisoriesFile, secretMasker } } = this;
270
262
  const results = [];
263
+ function makeRandomJobId() {
264
+ const array = new Uint32Array(1);
265
+ crypto.getRandomValues(array);
266
+ return `${array[0] % 1e10}`;
267
+ }
271
268
  function makeUsageData(job) {
272
269
  return {
273
270
  trigger: "user",
@@ -304,10 +301,14 @@ var AzureLocalJobsRunner = class extends LocalJobsRunner {
304
301
  let dependencyNamesToUpdate = [];
305
302
  const securityUpdatesOnly = update["open-pull-requests-limit"] === 0;
306
303
  if (securityUpdatesOnly) {
307
- ({job, credentials} = builder.forDependenciesList({ command }));
304
+ const id = makeRandomJobId();
305
+ ({job, credentials} = builder.forDependenciesList({
306
+ id,
307
+ command
308
+ }));
308
309
  ({jobToken, credentialsToken} = this.makeTokens());
309
310
  server.add({
310
- id: job.id,
311
+ id,
311
312
  update,
312
313
  job,
313
314
  jobToken,
@@ -317,14 +318,14 @@ var AzureLocalJobsRunner = class extends LocalJobsRunner {
317
318
  await runJob({
318
319
  dependabotApiUrl,
319
320
  dependabotApiDockerUrl,
320
- jobId: job.id,
321
+ jobId: id,
321
322
  jobToken,
322
323
  credentialsToken,
323
324
  updaterImage,
324
325
  secretMasker,
325
326
  usage: makeUsageData(job)
326
327
  });
327
- const packagesToCheckForVulnerabilities = server.requests(job.id).find((o) => o.type === "update_dependency_list")?.data.dependencies?.map((d) => ({
328
+ const packagesToCheckForVulnerabilities = server.requests(id).find((o) => o.type === "update_dependency_list")?.data.dependencies?.map((d) => ({
328
329
  name: d.name,
329
330
  version: d.version
330
331
  }));
@@ -347,17 +348,19 @@ var AzureLocalJobsRunner = class extends LocalJobsRunner {
347
348
  if (dependencyNamesToUpdate.length) logger.trace(dependencyNamesToUpdate);
348
349
  } else {
349
350
  logger.info(`No vulnerabilities detected for update ${update["package-ecosystem"]} in ${update.directory}`);
350
- server.clear(job.id);
351
+ server.clear(id);
351
352
  continue;
352
353
  }
353
- server.clear(job.id);
354
+ server.clear(id);
354
355
  }
355
356
  const openPullRequestsLimit = update["open-pull-requests-limit"];
356
357
  const openPullRequestsCount = Object.entries(existingPullRequestsForPackageManager).length;
357
358
  if (!(openPullRequestsLimit > 0 && openPullRequestsCount >= openPullRequestsLimit)) {
358
359
  const dependenciesHaveVulnerabilities = dependencyNamesToUpdate.length && securityVulnerabilities.length;
359
360
  if (!securityUpdatesOnly || dependenciesHaveVulnerabilities) {
361
+ const id = makeRandomJobId();
360
362
  ({job, credentials} = builder.forUpdate({
363
+ id,
361
364
  command,
362
365
  dependencyNamesToUpdate,
363
366
  existingPullRequests: existingPullRequestDependenciesForPackageManager,
@@ -365,7 +368,7 @@ var AzureLocalJobsRunner = class extends LocalJobsRunner {
365
368
  }));
366
369
  ({jobToken, credentialsToken} = this.makeTokens());
367
370
  server.add({
368
- id: job.id,
371
+ id,
369
372
  update,
370
373
  job,
371
374
  jobToken,
@@ -375,17 +378,17 @@ var AzureLocalJobsRunner = class extends LocalJobsRunner {
375
378
  const { success, message } = await runJob({
376
379
  dependabotApiUrl,
377
380
  dependabotApiDockerUrl,
378
- jobId: job.id,
381
+ jobId: id,
379
382
  jobToken,
380
383
  credentialsToken,
381
384
  updaterImage,
382
385
  secretMasker,
383
386
  usage: makeUsageData(job)
384
387
  });
385
- const affectedPrs = server.allAffectedPrs(job.id);
386
- server.clear(job.id);
388
+ const affectedPrs = server.allAffectedPrs(id);
389
+ server.clear(id);
387
390
  results.push({
388
- id: job.id,
391
+ id,
389
392
  success,
390
393
  message,
391
394
  affectedPrs
@@ -394,7 +397,9 @@ var AzureLocalJobsRunner = class extends LocalJobsRunner {
394
397
  } else logger.warn(`Skipping update for ${packageEcosystem} packages as the open pull requests limit (${openPullRequestsLimit}) has already been reached`);
395
398
  const numberOfPullRequestsToUpdate = Object.keys(existingPullRequestsForPackageManager).length;
396
399
  if (numberOfPullRequestsToUpdate > 0) if (!dryRun) for (const pullRequestId in existingPullRequestsForPackageManager) {
400
+ const id = makeRandomJobId();
397
401
  ({job, credentials} = builder.forUpdate({
402
+ id,
398
403
  command,
399
404
  existingPullRequests: existingPullRequestDependenciesForPackageManager,
400
405
  pullRequestToUpdate: existingPullRequestsForPackageManager[pullRequestId],
@@ -402,7 +407,7 @@ var AzureLocalJobsRunner = class extends LocalJobsRunner {
402
407
  }));
403
408
  ({jobToken, credentialsToken} = this.makeTokens());
404
409
  server.add({
405
- id: job.id,
410
+ id,
406
411
  update,
407
412
  job,
408
413
  jobToken,
@@ -412,17 +417,17 @@ var AzureLocalJobsRunner = class extends LocalJobsRunner {
412
417
  const { success, message } = await runJob({
413
418
  dependabotApiUrl,
414
419
  dependabotApiDockerUrl,
415
- jobId: job.id,
420
+ jobId: id,
416
421
  jobToken,
417
422
  credentialsToken,
418
423
  updaterImage,
419
424
  secretMasker,
420
425
  usage: makeUsageData(job)
421
426
  });
422
- const affectedPrs = server.allAffectedPrs(job.id);
423
- server.clear(job.id);
427
+ const affectedPrs = server.allAffectedPrs(id);
428
+ server.clear(id);
424
429
  results.push({
425
- id: job.id,
430
+ id,
426
431
  success,
427
432
  message,
428
433
  affectedPrs
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["updates: DependabotUpdate[]","results: RunJobsResult","job: DependabotJobConfig | undefined","credentials: DependabotCredential[] | undefined","jobToken: string","credentialsToken: string","securityVulnerabilities: SecurityVulnerability[]","dependencyNamesToUpdate: string[]","packagesToCheckForVulnerabilities: Package[] | undefined"],"sources":["../../../src/local/azure/server.ts","../../../src/local/azure/runner.ts"],"sourcesContent":["import type { AzureDevOpsRepositoryUrl, AzureDevOpsWebApiClient, IPullRequestProperties } from '@paklo/core/azure';\nimport {\n buildPullRequestProperties,\n GitPullRequestMergeStrategy,\n getPullRequestChangedFilesForOutputData,\n getPullRequestCloseReasonForOutputData,\n getPullRequestDependenciesPropertyValueForOutputData,\n getPullRequestDescription,\n getPullRequestForDependencyNames,\n parsePullRequestProperties,\n} from '@paklo/core/azure';\nimport { type DependabotRequest, getBranchNameForUpdate } from '@paklo/core/dependabot';\nimport { logger } from '@paklo/core/logger';\nimport { LocalDependabotServer, type LocalDependabotServerOptions } from '../server';\n\nexport type AzureLocalDependabotServerOptions = LocalDependabotServerOptions & {\n url: AzureDevOpsRepositoryUrl;\n authorClient: AzureDevOpsWebApiClient;\n autoApprove: boolean;\n approverClient?: AzureDevOpsWebApiClient;\n setAutoComplete: boolean;\n mergeStrategy?: string;\n autoCompleteIgnoreConfigIds: number[];\n existingBranchNames: string[] | undefined;\n existingPullRequests: IPullRequestProperties[];\n};\n\nexport class AzureLocalDependabotServer extends LocalDependabotServer {\n // biome-ignore lint/correctness/noUnusedPrivateClassMembers: options is used\n private readonly options: AzureLocalDependabotServerOptions;\n\n constructor(options: AzureLocalDependabotServerOptions) {\n super(options);\n this.options = options;\n }\n\n protected override async handle(id: string, request: DependabotRequest): Promise<boolean> {\n await super.handle(id, request); // common logic\n\n const { options, affectedPullRequestIds } = this;\n const {\n url,\n authorClient,\n approverClient,\n existingBranchNames,\n existingPullRequests,\n autoApprove,\n mergeStrategy,\n setAutoComplete,\n autoCompleteIgnoreConfigIds,\n author,\n dryRun,\n } = options;\n\n const { type, data } = request;\n const job = await this.job(id);\n if (!job) {\n logger.error(`No job found for ID '${id}', cannot process request of type '${type}'`);\n return false;\n }\n const { 'package-manager': packageManager } = job;\n logger.info(`Processing '${type}' for job ID '${id}'`);\n\n const update = this.update(id)!; // exists because job exists\n const { project, repository } = url;\n\n switch (type) {\n // Documentation on the 'data' model for each output type can be found here:\n // See: https://github.com/dependabot/cli/blob/main/internal/model/update.go\n\n case 'create_pull_request': {\n const title = data['pr-title'];\n if (dryRun) {\n logger.warn(`Skipping pull request creation of '${title}' as 'dryRun' is set to 'true'`);\n return true;\n }\n\n // Skip if active pull request limit reached.\n const openPullRequestsLimit = update['open-pull-requests-limit']!;\n\n // Parse the Dependabot metadata for the existing pull requests that are related to this update\n // Dependabot will use this to determine if we need to create new pull requests or update/close existing ones\n const existingPullRequestsForPackageManager = parsePullRequestProperties(existingPullRequests, packageManager);\n const existingPullRequestsCount = Object.entries(existingPullRequestsForPackageManager).length;\n const openPullRequestsCount = affectedPullRequestIds.get(id)!.created.length + existingPullRequestsCount;\n const hasReachedOpenPullRequestLimit =\n openPullRequestsLimit > 0 && openPullRequestsCount >= openPullRequestsLimit;\n\n if (hasReachedOpenPullRequestLimit) {\n logger.warn(\n `Skipping pull request creation of '${title}' as the open pull requests limit (${openPullRequestsLimit}) has been reached`,\n );\n return true;\n }\n\n const changedFiles = getPullRequestChangedFilesForOutputData(data);\n const dependencies = getPullRequestDependenciesPropertyValueForOutputData(data);\n const targetBranch = update['target-branch'] || (await authorClient.getDefaultBranch(project, repository));\n const sourceBranch = getBranchNameForUpdate(\n update['package-ecosystem'],\n targetBranch,\n update.directory || update.directories?.find((dir) => changedFiles[0]?.path?.startsWith(dir)),\n !Array.isArray(dependencies) ? dependencies['dependency-group-name'] : undefined,\n !Array.isArray(dependencies) ? dependencies.dependencies : dependencies,\n update['pull-request-branch-name']?.separator,\n );\n\n // Check if the source branch already exists or conflicts with an existing branch\n const existingBranch = existingBranchNames?.find((branch) => sourceBranch === branch) || [];\n if (existingBranch.length) {\n logger.error(\n `Unable to create pull request '${title}' as source branch '${sourceBranch}' already exists; Delete the existing branch and try again.`,\n );\n return false;\n }\n const conflictingBranches = existingBranchNames?.filter((branch) => sourceBranch.startsWith(branch)) || [];\n if (conflictingBranches.length) {\n logger.error(\n `Unable to create pull request '${title}' as source branch '${sourceBranch}' would conflict with existing branch(es) '${conflictingBranches.join(', ')}'; Delete the conflicting branch(es) and try again.`,\n );\n return false;\n }\n\n // Create a new pull request\n const newPullRequestId = await authorClient.createPullRequest({\n project: project,\n repository: repository,\n source: {\n commit: data['base-commit-sha'] || job.source.commit!,\n branch: sourceBranch,\n },\n target: {\n branch: targetBranch!,\n },\n author,\n title,\n description: getPullRequestDescription(packageManager, data['pr-body'], data.dependencies),\n commitMessage: data['commit-message'],\n autoComplete: setAutoComplete\n ? {\n ignorePolicyConfigIds: autoCompleteIgnoreConfigIds,\n mergeStrategy: (() => {\n switch (mergeStrategy) {\n case 'noFastForward':\n return GitPullRequestMergeStrategy.NoFastForward;\n case 'squash':\n return GitPullRequestMergeStrategy.Squash;\n case 'rebase':\n return GitPullRequestMergeStrategy.Rebase;\n case 'rebaseMerge':\n return GitPullRequestMergeStrategy.RebaseMerge;\n default:\n return GitPullRequestMergeStrategy.Squash;\n }\n })(),\n }\n : undefined,\n assignees: update.assignees,\n labels: update.labels?.map((label) => label?.trim()) || [],\n workItems: update.milestone ? [update.milestone] : [],\n changes: changedFiles,\n properties: buildPullRequestProperties(packageManager, dependencies),\n });\n\n // Auto-approve the pull request, if required\n if (autoApprove && approverClient && newPullRequestId) {\n await approverClient.approvePullRequest({\n project: project,\n repository: repository,\n pullRequestId: newPullRequestId,\n });\n }\n\n // Store the new pull request ID, so we can keep track of the total number of open pull requests\n if (newPullRequestId && newPullRequestId > 0) {\n affectedPullRequestIds.get(id)!.created.push(newPullRequestId);\n return true;\n } else {\n return false;\n }\n }\n\n case 'update_pull_request': {\n if (dryRun) {\n logger.warn(`Skipping pull request update as 'dryRun' is set to 'true'`);\n return true;\n }\n\n // Find the pull request to update\n const pullRequestToUpdate = getPullRequestForDependencyNames(\n existingPullRequests,\n packageManager,\n data['dependency-names'],\n );\n if (!pullRequestToUpdate) {\n logger.error(\n `Could not find pull request to update for package manager '${packageManager}' with dependencies '${data['dependency-names'].join(', ')}'`,\n );\n return false;\n }\n\n // Update the pull request\n const pullRequestWasUpdated = await authorClient.updatePullRequest({\n project: project,\n repository: repository,\n pullRequestId: pullRequestToUpdate.id,\n commit: data['base-commit-sha'] || job.source.commit!,\n author,\n changes: getPullRequestChangedFilesForOutputData(data),\n skipIfDraft: true,\n skipIfCommitsFromAuthorsOtherThan: author.email,\n skipIfNotBehindTargetBranch: true,\n });\n\n // Re-approve the pull request, if required\n if (autoApprove && approverClient && pullRequestWasUpdated) {\n await approverClient.approvePullRequest({\n project: project,\n repository: repository,\n pullRequestId: pullRequestToUpdate.id,\n });\n }\n\n if (pullRequestWasUpdated) {\n affectedPullRequestIds.get(id)!.updated.push(pullRequestToUpdate.id);\n return true;\n }\n return false;\n }\n\n case 'close_pull_request': {\n if (dryRun) {\n logger.warn(`Skipping pull request closure as 'dryRun' is set to 'true'`);\n return true;\n }\n\n // Find the pull request to close\n const pullRequestToClose = getPullRequestForDependencyNames(\n existingPullRequests,\n packageManager,\n data['dependency-names'],\n );\n if (!pullRequestToClose) {\n logger.error(\n `Could not find pull request to close for package manager '${packageManager}' with dependencies '${data['dependency-names'].join(', ')}'`,\n );\n return false;\n }\n\n // TODO: GitHub Dependabot will close with reason \"Superseded by ${new_pull_request_id}\" when another PR supersedes it.\n // How do we detect this? Do we need to?\n\n // Close the pull request\n const success = await authorClient.abandonPullRequest({\n project: project,\n repository: repository,\n pullRequestId: pullRequestToClose.id,\n comment: getPullRequestCloseReasonForOutputData(data),\n deleteSourceBranch: true,\n });\n if (success) {\n affectedPullRequestIds.get(id)!.closed.push(pullRequestToClose.id);\n return true;\n }\n return false;\n }\n\n case 'record_update_job_warning': {\n if (dryRun) {\n logger.warn(`Skipping warning as 'dryRun' is set to 'true'`);\n return true;\n }\n\n // add comment to each create/updated pull request\n const ids = affectedPullRequestIds.get(id)!.created.concat(affectedPullRequestIds.get(id)!.updated);\n for (const pullRequestId of ids) {\n await authorClient.addCommentThread({\n project: project,\n repository: repository,\n content: `### Dependabot Warning: ${data['warn-title']}\\n\\n${data['warn-description']}`,\n pullRequestId,\n });\n }\n\n return true;\n }\n\n // No action required\n case 'update_dependency_list':\n case 'create_dependency_submission':\n case 'mark_as_processed':\n case 'record_ecosystem_versions':\n case 'increment_metric':\n case 'record_ecosystem_meta':\n case 'record_cooldown_meta':\n case 'record_metrics': // from the runner\n return true;\n\n case 'record_update_job_error':\n logger.error(`Update job error: ${data['error-type']} ${JSON.stringify(data['error-details'])}`);\n return true;\n\n case 'record_update_job_unknown_error':\n logger.error(`Update job unknown error: ${data['error-type']}, ${JSON.stringify(data['error-details'])}`);\n return true;\n\n default:\n logger.warn(`Unknown dependabot request type '${type}', ignoring...`);\n return true;\n }\n }\n}\n","import { existsSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport {\n AzureDevOpsWebApiClient,\n DEVOPS_PR_PROPERTY_MICROSOFT_GIT_SOURCE_REF_NAME,\n type IPullRequestProperties,\n normalizeBranchName,\n parsePullRequestProperties,\n} from '@paklo/core/azure';\nimport {\n type DependabotCredential,\n DependabotJobBuilder,\n type DependabotJobConfig,\n type DependabotUpdate,\n mapPackageEcosystemToPackageManager,\n} from '@paklo/core/dependabot';\nimport {\n filterVulnerabilities,\n GitHubSecurityAdvisoryClient,\n getGhsaPackageEcosystemFromDependabotPackageManager,\n type Package,\n type SecurityVulnerability,\n SecurityVulnerabilitySchema,\n} from '@paklo/core/github';\nimport { logger } from '@paklo/core/logger';\nimport { type RunJobOptions, runJob } from '../../run';\nimport { LocalJobsRunner, type LocalJobsRunnerOptions, type RunJobsResult } from '../runner';\nimport { AzureLocalDependabotServer, type AzureLocalDependabotServerOptions } from './server';\n\nexport type AzureLocalJobsRunnerOptions = LocalJobsRunnerOptions &\n Omit<\n AzureLocalDependabotServerOptions,\n 'authorClient' | 'approverClient' | 'existingBranchNames' | 'existingPullRequests'\n > & {\n port?: number;\n securityAdvisoriesFile?: string;\n gitToken: string;\n githubToken?: string;\n autoApproveToken?: string;\n };\n\nexport class AzureLocalJobsRunner extends LocalJobsRunner {\n // biome-ignore-start lint/correctness/noUnusedPrivateClassMembers: variables are used\n private readonly options: AzureLocalJobsRunnerOptions;\n private readonly authorClient: AzureDevOpsWebApiClient;\n private readonly approverClient?: AzureDevOpsWebApiClient;\n // biome-ignore-end lint/correctness/noUnusedPrivateClassMembers: variables are used\n\n constructor(options: AzureLocalJobsRunnerOptions) {\n super({ ...options });\n this.options = options;\n const { url, gitToken, autoApprove, debug } = this.options;\n\n // Initialise the DevOps API clients (one for authoring the other for auto-approving (if configured))\n this.authorClient = new AzureDevOpsWebApiClient(url, gitToken, debug);\n this.approverClient = autoApprove\n ? new AzureDevOpsWebApiClient(url, options.autoApproveToken || gitToken, debug)\n : undefined;\n }\n\n public override async run(): Promise<RunJobsResult> {\n await super.run(); // common logic\n\n const {\n options: { url, port, config, targetUpdateIds, command },\n authorClient,\n approverClient,\n } = this;\n\n // Print a warning about multi-ecosystem updates not being fully supported\n // TODO: Implement full support for multi-ecosystem updates (not sure this will be possible on the local model)\n if (config['multi-ecosystem-groups'] || config.updates?.some((u) => u['multi-ecosystem-group'])) {\n logger.warn(\n 'Multi-ecosystem updates are not working yet. Only parsing and validation is supported at this time.',\n );\n }\n\n // Print a warning about the required workarounds for security-only updates, if any update is configured as such\n // TODO: If and when Dependabot supports a better way to do security-only updates, remove this.\n if (config.updates?.some((u) => u['open-pull-requests-limit'] === 0)) {\n logger.warn(\n 'Security-only updates incur a slight performance overhead due to limitations in Dependabot CLI. For more info, see: https://github.com/mburumaxwell/dependabot-azure-devops/blob/main/README.md#configuring-security-advisories-and-known-vulnerabilities',\n );\n }\n\n // Fetch the active pull requests created by the author user\n const existingBranchNames = await authorClient.getBranchNames(url.project, url.repository);\n const existingPullRequests = await authorClient.getActivePullRequestProperties(\n url.project,\n url.repository,\n await authorClient.getUserId(),\n );\n\n // Prepare local server\n const serverOptions: AzureLocalDependabotServerOptions = {\n authorClient,\n approverClient,\n existingBranchNames,\n existingPullRequests,\n ...this.options,\n };\n const server = new AzureLocalDependabotServer(serverOptions);\n server.start(port);\n // give the server a second to start\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n // The API urls is constant when working in this CLI. Asking people to setup NGROK or similar just to get\n // HTTPS for the job token to be used is too much hassle.\n // Using same value for dependabotApiUrl and dependabotApiDockerUrl so as to capture /record_metrics calls.\n const dependabotApiUrl = `http://host.docker.internal:${server.port}/api`;\n const dependabotApiDockerUrl = dependabotApiUrl;\n\n // If update identifiers are specified, select them; otherwise handle all\n let updates: DependabotUpdate[] = [];\n if (targetUpdateIds && targetUpdateIds.length > 0) {\n for (const id of targetUpdateIds) {\n const upd = config.updates[id];\n if (!upd) {\n logger.warn(\n `\n Unable to find target update id '${id}'.\n This value should be a zero based index of the update in your config file.\n Expected range: 0-${config.updates.length - 1}\n `,\n );\n } else {\n updates.push(upd);\n }\n }\n } else {\n updates = config.updates;\n }\n\n try {\n // Abandon all pull requests where the source branch has been deleted\n await this.abandonPullRequestsWhereSourceRefIsDeleted(existingBranchNames, existingPullRequests);\n\n // Perform updates for each of the [targeted] update blocks in dependabot.yaml\n return await this.performUpdates(\n server,\n updates,\n existingPullRequests,\n dependabotApiUrl,\n dependabotApiDockerUrl,\n command,\n );\n } finally {\n server.stop();\n }\n }\n\n /**\n * Abandon all pull requests where the source branch has been deleted.\n * @param existingBranchNames The names of the existing branches.\n * @param existingPullRequests The existing pull requests.\n */\n private async abandonPullRequestsWhereSourceRefIsDeleted(\n existingBranchNames?: string[],\n existingPullRequests?: IPullRequestProperties[],\n ): Promise<void> {\n if (!existingBranchNames || !existingPullRequests) return;\n\n const {\n options: { url, dryRun },\n authorClient,\n } = this;\n for (const pullRequestIndex in existingPullRequests) {\n const pullRequest = existingPullRequests[pullRequestIndex]!;\n const pullRequestSourceRefName = normalizeBranchName(\n pullRequest.properties?.find((x) => x.name === DEVOPS_PR_PROPERTY_MICROSOFT_GIT_SOURCE_REF_NAME)?.value,\n );\n if (pullRequestSourceRefName && !existingBranchNames.includes(pullRequestSourceRefName)) {\n // The source branch for the pull request has been deleted; abandon the pull request (if not dry run)\n if (!dryRun) {\n logger.warn(\n `Detected source branch for PR #${pullRequest.id} has been deleted; The pull request will be abandoned`,\n );\n await authorClient.abandonPullRequest({\n project: url.project,\n repository: url.repository,\n pullRequestId: pullRequest.id,\n // comment:\n // 'OK, I won't notify you again about this release, but will get in touch when a new version is available. ' +\n // 'If you'd rather skip all updates until the next major or minor version, add an ' +\n // '[`ignore` condition](https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference#ignore--) ' +\n // 'with the desired `update-types` to your config file.',\n comment:\n 'It might be a good idea to add an ' +\n '[`ignore` condition](https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference#ignore--) ' +\n 'with the desired `update-types` to your config file.',\n });\n }\n // Remove the pull request from the list of existing pull requests to ensures that we don't attempt to update it later in the process.\n existingPullRequests.splice(existingPullRequests.indexOf(pullRequest), 1);\n }\n }\n }\n\n /**\n * Performs the updates.\n * @param server The local Dependabot server.\n * @param updates The updates to perform.\n * @param existingPullRequests The existing pull requests.\n */\n private async performUpdates(\n server: AzureLocalDependabotServer,\n updates: DependabotUpdate[],\n existingPullRequests: IPullRequestProperties[],\n dependabotApiUrl: string,\n dependabotApiDockerUrl?: string,\n command?: DependabotJobConfig['command'],\n ): Promise<RunJobsResult> {\n const {\n options: { url, gitToken, githubToken, experiments, config, dryRun, securityAdvisoriesFile, secretMasker },\n } = this;\n\n const results: RunJobsResult = [];\n\n function makeUsageData(job: DependabotJobConfig): RunJobOptions['usage'] {\n return {\n trigger: 'user',\n provider: job.source.provider,\n owner: url.value.toString(),\n project: `${url.value.toString().replace(/\\/$/, '')}/${url.project}`,\n 'package-manager': job['package-manager'],\n };\n }\n\n for (const update of updates) {\n const packageEcosystem = update['package-ecosystem'];\n const packageManager = mapPackageEcosystemToPackageManager(packageEcosystem);\n\n // If there is an updater image, replace the placeholder in it\n let { updaterImage } = this.options;\n updaterImage = updaterImage?.replace(/\\{ecosystem\\}/i, packageEcosystem);\n\n // Parse the Dependabot metadata for the existing pull requests that are related to this update\n // Dependabot will use this to determine if we need to create new pull requests or update/close existing ones\n const existingPullRequestsForPackageManager = parsePullRequestProperties(existingPullRequests, packageManager);\n const existingPullRequestDependenciesForPackageManager = Object.values(existingPullRequestsForPackageManager);\n\n const builder = new DependabotJobBuilder({\n source: { provider: 'azure', ...url },\n config,\n update,\n systemAccessToken: gitToken,\n githubToken,\n experiments,\n debug: false,\n });\n\n let job: DependabotJobConfig | undefined;\n let credentials: DependabotCredential[] | undefined;\n let jobToken: string;\n let credentialsToken: string;\n\n // If this is a security-only update (i.e. 'open-pull-requests-limit: 0'), then we first need to discover the dependencies\n // that need updating and check each one for vulnerabilities. This is because Dependabot requires the list of vulnerable dependencies\n // to be supplied in the job definition of security-only update job, it will not automatically discover them like a versioned update does.\n // https://docs.github.com/en/code-security/dependabot/dependabot-security-updates/configuring-dependabot-security-updates#overriding-the-default-behavior-with-a-configuration-file\n let securityVulnerabilities: SecurityVulnerability[] = [];\n let dependencyNamesToUpdate: string[] = [];\n const securityUpdatesOnly = update['open-pull-requests-limit'] === 0;\n if (securityUpdatesOnly) {\n // Run an update job to discover all dependencies\n ({ job, credentials } = builder.forDependenciesList({ command }));\n ({ jobToken, credentialsToken } = this.makeTokens());\n server.add({ id: job.id, update, job, jobToken, credentialsToken, credentials });\n await runJob({\n dependabotApiUrl,\n dependabotApiDockerUrl,\n jobId: job.id,\n jobToken,\n credentialsToken,\n updaterImage,\n secretMasker,\n usage: makeUsageData(job),\n });\n\n const outputs = server.requests(job.id);\n const packagesToCheckForVulnerabilities: Package[] | undefined = outputs!\n .find((o) => o.type === 'update_dependency_list')\n ?.data.dependencies?.map((d) => ({ name: d.name, version: d.version }));\n if (packagesToCheckForVulnerabilities?.length) {\n logger.info(\n `Detected ${packagesToCheckForVulnerabilities.length} dependencies; Checking for vulnerabilities...`,\n );\n\n // parse security advisories from file (private)\n if (securityAdvisoriesFile) {\n const filePath = securityAdvisoriesFile;\n if (existsSync(filePath)) {\n const fileContents = await readFile(filePath, 'utf-8');\n securityVulnerabilities = await SecurityVulnerabilitySchema.array().parseAsync(JSON.parse(fileContents));\n } else {\n logger.info(`Private security advisories file '${filePath}' does not exist`);\n }\n }\n if (githubToken) {\n const ghsaClient = new GitHubSecurityAdvisoryClient(githubToken);\n const githubVulnerabilities = await ghsaClient.getSecurityVulnerabilitiesAsync(\n getGhsaPackageEcosystemFromDependabotPackageManager(packageManager),\n packagesToCheckForVulnerabilities || [],\n );\n securityVulnerabilities.push(...githubVulnerabilities);\n } else {\n logger.info(\n 'GitHub access token is not provided; Checking for vulnerabilities from GitHub is skipped. ' +\n 'This is not an issue if you are using private security advisories file.',\n );\n }\n\n securityVulnerabilities = filterVulnerabilities(securityVulnerabilities);\n\n // Only update dependencies that have vulnerabilities\n dependencyNamesToUpdate = Array.from(new Set(securityVulnerabilities.map((v) => v.package.name)));\n logger.info(\n `Detected ${securityVulnerabilities.length} vulnerabilities affecting ${dependencyNamesToUpdate.length} dependencies`,\n );\n if (dependencyNamesToUpdate.length) {\n logger.trace(dependencyNamesToUpdate);\n }\n } else {\n logger.info(`No vulnerabilities detected for update ${update['package-ecosystem']} in ${update.directory}`);\n server.clear(job.id);\n continue; // nothing more to do for this update\n }\n\n server.clear(job.id);\n }\n\n // Run an update job for \"all dependencies\"; this will create new pull requests for dependencies that need updating\n const openPullRequestsLimit = update['open-pull-requests-limit']!;\n const openPullRequestsCount = Object.entries(existingPullRequestsForPackageManager).length;\n const hasReachedOpenPullRequestLimit =\n openPullRequestsLimit > 0 && openPullRequestsCount >= openPullRequestsLimit;\n if (!hasReachedOpenPullRequestLimit) {\n const dependenciesHaveVulnerabilities = dependencyNamesToUpdate.length && securityVulnerabilities.length;\n if (!securityUpdatesOnly || dependenciesHaveVulnerabilities) {\n ({ job, credentials } = builder.forUpdate({\n command,\n dependencyNamesToUpdate,\n existingPullRequests: existingPullRequestDependenciesForPackageManager,\n securityVulnerabilities,\n }));\n ({ jobToken, credentialsToken } = this.makeTokens());\n server.add({ id: job.id, update, job, jobToken, credentialsToken, credentials });\n const { success, message } = await runJob({\n dependabotApiUrl,\n dependabotApiDockerUrl,\n jobId: job.id,\n jobToken,\n credentialsToken,\n updaterImage,\n secretMasker,\n usage: makeUsageData(job),\n });\n const affectedPrs = server.allAffectedPrs(job.id);\n server.clear(job.id);\n results.push({ id: job.id, success, message, affectedPrs });\n } else {\n logger.info('Nothing to update; dependencies are not affected by any known vulnerability');\n }\n } else {\n logger.warn(\n `Skipping update for ${packageEcosystem} packages as the open pull requests limit (${openPullRequestsLimit}) has already been reached`,\n );\n }\n\n // If there are existing pull requests, run an update job for each one; this will resolve merge conflicts and close pull requests that are no longer needed\n const numberOfPullRequestsToUpdate = Object.keys(existingPullRequestsForPackageManager).length;\n if (numberOfPullRequestsToUpdate > 0) {\n if (!dryRun) {\n for (const pullRequestId in existingPullRequestsForPackageManager) {\n ({ job, credentials } = builder.forUpdate({\n command,\n existingPullRequests: existingPullRequestDependenciesForPackageManager,\n pullRequestToUpdate: existingPullRequestsForPackageManager[pullRequestId]!,\n securityVulnerabilities,\n }));\n ({ jobToken, credentialsToken } = this.makeTokens());\n server.add({ id: job.id, update, job, jobToken, credentialsToken, credentials });\n const { success, message } = await runJob({\n dependabotApiUrl,\n dependabotApiDockerUrl,\n jobId: job.id,\n jobToken,\n credentialsToken,\n updaterImage,\n secretMasker,\n usage: makeUsageData(job),\n });\n const affectedPrs = server.allAffectedPrs(job.id);\n server.clear(job.id);\n results.push({ id: job.id, success, message, affectedPrs });\n }\n } else {\n logger.warn(\n `Skipping update of ${numberOfPullRequestsToUpdate} existing ${packageEcosystem} package pull request(s) as 'dryRun' is set to 'true'`,\n );\n }\n }\n }\n\n return results;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["updates: DependabotUpdate[]","results: RunJobsResult","job: DependabotJobConfig | undefined","credentials: DependabotCredential[] | undefined","jobToken: string","credentialsToken: string","securityVulnerabilities: SecurityVulnerability[]","dependencyNamesToUpdate: string[]","packagesToCheckForVulnerabilities: Package[] | undefined"],"sources":["../../../src/local/azure/server.ts","../../../src/local/azure/runner.ts"],"sourcesContent":["import type { AzureDevOpsRepositoryUrl, AzureDevOpsWebApiClient, IPullRequestProperties } from '@paklo/core/azure';\nimport {\n type AzdoPullRequestMergeStrategy,\n buildPullRequestProperties,\n getPullRequestChangedFilesForOutputData,\n getPullRequestCloseReasonForOutputData,\n getPullRequestDependenciesPropertyValueForOutputData,\n getPullRequestDescription,\n getPullRequestForDependencyNames,\n parsePullRequestProperties,\n} from '@paklo/core/azure';\nimport { type DependabotRequest, getBranchNameForUpdate } from '@paklo/core/dependabot';\nimport { logger } from '@paklo/core/logger';\nimport { LocalDependabotServer, type LocalDependabotServerOptions } from '../server';\n\nexport type AzureLocalDependabotServerOptions = LocalDependabotServerOptions & {\n url: AzureDevOpsRepositoryUrl;\n authorClient: AzureDevOpsWebApiClient;\n autoApprove: boolean;\n approverClient?: AzureDevOpsWebApiClient;\n setAutoComplete: boolean;\n mergeStrategy?: AzdoPullRequestMergeStrategy;\n autoCompleteIgnoreConfigIds: number[];\n existingBranchNames: string[] | undefined;\n existingPullRequests: IPullRequestProperties[];\n};\n\nexport class AzureLocalDependabotServer extends LocalDependabotServer {\n // biome-ignore lint/correctness/noUnusedPrivateClassMembers: options is used\n private readonly options: AzureLocalDependabotServerOptions;\n\n constructor(options: AzureLocalDependabotServerOptions) {\n super(options);\n this.options = options;\n }\n\n protected override async handle(id: string, request: DependabotRequest): Promise<boolean> {\n await super.handle(id, request); // common logic\n\n const { options, affectedPullRequestIds } = this;\n const {\n url,\n authorClient,\n approverClient,\n existingBranchNames,\n existingPullRequests,\n autoApprove,\n mergeStrategy,\n setAutoComplete,\n autoCompleteIgnoreConfigIds,\n author,\n dryRun,\n } = options;\n\n const { type, data } = request;\n const job = await this.job(id);\n if (!job) {\n logger.error(`No job found for ID '${id}', cannot process request of type '${type}'`);\n return false;\n }\n const { 'package-manager': packageManager } = job;\n logger.info(`Processing '${type}' for job ID '${id}'`);\n\n const update = this.update(id)!; // exists because job exists\n const { project, repository } = url;\n\n switch (type) {\n // Documentation on the 'data' model for each output type can be found here:\n // See: https://github.com/dependabot/cli/blob/main/internal/model/update.go\n\n case 'create_pull_request': {\n const title = data['pr-title'];\n if (dryRun) {\n logger.warn(`Skipping pull request creation of '${title}' as 'dryRun' is set to 'true'`);\n return true;\n }\n\n // Skip if active pull request limit reached.\n const openPullRequestsLimit = update['open-pull-requests-limit']!;\n\n // Parse the Dependabot metadata for the existing pull requests that are related to this update\n // Dependabot will use this to determine if we need to create new pull requests or update/close existing ones\n const existingPullRequestsForPackageManager = parsePullRequestProperties(existingPullRequests, packageManager);\n const existingPullRequestsCount = Object.entries(existingPullRequestsForPackageManager).length;\n const openPullRequestsCount = affectedPullRequestIds.get(id)!.created.length + existingPullRequestsCount;\n const hasReachedOpenPullRequestLimit =\n openPullRequestsLimit > 0 && openPullRequestsCount >= openPullRequestsLimit;\n\n if (hasReachedOpenPullRequestLimit) {\n logger.warn(\n `Skipping pull request creation of '${title}' as the open pull requests limit (${openPullRequestsLimit}) has been reached`,\n );\n return true;\n }\n\n const changedFiles = getPullRequestChangedFilesForOutputData(data);\n const dependencies = getPullRequestDependenciesPropertyValueForOutputData(data);\n const targetBranch = update['target-branch'] || (await authorClient.getDefaultBranch(project, repository));\n const sourceBranch = getBranchNameForUpdate(\n update['package-ecosystem'],\n targetBranch,\n update.directory || update.directories?.find((dir) => changedFiles[0]?.path?.startsWith(dir)),\n !Array.isArray(dependencies) ? dependencies['dependency-group-name'] : undefined,\n !Array.isArray(dependencies) ? dependencies.dependencies : dependencies,\n update['pull-request-branch-name']?.separator,\n );\n\n // Check if the source branch already exists or conflicts with an existing branch\n const existingBranch = existingBranchNames?.find((branch) => sourceBranch === branch) || [];\n if (existingBranch.length) {\n logger.error(\n `Unable to create pull request '${title}' as source branch '${sourceBranch}' already exists; Delete the existing branch and try again.`,\n );\n return false;\n }\n const conflictingBranches = existingBranchNames?.filter((branch) => sourceBranch.startsWith(branch)) || [];\n if (conflictingBranches.length) {\n logger.error(\n `Unable to create pull request '${title}' as source branch '${sourceBranch}' would conflict with existing branch(es) '${conflictingBranches.join(', ')}'; Delete the conflicting branch(es) and try again.`,\n );\n return false;\n }\n\n // Create a new pull request\n const newPullRequestId = await authorClient.createPullRequest({\n project: project,\n repository: repository,\n source: {\n commit: data['base-commit-sha'] || job.source.commit!,\n branch: sourceBranch,\n },\n target: {\n branch: targetBranch!,\n },\n author,\n title,\n description: getPullRequestDescription(packageManager, data['pr-body'], data.dependencies),\n commitMessage: data['commit-message'],\n autoComplete: setAutoComplete\n ? {\n ignorePolicyConfigIds: autoCompleteIgnoreConfigIds,\n mergeStrategy: mergeStrategy ?? 'squash',\n }\n : undefined,\n assignees: update.assignees,\n labels: update.labels?.map((label) => label?.trim()) || [],\n workItems: update.milestone ? [update.milestone] : [],\n changes: changedFiles,\n properties: buildPullRequestProperties(packageManager, dependencies),\n });\n\n // Auto-approve the pull request, if required\n if (autoApprove && approverClient && newPullRequestId) {\n await approverClient.approvePullRequest({\n project: project,\n repository: repository,\n pullRequestId: newPullRequestId,\n });\n }\n\n // Store the new pull request ID, so we can keep track of the total number of open pull requests\n if (newPullRequestId && newPullRequestId > 0) {\n affectedPullRequestIds.get(id)!.created.push(newPullRequestId);\n return true;\n } else {\n return false;\n }\n }\n\n case 'update_pull_request': {\n if (dryRun) {\n logger.warn(`Skipping pull request update as 'dryRun' is set to 'true'`);\n return true;\n }\n\n // Find the pull request to update\n const pullRequestToUpdate = getPullRequestForDependencyNames(\n existingPullRequests,\n packageManager,\n data['dependency-names'],\n );\n if (!pullRequestToUpdate) {\n logger.error(\n `Could not find pull request to update for package manager '${packageManager}' with dependencies '${data['dependency-names'].join(', ')}'`,\n );\n return false;\n }\n\n // Update the pull request\n const pullRequestWasUpdated = await authorClient.updatePullRequest({\n project: project,\n repository: repository,\n pullRequestId: pullRequestToUpdate.id,\n commit: data['base-commit-sha'] || job.source.commit!,\n author,\n changes: getPullRequestChangedFilesForOutputData(data),\n skipIfDraft: true,\n skipIfCommitsFromAuthorsOtherThan: author.email,\n skipIfNotBehindTargetBranch: true,\n });\n\n // Re-approve the pull request, if required\n if (autoApprove && approverClient && pullRequestWasUpdated) {\n await approverClient.approvePullRequest({\n project: project,\n repository: repository,\n pullRequestId: pullRequestToUpdate.id,\n });\n }\n\n if (pullRequestWasUpdated) {\n affectedPullRequestIds.get(id)!.updated.push(pullRequestToUpdate.id);\n return true;\n }\n return false;\n }\n\n case 'close_pull_request': {\n if (dryRun) {\n logger.warn(`Skipping pull request closure as 'dryRun' is set to 'true'`);\n return true;\n }\n\n // Find the pull request to close\n const pullRequestToClose = getPullRequestForDependencyNames(\n existingPullRequests,\n packageManager,\n data['dependency-names'],\n );\n if (!pullRequestToClose) {\n logger.error(\n `Could not find pull request to close for package manager '${packageManager}' with dependencies '${data['dependency-names'].join(', ')}'`,\n );\n return false;\n }\n\n // TODO: GitHub Dependabot will close with reason \"Superseded by ${new_pull_request_id}\" when another PR supersedes it.\n // How do we detect this? Do we need to?\n\n // Close the pull request\n const success = await authorClient.abandonPullRequest({\n project: project,\n repository: repository,\n pullRequestId: pullRequestToClose.id,\n comment: getPullRequestCloseReasonForOutputData(data),\n deleteSourceBranch: true,\n });\n if (success) {\n affectedPullRequestIds.get(id)!.closed.push(pullRequestToClose.id);\n return true;\n }\n return false;\n }\n\n case 'record_update_job_warning': {\n if (dryRun) {\n logger.warn(`Skipping warning as 'dryRun' is set to 'true'`);\n return true;\n }\n\n // add comment to each create/updated pull request\n const ids = affectedPullRequestIds.get(id)!.created.concat(affectedPullRequestIds.get(id)!.updated);\n for (const pullRequestId of ids) {\n await authorClient.addCommentThread({\n project: project,\n repository: repository,\n content: `### Dependabot Warning: ${data['warn-title']}\\n\\n${data['warn-description']}`,\n pullRequestId,\n });\n }\n\n return true;\n }\n\n // No action required\n case 'update_dependency_list':\n case 'create_dependency_submission':\n case 'mark_as_processed':\n case 'record_ecosystem_versions':\n case 'increment_metric':\n case 'record_ecosystem_meta':\n case 'record_cooldown_meta':\n case 'record_metrics': // from the runner\n return true;\n\n case 'record_update_job_error':\n logger.error(`Update job error: ${data['error-type']} ${JSON.stringify(data['error-details'])}`);\n return true;\n\n case 'record_update_job_unknown_error':\n logger.error(`Update job unknown error: ${data['error-type']}, ${JSON.stringify(data['error-details'])}`);\n return true;\n\n default:\n logger.warn(`Unknown dependabot request type '${type}', ignoring...`);\n return true;\n }\n }\n}\n","import { existsSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport {\n AzureDevOpsWebApiClient,\n DEVOPS_PR_PROPERTY_MICROSOFT_GIT_SOURCE_REF_NAME,\n type IPullRequestProperties,\n normalizeBranchName,\n parsePullRequestProperties,\n} from '@paklo/core/azure';\nimport {\n type DependabotCredential,\n DependabotJobBuilder,\n type DependabotJobConfig,\n type DependabotUpdate,\n mapPackageEcosystemToPackageManager,\n} from '@paklo/core/dependabot';\nimport {\n filterVulnerabilities,\n GitHubSecurityAdvisoryClient,\n getGhsaPackageEcosystemFromDependabotPackageManager,\n type Package,\n type SecurityVulnerability,\n SecurityVulnerabilitySchema,\n} from '@paklo/core/github';\nimport { logger } from '@paklo/core/logger';\nimport { type RunJobOptions, runJob } from '../../run';\nimport { LocalJobsRunner, type LocalJobsRunnerOptions, type RunJobsResult } from '../runner';\nimport { AzureLocalDependabotServer, type AzureLocalDependabotServerOptions } from './server';\n\nexport type AzureLocalJobsRunnerOptions = LocalJobsRunnerOptions &\n Omit<\n AzureLocalDependabotServerOptions,\n 'authorClient' | 'approverClient' | 'existingBranchNames' | 'existingPullRequests'\n > & {\n port?: number;\n securityAdvisoriesFile?: string;\n gitToken: string;\n githubToken?: string;\n autoApproveToken?: string;\n };\n\nexport class AzureLocalJobsRunner extends LocalJobsRunner {\n // biome-ignore-start lint/correctness/noUnusedPrivateClassMembers: variables are used\n private readonly options: AzureLocalJobsRunnerOptions;\n private readonly authorClient: AzureDevOpsWebApiClient;\n private readonly approverClient?: AzureDevOpsWebApiClient;\n // biome-ignore-end lint/correctness/noUnusedPrivateClassMembers: variables are used\n\n constructor(options: AzureLocalJobsRunnerOptions) {\n super({ ...options });\n this.options = options;\n const { url, gitToken, autoApprove, debug } = this.options;\n\n // Initialise the DevOps API clients (one for authoring the other for auto-approving (if configured))\n this.authorClient = new AzureDevOpsWebApiClient(url, gitToken, debug);\n this.approverClient = autoApprove\n ? new AzureDevOpsWebApiClient(url, options.autoApproveToken || gitToken, debug)\n : undefined;\n }\n\n public override async run(): Promise<RunJobsResult> {\n await super.run(); // common logic\n\n const {\n options: { url, port, config, targetUpdateIds, command },\n authorClient,\n approverClient,\n } = this;\n\n // Print a warning about multi-ecosystem updates not being fully supported\n // TODO: Implement full support for multi-ecosystem updates (not sure this will be possible on the local model)\n if (config['multi-ecosystem-groups'] || config.updates?.some((u) => u['multi-ecosystem-group'])) {\n logger.warn(\n 'Multi-ecosystem updates are not working yet. Only parsing and validation is supported at this time.',\n );\n }\n\n // Print a warning about the required workarounds for security-only updates, if any update is configured as such\n // TODO: If and when Dependabot supports a better way to do security-only updates, remove this.\n if (config.updates?.some((u) => u['open-pull-requests-limit'] === 0)) {\n logger.warn(\n 'Security-only updates incur a slight performance overhead due to limitations in Dependabot CLI. For more info, see: https://github.com/mburumaxwell/dependabot-azure-devops/blob/main/README.md#configuring-security-advisories-and-known-vulnerabilities',\n );\n }\n\n // Fetch the active pull requests created by the author user\n const existingBranchNames = await authorClient.getBranchNames(url.project, url.repository);\n const existingPullRequests = await authorClient.getActivePullRequestProperties(\n url.project,\n url.repository,\n await authorClient.getUserId(),\n );\n\n // Prepare local server\n const serverOptions: AzureLocalDependabotServerOptions = {\n authorClient,\n approverClient,\n existingBranchNames,\n existingPullRequests,\n ...this.options,\n };\n const server = new AzureLocalDependabotServer(serverOptions);\n server.start(port);\n // give the server a second to start\n await new Promise((resolve) => setTimeout(resolve, 1000));\n\n // The API urls is constant when working in this CLI. Asking people to setup NGROK or similar just to get\n // HTTPS for the job token to be used is too much hassle.\n // Using same value for dependabotApiUrl and dependabotApiDockerUrl so as to capture /record_metrics calls.\n const dependabotApiUrl = `http://host.docker.internal:${server.port}/api`;\n const dependabotApiDockerUrl = dependabotApiUrl;\n\n // If update identifiers are specified, select them; otherwise handle all\n let updates: DependabotUpdate[] = [];\n if (targetUpdateIds && targetUpdateIds.length > 0) {\n for (const id of targetUpdateIds) {\n const upd = config.updates[id];\n if (!upd) {\n logger.warn(\n `\n Unable to find target update id '${id}'.\n This value should be a zero based index of the update in your config file.\n Expected range: 0-${config.updates.length - 1}\n `,\n );\n } else {\n updates.push(upd);\n }\n }\n } else {\n updates = config.updates;\n }\n\n try {\n // Abandon all pull requests where the source branch has been deleted\n await this.abandonPullRequestsWhereSourceRefIsDeleted(existingBranchNames, existingPullRequests);\n\n // Perform updates for each of the [targeted] update blocks in dependabot.yaml\n return await this.performUpdates(\n server,\n updates,\n existingPullRequests,\n dependabotApiUrl,\n dependabotApiDockerUrl,\n command,\n );\n } finally {\n server.stop();\n }\n }\n\n /**\n * Abandon all pull requests where the source branch has been deleted.\n * @param existingBranchNames The names of the existing branches.\n * @param existingPullRequests The existing pull requests.\n */\n private async abandonPullRequestsWhereSourceRefIsDeleted(\n existingBranchNames?: string[],\n existingPullRequests?: IPullRequestProperties[],\n ): Promise<void> {\n if (!existingBranchNames || !existingPullRequests) return;\n\n const {\n options: { url, dryRun },\n authorClient,\n } = this;\n for (const pullRequestIndex in existingPullRequests) {\n const pullRequest = existingPullRequests[pullRequestIndex]!;\n const pullRequestSourceRefName = normalizeBranchName(\n pullRequest.properties?.find((x) => x.name === DEVOPS_PR_PROPERTY_MICROSOFT_GIT_SOURCE_REF_NAME)?.value,\n );\n if (pullRequestSourceRefName && !existingBranchNames.includes(pullRequestSourceRefName)) {\n // The source branch for the pull request has been deleted; abandon the pull request (if not dry run)\n if (!dryRun) {\n logger.warn(\n `Detected source branch for PR #${pullRequest.id} has been deleted; The pull request will be abandoned`,\n );\n await authorClient.abandonPullRequest({\n project: url.project,\n repository: url.repository,\n pullRequestId: pullRequest.id,\n // comment:\n // 'OK, I won't notify you again about this release, but will get in touch when a new version is available. ' +\n // 'If you'd rather skip all updates until the next major or minor version, add an ' +\n // '[`ignore` condition](https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference#ignore--) ' +\n // 'with the desired `update-types` to your config file.',\n comment:\n 'It might be a good idea to add an ' +\n '[`ignore` condition](https://docs.github.com/en/code-security/dependabot/working-with-dependabot/dependabot-options-reference#ignore--) ' +\n 'with the desired `update-types` to your config file.',\n });\n }\n // Remove the pull request from the list of existing pull requests to ensures that we don't attempt to update it later in the process.\n existingPullRequests.splice(existingPullRequests.indexOf(pullRequest), 1);\n }\n }\n }\n\n /**\n * Performs the updates.\n * @param server The local Dependabot server.\n * @param updates The updates to perform.\n * @param existingPullRequests The existing pull requests.\n */\n private async performUpdates(\n server: AzureLocalDependabotServer,\n updates: DependabotUpdate[],\n existingPullRequests: IPullRequestProperties[],\n dependabotApiUrl: string,\n dependabotApiDockerUrl?: string,\n command?: DependabotJobConfig['command'],\n ): Promise<RunJobsResult> {\n const {\n options: { url, gitToken, githubToken, experiments, config, dryRun, securityAdvisoriesFile, secretMasker },\n } = this;\n\n const results: RunJobsResult = [];\n\n function makeRandomJobId(): string {\n const array = new Uint32Array(1);\n crypto.getRandomValues(array);\n return `${array[0]! % 10000000000}`; // Limit to 10 digits to match GitHub's job IDs\n }\n\n function makeUsageData(job: DependabotJobConfig): RunJobOptions['usage'] {\n return {\n trigger: 'user',\n provider: job.source.provider,\n owner: url.value.toString(),\n project: `${url.value.toString().replace(/\\/$/, '')}/${url.project}`,\n 'package-manager': job['package-manager'],\n };\n }\n\n for (const update of updates) {\n const packageEcosystem = update['package-ecosystem'];\n const packageManager = mapPackageEcosystemToPackageManager(packageEcosystem);\n\n // If there is an updater image, replace the placeholder in it\n let { updaterImage } = this.options;\n updaterImage = updaterImage?.replace(/\\{ecosystem\\}/i, packageEcosystem);\n\n // Parse the Dependabot metadata for the existing pull requests that are related to this update\n // Dependabot will use this to determine if we need to create new pull requests or update/close existing ones\n const existingPullRequestsForPackageManager = parsePullRequestProperties(existingPullRequests, packageManager);\n const existingPullRequestDependenciesForPackageManager = Object.values(existingPullRequestsForPackageManager);\n\n const builder = new DependabotJobBuilder({\n source: { provider: 'azure', ...url },\n config,\n update,\n systemAccessToken: gitToken,\n githubToken,\n experiments,\n debug: false,\n });\n\n let job: DependabotJobConfig | undefined;\n let credentials: DependabotCredential[] | undefined;\n let jobToken: string;\n let credentialsToken: string;\n\n // If this is a security-only update (i.e. 'open-pull-requests-limit: 0'), then we first need to discover the dependencies\n // that need updating and check each one for vulnerabilities. This is because Dependabot requires the list of vulnerable dependencies\n // to be supplied in the job definition of security-only update job, it will not automatically discover them like a versioned update does.\n // https://docs.github.com/en/code-security/dependabot/dependabot-security-updates/configuring-dependabot-security-updates#overriding-the-default-behavior-with-a-configuration-file\n let securityVulnerabilities: SecurityVulnerability[] = [];\n let dependencyNamesToUpdate: string[] = [];\n const securityUpdatesOnly = update['open-pull-requests-limit'] === 0;\n if (securityUpdatesOnly) {\n // Run an update job to discover all dependencies\n const id = makeRandomJobId();\n ({ job, credentials } = builder.forDependenciesList({ id, command }));\n ({ jobToken, credentialsToken } = this.makeTokens());\n server.add({ id, update, job, jobToken, credentialsToken, credentials });\n await runJob({\n dependabotApiUrl,\n dependabotApiDockerUrl,\n jobId: id,\n jobToken,\n credentialsToken,\n updaterImage,\n secretMasker,\n usage: makeUsageData(job),\n });\n\n const outputs = server.requests(id);\n const packagesToCheckForVulnerabilities: Package[] | undefined = outputs!\n .find((o) => o.type === 'update_dependency_list')\n ?.data.dependencies?.map((d) => ({ name: d.name, version: d.version }));\n if (packagesToCheckForVulnerabilities?.length) {\n logger.info(\n `Detected ${packagesToCheckForVulnerabilities.length} dependencies; Checking for vulnerabilities...`,\n );\n\n // parse security advisories from file (private)\n if (securityAdvisoriesFile) {\n const filePath = securityAdvisoriesFile;\n if (existsSync(filePath)) {\n const fileContents = await readFile(filePath, 'utf-8');\n securityVulnerabilities = await SecurityVulnerabilitySchema.array().parseAsync(JSON.parse(fileContents));\n } else {\n logger.info(`Private security advisories file '${filePath}' does not exist`);\n }\n }\n if (githubToken) {\n const ghsaClient = new GitHubSecurityAdvisoryClient(githubToken);\n const githubVulnerabilities = await ghsaClient.getSecurityVulnerabilitiesAsync(\n getGhsaPackageEcosystemFromDependabotPackageManager(packageManager),\n packagesToCheckForVulnerabilities || [],\n );\n securityVulnerabilities.push(...githubVulnerabilities);\n } else {\n logger.info(\n 'GitHub access token is not provided; Checking for vulnerabilities from GitHub is skipped. ' +\n 'This is not an issue if you are using private security advisories file.',\n );\n }\n\n securityVulnerabilities = filterVulnerabilities(securityVulnerabilities);\n\n // Only update dependencies that have vulnerabilities\n dependencyNamesToUpdate = Array.from(new Set(securityVulnerabilities.map((v) => v.package.name)));\n logger.info(\n `Detected ${securityVulnerabilities.length} vulnerabilities affecting ${dependencyNamesToUpdate.length} dependencies`,\n );\n if (dependencyNamesToUpdate.length) {\n logger.trace(dependencyNamesToUpdate);\n }\n } else {\n logger.info(`No vulnerabilities detected for update ${update['package-ecosystem']} in ${update.directory}`);\n server.clear(id);\n continue; // nothing more to do for this update\n }\n\n server.clear(id);\n }\n\n // Run an update job for \"all dependencies\"; this will create new pull requests for dependencies that need updating\n const openPullRequestsLimit = update['open-pull-requests-limit']!;\n const openPullRequestsCount = Object.entries(existingPullRequestsForPackageManager).length;\n const hasReachedOpenPullRequestLimit =\n openPullRequestsLimit > 0 && openPullRequestsCount >= openPullRequestsLimit;\n if (!hasReachedOpenPullRequestLimit) {\n const dependenciesHaveVulnerabilities = dependencyNamesToUpdate.length && securityVulnerabilities.length;\n if (!securityUpdatesOnly || dependenciesHaveVulnerabilities) {\n const id = makeRandomJobId();\n ({ job, credentials } = builder.forUpdate({\n id,\n command,\n dependencyNamesToUpdate,\n existingPullRequests: existingPullRequestDependenciesForPackageManager,\n securityVulnerabilities,\n }));\n ({ jobToken, credentialsToken } = this.makeTokens());\n server.add({ id, update, job, jobToken, credentialsToken, credentials });\n const { success, message } = await runJob({\n dependabotApiUrl,\n dependabotApiDockerUrl,\n jobId: id,\n jobToken,\n credentialsToken,\n updaterImage,\n secretMasker,\n usage: makeUsageData(job),\n });\n const affectedPrs = server.allAffectedPrs(id);\n server.clear(id);\n results.push({ id, success, message, affectedPrs });\n } else {\n logger.info('Nothing to update; dependencies are not affected by any known vulnerability');\n }\n } else {\n logger.warn(\n `Skipping update for ${packageEcosystem} packages as the open pull requests limit (${openPullRequestsLimit}) has already been reached`,\n );\n }\n\n // If there are existing pull requests, run an update job for each one; this will resolve merge conflicts and close pull requests that are no longer needed\n const numberOfPullRequestsToUpdate = Object.keys(existingPullRequestsForPackageManager).length;\n if (numberOfPullRequestsToUpdate > 0) {\n if (!dryRun) {\n for (const pullRequestId in existingPullRequestsForPackageManager) {\n const id = makeRandomJobId();\n ({ job, credentials } = builder.forUpdate({\n id,\n command,\n existingPullRequests: existingPullRequestDependenciesForPackageManager,\n pullRequestToUpdate: existingPullRequestsForPackageManager[pullRequestId]!,\n securityVulnerabilities,\n }));\n ({ jobToken, credentialsToken } = this.makeTokens());\n server.add({ id, update, job, jobToken, credentialsToken, credentials });\n const { success, message } = await runJob({\n dependabotApiUrl,\n dependabotApiDockerUrl,\n jobId: id,\n jobToken,\n credentialsToken,\n updaterImage,\n secretMasker,\n usage: makeUsageData(job),\n });\n const affectedPrs = server.allAffectedPrs(id);\n server.clear(id);\n results.push({ id, success, message, affectedPrs });\n }\n } else {\n logger.warn(\n `Skipping update of ${numberOfPullRequestsToUpdate} existing ${packageEcosystem} package pull request(s) as 'dryRun' is set to 'true'`,\n );\n }\n }\n }\n\n return results;\n }\n}\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- import "../api-client-M8F9t7II.mjs";
2
- import { a as LocalJobsRunner, i as LocalDependabotServerOptions, n as LocalDependabotServer, o as LocalJobsRunnerOptions, r as LocalDependabotServerAddOptions, s as RunJobsResult, t as AffectedPullRequestIds } from "../server-DTAFwSrb.mjs";
1
+ import "../api-client-BoQ6jjRB.mjs";
2
+ import { a as LocalJobsRunner, i as LocalDependabotServerOptions, n as LocalDependabotServer, o as LocalJobsRunnerOptions, r as LocalDependabotServerAddOptions, s as RunJobsResult, t as AffectedPullRequestIds } from "../server-89g3AXRY.mjs";
3
3
  export { AffectedPullRequestIds, LocalDependabotServer, LocalDependabotServerAddOptions, LocalDependabotServerOptions, LocalJobsRunner, LocalJobsRunnerOptions, RunJobsResult };
@@ -1,3 +1,3 @@
1
- import { n as LocalJobsRunner, t as LocalDependabotServer } from "../server-M1ps5BVd.mjs";
1
+ import { n as LocalJobsRunner, t as LocalDependabotServer } from "../server-BxUu1gGo.mjs";
2
2
 
3
3
  export { LocalDependabotServer, LocalJobsRunner };