apify-test-tools 0.10.1-beta.5 → 0.10.1-beta.7

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.
Files changed (61) hide show
  1. package/CHANGELOG.md +1 -0
  2. package/bin/build-from-local.ts +19 -27
  3. package/bin/build.ts +1 -1
  4. package/bin/diff-changes.ts +26 -35
  5. package/bin/dockerignore.ts +24 -17
  6. package/bin/types.ts +7 -3
  7. package/bin/utils/config/actor-json.ts +49 -8
  8. package/bin/utils/config/load-config.ts +4 -24
  9. package/bin/utils/path/repo-relative.ts +27 -4
  10. package/dist/bin/build-from-local.d.ts +3 -2
  11. package/dist/bin/build-from-local.d.ts.map +1 -1
  12. package/dist/bin/build-from-local.js +16 -23
  13. package/dist/bin/build-from-local.js.map +1 -1
  14. package/dist/bin/build.js +1 -1
  15. package/dist/bin/build.js.map +1 -1
  16. package/dist/bin/diff-changes.d.ts.map +1 -1
  17. package/dist/bin/diff-changes.js +26 -29
  18. package/dist/bin/diff-changes.js.map +1 -1
  19. package/dist/bin/dockerignore.d.ts +11 -10
  20. package/dist/bin/dockerignore.d.ts.map +1 -1
  21. package/dist/bin/dockerignore.js +24 -15
  22. package/dist/bin/dockerignore.js.map +1 -1
  23. package/dist/bin/types.d.ts +6 -3
  24. package/dist/bin/types.d.ts.map +1 -1
  25. package/dist/bin/utils/config/actor-json.d.ts.map +1 -1
  26. package/dist/bin/utils/config/actor-json.js +35 -4
  27. package/dist/bin/utils/config/actor-json.js.map +1 -1
  28. package/dist/bin/utils/config/load-config.d.ts +1 -11
  29. package/dist/bin/utils/config/load-config.d.ts.map +1 -1
  30. package/dist/bin/utils/config/load-config.js +1 -10
  31. package/dist/bin/utils/config/load-config.js.map +1 -1
  32. package/dist/bin/utils/path/repo-relative.d.ts +4 -0
  33. package/dist/bin/utils/path/repo-relative.d.ts.map +1 -1
  34. package/dist/bin/utils/path/repo-relative.js +24 -5
  35. package/dist/bin/utils/path/repo-relative.js.map +1 -1
  36. package/dist/test/unit/bin/actor-filtering.test.js +8 -2
  37. package/dist/test/unit/bin/actor-filtering.test.js.map +1 -1
  38. package/dist/test/unit/bin/build-from-local.test.js +57 -18
  39. package/dist/test/unit/bin/build-from-local.test.js.map +1 -1
  40. package/dist/test/unit/bin/diff-changes.test.js +98 -132
  41. package/dist/test/unit/bin/diff-changes.test.js.map +1 -1
  42. package/dist/test/unit/bin/dockerignore.test.js +27 -24
  43. package/dist/test/unit/bin/dockerignore.test.js.map +1 -1
  44. package/dist/test/unit/bin/git-command.test.js +12 -42
  45. package/dist/test/unit/bin/git-command.test.js.map +1 -1
  46. package/dist/test/unit/bin/utils/config/load-config.test.js +40 -4
  47. package/dist/test/unit/bin/utils/config/load-config.test.js.map +1 -1
  48. package/dist/test/unit/bin/utils/path/repo-relative.test.js +5 -0
  49. package/dist/test/unit/bin/utils/path/repo-relative.test.js.map +1 -1
  50. package/dist/test/unit/should-built-and-test.test.js +55 -116
  51. package/dist/test/unit/should-built-and-test.test.js.map +1 -1
  52. package/dist/tsconfig.tsbuildinfo +1 -1
  53. package/package.json +1 -1
  54. package/test/unit/bin/actor-filtering.test.ts +8 -2
  55. package/test/unit/bin/build-from-local.test.ts +58 -21
  56. package/test/unit/bin/diff-changes.test.ts +133 -133
  57. package/test/unit/bin/dockerignore.test.ts +28 -28
  58. package/test/unit/bin/git-command.test.ts +14 -55
  59. package/test/unit/bin/utils/config/load-config.test.ts +54 -4
  60. package/test/unit/bin/utils/path/repo-relative.test.ts +6 -0
  61. package/test/unit/should-built-and-test.test.ts +98 -121
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "apify-test-tools",
3
- "version": "0.10.1-beta.5",
3
+ "version": "0.10.1-beta.7",
4
4
  "type": "module",
