@dependabit/action 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/LICENSE +21 -0
- package/README.md +225 -0
- package/action.yml +85 -0
- package/dist/actions/check.d.ts +33 -0
- package/dist/actions/check.d.ts.map +1 -0
- package/dist/actions/check.js +162 -0
- package/dist/actions/check.js.map +1 -0
- package/dist/actions/generate.d.ts +9 -0
- package/dist/actions/generate.d.ts.map +1 -0
- package/dist/actions/generate.js +152 -0
- package/dist/actions/generate.js.map +1 -0
- package/dist/actions/update.d.ts +9 -0
- package/dist/actions/update.d.ts.map +1 -0
- package/dist/actions/update.js +246 -0
- package/dist/actions/update.js.map +1 -0
- package/dist/actions/validate.d.ts +33 -0
- package/dist/actions/validate.d.ts.map +1 -0
- package/dist/actions/validate.js +226 -0
- package/dist/actions/validate.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +114 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +154 -0
- package/dist/logger.js.map +1 -0
- package/dist/utils/agent-config.d.ts +31 -0
- package/dist/utils/agent-config.d.ts.map +1 -0
- package/dist/utils/agent-config.js +42 -0
- package/dist/utils/agent-config.js.map +1 -0
- package/dist/utils/agent-router.d.ts +33 -0
- package/dist/utils/agent-router.d.ts.map +1 -0
- package/dist/utils/agent-router.js +57 -0
- package/dist/utils/agent-router.js.map +1 -0
- package/dist/utils/errors.d.ts +51 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +219 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/inputs.d.ts +35 -0
- package/dist/utils/inputs.d.ts.map +1 -0
- package/dist/utils/inputs.js +47 -0
- package/dist/utils/inputs.js.map +1 -0
- package/dist/utils/metrics.d.ts +66 -0
- package/dist/utils/metrics.d.ts.map +1 -0
- package/dist/utils/metrics.js +116 -0
- package/dist/utils/metrics.js.map +1 -0
- package/dist/utils/outputs.d.ts +43 -0
- package/dist/utils/outputs.d.ts.map +1 -0
- package/dist/utils/outputs.js +146 -0
- package/dist/utils/outputs.js.map +1 -0
- package/dist/utils/performance.d.ts +100 -0
- package/dist/utils/performance.d.ts.map +1 -0
- package/dist/utils/performance.js +185 -0
- package/dist/utils/performance.js.map +1 -0
- package/dist/utils/reporter.d.ts +43 -0
- package/dist/utils/reporter.d.ts.map +1 -0
- package/dist/utils/reporter.js +122 -0
- package/dist/utils/reporter.js.map +1 -0
- package/dist/utils/secrets.d.ts +45 -0
- package/dist/utils/secrets.d.ts.map +1 -0
- package/dist/utils/secrets.js +94 -0
- package/dist/utils/secrets.js.map +1 -0
- package/package.json +45 -0
- package/src/actions/check.ts +223 -0
- package/src/actions/generate.ts +181 -0
- package/src/actions/update.ts +284 -0
- package/src/actions/validate.ts +292 -0
- package/src/index.ts +43 -0
- package/src/logger.test.ts +200 -0
- package/src/logger.ts +210 -0
- package/src/utils/agent-config.ts +61 -0
- package/src/utils/agent-router.ts +67 -0
- package/src/utils/errors.ts +251 -0
- package/src/utils/inputs.ts +75 -0
- package/src/utils/metrics.ts +169 -0
- package/src/utils/outputs.ts +202 -0
- package/src/utils/performance.ts +248 -0
- package/src/utils/reporter.ts +169 -0
- package/src/utils/secrets.ts +124 -0
- package/test/actions/check.test.ts +216 -0
- package/test/actions/generate.test.ts +82 -0
- package/test/actions/update.test.ts +70 -0
- package/test/actions/validate.test.ts +257 -0
- package/test/utils/agent-config.test.ts +112 -0
- package/test/utils/agent-router.test.ts +129 -0
- package/test/utils/metrics.test.ts +221 -0
- package/test/utils/reporter.test.ts +196 -0
- package/test/utils/secrets.test.ts +217 -0
- package/tsconfig.json +15 -0
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Summary Reporter
|
|
3
|
+
* Generates human-readable summaries for dependency change reports
|
|
4
|
+
*/
|
|
5
|
+
export class SummaryReporter {
|
|
6
|
+
/**
|
|
7
|
+
* Generates a summary report for all dependency changes
|
|
8
|
+
*/
|
|
9
|
+
generateSummary(changes) {
|
|
10
|
+
if (changes.length === 0) {
|
|
11
|
+
return '✅ All dependencies are up to date. No changes detected.';
|
|
12
|
+
}
|
|
13
|
+
const breaking = changes.filter((c) => c.severity === 'breaking');
|
|
14
|
+
const major = changes.filter((c) => c.severity === 'major');
|
|
15
|
+
const minor = changes.filter((c) => c.severity === 'minor');
|
|
16
|
+
let summary = '# Dependency Changes Detected\n\n';
|
|
17
|
+
summary += `**Total Changes**: ${changes.length}\n`;
|
|
18
|
+
summary += `- 🔴 Breaking: ${breaking.length}\n`;
|
|
19
|
+
summary += `- 🟡 Major: ${major.length}\n`;
|
|
20
|
+
summary += `- 🟢 Minor: ${minor.length}\n\n`;
|
|
21
|
+
if (breaking.length > 0) {
|
|
22
|
+
summary += '## ⚠️ Breaking Changes\n\n';
|
|
23
|
+
breaking.forEach((change) => {
|
|
24
|
+
summary += this.formatChangeItem(change);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
if (major.length > 0) {
|
|
28
|
+
summary += '## 🔔 Major Updates\n\n';
|
|
29
|
+
major.forEach((change) => {
|
|
30
|
+
summary += this.formatChangeItem(change);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
if (minor.length > 0) {
|
|
34
|
+
summary += '## 📝 Minor Updates\n\n';
|
|
35
|
+
minor.forEach((change) => {
|
|
36
|
+
summary += this.formatChangeItem(change);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
return summary;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Generates detailed issue body for a single dependency change
|
|
43
|
+
*/
|
|
44
|
+
generateIssueBody(change) {
|
|
45
|
+
const { dependency, severity, changes, oldVersion, newVersion, releaseNotes } = change;
|
|
46
|
+
let body = '';
|
|
47
|
+
// Header with severity indicator
|
|
48
|
+
const severityEmoji = {
|
|
49
|
+
breaking: '⚠️',
|
|
50
|
+
major: '🔔',
|
|
51
|
+
minor: '📝'
|
|
52
|
+
}[severity];
|
|
53
|
+
body += `${severityEmoji} **${severity.toUpperCase()}** dependency update detected\n\n`;
|
|
54
|
+
// Dependency information
|
|
55
|
+
body += `## Dependency: ${dependency.name || dependency.id}\n\n`;
|
|
56
|
+
body += `- **URL**: ${dependency.url}\n`;
|
|
57
|
+
if (dependency.type) {
|
|
58
|
+
body += `- **Type**: ${dependency.type}\n`;
|
|
59
|
+
}
|
|
60
|
+
// Version change
|
|
61
|
+
if (oldVersion && newVersion) {
|
|
62
|
+
body += `\n## Version Change\n\n`;
|
|
63
|
+
body += `\`${oldVersion}\` → \`${newVersion}\`\n`;
|
|
64
|
+
}
|
|
65
|
+
// Changes detected
|
|
66
|
+
body += `\n## Changes Detected\n\n`;
|
|
67
|
+
changes.forEach((change) => {
|
|
68
|
+
body += `- ${change}\n`;
|
|
69
|
+
});
|
|
70
|
+
// Release notes if available
|
|
71
|
+
if (releaseNotes) {
|
|
72
|
+
body += `\n## Release Notes\n\n`;
|
|
73
|
+
body += releaseNotes;
|
|
74
|
+
}
|
|
75
|
+
// Action required for breaking changes
|
|
76
|
+
if (severity === 'breaking') {
|
|
77
|
+
body += `\n## ⚠️ Action Required\n\n`;
|
|
78
|
+
body += `This is a **breaking change** that may require updates to your code.\n`;
|
|
79
|
+
body += `Please review the changes and update your implementation accordingly.\n`;
|
|
80
|
+
}
|
|
81
|
+
return body;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Formats change summary for display
|
|
85
|
+
*/
|
|
86
|
+
formatChangeSummary(change) {
|
|
87
|
+
let summary = '';
|
|
88
|
+
if (change.oldVersion && change.newVersion) {
|
|
89
|
+
summary += `Version: ${change.oldVersion} → ${change.newVersion}\n`;
|
|
90
|
+
}
|
|
91
|
+
if (change.changes.includes('content')) {
|
|
92
|
+
summary += 'content updated\n';
|
|
93
|
+
if (change.contentDiff) {
|
|
94
|
+
summary += `Changes: ${change.contentDiff}\n`;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (change.changes.includes('metadata')) {
|
|
98
|
+
summary += 'metadata updated\n';
|
|
99
|
+
}
|
|
100
|
+
if (change.changes.includes('version')) {
|
|
101
|
+
summary += 'version updated\n';
|
|
102
|
+
}
|
|
103
|
+
return summary.trim();
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Formats a single change item for the summary
|
|
107
|
+
*/
|
|
108
|
+
formatChangeItem(change) {
|
|
109
|
+
const name = change.dependency.name || change.dependency.id;
|
|
110
|
+
let item = `### ${name}\n\n`;
|
|
111
|
+
item += `- **URL**: ${change.dependency.url}\n`;
|
|
112
|
+
if (change.oldVersion && change.newVersion) {
|
|
113
|
+
item += `- **Version**: \`${change.oldVersion}\` → \`${change.newVersion}\`\n`;
|
|
114
|
+
}
|
|
115
|
+
if (change.changes.length > 0) {
|
|
116
|
+
item += `- **Changes**: ${change.changes.join(', ')}\n`;
|
|
117
|
+
}
|
|
118
|
+
item += '\n';
|
|
119
|
+
return item;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=reporter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["../../src/utils/reporter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret resolution utility for GitHub Actions and environment variables
|
|
3
|
+
* Safely resolves secrets from GitHub Secrets and environment variables
|
|
4
|
+
*/
|
|
5
|
+
export interface SecretResolverConfig {
|
|
6
|
+
prefix?: string;
|
|
7
|
+
enableCache?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface DependencyAuthConfig {
|
|
10
|
+
[domain: string]: {
|
|
11
|
+
secretName: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Resolves secrets from environment variables and GitHub Secrets
|
|
16
|
+
*/
|
|
17
|
+
export declare class SecretResolver {
|
|
18
|
+
private prefix;
|
|
19
|
+
private enableCache;
|
|
20
|
+
private cache;
|
|
21
|
+
constructor(config?: SecretResolverConfig);
|
|
22
|
+
/**
|
|
23
|
+
* Resolve a single secret by name
|
|
24
|
+
*/
|
|
25
|
+
resolve(secretName: string): Promise<string>;
|
|
26
|
+
/**
|
|
27
|
+
* Resolve multiple secrets at once
|
|
28
|
+
*/
|
|
29
|
+
resolveMultiple(secretNames: string[], options?: {
|
|
30
|
+
allowPartial?: boolean;
|
|
31
|
+
}): Promise<Record<string, string>>;
|
|
32
|
+
/**
|
|
33
|
+
* Resolve per-dependency authentication configuration
|
|
34
|
+
*/
|
|
35
|
+
resolveDependencyAuth(config: DependencyAuthConfig): Promise<Record<string, string>>;
|
|
36
|
+
/**
|
|
37
|
+
* Validate secret name format
|
|
38
|
+
*/
|
|
39
|
+
validate(secretName: string): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Clear the secret cache
|
|
42
|
+
*/
|
|
43
|
+
clearCache(): void;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=secrets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../src/utils/secrets.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB;IACnC,CAAC,MAAM,EAAE,MAAM,GAAG;QAChB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,WAAW,CAAU;IAC7B,OAAO,CAAC,KAAK,CAAsB;IAEnC,YAAY,MAAM,GAAE,oBAAyB,EAI5C;IAED;;OAEG;IACG,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAwBjD;IAED;;OAEG;IACG,eAAe,CACnB,WAAW,EAAE,MAAM,EAAE,EACrB,OAAO,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,OAAO,CAAA;KAAE,GACnC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAqBjC;IAED;;OAEG;IACG,qBAAqB,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CASzF;IAED;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAUpC;IAED;;OAEG;IACH,UAAU,IAAI,IAAI,CAEjB;CACF"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret resolution utility for GitHub Actions and environment variables
|
|
3
|
+
* Safely resolves secrets from GitHub Secrets and environment variables
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Resolves secrets from environment variables and GitHub Secrets
|
|
7
|
+
*/
|
|
8
|
+
export class SecretResolver {
|
|
9
|
+
prefix;
|
|
10
|
+
enableCache;
|
|
11
|
+
cache;
|
|
12
|
+
constructor(config = {}) {
|
|
13
|
+
this.prefix = config.prefix || '';
|
|
14
|
+
this.enableCache = config.enableCache ?? false;
|
|
15
|
+
this.cache = new Map();
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Resolve a single secret by name
|
|
19
|
+
*/
|
|
20
|
+
async resolve(secretName) {
|
|
21
|
+
// Parse GitHub Actions secret reference format: ${{ secrets.NAME }}
|
|
22
|
+
const match = secretName.match(/\$\{\{\s*secrets\.([A-Z_]+)\s*\}\}/);
|
|
23
|
+
const actualName = match ? match[1] : secretName;
|
|
24
|
+
const envKey = this.prefix + actualName;
|
|
25
|
+
// Check cache first
|
|
26
|
+
if (this.enableCache && this.cache.has(envKey)) {
|
|
27
|
+
return this.cache.get(envKey);
|
|
28
|
+
}
|
|
29
|
+
// Resolve from environment
|
|
30
|
+
const value = process.env[envKey];
|
|
31
|
+
if (value === undefined) {
|
|
32
|
+
throw new Error(`Secret ${actualName} not found`);
|
|
33
|
+
}
|
|
34
|
+
// Cache if enabled
|
|
35
|
+
if (this.enableCache) {
|
|
36
|
+
this.cache.set(envKey, value);
|
|
37
|
+
}
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Resolve multiple secrets at once
|
|
42
|
+
*/
|
|
43
|
+
async resolveMultiple(secretNames, options) {
|
|
44
|
+
const result = {};
|
|
45
|
+
const errors = [];
|
|
46
|
+
for (const name of secretNames) {
|
|
47
|
+
try {
|
|
48
|
+
result[name] = await this.resolve(name);
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
if (options?.allowPartial) {
|
|
52
|
+
// Skip missing secrets when allowPartial is true
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
errors.push(error.message);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (errors.length > 0 && !options?.allowPartial) {
|
|
59
|
+
throw new Error(errors[0]); // Throw first error
|
|
60
|
+
}
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Resolve per-dependency authentication configuration
|
|
65
|
+
*/
|
|
66
|
+
async resolveDependencyAuth(config) {
|
|
67
|
+
const result = {};
|
|
68
|
+
for (const [domain, authConfig] of Object.entries(config)) {
|
|
69
|
+
const secretValue = await this.resolve(authConfig.secretName);
|
|
70
|
+
result[domain] = secretValue;
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Validate secret name format
|
|
76
|
+
*/
|
|
77
|
+
validate(secretName) {
|
|
78
|
+
// Handle GitHub Actions secret reference
|
|
79
|
+
if (secretName.startsWith('${{')) {
|
|
80
|
+
const match = secretName.match(/\$\{\{\s*secrets\.([A-Z_][A-Z0-9_]*)\s*\}\}/);
|
|
81
|
+
return match !== null;
|
|
82
|
+
}
|
|
83
|
+
// Standard environment variable naming convention
|
|
84
|
+
// Must start with letter or underscore, contain only alphanumeric and underscores
|
|
85
|
+
return /^[A-Z_][A-Z0-9_]*$/.test(secretName);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Clear the secret cache
|
|
89
|
+
*/
|
|
90
|
+
clearCache() {
|
|
91
|
+
this.cache.clear();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=secrets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/utils/secrets.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dependabit/action",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "GitHub Action entry points for dependency tracking",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@actions/core": "^3.0.0",
|
|
16
|
+
"@actions/github": "^9.0.0",
|
|
17
|
+
"zod": "^4.3.6",
|
|
18
|
+
"@dependabit/detector": "0.1.1",
|
|
19
|
+
"@dependabit/github-client": "0.1.1",
|
|
20
|
+
"@dependabit/manifest": "0.1.1",
|
|
21
|
+
"@dependabit/monitor": "0.1.1"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/node": "^25.2.2",
|
|
25
|
+
"@vercel/ncc": "^0.38.4",
|
|
26
|
+
"tsx": "^4.21.0",
|
|
27
|
+
"typescript": "^5.9.3",
|
|
28
|
+
"vitest": "^4.0.18"
|
|
29
|
+
},
|
|
30
|
+
"keywords": [
|
|
31
|
+
"github-action",
|
|
32
|
+
"dependency",
|
|
33
|
+
"tracking"
|
|
34
|
+
],
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsgo -p tsconfig.json",
|
|
38
|
+
"build:action": "tsgo -p tsconfig.json && ncc build dist/index.js -o action-dist --source-map --license licenses.txt",
|
|
39
|
+
"clean": "rm -rf dist action-dist",
|
|
40
|
+
"dev": "tsx watch src/index.ts",
|
|
41
|
+
"type-check": "tsgo --noEmit -p tsconfig.json",
|
|
42
|
+
"test": "vitest run",
|
|
43
|
+
"test:watch": "vitest"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check Action
|
|
3
|
+
* Monitors dependencies for changes and creates issues when updates are detected
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Monitor } from '@dependabit/monitor';
|
|
7
|
+
import type { DependencyConfig } from '@dependabit/monitor';
|
|
8
|
+
import { IssueManager, RateLimitHandler } from '@dependabit/github-client';
|
|
9
|
+
import { SummaryReporter } from '../utils/reporter.js';
|
|
10
|
+
import type { DependencyChange } from '../utils/reporter.js';
|
|
11
|
+
|
|
12
|
+
export interface Manifest {
|
|
13
|
+
version: string;
|
|
14
|
+
dependencies: Array<
|
|
15
|
+
DependencyConfig & {
|
|
16
|
+
name?: string;
|
|
17
|
+
type?: string;
|
|
18
|
+
lastChanged?: string;
|
|
19
|
+
}
|
|
20
|
+
>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface CheckActionResult {
|
|
24
|
+
checked: number;
|
|
25
|
+
skipped: number;
|
|
26
|
+
changes: DependencyChange[];
|
|
27
|
+
issuesCreated: number;
|
|
28
|
+
errors: number;
|
|
29
|
+
rateLimitWarnings?: string[];
|
|
30
|
+
updatedManifest: Manifest;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Main check action - monitors dependencies and creates issues
|
|
35
|
+
*/
|
|
36
|
+
export async function checkAction(
|
|
37
|
+
manifest: Manifest,
|
|
38
|
+
options?: {
|
|
39
|
+
owner?: string;
|
|
40
|
+
repo?: string;
|
|
41
|
+
createIssues?: boolean;
|
|
42
|
+
dryRun?: boolean;
|
|
43
|
+
}
|
|
44
|
+
): Promise<CheckActionResult> {
|
|
45
|
+
const {
|
|
46
|
+
owner = process.env['GITHUB_REPOSITORY_OWNER'] || '',
|
|
47
|
+
repo = process.env['GITHUB_REPOSITORY']?.split('/')[1] || '',
|
|
48
|
+
createIssues = true,
|
|
49
|
+
dryRun = false
|
|
50
|
+
} = options || {};
|
|
51
|
+
|
|
52
|
+
const monitor = new Monitor();
|
|
53
|
+
const issueManager = new IssueManager();
|
|
54
|
+
const rateLimitHandler = new RateLimitHandler();
|
|
55
|
+
const reporter = new SummaryReporter();
|
|
56
|
+
|
|
57
|
+
const result: CheckActionResult = {
|
|
58
|
+
checked: 0,
|
|
59
|
+
skipped: 0,
|
|
60
|
+
changes: [],
|
|
61
|
+
issuesCreated: 0,
|
|
62
|
+
errors: 0,
|
|
63
|
+
rateLimitWarnings: [],
|
|
64
|
+
updatedManifest: {
|
|
65
|
+
...manifest,
|
|
66
|
+
dependencies: manifest.dependencies.map((dep) => ({ ...dep }))
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
// Check rate limit before starting
|
|
71
|
+
const rateLimit = await rateLimitHandler.checkRateLimit();
|
|
72
|
+
if (rateLimit.warning) {
|
|
73
|
+
result.rateLimitWarnings?.push(rateLimit.warning);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Filter enabled dependencies
|
|
77
|
+
const enabledDeps = manifest.dependencies.filter((dep) => {
|
|
78
|
+
if (dep.monitoring?.enabled === false) {
|
|
79
|
+
result.skipped++;
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
if (dep.monitoring?.ignoreChanges === true) {
|
|
83
|
+
result.skipped++;
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
return true;
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
console.log(`Checking ${enabledDeps.length} dependencies (${result.skipped} skipped)...`);
|
|
90
|
+
|
|
91
|
+
// Reserve budget for all checks upfront
|
|
92
|
+
const budgetNeeded = enabledDeps.length + 10; // Extra buffer for issue operations
|
|
93
|
+
const budgetReservation = await rateLimitHandler.reserveBudget(budgetNeeded);
|
|
94
|
+
|
|
95
|
+
if (!budgetReservation.reserved) {
|
|
96
|
+
console.warn(`Insufficient API quota: ${budgetReservation.reason}`);
|
|
97
|
+
if (budgetReservation.waitTime) {
|
|
98
|
+
console.log(
|
|
99
|
+
`Waiting ${Math.ceil(budgetReservation.waitTime / 1000)} seconds for rate limit reset...`
|
|
100
|
+
);
|
|
101
|
+
await rateLimitHandler.waitIfNeeded();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Check all dependencies
|
|
106
|
+
const checkResults = await monitor.checkAll(enabledDeps);
|
|
107
|
+
|
|
108
|
+
// Process results
|
|
109
|
+
for (const checkResult of checkResults) {
|
|
110
|
+
if (!checkResult) continue;
|
|
111
|
+
|
|
112
|
+
const depIndex = manifest.dependencies.findIndex((d) => d.id === checkResult.dependency.id);
|
|
113
|
+
|
|
114
|
+
if (checkResult.error) {
|
|
115
|
+
console.error(`Error checking ${checkResult.dependency.id}: ${checkResult.error}`);
|
|
116
|
+
result.errors++;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
result.checked++;
|
|
121
|
+
|
|
122
|
+
// Update manifest with new state
|
|
123
|
+
if (checkResult.newSnapshot && depIndex >= 0) {
|
|
124
|
+
const dep = result.updatedManifest.dependencies[depIndex];
|
|
125
|
+
if (dep) {
|
|
126
|
+
dep.currentStateHash = checkResult.newSnapshot.stateHash;
|
|
127
|
+
dep.lastChecked = checkResult.newSnapshot.fetchedAt.toISOString();
|
|
128
|
+
|
|
129
|
+
if (checkResult.newSnapshot.version) {
|
|
130
|
+
dep.currentVersion = checkResult.newSnapshot.version;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Handle detected changes
|
|
136
|
+
if (checkResult.hasChanged && checkResult.changes && checkResult.severity) {
|
|
137
|
+
const change: DependencyChange = {
|
|
138
|
+
dependency: {
|
|
139
|
+
id: checkResult.dependency.id,
|
|
140
|
+
...(checkResult.dependency.name && { name: checkResult.dependency.name }),
|
|
141
|
+
url: checkResult.dependency.url,
|
|
142
|
+
...(checkResult.dependency.type && { type: checkResult.dependency.type })
|
|
143
|
+
},
|
|
144
|
+
severity: checkResult.severity,
|
|
145
|
+
changes: checkResult.changes.changes,
|
|
146
|
+
oldVersion: checkResult.changes.oldVersion,
|
|
147
|
+
newVersion: checkResult.changes.newVersion
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
result.changes.push(change);
|
|
151
|
+
|
|
152
|
+
// Update lastChanged timestamp
|
|
153
|
+
if (depIndex >= 0) {
|
|
154
|
+
const dep = result.updatedManifest.dependencies[depIndex];
|
|
155
|
+
if (dep) {
|
|
156
|
+
dep.lastChanged = new Date().toISOString();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Create issue if enabled
|
|
161
|
+
if (createIssues && !dryRun && owner && repo) {
|
|
162
|
+
try {
|
|
163
|
+
// Check rate limit before creating issue
|
|
164
|
+
await rateLimitHandler.waitIfNeeded();
|
|
165
|
+
|
|
166
|
+
// Check if issue already exists
|
|
167
|
+
const existing = await issueManager.findExistingIssue({
|
|
168
|
+
owner,
|
|
169
|
+
repo,
|
|
170
|
+
dependencyId: checkResult.dependency.id
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
if (existing) {
|
|
174
|
+
// Update existing issue
|
|
175
|
+
const updateBody = reporter.generateIssueBody(change);
|
|
176
|
+
await issueManager.updateIssue({
|
|
177
|
+
owner,
|
|
178
|
+
repo,
|
|
179
|
+
issueNumber: existing.number,
|
|
180
|
+
body: updateBody,
|
|
181
|
+
severity: checkResult.severity,
|
|
182
|
+
append: true
|
|
183
|
+
});
|
|
184
|
+
console.log(
|
|
185
|
+
`Updated existing issue #${existing.number} for ${checkResult.dependency.id}`
|
|
186
|
+
);
|
|
187
|
+
} else {
|
|
188
|
+
// Create new issue
|
|
189
|
+
const issueBody = reporter.generateIssueBody(change);
|
|
190
|
+
const issue = await issueManager.createIssue({
|
|
191
|
+
owner,
|
|
192
|
+
repo,
|
|
193
|
+
title: `Dependency Update: ${change.dependency.name || change.dependency.id}`,
|
|
194
|
+
body: issueBody,
|
|
195
|
+
severity: checkResult.severity,
|
|
196
|
+
dependency: {
|
|
197
|
+
id: checkResult.dependency.id,
|
|
198
|
+
url: checkResult.dependency.url
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
result.issuesCreated++;
|
|
202
|
+
console.log(`Created issue #${issue.number} for ${checkResult.dependency.id}`);
|
|
203
|
+
}
|
|
204
|
+
} catch (error) {
|
|
205
|
+
console.error(`Failed to create/update issue for ${checkResult.dependency.id}:`, error);
|
|
206
|
+
result.errors++;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// Generate and log summary
|
|
213
|
+
const summary = reporter.generateSummary(result.changes);
|
|
214
|
+
console.log('\n' + summary);
|
|
215
|
+
|
|
216
|
+
// Check rate limit after processing
|
|
217
|
+
const finalRateLimit = await rateLimitHandler.checkRateLimit();
|
|
218
|
+
if (finalRateLimit.warning && !result.rateLimitWarnings?.includes(finalRateLimit.warning)) {
|
|
219
|
+
result.rateLimitWarnings?.push(finalRateLimit.warning);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return result;
|
|
223
|
+
}
|