apify-test-tools 0.8.6 → 0.9.0-beta.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/README.md +83 -13
- package/bin/build-from-local.ts +35 -34
- package/bin/build.ts +55 -59
- package/bin/diff-changes.ts +166 -125
- package/bin/dockerignore.ts +50 -0
- package/bin/main.ts +7 -7
- package/bin/path-utils.ts +13 -0
- package/bin/test-report.ts +5 -5
- package/bin/types.ts +17 -5
- package/bin/utils.ts +122 -95
- package/dist/bin/build-from-local.d.ts +2 -2
- package/dist/bin/build-from-local.d.ts.map +1 -1
- package/dist/bin/build-from-local.js +33 -28
- package/dist/bin/build-from-local.js.map +1 -1
- package/dist/bin/build.d.ts +5 -8
- package/dist/bin/build.d.ts.map +1 -1
- package/dist/bin/build.js +49 -56
- package/dist/bin/build.js.map +1 -1
- package/dist/bin/diff-changes.d.ts +0 -6
- package/dist/bin/diff-changes.d.ts.map +1 -1
- package/dist/bin/diff-changes.js +129 -89
- package/dist/bin/diff-changes.js.map +1 -1
- package/dist/bin/dockerignore.d.ts +17 -0
- package/dist/bin/dockerignore.d.ts.map +1 -0
- package/dist/bin/dockerignore.js +41 -0
- package/dist/bin/dockerignore.js.map +1 -0
- package/dist/bin/main.js +7 -7
- package/dist/bin/main.js.map +1 -1
- package/dist/bin/path-utils.d.ts +4 -0
- package/dist/bin/path-utils.d.ts.map +1 -0
- package/dist/bin/path-utils.js +9 -0
- package/dist/bin/path-utils.js.map +1 -0
- package/dist/bin/test-report.js +3 -3
- package/dist/bin/test-report.js.map +1 -1
- package/dist/bin/types.d.ts +15 -4
- package/dist/bin/types.d.ts.map +1 -1
- package/dist/bin/utils.d.ts +2 -19
- package/dist/bin/utils.d.ts.map +1 -1
- package/dist/bin/utils.js +82 -81
- package/dist/bin/utils.js.map +1 -1
- package/dist/lib/lib.d.ts +10 -4
- package/dist/lib/lib.d.ts.map +1 -1
- package/dist/lib/lib.js +28 -22
- package/dist/lib/lib.js.map +1 -1
- package/dist/lib/types.d.ts +2 -2
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/utils.d.ts +1 -1
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +4 -4
- package/dist/lib/utils.js.map +1 -1
- package/dist/test/unit/bin/build-from-local.test.js +55 -86
- package/dist/test/unit/bin/build-from-local.test.js.map +1 -1
- package/dist/test/unit/bin/diff-changes.test.js +358 -36
- package/dist/test/unit/bin/diff-changes.test.js.map +1 -1
- package/dist/test/unit/bin/dockerignore.test.d.ts +2 -0
- package/dist/test/unit/bin/dockerignore.test.d.ts.map +1 -0
- package/dist/test/unit/bin/dockerignore.test.js +102 -0
- package/dist/test/unit/bin/dockerignore.test.js.map +1 -0
- package/dist/test/unit/bin/path-utils.test.d.ts +2 -0
- package/dist/test/unit/bin/path-utils.test.d.ts.map +1 -0
- package/dist/test/unit/bin/path-utils.test.js +14 -0
- package/dist/test/unit/bin/path-utils.test.js.map +1 -0
- package/dist/test/unit/bin/utils.test.d.ts +2 -0
- package/dist/test/unit/bin/utils.test.d.ts.map +1 -0
- package/dist/test/unit/bin/utils.test.js +293 -0
- package/dist/test/unit/bin/utils.test.js.map +1 -0
- package/dist/test/unit/should-built-and-test.test.js +83 -32
- package/dist/test/unit/should-built-and-test.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/lib/lib.ts +28 -22
- package/lib/types.ts +2 -2
- package/lib/utils.ts +4 -4
- package/package.json +62 -61
- package/test/unit/bin/build-from-local.test.ts +62 -121
- package/test/unit/bin/diff-changes.test.ts +397 -41
- package/test/unit/bin/dockerignore.test.ts +123 -0
- package/test/unit/bin/path-utils.test.ts +17 -0
- package/test/unit/bin/utils.test.ts +343 -0
- package/test/unit/should-built-and-test.test.ts +89 -32
package/dist/bin/build.js
CHANGED
|
@@ -2,40 +2,40 @@ import { ApifyClient } from 'apify-client';
|
|
|
2
2
|
import { ACTOR_SOURCE_TYPES } from '@apify/consts';
|
|
3
3
|
export class ApifyBuilder {
|
|
4
4
|
apifyClient;
|
|
5
|
-
|
|
6
|
-
constructor(apifyClient,
|
|
5
|
+
actorFullName;
|
|
6
|
+
constructor(apifyClient, actorFullName) {
|
|
7
7
|
this.apifyClient = apifyClient;
|
|
8
|
-
this.
|
|
8
|
+
this.actorFullName = actorFullName;
|
|
9
9
|
}
|
|
10
10
|
// Usually 'latest' but not necessarily (can be e.g. 'version-0')
|
|
11
11
|
getDefaultVersionAndTag = async () => {
|
|
12
|
-
const actorClient = this.apifyClient.actor(this.
|
|
12
|
+
const actorClient = this.apifyClient.actor(this.actorFullName);
|
|
13
13
|
const actorInfo = await actorClient.get();
|
|
14
14
|
if (!actorInfo) {
|
|
15
|
-
throw new Error(`[${this.
|
|
15
|
+
throw new Error(`[${this.actorFullName}] not found. It is not published or we are missing token to access it privately or its name is misspelled`);
|
|
16
16
|
}
|
|
17
17
|
const defaultBuildTag = actorInfo.defaultRunOptions.build;
|
|
18
|
-
console.error(`Default build tag for ${this.
|
|
18
|
+
console.error(`Default build tag for ${this.actorFullName} is ${defaultBuildTag}`);
|
|
19
19
|
// We could technically allow this but in most cases this is accidentally set wrongly and there is a workaround
|
|
20
20
|
if (defaultBuildTag.match(/\d+\.\d+\.\d+/)) {
|
|
21
|
-
throw new Error(`[${this.
|
|
21
|
+
throw new Error(`[${this.actorFullName}] Default build is a build number, not a tag. While this could work, ` +
|
|
22
22
|
`we want to have a default as tag so this is often an accidental misconfiguration from the dev`);
|
|
23
23
|
}
|
|
24
24
|
// I reported that buildNumber should probably not be optional
|
|
25
25
|
if (!actorInfo.taggedBuilds?.[defaultBuildTag]?.buildNumber) {
|
|
26
|
-
throw new Error(`[${this.
|
|
26
|
+
throw new Error(`[${this.actorFullName}] No build found for tag "${defaultBuildTag}". ` +
|
|
27
27
|
`The first build must be triggered manually on the platform before CI can take over.`);
|
|
28
28
|
}
|
|
29
29
|
const defaultBuildNumber = actorInfo.taggedBuilds[defaultBuildTag].buildNumber;
|
|
30
30
|
const defaultVersionNumber = defaultBuildNumber.match(/(\d+\.\d+)\.\d+/)[1];
|
|
31
|
-
console.error(`Default version for ${this.
|
|
31
|
+
console.error(`Default version for ${this.actorFullName} is ${defaultVersionNumber}`);
|
|
32
32
|
return { defaultBuildNumber, defaultVersionNumber, defaultBuildTag };
|
|
33
33
|
};
|
|
34
34
|
startActorBuild = async ({ buildTag, versionNumber, gitRepoUrl, useDockerCache, }) => {
|
|
35
|
-
const actorClient = this.apifyClient.actor(this.
|
|
35
|
+
const actorClient = this.apifyClient.actor(this.actorFullName);
|
|
36
36
|
const actorInfo = await actorClient.get();
|
|
37
37
|
if (!actorInfo) {
|
|
38
|
-
throw new Error(`No actor named '${this.
|
|
38
|
+
throw new Error(`No actor named '${this.actorFullName}' was found on the platform. If this` +
|
|
39
39
|
' is unexpected, make sure the actor you are targeting is spelled the' +
|
|
40
40
|
' same as the folder in the repository.');
|
|
41
41
|
}
|
|
@@ -59,15 +59,15 @@ export class ApifyBuilder {
|
|
|
59
59
|
}
|
|
60
60
|
// We also get back actId so the testing actor can both match by actor ID and name
|
|
61
61
|
const { id, actId, buildNumber } = await actorClient.build(versionNumber, { useCache: useDockerCache });
|
|
62
|
-
console.error(`[${this.
|
|
63
|
-
return { buildId: id,
|
|
62
|
+
console.error(`[${this.actorFullName}]: ${id} (${buildNumber})`);
|
|
63
|
+
return { buildId: id, actorRawId: actId, buildNumber, actorFullName: this.actorFullName };
|
|
64
64
|
};
|
|
65
65
|
startActorBuildFromSourceFiles = async (sourceFiles) => {
|
|
66
66
|
const ZIP_VERSION = '0.98';
|
|
67
|
-
const actorClient = this.apifyClient.actor(this.
|
|
67
|
+
const actorClient = this.apifyClient.actor(this.actorFullName);
|
|
68
68
|
const actorInfo = await actorClient.get();
|
|
69
69
|
if (!actorInfo) {
|
|
70
|
-
throw new Error(`No actor named '${this.
|
|
70
|
+
throw new Error(`No actor named '${this.actorFullName}' was found on the platform. If this` +
|
|
71
71
|
' is unexpected, make sure the actor you are targeting is spelled the' +
|
|
72
72
|
' same as the folder in the repository.');
|
|
73
73
|
}
|
|
@@ -86,44 +86,36 @@ export class ApifyBuilder {
|
|
|
86
86
|
await actorClient.version(ZIP_VERSION).update(actorVersion);
|
|
87
87
|
}
|
|
88
88
|
const { id, actId, buildNumber } = await actorClient.build(ZIP_VERSION, { useCache: false });
|
|
89
|
-
console.error(`[${this.
|
|
90
|
-
return { buildId: id,
|
|
89
|
+
console.error(`[${this.actorFullName}]: ${id} (${buildNumber})`);
|
|
90
|
+
return { buildId: id, actorRawId: actId, buildNumber, actorFullName: this.actorFullName };
|
|
91
91
|
};
|
|
92
|
-
waitForBuildToFinish = async (buildId
|
|
92
|
+
waitForBuildToFinish = async (buildId) => {
|
|
93
93
|
const build = await this.apifyClient.build(buildId).waitForFinish();
|
|
94
94
|
const versionNumber = build.buildNumber;
|
|
95
95
|
if (build.status === 'FAILED' || build.status === 'TIMED-OUT') {
|
|
96
|
-
console.error(`[${this.
|
|
96
|
+
console.error(`[${this.actorFullName}]: ${versionNumber}`);
|
|
97
97
|
try {
|
|
98
98
|
const log = await this.apifyClient.build(buildId).log().get();
|
|
99
99
|
const logTail = log?.split('\n').slice(-40).join('\n');
|
|
100
100
|
console.error(`\n--- BUILD LOG (last 40 lines) ---\n${logTail}\n---`);
|
|
101
101
|
}
|
|
102
102
|
catch (err) {
|
|
103
|
-
console.error(`[${this.
|
|
103
|
+
console.error(`[${this.actorFullName}]: Failed to fetch build log: ${err}`);
|
|
104
104
|
}
|
|
105
|
-
throw new Error(`[BUILD][${
|
|
105
|
+
throw new Error(`[BUILD][${this.actorFullName}]: Build ${buildId} (${versionNumber}) failed. ` +
|
|
106
106
|
`Not continuing with other builds and tests.`);
|
|
107
107
|
}
|
|
108
|
-
console.error(`[${this.
|
|
108
|
+
console.error(`[${this.actorFullName}]: ${versionNumber}`);
|
|
109
109
|
return build;
|
|
110
110
|
};
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
static fromActorName = (actorName) => {
|
|
115
|
-
const username = actorName.split('/')[0];
|
|
116
|
-
// GitHib secrets only allow word characters (alphanum + underscore)
|
|
117
|
-
const usernameInGitHubSecretsFormat = username.replaceAll(/\W/g, '_').toUpperCase();
|
|
118
|
-
const usernameEnvVar = `APIFY_TOKEN_${usernameInGitHubSecretsFormat}`;
|
|
119
|
-
const token = process.env[usernameEnvVar];
|
|
111
|
+
static fromActorConfig = (actorConfig) => {
|
|
112
|
+
const { actorFullName, tokenEnvVar } = actorConfig;
|
|
113
|
+
const token = process.env[tokenEnvVar];
|
|
120
114
|
if (!token) {
|
|
121
|
-
throw new Error(`
|
|
122
|
-
`Have you set secret env var to this GitHub repo with key: ${usernameEnvVar}?`);
|
|
115
|
+
throw new Error(`Env var ${tokenEnvVar} is not set (needed for actor "${actorFullName}").`);
|
|
123
116
|
}
|
|
124
117
|
const apifyClient = new ApifyClient({ token });
|
|
125
|
-
|
|
126
|
-
return builder;
|
|
118
|
+
return new ApifyBuilder(apifyClient, actorFullName);
|
|
127
119
|
};
|
|
128
120
|
/**
|
|
129
121
|
* Deletes build of all versions. Apify API doesn't allow to delete default build and we explicitly skip it
|
|
@@ -152,7 +144,7 @@ export class ApifyBuilder {
|
|
|
152
144
|
// but also not too long because it increases the risk of users using outdated versions
|
|
153
145
|
const DEFAULT_DAYS_BACK_PROD_VERSIONS = 30;
|
|
154
146
|
const DEFAULT_DAYS_BACK_DEVEL = 7;
|
|
155
|
-
const actorInfo = (await this.apifyClient.actor(this.
|
|
147
|
+
const actorInfo = (await this.apifyClient.actor(this.actorFullName).get());
|
|
156
148
|
// 'devel' used to be hardcoded for testing version 0.99, once we get rid of this tag everywhere, we can remove this code
|
|
157
149
|
const taggedDevelBuildNumber = actorInfo.taggedBuilds.devel?.buildNumber;
|
|
158
150
|
const allTags = Object.keys(actorInfo.taggedBuilds ?? {});
|
|
@@ -161,60 +153,60 @@ export class ApifyBuilder {
|
|
|
161
153
|
buildNumber: actorInfo.taggedBuilds[tag].buildNumber,
|
|
162
154
|
tag,
|
|
163
155
|
}));
|
|
164
|
-
const { items } = await this.apifyClient.actor(this.
|
|
156
|
+
const { items } = await this.apifyClient.actor(this.actorFullName).builds().list();
|
|
165
157
|
// Deleting default build throws an error, so we skip it
|
|
166
|
-
const { defaultBuildNumber, defaultBuildTag } = await
|
|
158
|
+
const { defaultBuildNumber, defaultBuildTag } = await this.getDefaultVersionAndTag();
|
|
167
159
|
const daysAgoUnixProd = Date.now() - DEFAULT_DAYS_BACK_PROD_VERSIONS * 24 * 60 * 60 * 1000;
|
|
168
160
|
const daysAgoUnixDevel = Date.now() - DEFAULT_DAYS_BACK_DEVEL * 24 * 60 * 60 * 1000;
|
|
169
161
|
const buildsToDelete = items.filter((build) => {
|
|
170
162
|
if (build.buildNumber === defaultBuildNumber) {
|
|
171
|
-
console.error(`[DELETE OLD BUILDS][${this.
|
|
163
|
+
console.error(`[DELETE OLD BUILDS][${this.actorFullName}]: Skipping default build ${defaultBuildNumber} (${defaultBuildTag}). ` +
|
|
172
164
|
`We never delete default builds`);
|
|
173
165
|
return false;
|
|
174
166
|
}
|
|
175
167
|
const protectedTagFound = protectedBuildNumbers.find((protectedBuildNumber) => protectedBuildNumber.buildNumber === build.buildNumber);
|
|
176
168
|
if (protectedTagFound) {
|
|
177
|
-
console.error(`[DELETE OLD BUILDS][${this.
|
|
169
|
+
console.error(`[DELETE OLD BUILDS][${this.actorFullName}]: Skipping protected build ${protectedTagFound.buildNumber} (${protectedTagFound.tag}).`);
|
|
178
170
|
return false;
|
|
179
171
|
}
|
|
180
172
|
if (taggedDevelBuildNumber && build.buildNumber === taggedDevelBuildNumber) {
|
|
181
173
|
const shouldDeleteDevelBuild = build.startedAt.getTime() < daysAgoUnixDevel;
|
|
182
174
|
if (shouldDeleteDevelBuild) {
|
|
183
|
-
console.error(`[DELETE OLD BUILDS][${this.
|
|
175
|
+
console.error(`[DELETE OLD BUILDS][${this.actorFullName}]: Removing olf devel build ${taggedDevelBuildNumber}.`);
|
|
184
176
|
}
|
|
185
177
|
return shouldDeleteDevelBuild;
|
|
186
178
|
}
|
|
187
179
|
return build.startedAt.getTime() < daysAgoUnixProd;
|
|
188
180
|
});
|
|
189
|
-
console.error(`[DELETE OLD BUILDS][${this.
|
|
181
|
+
console.error(`[DELETE OLD BUILDS][${this.actorFullName}]: Deleting ${buildsToDelete.length} old builds that are non-default and ` +
|
|
190
182
|
`older than 30 days from total ${items.length}`);
|
|
191
183
|
for (const build of buildsToDelete) {
|
|
192
184
|
await this.apifyClient.build(build.id).delete();
|
|
193
185
|
}
|
|
194
186
|
}
|
|
195
187
|
}
|
|
196
|
-
export const waitAndSummarizeBuilds = async (startedBuilds, label) => {
|
|
188
|
+
export const waitAndSummarizeBuilds = async (startedBuilds, buildersMap, label) => {
|
|
197
189
|
console.error('=========================================');
|
|
198
190
|
console.error(`FINISHED ${label}:`);
|
|
199
191
|
await Promise.all(startedBuilds.map(async (buildData) => {
|
|
200
|
-
const builder =
|
|
201
|
-
await builder.waitForBuildToFinish(buildData.buildId
|
|
192
|
+
const builder = buildersMap.get(buildData.actorFullName);
|
|
193
|
+
await builder.waitForBuildToFinish(buildData.buildId);
|
|
202
194
|
}));
|
|
203
195
|
console.error('=========================================');
|
|
204
196
|
console.error('SUMMARY:');
|
|
205
|
-
for (const buildData of startedBuilds.sort((a, b) => a.
|
|
206
|
-
console.error(`[${buildData.
|
|
197
|
+
for (const buildData of startedBuilds.sort((a, b) => a.actorFullName.localeCompare(b.actorFullName))) {
|
|
198
|
+
console.error(`[${buildData.actorFullName}]: ${buildData.buildNumber}`);
|
|
207
199
|
}
|
|
208
200
|
console.error('=========================================');
|
|
209
201
|
return startedBuilds;
|
|
210
202
|
};
|
|
211
203
|
export const runBuilds = async ({ repoUrl, branch, actorConfigs, isLatest = false, dryRun, useDockerCache, }) => {
|
|
212
204
|
const buildConfigs = [];
|
|
213
|
-
for (const
|
|
205
|
+
for (const actorConfig of actorConfigs) {
|
|
214
206
|
let versionNumber;
|
|
215
207
|
let buildTag;
|
|
216
208
|
if (isLatest) {
|
|
217
|
-
const { defaultVersionNumber, defaultBuildTag } = await ApifyBuilder.
|
|
209
|
+
const { defaultVersionNumber, defaultBuildTag } = await ApifyBuilder.fromActorConfig(actorConfig).getDefaultVersionAndTag();
|
|
218
210
|
versionNumber = defaultVersionNumber;
|
|
219
211
|
buildTag = defaultBuildTag;
|
|
220
212
|
}
|
|
@@ -223,26 +215,27 @@ export const runBuilds = async ({ repoUrl, branch, actorConfigs, isLatest = fals
|
|
|
223
215
|
}
|
|
224
216
|
// Depending on if these are miniactors or standaloneActors
|
|
225
217
|
let gitRepoUrl = `${repoUrl}#${branch}`;
|
|
226
|
-
if (folder) {
|
|
227
|
-
gitRepoUrl = `${gitRepoUrl}:${folder}`;
|
|
218
|
+
if (actorConfig.folder) {
|
|
219
|
+
gitRepoUrl = `${gitRepoUrl}:${actorConfig.folder}`;
|
|
228
220
|
}
|
|
229
|
-
buildConfigs.push({
|
|
221
|
+
buildConfigs.push({ actorConfig, gitRepoUrl, versionNumber, buildTag, useDockerCache });
|
|
230
222
|
}
|
|
231
223
|
if (dryRun) {
|
|
232
224
|
return buildConfigs;
|
|
233
225
|
}
|
|
226
|
+
const buildersByActorFullName = new Map(actorConfigs.map((actorConfig) => [actorConfig.actorFullName, ApifyBuilder.fromActorConfig(actorConfig)]));
|
|
234
227
|
console.error('=========================================');
|
|
235
228
|
console.error('STARTED BUILDS:');
|
|
236
229
|
const startedBuilds = await Promise.all(buildConfigs.map(async (buildConfig) => {
|
|
237
|
-
const builder =
|
|
230
|
+
const builder = buildersByActorFullName.get(buildConfig.actorConfig.actorFullName);
|
|
238
231
|
const buildData = await builder.startActorBuild(buildConfig);
|
|
239
232
|
return buildData;
|
|
240
233
|
}));
|
|
241
|
-
return waitAndSummarizeBuilds(startedBuilds, 'BUILDS');
|
|
234
|
+
return waitAndSummarizeBuilds(startedBuilds, buildersByActorFullName, 'BUILDS');
|
|
242
235
|
};
|
|
243
236
|
export const deleteOldBuilds = async (actorConfigs) => {
|
|
244
|
-
for (const
|
|
245
|
-
await ApifyBuilder.
|
|
237
|
+
for (const actorConfig of actorConfigs) {
|
|
238
|
+
await ApifyBuilder.fromActorConfig(actorConfig).deleteOldBuilds();
|
|
246
239
|
}
|
|
247
240
|
};
|
|
248
241
|
//# sourceMappingURL=build.js.map
|
package/dist/bin/build.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../bin/build.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAWnD,MAAM,OAAO,YAAY;IAEA;IACA;IAFrB,YACqB,WAAwB,EACxB,
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../bin/build.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,12 +5,6 @@ interface ShouldBuildAndTestOptions {
|
|
|
5
5
|
isLatest?: boolean;
|
|
6
6
|
commits: Commit[];
|
|
7
7
|
}
|
|
8
|
-
export declare const maybeParseActorFolder: (lowercaseFilePath: string) => {
|
|
9
|
-
isActorFolder: true;
|
|
10
|
-
actorName: string;
|
|
11
|
-
} | {
|
|
12
|
-
isActorFolder: false;
|
|
13
|
-
};
|
|
14
8
|
export declare const getChangedActors: ({ filepathsChanged, actorConfigs, isLatest, commits, }: ShouldBuildAndTestOptions) => ActorConfig[];
|
|
15
9
|
export {};
|
|
16
10
|
//# sourceMappingURL=diff-changes.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff-changes.d.ts","sourceRoot":"","sources":["../../bin/diff-changes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"diff-changes.d.ts","sourceRoot":"","sources":["../../bin/diff-changes.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEtD,UAAU,yBAAyB;IAC/B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;CACrB;AA8JD,eAAO,MAAM,gBAAgB,GAAI,wDAK9B,yBAAyB,KAAG,WAAW,EAwCzC,CAAC"}
|
package/dist/bin/diff-changes.js
CHANGED
|
@@ -1,111 +1,151 @@
|
|
|
1
1
|
import { isCosmeticOnlyJsonSchemaChange } from './diff-json-schema.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
import { loadDockerIgnore } from './dockerignore.js';
|
|
3
|
+
import { findContainingScope, hoistPath, isPathWithinScope } from './path-utils.js';
|
|
4
|
+
const IGNORED_TOP_LEVEL_FILES = [
|
|
5
|
+
'.vscode/',
|
|
6
|
+
'.gitignore',
|
|
7
|
+
'.husky/',
|
|
8
|
+
'.eslintrc',
|
|
9
|
+
'eslint.config.mjs',
|
|
10
|
+
'.prettierrc',
|
|
11
|
+
'.editorconfig',
|
|
12
|
+
];
|
|
13
|
+
// Expects an already-hoisted path (relative to the matched context entry, see findContainingScope).
|
|
14
|
+
const isIgnoredTopLevelFile = (hoistedLowercaseFilePath) => IGNORED_TOP_LEVEL_FILES.some((pattern) => hoistedLowercaseFilePath.startsWith(pattern));
|
|
15
|
+
/**
|
|
16
|
+
* Classify a single file change for a single actor.
|
|
17
|
+
*
|
|
18
|
+
* Steps (in order):
|
|
19
|
+
* 1. CHANGELOG.md, by filename, anywhere → cosmetic. There is a single repo-wide shared changelog,
|
|
20
|
+
* not one per actor, so it applies to every actor regardless of context/folder.
|
|
21
|
+
* 2. Context matching (actorConfig.contextPaths) → outside-context if no match
|
|
22
|
+
* 3. Hardcoded ignore list, checked against the path hoisted relative to the matched context entry → ignored
|
|
23
|
+
* 4. .dockerignore filtering (patterns relative to dockerContextDir), skipped for the actor's own `.actor/`
|
|
24
|
+
* dir → ignored if matched
|
|
25
|
+
* 5. README.md by filename → cosmetic if inside the actor's own folder, otherwise ignored
|
|
26
|
+
* 6. .json inside the actor's own `.actor/` dir with only cosmetic schema diffs → cosmetic (semantically verified)
|
|
27
|
+
* 7. Everything else → functional
|
|
28
|
+
*/
|
|
29
|
+
const classifyFileChange = (originalFilePath, actorConfig, commits, dockerIgnoreMatcher) => {
|
|
30
|
+
const lowercaseFilePath = originalFilePath.toLowerCase();
|
|
31
|
+
// TODO: hardcodes that there's a single repo-wide changelog belonging to every actor. Should instead
|
|
32
|
+
// be derived from parsing actor.json (readme, changelog, schema paths), see
|
|
33
|
+
// https://github.com/apify/apify-test-tools/issues/106
|
|
34
|
+
if (lowercaseFilePath.endsWith('changelog.md')) {
|
|
35
|
+
return { impact: 'cosmetic', semanticallyVerified: false };
|
|
36
|
+
}
|
|
37
|
+
const lowercaseContextPaths = actorConfig.contextPaths.map((contextPath) => contextPath.toLowerCase());
|
|
38
|
+
const matchedContext = findContainingScope(lowercaseFilePath, lowercaseContextPaths);
|
|
39
|
+
if (matchedContext === undefined) {
|
|
40
|
+
return { impact: 'outside-context' };
|
|
41
|
+
}
|
|
42
|
+
const hoistedFilePath = hoistPath(lowercaseFilePath, matchedContext);
|
|
43
|
+
if (isIgnoredTopLevelFile(hoistedFilePath)) {
|
|
44
|
+
return { impact: 'ignored' };
|
|
7
45
|
}
|
|
8
|
-
|
|
46
|
+
const lowercaseFolder = actorConfig.folder.toLowerCase();
|
|
47
|
+
const actorDotDir = lowercaseFolder ? `${lowercaseFolder}/.actor` : '.actor';
|
|
48
|
+
const isUnderActorDotDir = isPathWithinScope(lowercaseFilePath, actorDotDir);
|
|
49
|
+
// .actor/ can legitimately be listed in .dockerignore (the Apify platform evaluates it before
|
|
50
|
+
// the Docker build, so excluding it from the build context is a valid caching optimization) —
|
|
51
|
+
// that shouldn't cause changes to .actor/ itself to be ignored here.
|
|
52
|
+
if (!isUnderActorDotDir && dockerIgnoreMatcher(originalFilePath)) {
|
|
53
|
+
return { impact: 'ignored' };
|
|
54
|
+
}
|
|
55
|
+
const isInActorFolder = isPathWithinScope(lowercaseFilePath, lowercaseFolder);
|
|
56
|
+
if (lowercaseFilePath.endsWith('readme.md')) {
|
|
57
|
+
return isInActorFolder ? { impact: 'cosmetic', semanticallyVerified: false } : { impact: 'ignored' };
|
|
58
|
+
}
|
|
59
|
+
if (lowercaseFilePath.endsWith('.json') && isUnderActorDotDir) {
|
|
60
|
+
const isCosmetic = isCosmeticOnlyJsonSchemaChange(commits, originalFilePath);
|
|
61
|
+
if (isCosmetic) {
|
|
62
|
+
return { impact: 'cosmetic', semanticallyVerified: true };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return { impact: 'functional' };
|
|
9
66
|
};
|
|
10
67
|
/**
|
|
11
|
-
*
|
|
68
|
+
* Check if a file falls inside another actor's folder.
|
|
69
|
+
* Root actors (folder === "") never exclude files from siblings.
|
|
12
70
|
*/
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
'.gitignore',
|
|
18
|
-
'readme.md',
|
|
19
|
-
'.husky/',
|
|
20
|
-
'.eslintrc',
|
|
21
|
-
'eslint.config.mjs',
|
|
22
|
-
'.prettierrc',
|
|
23
|
-
'.editorconfig',
|
|
24
|
-
'.actor/',
|
|
25
|
-
];
|
|
26
|
-
// Strip out deprecated /code and /shared folders, treat them as top-level code
|
|
27
|
-
const sanitizedLowercaseFilePath = lowercaseFilePath.replace(/^code\//, '').replace(/^shared\//, '');
|
|
28
|
-
return IGNORED_TOP_LEVEL_FILES.some((ignoredFile) => sanitizedLowercaseFilePath.startsWith(ignoredFile));
|
|
71
|
+
const isExcludedBySibling = (lowercaseFilePath, actor, allActors) => {
|
|
72
|
+
return allActors.some((other) => other.folder !== actor.folder &&
|
|
73
|
+
other.folder !== '' &&
|
|
74
|
+
isPathWithinScope(lowercaseFilePath, other.folder.toLowerCase()));
|
|
29
75
|
};
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
76
|
+
/**
|
|
77
|
+
* Maps each changed file to the set of actor names it triggered a change for.
|
|
78
|
+
*/
|
|
79
|
+
const buildFileToActorsMap = (actorsChangedMap) => {
|
|
80
|
+
const fileToActors = new Map();
|
|
81
|
+
for (const { actorConfig, files } of actorsChangedMap.values()) {
|
|
82
|
+
for (const file of files) {
|
|
83
|
+
const actors = fileToActors.get(file) ?? new Set();
|
|
84
|
+
actors.add(actorConfig.actorFullName);
|
|
85
|
+
fileToActors.set(file, actors);
|
|
86
|
+
}
|
|
35
87
|
}
|
|
36
|
-
|
|
37
|
-
|
|
88
|
+
return fileToActors;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Groups files by their identical actor-set (files triggering a change for the exact same
|
|
92
|
+
* actors are grouped together), then orders the groups by descending actor-set size
|
|
93
|
+
* (most-shared groups first), breaking ties alphabetically by actor names.
|
|
94
|
+
*/
|
|
95
|
+
const groupFilesByActorSet = (fileToActors) => {
|
|
96
|
+
const groupsByKey = new Map();
|
|
97
|
+
for (const [file, actorsSet] of fileToActors) {
|
|
98
|
+
const actors = Array.from(actorsSet).sort();
|
|
99
|
+
const key = actors.join(',');
|
|
100
|
+
const group = groupsByKey.get(key) ?? { actors, files: [] };
|
|
101
|
+
group.files.push(file);
|
|
102
|
+
groupsByKey.set(key, group);
|
|
38
103
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
// This is some super weird case that happened once in the past but I don't remember the context anymore
|
|
43
|
-
if (actorConfigChanged === undefined) {
|
|
44
|
-
console.error('SHOULD NEVER HAPPEN: changes was found in an actor folder which no longer exists in the current commit, skipping this file', {
|
|
45
|
-
actorName: actorFolderInfo.actorName,
|
|
46
|
-
lowercaseFilePath,
|
|
47
|
-
});
|
|
48
|
-
return { impact: 'ignored' };
|
|
104
|
+
return Array.from(groupsByKey.values()).sort((groupA, groupB) => {
|
|
105
|
+
if (groupB.actors.length !== groupA.actors.length) {
|
|
106
|
+
return groupB.actors.length - groupA.actors.length;
|
|
49
107
|
}
|
|
50
|
-
|
|
51
|
-
|
|
108
|
+
return groupA.actors.join(',').localeCompare(groupB.actors.join(','));
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
const logChangeGroups = (groups) => {
|
|
112
|
+
for (const { actors, files } of groups) {
|
|
113
|
+
if (actors.length > 1) {
|
|
114
|
+
console.error(`[DIFF]: Shared changes for actors ${actors.join(', ')}: ${files.join(', ')}`);
|
|
52
115
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
return { impact: 'cosmetic', semanticallyVerified: true, includes: actorConfigChanged };
|
|
116
|
+
else {
|
|
117
|
+
console.error(`[DIFF]: Changes specific to actor ${actors[0]}: ${files.join(', ')}`);
|
|
56
118
|
}
|
|
57
|
-
return { impact: 'functional', includes: actorConfigChanged };
|
|
58
119
|
}
|
|
59
|
-
// For any other files, we assume they can interact with the code
|
|
60
|
-
return { impact: 'functional', includes: 'all-actors' };
|
|
61
120
|
};
|
|
62
121
|
export const getChangedActors = ({ filepathsChanged, actorConfigs, isLatest = false, commits, }) => {
|
|
63
|
-
// folder -> ActorConfig
|
|
64
122
|
const actorsChangedMap = new Map();
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (fileChange.impact === 'cosmetic' && !isLatest) {
|
|
72
|
-
continue;
|
|
73
|
-
}
|
|
74
|
-
if (fileChange.includes !== 'all-actors') {
|
|
75
|
-
actorsChangedMap.set(fileChange.includes.folder, fileChange.includes);
|
|
76
|
-
}
|
|
77
|
-
else if (fileChange.includes === 'all-actors') {
|
|
78
|
-
// Standalone Actors are handled always via specific actors change, not all-actors
|
|
79
|
-
for (const actorConfig of actorConfigsWithoutStandalone) {
|
|
80
|
-
actorsChangedMap.set(actorConfig.folder, actorConfig);
|
|
123
|
+
for (const actorConfig of actorConfigs) {
|
|
124
|
+
const dockerIgnoreMatcher = loadDockerIgnore(actorConfig.dockerContextDir);
|
|
125
|
+
for (const originalFilePath of filepathsChanged) {
|
|
126
|
+
const lowercaseFilePath = originalFilePath.toLowerCase();
|
|
127
|
+
if (isExcludedBySibling(lowercaseFilePath, actorConfig, actorConfigs)) {
|
|
128
|
+
continue;
|
|
81
129
|
}
|
|
130
|
+
const change = classifyFileChange(originalFilePath, actorConfig, commits, dockerIgnoreMatcher);
|
|
131
|
+
if (change.impact === 'ignored' || change.impact === 'outside-context')
|
|
132
|
+
continue;
|
|
133
|
+
if (change.impact === 'cosmetic' && !isLatest)
|
|
134
|
+
continue;
|
|
135
|
+
const entry = actorsChangedMap.get(actorConfig.folder) ?? { actorConfig, files: [] };
|
|
136
|
+
entry.files.push(originalFilePath);
|
|
137
|
+
actorsChangedMap.set(actorConfig.folder, entry);
|
|
82
138
|
}
|
|
83
139
|
}
|
|
84
|
-
const actorsChanged = Array.from(actorsChangedMap.values());
|
|
85
|
-
//
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
.map((file) => ({ file, change: classifyFileChange(file, actorConfigs, commits) }))
|
|
91
|
-
.filter(({ change }) => change.impact === 'cosmetic');
|
|
92
|
-
const semanticallyVerifiedFiles = cosmeticChanges
|
|
93
|
-
.filter(({ change }) => change.semanticallyVerified)
|
|
94
|
-
.map(({ file }) => file);
|
|
95
|
-
const inherentlyCosmeticFiles = cosmeticChanges
|
|
96
|
-
.filter(({ change }) => !change.semanticallyVerified)
|
|
97
|
-
.map(({ file }) => file);
|
|
98
|
-
console.error(`[DIFF]: Cosmetic-only JSON schema changes (semantically verified, only trigger release build): ${formatFiles(semanticallyVerifiedFiles)}`);
|
|
99
|
-
console.error(`[DIFF]: Inherently cosmetic files (README, CHANGELOG — only trigger release build): ${formatFiles(inherentlyCosmeticFiles)}`);
|
|
100
|
-
const functionalFilesChanged = filepathsChanged.filter((file) => classifyFileChange(file, actorConfigs, commits).impact === 'functional');
|
|
101
|
-
console.error(`[DIFF]: Functional files (trigger test & release build): ${formatFiles(functionalFilesChanged)}`);
|
|
140
|
+
const actorsChanged = Array.from(actorsChangedMap.values()).map((entry) => entry.actorConfig);
|
|
141
|
+
// Log changes grouped by actor set, so changes shared across actors are logged once
|
|
142
|
+
// instead of being repeated per actor.
|
|
143
|
+
const fileToActors = buildFileToActorsMap(actorsChangedMap);
|
|
144
|
+
const groups = groupFilesByActorSet(fileToActors);
|
|
145
|
+
logChangeGroups(groups);
|
|
102
146
|
if (actorsChanged.length > 0) {
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
.filter((config) => config.isStandalone)
|
|
106
|
-
.map((config) => config.actorName);
|
|
107
|
-
console.error(`[DIFF]: MiniActors to be built and tested: ${miniactors.join(', ')}`);
|
|
108
|
-
console.error(`[DIFF]: Standalone Actors to be built and tested: ${standaloneActors.join(', ')}`);
|
|
147
|
+
const actors = actorsChanged.map((config) => config.actorFullName);
|
|
148
|
+
console.error(`[DIFF]: Actors to be built and tested: ${actors.join(', ')}`);
|
|
109
149
|
}
|
|
110
150
|
else {
|
|
111
151
|
console.error(`[DIFF]: No relevant files changed, skipping builds and tests`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diff-changes.js","sourceRoot":"","sources":["../../bin/diff-changes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"diff-changes.js","sourceRoot":"","sources":["../../bin/diff-changes.ts"],"names":[],"mappings":"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"}
|