5
5
  "description": "TBD",
6
6
  "repository": {
@@ -2,12 +2,18 @@ import { describe, expect, it } from 'vitest';
2
2
 
3
3
  import { selectActors } from '../../../bin/actor-filtering.js';
4
4
  import type { ActorConfig } from '../../../bin/types.js';
5
+ import { ExistingDir, ExistingFile, RelativeDir } from '../../../bin/utils/path/repo-relative.js';
5
6
 
6
7
  const actor = (actorFullName: string): ActorConfig => ({
7
8
  actorFullName,
8
- folder: actorFullName.split('/')[1],
9
+ folder: new ExistingDir('.'),
9
10
  tokenEnvVar: 'TOKEN',
10
- dockerContextDir: '.',
11
+ actorJson: {
12
+ // kind of a hack, but its not supposed to be read here
13
+ file: new ExistingFile('package.json'),
14
+ dockerContextDir: RelativeDir.ROOT,
15
+ },
16
+ dockerContextDir: new RelativeDir('.'),
11
17
  contextPaths: [],
12
18
  });
13
19
 
@@ -1,5 +1,3 @@
1
- import type * as ChildProcessModule from 'node:child_process';
2
- import { spawnSync } from 'node:child_process';
3
1
  import fs from 'node:fs/promises';
4
2
  import os from 'node:os';
5
3
  import path from 'node:path';
@@ -15,22 +13,12 @@ import {
15
13
  // @ts-ignore: editor-only TS6059 — test/tsconfig.json's rootDir doesn't span bin/, but the root
16
14
  // tsconfig (used for the real build and for eslint's type-aware linting) has no such restriction.
17
15
  } from '../../../bin/build-from-local.js';
16
+ import type { ActorConfig } from '../../../bin/types.js';
18
17
  import * as Utils from '../../../bin/utils.js';
19
-
20
- // Defaults to the real spawnSync so `git init`/`git ls-files` calls made by the code under test
21
- // (and by test setup below) actually run — individual tests override this via mockReturnValue
22
- // where they need to fake git's output, and vi.restoreAllMocks() reverts back to this passthrough.
23
- vi.mock('node:child_process', async (importOriginal) => {
24
- const actual = await importOriginal<typeof ChildProcessModule>();
25
- return { ...actual, spawnSync: vi.fn(actual.spawnSync) };
26
- });
18
+ import { ExistingDir, ExistingFile, RelativeDir } from '../../../bin/utils/path/repo-relative.js';
27
19
 
28
20
  const mkTempDir = async (prefix: string) => fs.mkdtemp(path.join(os.tmpdir(), prefix));
29
21
 
30
- const initGitRepo = (dir: string) => {
31
- spawnSync('git', ['init', '-q'], { cwd: dir });
32
- };
33
-
34
22
  describe('build-from-local helpers', () => {
35
23
  const tempDirs: string[] = [];
36
24
 
@@ -43,22 +31,56 @@ describe('build-from-local helpers', () => {
43
31
  it('drops secret-pattern files and gitignored files, keeps everything else', async () => {
44
32
  const rootDir = await mkTempDir('apify-test-tools-collect-');
45
33
  tempDirs.push(rootDir);
46
- initGitRepo(rootDir);
47
34
 
48
35
  await fs.writeFile(path.join(rootDir, 'main.js'), 'console.log(1)');
49
36
  await fs.writeFile(path.join(rootDir, '.env'), 'SECRET=1');
37
+ await fs.writeFile(path.join(rootDir, 'docker-ignored.txt'), 'ignored');
38
+ await fs.writeFile(path.join(rootDir, '.dockerignore'), 'docker-ignored.txt\n');
50
39
  await fs.mkdir(path.join(rootDir, 'sub'));
51
40
  await fs.writeFile(path.join(rootDir, 'sub', 'ignored.log'), 'log');
52
41
 
53
- // Only the gitignore side is mocked — isSecretFile runs for real, so this also
54
- // proves the secret-pattern backstop applies independently of .gitignore.
42
+ vi.spyOn(Utils, 'listRepoFilePaths').mockResolvedValue([
43
+ 'main.js',
44
+ '.env',
45
+ 'docker-ignored.txt',
46
+ 'sub/ignored.log',
47
+ ]);
55
48
  vi.spyOn(Utils, 'getGitignoredPaths').mockImplementation(
56
49
  async (relativePaths) => new Set(relativePaths.filter((p) => p.endsWith('.log'))),
57
50
  );
58
51
 
59
- const result = await collectNonIgnoredFiles(rootDir, rootDir);
52
+ const originalCwd = process.cwd();
53
+ process.chdir(rootDir);
54
+ try {
55
+ expect(await collectNonIgnoredFiles(RelativeDir.ROOT, rootDir)).toStrictEqual([
56
+ path.join(rootDir, 'main.js'),
57
+ ]);
58
+ } finally {
59
+ process.chdir(originalCwd);
60
+ }
61
+ });
60
62
 
61
- expect(result).toStrictEqual([path.join(rootDir, 'main.js')]);
63
+ it('matches .dockerignore relative to a nested Docker context', async () => {
64
+ const rootDir = await mkTempDir('apify-test-tools-nested-context-');
65
+ tempDirs.push(rootDir);
66
+ await fs.mkdir(path.join(rootDir, 'actors', 'shopify'), { recursive: true });
67
+ await fs.writeFile(path.join(rootDir, 'actors', 'shopify', '.dockerignore'), 'dist/\n');
68
+
69
+ vi.spyOn(Utils, 'listRepoFilePaths').mockResolvedValue([
70
+ 'actors/shopify/dist/bundle.js',
71
+ 'actors/shopify/src/main.ts',
72
+ ]);
73
+ vi.spyOn(Utils, 'getGitignoredPaths').mockResolvedValue(new Set());
74
+
75
+ const originalCwd = process.cwd();
76
+ process.chdir(rootDir);
77
+ try {
78
+ expect(await collectNonIgnoredFiles(new RelativeDir('actors/shopify'), rootDir)).toStrictEqual([
79
+ path.join(rootDir, 'actors', 'shopify', 'src', 'main.ts'),
80
+ ]);
81
+ } finally {
82
+ process.chdir(originalCwd);
83
+ }
62
84
  });
63
85
  });
64
86
 
@@ -146,7 +168,6 @@ describe('build-from-local helpers', () => {
146
168
  it("always collects the actor's own .actor/actor.json for a monorepo actor, since flattenMonorepoContext depends on it", async () => {
147
169
  const repoRoot = await mkTempDir('apify-test-tools-collect-source-');
148
170
  tempDirs.push(repoRoot);
149
- initGitRepo(repoRoot);
150
171
 
151
172
  const originalCwd = process.cwd();
152
173
  // We simulate the working directory being the repo root, since collectSourceFiles uses relative paths to the repo root.
@@ -161,7 +182,23 @@ describe('build-from-local helpers', () => {
161
182
  );
162
183
  await fs.writeFile(path.join(cwd, 'package.json'), '{}');
163
184
 
164
- const sourceFiles = await collectSourceFiles('owner/actor', actorDir);
185
+ vi.spyOn(Utils, 'listRepoFilePaths').mockResolvedValue([
186
+ 'actors/owner_actor/.actor/actor.json',
187
+ 'package.json',
188
+ ]);
189
+ vi.spyOn(Utils, 'getGitignoredPaths').mockResolvedValue(new Set());
190
+ const actorConfig: ActorConfig = {
191
+ actorFullName: 'owner/actor',
192
+ folder: new ExistingDir('actors/owner_actor'),
193
+ tokenEnvVar: 'APIFY_TOKEN',
194
+ actorJson: {
195
+ file: new ExistingFile('actors/owner_actor/.actor/actor.json'),
196
+ dockerContextDir: RelativeDir.ROOT,
197
+ },
198
+ dockerContextDir: RelativeDir.ROOT,
199
+ contextPaths: [RelativeDir.ROOT],
200
+ };
201
+ const sourceFiles = await collectSourceFiles(actorConfig);
165
202
  expect(sourceFiles.map((file) => file.name)).toContain('.actor/actor.json');
166
203
  } finally {
167
204
  process.chdir(originalCwd);
@@ -1,33 +1,63 @@
1
- import { beforeEach, describe, expect, it, vi } from 'vitest';
1
+ import fs from 'node:fs';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+
5
+ import { afterAll, beforeEach, describe, expect, it, vi } from 'vitest';
2
6
 
3
7
  import { getChangedActors } from '../../../bin/diff-changes.js';
4
8
  import * as DiffJsonSchema from '../../../bin/diff-json-schema.js';
5
9
  import * as Dockerignore from '../../../bin/dockerignore.js';
6
10
  import { logger } from '../../../bin/logger.js';
7
11
  import type { ActorConfig } from '../../../bin/types.js';
8
-
9
- const miniActor: ActorConfig = {
10
- actorFullName: 'foo/bar',
11
- folder: 'actors/foo_bar',
12
- tokenEnvVar: 'APIFY_TOKEN_FOO',
13
- dockerContextDir: '',
14
- contextPaths: [''],
15
- };
16
- const standaloneActor: ActorConfig = {
17
- actorFullName: 'owner/standalone',
18
- folder: 'standalone-actors/standalone',
19
- tokenEnvVar: 'APIFY_TOKEN_OWNER',
20
- dockerContextDir: 'standalone-actors/standalone',
21
- contextPaths: ['standalone-actors/standalone'],
12
+ import { ExistingDir, RelativeDir, RelativeFile } from '../../../bin/utils/path/repo-relative.js';
13
+
14
+ const originalCwd = process.cwd();
15
+ const fixtureRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'apify-diff-changes-'));
16
+ process.chdir(fixtureRoot);
17
+ fs.writeFileSync('package.json', '{}');
18
+
19
+ const actorConfig = (
20
+ actorFullName: string,
21
+ folder: string,
22
+ tokenEnvVar: string,
23
+ dockerContextDir: string,
24
+ contextPaths: string[],
25
+ ): ActorConfig => {
26
+ const folderPath = folder || '.';
27
+ fs.mkdirSync(folderPath, { recursive: true });
28
+ return {
29
+ actorFullName,
30
+ folder: new ExistingDir(folderPath),
31
+ tokenEnvVar,
32
+ actorJson: {
33
+ file: new RelativeFile(path.join(folderPath, '.actor/actor.json')),
34
+ dockerContextDir: new RelativeDir(dockerContextDir || '.'),
35
+ changelog: new RelativeFile('CHANGELOG.md'),
36
+ },
37
+ dockerContextDir: new RelativeDir(dockerContextDir || '.'),
38
+ contextPaths: contextPaths.map((contextPath) => new RelativeDir(contextPath || '.')),
39
+ };
22
40
  };
41
+
42
+ afterAll(() => {
43
+ process.chdir(originalCwd);
44
+ fs.rmSync(fixtureRoot, { recursive: true, force: true });
45
+ });
46
+
47
+ const miniActor = actorConfig('foo/bar', 'actors/foo_bar', 'APIFY_TOKEN_FOO', '', ['']);
48
+ const standaloneActor = actorConfig(
49
+ 'owner/standalone',
50
+ 'standalone-actors/standalone',
51
+ 'APIFY_TOKEN_OWNER',
52
+ 'standalone-actors/standalone',
53
+ ['standalone-actors/standalone'],
54
+ );
23
55
  const actorConfigs = [miniActor, standaloneActor];
24
- const amazonActor: ActorConfig = {
25
- actorFullName: 'junglee/amazon-crawler',
26
- folder: 'actors/junglee_Amazon-crawler',
27
- tokenEnvVar: 'APIFY_TOKEN_JUNGLEE',
28
- dockerContextDir: '',
29
- contextPaths: ['actors/junglee_Amazon-crawler', 'code', 'shared'],
30
- };
56
+ const amazonActor = actorConfig('junglee/amazon-crawler', 'actors/junglee_Amazon-crawler', 'APIFY_TOKEN_JUNGLEE', '', [
57
+ 'actors/junglee_Amazon-crawler',
58
+ 'code',
59
+ 'shared',
60
+ ]);
31
61
 
32
62
  const commits = [{ sha: 'Commit1', author: '', date: '', message: '' }];
33
63
 
@@ -49,6 +79,15 @@ describe('getChangedActors', () => {
49
79
  expect(result).toEqual([]);
50
80
  });
51
81
 
82
+ it('does not ignore source files whose names contain an ignored file name', async () => {
83
+ const result = await getChangedActors({
84
+ filepathsChanged: ['actors/foo_bar/src/.gitignore-helper.ts'],
85
+ actorConfigs,
86
+ commits,
87
+ });
88
+ expect(result).toEqual([miniActor]);
89
+ });
90
+
52
91
  it('returns the actor when a functional file in its folder changes', async () => {
53
92
  const result = await getChangedActors({
54
93
  filepathsChanged: ['actors/foo_bar/src/main.ts'],
@@ -101,7 +140,6 @@ describe('getChangedActors', () => {
101
140
  });
102
141
 
103
142
  it('returns actor when JSON file has functional changes', async () => {
104
- vi.spyOn(DiffJsonSchema, 'isCosmeticOnlyJsonSchemaChange').mockResolvedValue(false);
105
143
  const result = await getChangedActors({
106
144
  filepathsChanged: ['actors/foo_bar/.actor/actor.json'],
107
145
  actorConfigs,
@@ -128,9 +166,13 @@ describe('getChangedActors', () => {
128
166
  filepathsChanged: ['actors/foo_bar/.actor/input_schema.json'],
129
167
  actorConfigs,
130
168
  commits,
131
- isLatest: true,
169
+ isLatest: false,
132
170
  });
133
- expect(result).toEqual([miniActor]);
171
+ expect(result).toEqual([]);
172
+ expect(DiffJsonSchema.isCosmeticOnlyJsonSchemaChange).toHaveBeenCalledWith(
173
+ commits,
174
+ 'actors/foo_bar/.actor/input_schema.json',
175
+ );
134
176
  });
135
177
 
136
178
  it('does not trigger narrow-context actor when shared file changes', async () => {
@@ -164,6 +206,30 @@ describe('getChangedActors', () => {
164
206
  expect(result).toEqual([]);
165
207
  });
166
208
 
209
+ it('treats any changelog filename as cosmetic regardless of configured paths', async () => {
210
+ const result = await getChangedActors({
211
+ filepathsChanged: ['docs/CHANGELOG.md'],
212
+ actorConfigs: [miniActor, standaloneActor],
213
+ commits,
214
+ isLatest: true,
215
+ });
216
+ expect(result).toEqual([miniActor, standaloneActor]);
217
+ });
218
+
219
+ it('does not special-case a configured readme outside the actor context', async () => {
220
+ const configuredActor: ActorConfig = {
221
+ ...standaloneActor,
222
+ actorJson: { ...standaloneActor.actorJson, readme: new RelativeFile('docs/guide.md') },
223
+ };
224
+ const result = await getChangedActors({
225
+ filepathsChanged: ['docs/guide.md'],
226
+ actorConfigs: [configuredActor],
227
+ commits,
228
+ isLatest: true,
229
+ });
230
+ expect(result).toEqual([]);
231
+ });
232
+
167
233
  it('triggers narrow-context actor when its own folder changes', async () => {
168
234
  const result = await getChangedActors({
169
235
  filepathsChanged: ['standalone-actors/standalone/src/main.ts'],
@@ -194,13 +260,7 @@ describe('getChangedActors', () => {
194
260
  });
195
261
 
196
262
  it('matches folder where folder name differs from actor name', async () => {
197
- const ownerlessActor: ActorConfig = {
198
- actorFullName: 'myteam/shopify-scraper',
199
- folder: 'actors/shopify',
200
- tokenEnvVar: 'APIFY_TOKEN_MYTEAM',
201
- dockerContextDir: '',
202
- contextPaths: [''],
203
- };
263
+ const ownerlessActor = actorConfig('myteam/shopify-scraper', 'actors/shopify', 'APIFY_TOKEN_MYTEAM', '', ['']);
204
264
  const result = await getChangedActors({
205
265
  filepathsChanged: ['actors/shopify/src/main.ts'],
206
266
  actorConfigs: [ownerlessActor],
@@ -210,13 +270,7 @@ describe('getChangedActors', () => {
210
270
  });
211
271
 
212
272
  it('in single-actor repo, .actor/ changes trigger builds', async () => {
213
- const rootActor: ActorConfig = {
214
- actorFullName: 'myteam/my-actor',
215
- folder: '',
216
- tokenEnvVar: 'BUILDER_APIFY_TOKEN',
217
- dockerContextDir: '',
218
- contextPaths: [''],
219
- };
273
+ const rootActor = actorConfig('myteam/my-actor', '', 'BUILDER_APIFY_TOKEN', '', ['']);
220
274
  const result = await getChangedActors({
221
275
  filepathsChanged: ['.actor/actor.json'],
222
276
  actorConfigs: [rootActor],
@@ -234,23 +288,26 @@ describe('getChangedActors', () => {
234
288
  expect(result).toEqual([miniActor]);
235
289
  });
236
290
 
237
- it('file paths are matched case-insensitively', async () => {
291
+ it('file paths are matched case-sensitively', async () => {
292
+ const narrowActor = actorConfig('foo/bar', 'actors/foo_bar', 'APIFY_TOKEN_FOO', 'actors/foo_bar', [
293
+ 'actors/foo_bar',
294
+ ]);
238
295
  const result = await getChangedActors({
239
296
  filepathsChanged: ['Actors/FOO_BAR/Main.ts'],
240
- actorConfigs,
297
+ actorConfigs: [narrowActor],
241
298
  commits,
242
299
  });
243
- expect(result).toEqual([miniActor]);
300
+ expect(result).toEqual([]);
244
301
  });
245
302
 
246
303
  it('triggers actor with contextPaths override when file matches an override path', async () => {
247
- const overrideActor: ActorConfig = {
248
- actorFullName: 'team/override-actor',
249
- folder: 'actors/override',
250
- tokenEnvVar: 'APIFY_TOKEN_TEAM',
251
- dockerContextDir: 'actors/override',
252
- contextPaths: ['actors/override', 'packages'],
253
- };
304
+ const overrideActor = actorConfig(
305
+ 'team/override-actor',
306
+ 'actors/override',
307
+ 'APIFY_TOKEN_TEAM',
308
+ 'actors/override',
309
+ ['actors/override', 'packages'],
310
+ );
254
311
  const result = await getChangedActors({
255
312
  filepathsChanged: ['packages/shared/utils.ts'],
256
313
  actorConfigs: [overrideActor],
@@ -260,13 +317,13 @@ describe('getChangedActors', () => {
260
317
  });
261
318
 
262
319
  it('does not trigger actor with contextPaths override when file is outside all override paths', async () => {
263
- const overrideActor: ActorConfig = {
264
- actorFullName: 'team/override-actor',
265
- folder: 'actors/override',
266
- tokenEnvVar: 'APIFY_TOKEN_TEAM',
267
- dockerContextDir: 'actors/override',
268
- contextPaths: ['actors/override', 'packages'],
269
- };
320
+ const overrideActor = actorConfig(
321
+ 'team/override-actor',
322
+ 'actors/override',
323
+ 'APIFY_TOKEN_TEAM',
324
+ 'actors/override',
325
+ ['actors/override', 'packages'],
326
+ );
270
327
  const result = await getChangedActors({
271
328
  filepathsChanged: ['other-dir/file.ts'],
272
329
  actorConfigs: [overrideActor],
@@ -276,20 +333,8 @@ describe('getChangedActors', () => {
276
333
  });
277
334
 
278
335
  it('broad-context actor skips files in sibling actor folders', async () => {
279
- const actorA: ActorConfig = {
280
- actorFullName: 'team/actor-a',
281
- folder: 'actors/a',
282
- tokenEnvVar: 'APIFY_TOKEN_TEAM',
283
- dockerContextDir: '',
284
- contextPaths: [''],
285
- };
286
- const actorB: ActorConfig = {
287
- actorFullName: 'team/actor-b',
288
- folder: 'actors/b',
289
- tokenEnvVar: 'APIFY_TOKEN_TEAM',
290
- dockerContextDir: '',
291
- contextPaths: [''],
292
- };
336
+ const actorA = actorConfig('team/actor-a', 'actors/a', 'APIFY_TOKEN_TEAM', '', ['']);
337
+ const actorB = actorConfig('team/actor-b', 'actors/b', 'APIFY_TOKEN_TEAM', '', ['']);
293
338
  const result = await getChangedActors({
294
339
  filepathsChanged: ['actors/b/src/main.ts'],
295
340
  actorConfigs: [actorA, actorB],
@@ -298,21 +343,11 @@ describe('getChangedActors', () => {
298
343
  expect(result).toEqual([actorB]);
299
344
  });
300
345
 
301
- it('root actor (folder="") is excluded from sibling actor folder files', async () => {
302
- const rootActor: ActorConfig = {
303
- actorFullName: 'team/root',
304
- folder: '',
305
- tokenEnvVar: 'APIFY_TOKEN_TEAM',
306
- dockerContextDir: '',
307
- contextPaths: [''],
308
- };
309
- const childActor: ActorConfig = {
310
- actorFullName: 'team/child',
311
- folder: 'actors/child',
312
- tokenEnvVar: 'APIFY_TOKEN_TEAM',
313
- dockerContextDir: 'actors/child',
314
- contextPaths: ['actors/child'],
315
- };
346
+ it('root actor is excluded from sibling actor folder files', async () => {
347
+ const rootActor = actorConfig('team/root', '', 'APIFY_TOKEN_TEAM', '', ['']);
348
+ const childActor = actorConfig('team/child', 'actors/child', 'APIFY_TOKEN_TEAM', 'actors/child', [
349
+ 'actors/child',
350
+ ]);
316
351
  const result = await getChangedActors({
317
352
  filepathsChanged: ['actors/child/src/main.ts'],
318
353
  actorConfigs: [rootActor, childActor],
@@ -322,21 +357,11 @@ describe('getChangedActors', () => {
322
357
  expect(result).toContainEqual(childActor);
323
358
  });
324
359
 
325
- it('root actor (folder="") sees files outside any actor folder', async () => {
326
- const rootActor: ActorConfig = {
327
- actorFullName: 'team/root',
328
- folder: '',
329
- tokenEnvVar: 'APIFY_TOKEN_TEAM',
330
- dockerContextDir: '',
331
- contextPaths: [''],
332
- };
333
- const childActor: ActorConfig = {
334
- actorFullName: 'team/child',
335
- folder: 'actors/child',
336
- tokenEnvVar: 'APIFY_TOKEN_TEAM',
337
- dockerContextDir: 'actors/child',
338
- contextPaths: ['actors/child'],
339
- };
360
+ it('root actor sees files outside any actor folder', async () => {
361
+ const rootActor = actorConfig('team/root', '', 'APIFY_TOKEN_TEAM', '', ['']);
362
+ const childActor = actorConfig('team/child', 'actors/child', 'APIFY_TOKEN_TEAM', 'actors/child', [
363
+ 'actors/child',
364
+ ]);
340
365
  const result = await getChangedActors({
341
366
  filepathsChanged: ['lib/shared-utils.ts'],
342
367
  actorConfigs: [rootActor, childActor],
@@ -369,7 +394,6 @@ describe('getChangedActors', () => {
369
394
  });
370
395
 
371
396
  it('JSON file in context but outside actor folder is functional (not checked for cosmetic)', async () => {
372
- vi.spyOn(DiffJsonSchema, 'isCosmeticOnlyJsonSchemaChange').mockResolvedValue(true);
373
397
  const result = await getChangedActors({
374
398
  filepathsChanged: ['lib/config.json'],
375
399
  actorConfigs: [miniActor],
@@ -398,7 +422,7 @@ describe('getChangedActors', () => {
398
422
  expect(result).toEqual([miniActor]);
399
423
  });
400
424
 
401
- it('hoists a standalone actor own top-level dev file relative to its context before checking the ignore list', async () => {
425
+ it('ignores a standalone actor top-level dev file relative to its context', async () => {
402
426
  const result = await getChangedActors({
403
427
  filepathsChanged: ['standalone-actors/standalone/.eslintrc'],
404
428
  actorConfigs,
@@ -409,7 +433,7 @@ describe('getChangedActors', () => {
409
433
 
410
434
  it('does not special-case code/ and shared/ prefixes anymore — must be declared via overrideActorContext', async () => {
411
435
  const result = await getChangedActors({
412
- filepathsChanged: ['code/.eslintrc'],
436
+ filepathsChanged: ['code/some/code.ts'],
413
437
  actorConfigs: [miniActor],
414
438
  commits,
415
439
  });
@@ -465,20 +489,8 @@ describe('getChangedActors logging', () => {
465
489
  });
466
490
 
467
491
  it('logs a single "shared" group when two actors are triggered by the exact same file', async () => {
468
- const actorA: ActorConfig = {
469
- actorFullName: 'team/actor-a',
470
- folder: 'actors/a',
471
- tokenEnvVar: 'APIFY_TOKEN_TEAM',
472
- dockerContextDir: '',
473
- contextPaths: ['', 'shared'],
474
- };
475
- const actorB: ActorConfig = {
476
- actorFullName: 'team/actor-b',
477
- folder: 'actors/b',
478
- tokenEnvVar: 'APIFY_TOKEN_TEAM',
479
- dockerContextDir: '',
480
- contextPaths: ['', 'shared'],
481
- };
492
+ const actorA = actorConfig('team/actor-a', 'actors/a', 'APIFY_TOKEN_TEAM', '', ['', 'shared']);
493
+ const actorB = actorConfig('team/actor-b', 'actors/b', 'APIFY_TOKEN_TEAM', '', ['', 'shared']);
482
494
 
483
495
  await getChangedActors({
484
496
  filepathsChanged: ['shared/shared.ts'],
@@ -494,20 +506,8 @@ describe('getChangedActors logging', () => {
494
506
  });
495
507
 
496
508
  it('logs shared and specific groups in descending-size order for partial overlap across actors', async () => {
497
- const actorA: ActorConfig = {
498
- actorFullName: 'team/actor-a',
499
- folder: 'actors/a',
500
- tokenEnvVar: 'APIFY_TOKEN_TEAM',
501
- dockerContextDir: '',
502
- contextPaths: [''],
503
- };
504
- const actorB: ActorConfig = {
505
- actorFullName: 'team/actor-b',
506
- folder: 'actors/b',
507
- tokenEnvVar: 'APIFY_TOKEN_TEAM',
508
- dockerContextDir: '',
509
- contextPaths: [''],
510
- };
509
+ const actorA = actorConfig('team/actor-a', 'actors/a', 'APIFY_TOKEN_TEAM', '', ['']);
510
+ const actorB = actorConfig('team/actor-b', 'actors/b', 'APIFY_TOKEN_TEAM', '', ['']);
511
511
 
512
512
  await getChangedActors({
513
513
  filepathsChanged: ['shared.ts', 'actors/a/a-only.ts', 'actors/b/b-only.ts'],
@@ -515,7 +515,7 @@ describe('getChangedActors logging', () => {
515
515
  commits,
516
516
  });
517
517
 
518
- const errorCalls = (logger.info as unknown as ReturnType<typeof vi.fn>).mock.calls.map((call) => call[0]);
518
+ const errorCalls = vi.mocked(logger.info).mock.calls.map((call) => call[0]);
519
519
 
520
520
  expect(errorCalls).toEqual([
521
521
  '[DIFF]: Shared changes for actors team/actor-a, team/actor-b: shared.ts',
@@ -527,7 +527,7 @@ describe('getChangedActors logging', () => {
527
527
 
528
528
  it('logs no group lines when zero actors changed', async () => {
529
529
  await getChangedActors({
530
- filepathsChanged: ['.gitignore', 'README.md'],
530
+ filepathsChanged: ['.gitignore', '.prettierrc'],
531
531
  actorConfigs,
532
532
  commits,
533
533
  });