Skip to content

Commit acaf57e

Browse files
Add the CI check dependencies for update
1 parent 175bbef commit acaf57e

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

ci/build-all-steps.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,15 @@ steps:
106106
)
107107
displayName: Push release branch
108108

109+
- script: node ./ci/check-dependencies.js
110+
displayName: Check dependencies for updates
111+
condition: |
112+
and(
113+
succeeded(),
114+
eq(variables['build.reason'], 'PullRequest'),
115+
eq(variables['System.PullRequest.TargetBranch'], 'master')
116+
)
117+
109118
- script: node ./ci/check-downgrading.js --task "$(task_pattern_fordowngradingcheck)" --sprint $(currentSprint) --week $(currentSprintWeek)
110119
displayName: Check for downgrading tasks
111120
# remove SourceBranch condition after merging users/merlynop/node20merge-2 ; see https://github.com/microsoft/azure-pipelines-tasks/pull/20819

ci/check-dependencies.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
const { execSync } = require('node:child_process');
2+
const { readFileSync } = require('node:fs');
3+
const { get } = require('node:https');
4+
const { resolve } = require('node:path');
5+
const { styleText } = require('node:util');
6+
7+
const TASKS_PATH = 'Tasks/';
8+
const skippedDependencies = [
9+
"@types/",
10+
"typescript"
11+
];
12+
13+
async function checkAvailableDependencies() {
14+
const tasks = new Set(execSync('git diff --name-only origin/master').toString('utf-8').split('\n').filter(x => x.includes(TASKS_PATH)).map(x => x.split('/')[1]));
15+
const outdatedDependencies = [];
16+
17+
console.log('Found tasks:', tasks.size);
18+
let i = 0;
19+
20+
for (const task of tasks) {
21+
i++;
22+
console.log(`\x1b[A\x1b[KChecking task ${i}/${tasks.size}: ${task}`);
23+
24+
const { dependencies = {}, devDependencies = {} } = JSON.parse(readFileSync(resolve(TASKS_PATH, task, "package.json")));
25+
const allDeps = { ...dependencies, ...devDependencies };
26+
27+
for (const [dependency, currentVersion] of Object.entries(allDeps)) {
28+
if (skippedDependencies.find(x => dependency.includes(x))) continue;
29+
30+
const latestVersion = await getLatestVersion(dependency);
31+
32+
if (latestVersion && latestVersion !== currentVersion.replace(/^[^\d]*/, '')) {
33+
outdatedDependencies.push({
34+
task,
35+
dependency,
36+
currentVersion,
37+
latestVersion
38+
});
39+
}
40+
}
41+
}
42+
43+
if (process.env["TF_BUILD"] == "True" && outdatedDependencies.length > 0) {
44+
console.log('##vso[task.logissue type=warning]Found the outdated dependencies in changed tasks. Please see the warnings in the "Check dependencies for updates" task');
45+
}
46+
47+
outdatedDependencies.forEach(x => {
48+
if (process.env["TF_BUILD"] == "True") {
49+
console.log(`##vso[task.logissue type=warning]The task "${x.task}" has dependency "${x.dependency}" that can be updated from ${x.currentVersion} to ${x.latestVersion}`);
50+
} else {
51+
console.warn(styleText('yellow', `Warning: The task "${x.task}" has dependency "${x.dependency}" that can be updated from ${styleText('red', x.currentVersion)} to ${styleText('greenBright', x.latestVersion)}`));
52+
}
53+
});
54+
}
55+
56+
async function getLatestVersion(dependency) {
57+
const response = await fetch(`https://registry.npmjs.org/${encodeURIComponent(dependency)}/latest`);
58+
const json = await response.json();
59+
return json.version;
60+
}
61+
62+
checkAvailableDependencies();

0 commit comments

Comments
 (0)