Skip to content

Commit

Permalink
Do not run security-only update when there are no vulnerable dependen…
Browse files Browse the repository at this point in the history
…cies
  • Loading branch information
rhyskoedijk committed Oct 22, 2024
1 parent 6609b2b commit 0934cfe
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 22 deletions.
42 changes: 24 additions & 18 deletions extension/tasks/dependabotV2/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { IDependabotUpdateOperationResult } from './utils/dependabot-cli/interfa
import { IDependabotUpdate } from './utils/dependabot/interfaces/IDependabotConfig';
import parseDependabotConfigFile from './utils/dependabot/parseConfigFile';
import parseTaskInputConfiguration from './utils/getSharedVariables';
import { getSecurityAdvisories, ISecurityAdvisory } from './utils/github/getSecurityAdvisories';
import { getSecurityAdvisories, IDependency, ISecurityAdvisory } from './utils/github/getSecurityAdvisories';

async function run() {
let dependabot: DependabotCli = undefined;
Expand Down Expand Up @@ -118,11 +118,9 @@ async function run() {
);

// Get the list of security advisories that apply to the discovered dependencies
const dependenciesToCheckForSecurityAdvisories = discoveredDependencyListOutputs
const dependenciesToCheckForSecurityAdvisories: IDependency[] = discoveredDependencyListOutputs
?.find((x) => x.output.type == 'update_dependency_list')
?.output?.data?.dependencies?.map((d) => {
d.name, d.version;
});
?.output?.data?.dependencies?.map((d) => ({ name: d.name, version: d.version }));
securityAdvisories = await getSecurityAdvisories(
taskInputs.githubAccessToken,
packageEcosystem,
Expand All @@ -134,20 +132,28 @@ async function run() {
}

// Run an update job for "all dependencies"; this will create new pull requests for dependencies that need updating
failedTasks += handleUpdateOperationResults(
await dependabot.update(
DependabotJobBuilder.updateAllDependenciesJob(
taskInputs,
updateId,
update,
dependabotConfig.registries,
dependencyNamesToUpdate,
existingPullRequestDependencies,
securityAdvisories,
const dependenciesHaveVulnerabilities = (dependencyNamesToUpdate.length && securityAdvisories.length);
if (!securityUpdatesOnly || dependenciesHaveVulnerabilities)
{
failedTasks += handleUpdateOperationResults(
await dependabot.update(
DependabotJobBuilder.updateAllDependenciesJob(
taskInputs,
updateId,
update,
dependabotConfig.registries,
dependencyNamesToUpdate,
existingPullRequestDependencies,
securityAdvisories,
),
dependabotUpdaterOptions,
),
dependabotUpdaterOptions,
),
);
);
}
else
{
console.info('Nothing to update; dependencies are not affected by any known vulnerability')
}

// 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
const numberOfPullRequestsToUpdate = Object.keys(existingPullRequests).length;
Expand Down
16 changes: 12 additions & 4 deletions extension/tasks/dependabotV2/utils/github/getSecurityAdvisories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ const GITHUB_ECOSYSTEM: { [key: string]: string } = {
swift: 'SWIFT',
};

/**
* Dependency object
*/
export interface IDependency {
name: string;
version?: string;
}

/**
* Security advisory object
*/
Expand All @@ -40,7 +48,7 @@ export interface ISecurityAdvisory {
export async function getSecurityAdvisories(
accessToken: string,
packageEcosystem: string,
dependencies: { name: string; version?: string }[],
dependencies: IDependency[],
): Promise<ISecurityAdvisory[]> {
const ecosystem = GITHUB_ECOSYSTEM[packageEcosystem];
const query = `
Expand All @@ -64,7 +72,7 @@ export async function getSecurityAdvisories(
// GitHub API doesn't support querying multiple dependencies at once, so we need to make a request for each dependency individually.
// To speed up the process, we can make the requests in parallel, 100 at a time. We batch the requests to avoid hitting the rate limit too quickly.
// https://docs.github.com/en/graphql/overview/rate-limits-and-node-limits-for-the-graphql-api
console.log(`Checking security advisories for ${dependencies.length} dependencies...`);
console.info(`Checking security advisories for ${dependencies.length} dependencies...`);
const dependencyNames = dependencies.map((dependency) => dependency.name);
const securityAdvisories = await batchSecurityAdvisoryQuery(100, dependencyNames, async (dependencyName) => {
const variables = {
Expand Down Expand Up @@ -127,8 +135,8 @@ export async function getSecurityAdvisories(
});

const vulnerableDependencyCount = new Set(affectedAdvisories.map((advisory) => advisory['dependency-name'])).size;
console.log(
`Found ${vulnerableDependencyCount} vulnerable dependencies affected by ${affectedAdvisories.length} security advisories`,
console.info(
`Found ${affectedAdvisories.length} vulnerabilities; affecting ${vulnerableDependencyCount} dependencies`,
);
return affectedAdvisories;
}
Expand Down

0 comments on commit 0934cfe

Please sign in to comment.