@paklo/runner 0.5.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-ChgKTE6u.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-BHIHnndG.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-ChgKTE6u.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()) || [],
@@ -202,10 +194,6 @@ var AzureLocalJobsRunner = class extends LocalJobsRunner {
202
194
  await super.run();
203
195
  const { options: { url, port, config, targetUpdateIds, command }, authorClient, approverClient } = this;
204
196
  if (config["multi-ecosystem-groups"] || config.updates?.some((u) => u["multi-ecosystem-group"])) logger.warn("Multi-ecosystem updates are not working yet. Only parsing and validation is supported at this time.");
205
- if (config.updates?.some((u) => !u.schedule)) logger.warn(`
206
- Some updates are missing a schedule configuration.
207
- This tool will require all updates to have a schedule on or after 2025-Nov-30.
208
- `);
209
197
  if (config.updates?.some((u) => u["open-pull-requests-limit"] === 0)) logger.warn("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");
210
198
  const existingBranchNames = await authorClient.getBranchNames(url.project, url.repository);
211
199
  const existingPullRequests = await authorClient.getActivePullRequestProperties(url.project, url.repository, await authorClient.getUserId());
@@ -272,6 +260,11 @@ var AzureLocalJobsRunner = class extends LocalJobsRunner {
272
260
  async performUpdates(server, updates, existingPullRequests, dependabotApiUrl, dependabotApiDockerUrl, command) {
273
261
  const { options: { url, gitToken, githubToken, experiments, config, dryRun, securityAdvisoriesFile, secretMasker } } = this;
274
262
  const results = [];
263
+ function makeRandomJobId() {
264
+ const array = new Uint32Array(1);
265
+ crypto.getRandomValues(array);
266
+ return `${array[0] % 1e10}`;
267
+ }
275
268
  function makeUsageData(job) {
276
269
  return {
277
270
  trigger: "user",
@@ -308,10 +301,14 @@ var AzureLocalJobsRunner = class extends LocalJobsRunner {
308
301
  let dependencyNamesToUpdate = [];
309
302
  const securityUpdatesOnly = update["open-pull-requests-limit"] === 0;
310
303
  if (securityUpdatesOnly) {
311
- ({job, credentials} = builder.forDependenciesList({ command }));
304
+ const id = makeRandomJobId();
305
+ ({job, credentials} = builder.forDependenciesList({
306
+ id,
307
+ command
308
+ }));
312
309
  ({jobToken, credentialsToken} = this.makeTokens());
313
310
  server.add({
314
- id: job.id,
311
+ id,
315
312
  update,
316
313
  job,
317
314
  jobToken,
@@ -321,14 +318,14 @@ var AzureLocalJobsRunner = class extends LocalJobsRunner {
321
318
  await runJob({
322
319
  dependabotApiUrl,
323
320
  dependabotApiDockerUrl,
324
- jobId: job.id,
321
+ jobId: id,
325
322
  jobToken,
326
323
  credentialsToken,
327
324
  updaterImage,
328
325
  secretMasker,
329
326
  usage: makeUsageData(job)
330
327
  });
331
- 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) => ({
332
329
  name: d.name,
333
330
  version: d.version
334
331
  }));
@@ -351,17 +348,19 @@ var AzureLocalJobsRunner = class extends LocalJobsRunner {
351
348
  if (dependencyNamesToUpdate.length) logger.trace(dependencyNamesToUpdate);
352
349
  } else {
353
350
  logger.info(`No vulnerabilities detected for update ${update["package-ecosystem"]} in ${update.directory}`);
354
- server.clear(job.id);
351
+ server.clear(id);
355
352
  continue;
356
353
  }
357
- server.clear(job.id);
354
+ server.clear(id);
358
355
  }
359
356
  const openPullRequestsLimit = update["open-pull-requests-limit"];
360
357
  const openPullRequestsCount = Object.entries(existingPullRequestsForPackageManager).length;
361
358
  if (!(openPullRequestsLimit > 0 && openPullRequestsCount >= openPullRequestsLimit)) {
362
359
  const dependenciesHaveVulnerabilities = dependencyNamesToUpdate.length && securityVulnerabilities.length;
363
360
  if (!securityUpdatesOnly || dependenciesHaveVulnerabilities) {
361
+ const id = makeRandomJobId();
364
362
  ({job, credentials} = builder.forUpdate({
363
+ id,
365
364
  command,
366
365
  dependencyNamesToUpdate,
367
366
  existingPullRequests: existingPullRequestDependenciesForPackageManager,
@@ -369,7 +368,7 @@ var AzureLocalJobsRunner = class extends LocalJobsRunner {
369
368
  }));
370
369
  ({jobToken, credentialsToken} = this.makeTokens());
371
370
  server.add({
372
- id: job.id,
371
+ id,
373
372
  update,
374
373
  job,
375
374
  jobToken,
@@ -379,17 +378,17 @@ var AzureLocalJobsRunner = class extends LocalJobsRunner {
379
378
  const { success, message } = await runJob({
380
379
  dependabotApiUrl,
381
380
  dependabotApiDockerUrl,
382
- jobId: job.id,
381
+ jobId: id,
383
382
  jobToken,
384
383
  credentialsToken,
385
384
  updaterImage,
386
385
  secretMasker,
387
386
  usage: makeUsageData(job)
388
387
  });
389
- const affectedPrs = server.allAffectedPrs(job.id);
390
- server.clear(job.id);
388
+ const affectedPrs = server.allAffectedPrs(id);
389
+ server.clear(id);
391
390
  results.push({
392
- id: job.id,
391
+ id,
393
392
  success,
394
393
  message,
395
394
  affectedPrs
@@ -398,7 +397,9 @@ var AzureLocalJobsRunner = class extends LocalJobsRunner {
398
397
  } else logger.warn(`Skipping update for ${packageEcosystem} packages as the open pull requests limit (${openPullRequestsLimit}) has already been reached`);
399
398
  const numberOfPullRequestsToUpdate = Object.keys(existingPullRequestsForPackageManager).length;
400
399
  if (numberOfPullRequestsToUpdate > 0) if (!dryRun) for (const pullRequestId in existingPullRequestsForPackageManager) {
400
+ const id = makeRandomJobId();
401
401
  ({job, credentials} = builder.forUpdate({
402
+ id,
402
403
  command,
403
404
  existingPullRequests: existingPullRequestDependenciesForPackageManager,
404
405
  pullRequestToUpdate: existingPullRequestsForPackageManager[pullRequestId],
@@ -406,7 +407,7 @@ var AzureLocalJobsRunner = class extends LocalJobsRunner {
406
407
  }));
407
408
  ({jobToken, credentialsToken} = this.makeTokens());
408
409
  server.add({
409
- id: job.id,
410
+ id,
410
411
  update,
411
412
  job,
412
413
  jobToken,
@@ -416,17 +417,17 @@ var AzureLocalJobsRunner = class extends LocalJobsRunner {
416
417
  const { success, message } = await runJob({
417
418
  dependabotApiUrl,
418
419
  dependabotApiDockerUrl,
419
- jobId: job.id,
420
+ jobId: id,
420
421
  jobToken,
421
422
  credentialsToken,
422
423
  updaterImage,
423
424
  secretMasker,
424
425
  usage: makeUsageData(job)
425
426
  });
426
- const affectedPrs = server.allAffectedPrs(job.id);
427
- server.clear(job.id);
427
+ const affectedPrs = server.allAffectedPrs(id);
428
+ server.clear(id);
428
429
  results.push({
429
- id: job.id,
430
+ id,
430
431
  success,
431
432
  message,
432
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 missing schedules\n // TODO: remove this and enforce schedules on or after 2025-Nov-30\n if (config.updates?.some((u) => !u.schedule)) {\n logger.warn(\n `\n Some updates are missing a schedule configuration.\n This tool will require all updates to have a schedule on or after 2025-Nov-30.\n `,\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-BHIHnndG.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 };