apify-test-tools 0.10.2-beta.0 → 0.10.2-beta.10
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/.gitattributes +2 -0
- package/.github/actions/checkout-restore-dependencies/action.yaml +64 -27
- package/.github/cli/apify-test-tools.mjs +360 -0
- package/.github/scripts/check-major-tag-refs.mjs +1 -1
- package/.github/scripts/mask-config-secrets.sh +17 -0
- package/.github/scripts/run-with-apify-tokens.mjs +37 -12
- package/.github/workflows/_check_code.yaml +25 -0
- package/.github/workflows/_move_major_tag.yaml +3 -81
- package/.github/workflows/_tests.yaml +34 -0
- package/.github/workflows/_update_release_metadata.yaml +0 -12
- package/.github/workflows/manual_move_major_tag.yaml +3 -3
- package/.github/workflows/manual_release_stable.yaml +3 -13
- package/.github/workflows/on_master.yaml +9 -5
- package/.github/workflows/on_pull_request.yaml +3 -48
- package/.github/workflows/public_platform-tests-claude-investigate-and-fix.yaml +13 -2
- package/.github/workflows/public_platform-tests.yaml +24 -1
- package/.github/workflows/public_pr-build-test.yaml +62 -49
- package/.github/workflows/public_push-build-latest.yaml +41 -8
- package/.husky/pre-commit +5 -0
- package/.prettierignore +3 -0
- package/CHANGELOG.md +17 -0
- package/CONTRIBUTING.md +105 -21
- package/README.md +218 -597
- package/bin/affected-actors.ts +198 -0
- package/bin/build-from-local.ts +65 -13
- package/bin/build.ts +123 -41
- package/bin/diff-changes.ts +55 -25
- package/bin/diff-json-schema.ts +5 -6
- package/bin/git.ts +69 -99
- package/bin/main.ts +96 -122
- package/bin/slack.ts +43 -10
- package/bin/stdin-input.ts +65 -0
- package/bin/test-report.ts +6 -9
- package/bin/types.ts +16 -0
- package/dist/bin/affected-actors.d.ts +46 -0
- package/dist/bin/affected-actors.d.ts.map +1 -0
- package/dist/bin/affected-actors.js +135 -0
- package/dist/bin/affected-actors.js.map +1 -0
- package/dist/bin/build-from-local.d.ts +12 -3
- package/dist/bin/build-from-local.d.ts.map +1 -1
- package/dist/bin/build-from-local.js +34 -12
- package/dist/bin/build-from-local.js.map +1 -1
- package/dist/bin/build.d.ts +30 -7
- package/dist/bin/build.d.ts.map +1 -1
- package/dist/bin/build.js +85 -26
- package/dist/bin/build.js.map +1 -1
- package/dist/bin/diff-changes.d.ts +12 -4
- package/dist/bin/diff-changes.d.ts.map +1 -1
- package/dist/bin/diff-changes.js +31 -20
- package/dist/bin/diff-changes.js.map +1 -1
- package/dist/bin/diff-json-schema.d.ts +2 -2
- package/dist/bin/diff-json-schema.d.ts.map +1 -1
- package/dist/bin/diff-json-schema.js +1 -4
- package/dist/bin/diff-json-schema.js.map +1 -1
- package/dist/bin/git.d.ts +23 -21
- package/dist/bin/git.d.ts.map +1 -1
- package/dist/bin/git.js +60 -83
- package/dist/bin/git.js.map +1 -1
- package/dist/bin/main.js +82 -93
- package/dist/bin/main.js.map +1 -1
- package/dist/bin/slack.d.ts +14 -4
- package/dist/bin/slack.d.ts.map +1 -1
- package/dist/bin/slack.js +39 -6
- package/dist/bin/slack.js.map +1 -1
- package/dist/bin/stdin-input.d.ts +17 -0
- package/dist/bin/stdin-input.d.ts.map +1 -0
- package/dist/bin/stdin-input.js +54 -0
- package/dist/bin/stdin-input.js.map +1 -0
- package/dist/bin/test-report.d.ts.map +1 -1
- package/dist/bin/test-report.js +6 -8
- package/dist/bin/test-report.js.map +1 -1
- package/dist/bin/types.d.ts +14 -0
- package/dist/bin/types.d.ts.map +1 -1
- package/dist/lib/extend-expect.d.ts.map +1 -1
- package/dist/lib/extend-expect.js +37 -218
- package/dist/lib/extend-expect.js.map +1 -1
- package/dist/lib/lib.d.ts +1 -2
- package/dist/lib/lib.d.ts.map +1 -1
- package/dist/lib/lib.js +15 -22
- package/dist/lib/lib.js.map +1 -1
- package/dist/lib/run-checks.d.ts +14 -0
- package/dist/lib/run-checks.d.ts.map +1 -0
- package/dist/lib/run-checks.js +82 -0
- package/dist/lib/run-checks.js.map +1 -0
- package/dist/lib/run-test-result.d.ts +3 -6
- package/dist/lib/run-test-result.d.ts.map +1 -1
- package/dist/lib/run-test-result.js +41 -54
- package/dist/lib/run-test-result.js.map +1 -1
- package/dist/test/bundle/cli-bundle.test.d.ts +2 -0
- package/dist/test/bundle/cli-bundle.test.d.ts.map +1 -0
- package/dist/test/bundle/cli-bundle.test.js +190 -0
- package/dist/test/bundle/cli-bundle.test.js.map +1 -0
- package/dist/test/e2e/cli-bundle.e2e.test.d.ts +2 -0
- package/dist/test/e2e/cli-bundle.e2e.test.d.ts.map +1 -0
- package/dist/test/e2e/cli-bundle.e2e.test.js +138 -0
- package/dist/test/e2e/cli-bundle.e2e.test.js.map +1 -0
- package/dist/test/e2e/git-build-release.e2e.test.d.ts +2 -0
- package/dist/test/e2e/git-build-release.e2e.test.d.ts.map +1 -0
- package/dist/test/e2e/git-build-release.e2e.test.js +87 -0
- package/dist/test/e2e/git-build-release.e2e.test.js.map +1 -0
- package/dist/test/e2e/helpers.d.ts +37 -0
- package/dist/test/e2e/helpers.d.ts.map +1 -0
- package/dist/test/e2e/helpers.js +57 -0
- package/dist/test/e2e/helpers.js.map +1 -0
- package/dist/test/unit/bin/affected-actors-cli.test.d.ts +2 -0
- package/dist/test/unit/bin/affected-actors-cli.test.d.ts.map +1 -0
- package/dist/test/unit/bin/affected-actors-cli.test.js +167 -0
- package/dist/test/unit/bin/affected-actors-cli.test.js.map +1 -0
- package/dist/test/unit/bin/affected-actors.test.d.ts +2 -0
- package/dist/test/unit/bin/affected-actors.test.d.ts.map +1 -0
- package/dist/test/unit/bin/affected-actors.test.js +141 -0
- package/dist/test/unit/bin/affected-actors.test.js.map +1 -0
- package/dist/test/unit/bin/build-cli.test.d.ts +2 -0
- package/dist/test/unit/bin/build-cli.test.d.ts.map +1 -0
- package/dist/test/unit/bin/build-cli.test.js +44 -0
- package/dist/test/unit/bin/build-cli.test.js.map +1 -0
- package/dist/test/unit/bin/build-from-local.test.js +65 -1
- package/dist/test/unit/bin/build-from-local.test.js.map +1 -1
- package/dist/test/unit/bin/build.test.js +223 -3
- package/dist/test/unit/bin/build.test.js.map +1 -1
- package/dist/test/unit/bin/compiled-cli.d.ts +6 -0
- package/dist/test/unit/bin/compiled-cli.d.ts.map +1 -0
- package/dist/test/unit/bin/compiled-cli.js +16 -0
- package/dist/test/unit/bin/compiled-cli.js.map +1 -0
- package/dist/test/unit/bin/diff-changes.test.js +205 -85
- package/dist/test/unit/bin/diff-changes.test.js.map +1 -1
- package/dist/test/unit/bin/diff.test.js +25 -28
- package/dist/test/unit/bin/diff.test.js.map +1 -1
- package/dist/test/unit/bin/git.test.js +69 -152
- package/dist/test/unit/bin/git.test.js.map +1 -1
- package/dist/test/unit/bin/slack.test.d.ts +2 -0
- package/dist/test/unit/bin/slack.test.d.ts.map +1 -0
- package/dist/test/unit/bin/slack.test.js +71 -0
- package/dist/test/unit/bin/slack.test.js.map +1 -0
- package/dist/test/unit/bin/stdin-input.test.d.ts +2 -0
- package/dist/test/unit/bin/stdin-input.test.d.ts.map +1 -0
- package/dist/test/unit/bin/stdin-input.test.js +50 -0
- package/dist/test/unit/bin/stdin-input.test.js.map +1 -0
- package/dist/test/unit/github-scripts/mask-config-secrets.test.d.ts +2 -0
- package/dist/test/unit/github-scripts/mask-config-secrets.test.d.ts.map +1 -0
- package/dist/test/unit/github-scripts/mask-config-secrets.test.js +50 -0
- package/dist/test/unit/github-scripts/mask-config-secrets.test.js.map +1 -0
- package/dist/test/unit/github-scripts/run-with-apify-tokens.test.d.ts +2 -0
- package/dist/test/unit/github-scripts/run-with-apify-tokens.test.d.ts.map +1 -0
- package/dist/test/unit/github-scripts/run-with-apify-tokens.test.js +102 -0
- package/dist/test/unit/github-scripts/run-with-apify-tokens.test.js.map +1 -0
- package/dist/test/unit/run-checks.test.d.ts +2 -0
- package/dist/test/unit/run-checks.test.d.ts.map +1 -0
- package/dist/test/unit/run-checks.test.js +62 -0
- package/dist/test/unit/run-checks.test.js.map +1 -0
- package/dist/test/unit/run-test-result.test.d.ts +2 -0
- package/dist/test/unit/run-test-result.test.d.ts.map +1 -0
- package/dist/test/unit/run-test-result.test.js +34 -0
- package/dist/test/unit/run-test-result.test.js.map +1 -0
- package/dist/test/unit/should-built-and-test.test.js +41 -38
- package/dist/test/unit/should-built-and-test.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/docs/cli.md +373 -0
- package/docs/lib.md +271 -0
- package/docs/workflows.md +367 -0
- package/lib/extend-expect.ts +48 -258
- package/lib/lib.ts +24 -28
- package/lib/run-checks.ts +101 -0
- package/lib/run-test-result.ts +45 -55
- package/package.json +15 -3
- package/test/bundle/cli-bundle.test.ts +235 -0
- package/test/e2e/cli-bundle.e2e.test.ts +207 -0
- package/test/e2e/git-build-release.e2e.test.ts +113 -0
- package/test/e2e/helpers.ts +82 -0
- package/test/unit/bin/affected-actors-cli.test.ts +201 -0
- package/test/unit/bin/affected-actors.test.ts +182 -0
- package/test/unit/bin/build-cli.test.ts +55 -0
- package/test/unit/bin/build-from-local.test.ts +71 -0
- package/test/unit/bin/build.test.ts +279 -3
- package/test/unit/bin/compiled-cli.ts +17 -0
- package/test/unit/bin/diff-changes.test.ts +229 -85
- package/test/unit/bin/diff.test.ts +25 -28
- package/test/unit/bin/git.test.ts +85 -176
- package/test/unit/bin/slack.test.ts +84 -0
- package/test/unit/bin/stdin-input.test.ts +61 -0
- package/test/unit/github-scripts/mask-config-secrets.test.ts +61 -0
- package/test/unit/github-scripts/run-with-apify-tokens.test.ts +115 -0
- package/test/unit/run-checks.test.ts +76 -0
- package/test/unit/run-test-result.test.ts +44 -0
- package/test/unit/should-built-and-test.test.ts +46 -39
- package/.github/scripts/check-package-version-bump.mjs +0 -74
- package/.github/workflows-package-version +0 -1
|
@@ -39,90 +39,97 @@ const amazonActor = actorConfig('junglee/amazon-crawler', 'actors/junglee_Amazon
|
|
|
39
39
|
'code',
|
|
40
40
|
'shared',
|
|
41
41
|
]);
|
|
42
|
-
const
|
|
42
|
+
const range = { fromRef: 'Commit0', toRef: 'Commit1' };
|
|
43
|
+
// What a PR (functional changes only) or a release (isLatest, all changes) builds, in config order
|
|
44
|
+
const changedActorsFor = async ({ isLatest = false, ...options }) => {
|
|
45
|
+
const { functional, cosmetic } = await getChangedActors(options);
|
|
46
|
+
const changed = isLatest ? [...functional, ...cosmetic] : functional;
|
|
47
|
+
return options.actorConfigs.filter((config) => changed.includes(config));
|
|
48
|
+
};
|
|
43
49
|
describe('getChangedActors', () => {
|
|
44
50
|
beforeEach(() => {
|
|
51
|
+
vi.restoreAllMocks();
|
|
45
52
|
vi.spyOn(DiffJsonSchema, 'isCosmeticOnlyJsonSchemaChange').mockResolvedValue(false);
|
|
46
53
|
});
|
|
47
54
|
it('returns empty array when no files changed', async () => {
|
|
48
|
-
expect(await
|
|
55
|
+
expect(await changedActorsFor({ filepathsChanged: [], actorConfigs, range })).toEqual([]);
|
|
49
56
|
});
|
|
50
57
|
it('returns empty array when only ignored top-level files changed', async () => {
|
|
51
|
-
const result = await
|
|
58
|
+
const result = await changedActorsFor({
|
|
52
59
|
filepathsChanged: ['.gitignore', 'README.md', '.husky/pre-commit', '.vscode/settings.json'],
|
|
53
60
|
actorConfigs,
|
|
54
|
-
|
|
61
|
+
range,
|
|
55
62
|
});
|
|
56
63
|
expect(result).toEqual([]);
|
|
57
64
|
});
|
|
58
65
|
it('does not ignore source files whose names contain an ignored file name', async () => {
|
|
59
|
-
const result = await
|
|
66
|
+
const result = await changedActorsFor({
|
|
60
67
|
filepathsChanged: ['actors/foo_bar/src/.gitignore-helper.ts'],
|
|
61
68
|
actorConfigs,
|
|
62
|
-
|
|
69
|
+
range,
|
|
63
70
|
});
|
|
64
71
|
expect(result).toEqual([miniActor]);
|
|
65
72
|
});
|
|
66
73
|
it('returns the actor when a functional file in its folder changes', async () => {
|
|
67
|
-
const result = await
|
|
74
|
+
const result = await changedActorsFor({
|
|
68
75
|
filepathsChanged: ['actors/foo_bar/src/main.ts'],
|
|
69
76
|
actorConfigs,
|
|
70
|
-
|
|
77
|
+
range,
|
|
71
78
|
});
|
|
72
79
|
expect(result).toEqual([miniActor]);
|
|
73
80
|
});
|
|
74
81
|
it('returns actor when isLatest and README in actor folder changed (cosmetic)', async () => {
|
|
75
|
-
const result = await
|
|
82
|
+
const result = await changedActorsFor({
|
|
76
83
|
filepathsChanged: ['actors/foo_bar/README.md'],
|
|
77
84
|
actorConfigs,
|
|
78
|
-
|
|
85
|
+
range,
|
|
79
86
|
isLatest: true,
|
|
80
87
|
});
|
|
81
88
|
expect(result).toEqual([miniActor]);
|
|
82
89
|
});
|
|
83
90
|
it('does not return actor when not isLatest and only README changed (cosmetic)', async () => {
|
|
84
|
-
const result = await
|
|
91
|
+
const result = await changedActorsFor({
|
|
85
92
|
filepathsChanged: ['actors/foo_bar/README.md'],
|
|
86
93
|
actorConfigs,
|
|
87
|
-
|
|
94
|
+
range,
|
|
88
95
|
isLatest: false,
|
|
89
96
|
});
|
|
90
97
|
expect(result).toEqual([]);
|
|
91
98
|
});
|
|
92
99
|
it('returns actor when isLatest and JSON file has only cosmetic changes', async () => {
|
|
93
100
|
vi.spyOn(DiffJsonSchema, 'isCosmeticOnlyJsonSchemaChange').mockResolvedValue(true);
|
|
94
|
-
const result = await
|
|
101
|
+
const result = await changedActorsFor({
|
|
95
102
|
filepathsChanged: ['actors/foo_bar/.actor/actor.json'],
|
|
96
103
|
actorConfigs,
|
|
97
|
-
|
|
104
|
+
range,
|
|
98
105
|
isLatest: true,
|
|
99
106
|
});
|
|
100
107
|
expect(result).toEqual([miniActor]);
|
|
101
108
|
});
|
|
102
109
|
it('does not return actor when not isLatest and JSON file has only cosmetic changes', async () => {
|
|
103
110
|
vi.spyOn(DiffJsonSchema, 'isCosmeticOnlyJsonSchemaChange').mockResolvedValue(true);
|
|
104
|
-
const result = await
|
|
111
|
+
const result = await changedActorsFor({
|
|
105
112
|
filepathsChanged: ['actors/foo_bar/.actor/actor.json'],
|
|
106
113
|
actorConfigs,
|
|
107
|
-
|
|
114
|
+
range,
|
|
108
115
|
isLatest: false,
|
|
109
116
|
});
|
|
110
117
|
expect(result).toEqual([]);
|
|
111
118
|
});
|
|
112
119
|
it('returns actor when JSON file has functional changes', async () => {
|
|
113
|
-
const result = await
|
|
120
|
+
const result = await changedActorsFor({
|
|
114
121
|
filepathsChanged: ['actors/foo_bar/.actor/actor.json'],
|
|
115
122
|
actorConfigs,
|
|
116
|
-
|
|
123
|
+
range,
|
|
117
124
|
});
|
|
118
125
|
expect(result).toEqual([miniActor]);
|
|
119
126
|
});
|
|
120
127
|
it('JSON file in actor folder but outside .actor/ is functional, not checked for cosmetic', async () => {
|
|
121
128
|
vi.spyOn(DiffJsonSchema, 'isCosmeticOnlyJsonSchemaChange').mockResolvedValue(true);
|
|
122
|
-
const result = await
|
|
129
|
+
const result = await changedActorsFor({
|
|
123
130
|
filepathsChanged: ['actors/foo_bar/package.json'],
|
|
124
131
|
actorConfigs,
|
|
125
|
-
|
|
132
|
+
range,
|
|
126
133
|
isLatest: false,
|
|
127
134
|
});
|
|
128
135
|
expect(result).toEqual([miniActor]);
|
|
@@ -130,48 +137,48 @@ describe('getChangedActors', () => {
|
|
|
130
137
|
});
|
|
131
138
|
it('JSON file under .actor/ inside actor folder is checked for cosmetic changes', async () => {
|
|
132
139
|
vi.spyOn(DiffJsonSchema, 'isCosmeticOnlyJsonSchemaChange').mockResolvedValue(true);
|
|
133
|
-
const result = await
|
|
140
|
+
const result = await changedActorsFor({
|
|
134
141
|
filepathsChanged: ['actors/foo_bar/.actor/input_schema.json'],
|
|
135
142
|
actorConfigs,
|
|
136
|
-
|
|
143
|
+
range,
|
|
137
144
|
isLatest: false,
|
|
138
145
|
});
|
|
139
146
|
expect(result).toEqual([]);
|
|
140
|
-
expect(DiffJsonSchema.isCosmeticOnlyJsonSchemaChange).toHaveBeenCalledWith(
|
|
147
|
+
expect(DiffJsonSchema.isCosmeticOnlyJsonSchemaChange).toHaveBeenCalledWith(range, 'actors/foo_bar/.actor/input_schema.json');
|
|
141
148
|
});
|
|
142
149
|
it('does not trigger narrow-context actor when shared file changes', async () => {
|
|
143
|
-
const result = await
|
|
150
|
+
const result = await changedActorsFor({
|
|
144
151
|
filepathsChanged: ['shared/utils.ts'],
|
|
145
152
|
actorConfigs,
|
|
146
|
-
|
|
153
|
+
range,
|
|
147
154
|
});
|
|
148
155
|
expect(result).toContainEqual(miniActor);
|
|
149
156
|
expect(result).not.toContainEqual(standaloneActor);
|
|
150
157
|
});
|
|
151
158
|
it('root-level changelog outside any actor folder is cosmetic for every actor when isLatest', async () => {
|
|
152
|
-
const result = await
|
|
159
|
+
const result = await changedActorsFor({
|
|
153
160
|
filepathsChanged: ['CHANGELOG.md'],
|
|
154
161
|
actorConfigs,
|
|
155
|
-
|
|
162
|
+
range,
|
|
156
163
|
isLatest: true,
|
|
157
164
|
});
|
|
158
165
|
expect(result).toEqual(expect.arrayContaining([miniActor, standaloneActor]));
|
|
159
166
|
expect(result).toHaveLength(2);
|
|
160
167
|
});
|
|
161
168
|
it('root-level changelog is not cosmetic-triggered when not isLatest', async () => {
|
|
162
|
-
const result = await
|
|
169
|
+
const result = await changedActorsFor({
|
|
163
170
|
filepathsChanged: ['CHANGELOG.md'],
|
|
164
171
|
actorConfigs,
|
|
165
|
-
|
|
172
|
+
range,
|
|
166
173
|
isLatest: false,
|
|
167
174
|
});
|
|
168
175
|
expect(result).toEqual([]);
|
|
169
176
|
});
|
|
170
177
|
it('treats any changelog filename as cosmetic regardless of configured paths', async () => {
|
|
171
|
-
const result = await
|
|
178
|
+
const result = await changedActorsFor({
|
|
172
179
|
filepathsChanged: ['docs/CHANGELOG.md'],
|
|
173
180
|
actorConfigs: [miniActor, standaloneActor],
|
|
174
|
-
|
|
181
|
+
range,
|
|
175
182
|
isLatest: true,
|
|
176
183
|
});
|
|
177
184
|
expect(result).toEqual([miniActor, standaloneActor]);
|
|
@@ -181,63 +188,63 @@ describe('getChangedActors', () => {
|
|
|
181
188
|
...standaloneActor,
|
|
182
189
|
actorJson: { ...standaloneActor.actorJson, readme: new RelativeFile('docs/guide.md') },
|
|
183
190
|
};
|
|
184
|
-
const result = await
|
|
191
|
+
const result = await changedActorsFor({
|
|
185
192
|
filepathsChanged: ['docs/guide.md'],
|
|
186
193
|
actorConfigs: [configuredActor],
|
|
187
|
-
|
|
194
|
+
range,
|
|
188
195
|
isLatest: true,
|
|
189
196
|
});
|
|
190
197
|
expect(result).toEqual([]);
|
|
191
198
|
});
|
|
192
199
|
it('triggers narrow-context actor when its own folder changes', async () => {
|
|
193
|
-
const result = await
|
|
200
|
+
const result = await changedActorsFor({
|
|
194
201
|
filepathsChanged: ['standalone-actors/standalone/src/main.ts'],
|
|
195
202
|
actorConfigs,
|
|
196
|
-
|
|
203
|
+
range,
|
|
197
204
|
});
|
|
198
205
|
expect(result).toContainEqual(standaloneActor);
|
|
199
206
|
});
|
|
200
207
|
it('deduplicates actors when multiple files in same actor folder change', async () => {
|
|
201
|
-
const result = await
|
|
208
|
+
const result = await changedActorsFor({
|
|
202
209
|
filepathsChanged: ['actors/foo_bar/src/main.ts', 'actors/foo_bar/package.json'],
|
|
203
210
|
actorConfigs,
|
|
204
|
-
|
|
211
|
+
range,
|
|
205
212
|
});
|
|
206
213
|
expect(result).toHaveLength(1);
|
|
207
214
|
expect(result).toContainEqual(miniActor);
|
|
208
215
|
});
|
|
209
216
|
it('handles mixed changes: returns both broad and narrow-context actors', async () => {
|
|
210
|
-
const result = await
|
|
217
|
+
const result = await changedActorsFor({
|
|
211
218
|
filepathsChanged: ['actors/foo_bar/src/main.ts', 'standalone-actors/standalone/Dockerfile'],
|
|
212
219
|
actorConfigs,
|
|
213
|
-
|
|
220
|
+
range,
|
|
214
221
|
});
|
|
215
222
|
expect(result).toContainEqual(miniActor);
|
|
216
223
|
expect(result).toContainEqual(standaloneActor);
|
|
217
224
|
});
|
|
218
225
|
it('matches folder where folder name differs from actor name', async () => {
|
|
219
226
|
const ownerlessActor = actorConfig('myteam/shopify-scraper', 'actors/shopify', 'APIFY_TOKEN_MYTEAM', '', ['']);
|
|
220
|
-
const result = await
|
|
227
|
+
const result = await changedActorsFor({
|
|
221
228
|
filepathsChanged: ['actors/shopify/src/main.ts'],
|
|
222
229
|
actorConfigs: [ownerlessActor],
|
|
223
|
-
|
|
230
|
+
range,
|
|
224
231
|
});
|
|
225
232
|
expect(result).toEqual([ownerlessActor]);
|
|
226
233
|
});
|
|
227
234
|
it('in single-actor repo, .actor/ changes trigger builds', async () => {
|
|
228
235
|
const rootActor = actorConfig('myteam/my-actor', '', 'BUILDER_APIFY_TOKEN', '', ['']);
|
|
229
|
-
const result = await
|
|
236
|
+
const result = await changedActorsFor({
|
|
230
237
|
filepathsChanged: ['.actor/actor.json'],
|
|
231
238
|
actorConfigs: [rootActor],
|
|
232
|
-
|
|
239
|
+
range,
|
|
233
240
|
});
|
|
234
241
|
expect(result).toEqual([rootActor]);
|
|
235
242
|
});
|
|
236
243
|
it('in multi-actor repo, .actor/ changes only trigger broad-context actors', async () => {
|
|
237
|
-
const result = await
|
|
244
|
+
const result = await changedActorsFor({
|
|
238
245
|
filepathsChanged: ['.actor/actor.json'],
|
|
239
246
|
actorConfigs,
|
|
240
|
-
|
|
247
|
+
range,
|
|
241
248
|
});
|
|
242
249
|
expect(result).toEqual([miniActor]);
|
|
243
250
|
});
|
|
@@ -245,38 +252,38 @@ describe('getChangedActors', () => {
|
|
|
245
252
|
const narrowActor = actorConfig('foo/bar', 'actors/foo_bar', 'APIFY_TOKEN_FOO', 'actors/foo_bar', [
|
|
246
253
|
'actors/foo_bar',
|
|
247
254
|
]);
|
|
248
|
-
const result = await
|
|
255
|
+
const result = await changedActorsFor({
|
|
249
256
|
filepathsChanged: ['Actors/FOO_BAR/Main.ts'],
|
|
250
257
|
actorConfigs: [narrowActor],
|
|
251
|
-
|
|
258
|
+
range,
|
|
252
259
|
});
|
|
253
260
|
expect(result).toEqual([]);
|
|
254
261
|
});
|
|
255
262
|
it('triggers actor with contextPaths override when file matches an override path', async () => {
|
|
256
263
|
const overrideActor = actorConfig('team/override-actor', 'actors/override', 'APIFY_TOKEN_TEAM', 'actors/override', ['actors/override', 'packages']);
|
|
257
|
-
const result = await
|
|
264
|
+
const result = await changedActorsFor({
|
|
258
265
|
filepathsChanged: ['packages/shared/utils.ts'],
|
|
259
266
|
actorConfigs: [overrideActor],
|
|
260
|
-
|
|
267
|
+
range,
|
|
261
268
|
});
|
|
262
269
|
expect(result).toEqual([overrideActor]);
|
|
263
270
|
});
|
|
264
271
|
it('does not trigger actor with contextPaths override when file is outside all override paths', async () => {
|
|
265
272
|
const overrideActor = actorConfig('team/override-actor', 'actors/override', 'APIFY_TOKEN_TEAM', 'actors/override', ['actors/override', 'packages']);
|
|
266
|
-
const result = await
|
|
273
|
+
const result = await changedActorsFor({
|
|
267
274
|
filepathsChanged: ['other-dir/file.ts'],
|
|
268
275
|
actorConfigs: [overrideActor],
|
|
269
|
-
|
|
276
|
+
range,
|
|
270
277
|
});
|
|
271
278
|
expect(result).toEqual([]);
|
|
272
279
|
});
|
|
273
280
|
it('broad-context actor skips files in sibling actor folders', async () => {
|
|
274
281
|
const actorA = actorConfig('team/actor-a', 'actors/a', 'APIFY_TOKEN_TEAM', '', ['']);
|
|
275
282
|
const actorB = actorConfig('team/actor-b', 'actors/b', 'APIFY_TOKEN_TEAM', '', ['']);
|
|
276
|
-
const result = await
|
|
283
|
+
const result = await changedActorsFor({
|
|
277
284
|
filepathsChanged: ['actors/b/src/main.ts'],
|
|
278
285
|
actorConfigs: [actorA, actorB],
|
|
279
|
-
|
|
286
|
+
range,
|
|
280
287
|
});
|
|
281
288
|
expect(result).toEqual([actorB]);
|
|
282
289
|
});
|
|
@@ -285,10 +292,10 @@ describe('getChangedActors', () => {
|
|
|
285
292
|
const childActor = actorConfig('team/child', 'actors/child', 'APIFY_TOKEN_TEAM', 'actors/child', [
|
|
286
293
|
'actors/child',
|
|
287
294
|
]);
|
|
288
|
-
const result = await
|
|
295
|
+
const result = await changedActorsFor({
|
|
289
296
|
filepathsChanged: ['actors/child/src/main.ts'],
|
|
290
297
|
actorConfigs: [rootActor, childActor],
|
|
291
|
-
|
|
298
|
+
range,
|
|
292
299
|
});
|
|
293
300
|
expect(result).not.toContainEqual(rootActor);
|
|
294
301
|
expect(result).toContainEqual(childActor);
|
|
@@ -298,95 +305,154 @@ describe('getChangedActors', () => {
|
|
|
298
305
|
const childActor = actorConfig('team/child', 'actors/child', 'APIFY_TOKEN_TEAM', 'actors/child', [
|
|
299
306
|
'actors/child',
|
|
300
307
|
]);
|
|
301
|
-
const result = await
|
|
308
|
+
const result = await changedActorsFor({
|
|
302
309
|
filepathsChanged: ['lib/shared-utils.ts'],
|
|
303
310
|
actorConfigs: [rootActor, childActor],
|
|
304
|
-
|
|
311
|
+
range,
|
|
305
312
|
});
|
|
306
313
|
expect(result).toContainEqual(rootActor);
|
|
307
314
|
expect(result).not.toContainEqual(childActor);
|
|
308
315
|
});
|
|
309
316
|
it('file matched by .dockerignore is treated as ignored', async () => {
|
|
310
317
|
vi.spyOn(Dockerignore, 'loadDockerIgnore').mockReturnValue((filePath) => filePath === 'actors/foo_bar/node_modules/foo.js');
|
|
311
|
-
const result = await
|
|
318
|
+
const result = await changedActorsFor({
|
|
312
319
|
filepathsChanged: ['actors/foo_bar/node_modules/foo.js'],
|
|
313
320
|
actorConfigs: [miniActor],
|
|
314
|
-
|
|
321
|
+
range,
|
|
315
322
|
});
|
|
316
323
|
expect(result).toEqual([]);
|
|
317
324
|
});
|
|
318
325
|
it('file not matched by .dockerignore is classified normally', async () => {
|
|
319
326
|
vi.spyOn(Dockerignore, 'loadDockerIgnore').mockReturnValue((filePath) => filePath.includes('node_modules'));
|
|
320
|
-
const result = await
|
|
327
|
+
const result = await changedActorsFor({
|
|
321
328
|
filepathsChanged: ['actors/foo_bar/src/main.ts'],
|
|
322
329
|
actorConfigs: [miniActor],
|
|
323
|
-
|
|
330
|
+
range,
|
|
331
|
+
});
|
|
332
|
+
expect(result).toEqual([miniActor]);
|
|
333
|
+
});
|
|
334
|
+
it('test file listed in .dockerignore triggers a build when it matches the test files glob', async () => {
|
|
335
|
+
vi.spyOn(Dockerignore, 'loadDockerIgnore').mockReturnValue((filePath) => filePath.startsWith('test/'));
|
|
336
|
+
const result = await changedActorsFor({
|
|
337
|
+
filepathsChanged: ['test/platform/daily/foo.test.ts'],
|
|
338
|
+
actorConfigs: [miniActor],
|
|
339
|
+
range,
|
|
340
|
+
testFilesGlob: 'test/platform/**',
|
|
341
|
+
});
|
|
342
|
+
expect(result).toEqual([miniActor]);
|
|
343
|
+
});
|
|
344
|
+
it('test file listed in .dockerignore stays ignored without a test files glob', async () => {
|
|
345
|
+
vi.spyOn(Dockerignore, 'loadDockerIgnore').mockReturnValue((filePath) => filePath.startsWith('test/'));
|
|
346
|
+
const result = await changedActorsFor({
|
|
347
|
+
filepathsChanged: ['test/platform/daily/foo.test.ts'],
|
|
348
|
+
actorConfigs: [miniActor],
|
|
349
|
+
range,
|
|
350
|
+
});
|
|
351
|
+
expect(result).toEqual([]);
|
|
352
|
+
});
|
|
353
|
+
it('test files glob matches case-insensitively and does not bypass .dockerignore for other files', async () => {
|
|
354
|
+
vi.spyOn(Dockerignore, 'loadDockerIgnore').mockReturnValue(() => true);
|
|
355
|
+
const result = await changedActorsFor({
|
|
356
|
+
filepathsChanged: ['Test/Platform/Foo.test.ts'],
|
|
357
|
+
actorConfigs: [miniActor],
|
|
358
|
+
range,
|
|
359
|
+
testFilesGlob: 'test/platform/**',
|
|
324
360
|
});
|
|
325
361
|
expect(result).toEqual([miniActor]);
|
|
362
|
+
expect(await changedActorsFor({
|
|
363
|
+
filepathsChanged: ['actors/foo_bar/node_modules/foo.js'],
|
|
364
|
+
actorConfigs: [miniActor],
|
|
365
|
+
range,
|
|
366
|
+
testFilesGlob: 'test/platform/**',
|
|
367
|
+
})).toEqual([]);
|
|
368
|
+
});
|
|
369
|
+
it('test file outside an actor context still does not trigger it', async () => {
|
|
370
|
+
vi.spyOn(Dockerignore, 'loadDockerIgnore').mockReturnValue(() => true);
|
|
371
|
+
const result = await changedActorsFor({
|
|
372
|
+
filepathsChanged: ['test/platform/daily/foo.test.ts'],
|
|
373
|
+
actorConfigs: [standaloneActor],
|
|
374
|
+
range,
|
|
375
|
+
testFilesGlob: 'test/platform/**',
|
|
376
|
+
});
|
|
377
|
+
expect(result).toEqual([]);
|
|
378
|
+
});
|
|
379
|
+
it('test file listed in .dockerignore triggers an actor whose overrideActorContext includes it', async () => {
|
|
380
|
+
vi.spyOn(Dockerignore, 'loadDockerIgnore').mockReturnValue(() => true);
|
|
381
|
+
const actorWithTests = {
|
|
382
|
+
...standaloneActor,
|
|
383
|
+
contextPaths: [...standaloneActor.contextPaths, new RelativeDir('test')],
|
|
384
|
+
};
|
|
385
|
+
const result = await changedActorsFor({
|
|
386
|
+
filepathsChanged: ['test/platform/standalone.test.ts'],
|
|
387
|
+
actorConfigs: [actorWithTests],
|
|
388
|
+
range,
|
|
389
|
+
testFilesGlob: 'test/platform/**',
|
|
390
|
+
});
|
|
391
|
+
expect(result).toEqual([actorWithTests]);
|
|
326
392
|
});
|
|
327
393
|
it('JSON file in context but outside actor folder is functional (not checked for cosmetic)', async () => {
|
|
328
|
-
const result = await
|
|
394
|
+
const result = await changedActorsFor({
|
|
329
395
|
filepathsChanged: ['lib/config.json'],
|
|
330
396
|
actorConfigs: [miniActor],
|
|
331
|
-
|
|
397
|
+
range,
|
|
332
398
|
});
|
|
333
399
|
expect(result).toEqual([miniActor]);
|
|
334
400
|
});
|
|
335
401
|
it('README outside actor folder but inside context is ignored (not cosmetic)', async () => {
|
|
336
|
-
const result = await
|
|
402
|
+
const result = await changedActorsFor({
|
|
337
403
|
filepathsChanged: ['docs/README.md'],
|
|
338
404
|
actorConfigs: [miniActor],
|
|
339
|
-
|
|
405
|
+
range,
|
|
340
406
|
isLatest: true,
|
|
341
407
|
});
|
|
342
408
|
expect(result).toEqual([]);
|
|
343
409
|
});
|
|
344
410
|
it('README inside actor folder is cosmetic', async () => {
|
|
345
|
-
const result = await
|
|
411
|
+
const result = await changedActorsFor({
|
|
346
412
|
filepathsChanged: ['actors/foo_bar/README.md'],
|
|
347
413
|
actorConfigs: [miniActor],
|
|
348
|
-
|
|
414
|
+
range,
|
|
349
415
|
isLatest: true,
|
|
350
416
|
});
|
|
351
417
|
expect(result).toEqual([miniActor]);
|
|
352
418
|
});
|
|
353
419
|
it('ignores a standalone actor top-level dev file relative to its context', async () => {
|
|
354
|
-
const result = await
|
|
420
|
+
const result = await changedActorsFor({
|
|
355
421
|
filepathsChanged: ['standalone-actors/standalone/.eslintrc'],
|
|
356
422
|
actorConfigs,
|
|
357
|
-
|
|
423
|
+
range,
|
|
358
424
|
});
|
|
359
425
|
expect(result).toEqual([]);
|
|
360
426
|
});
|
|
361
427
|
it('does not special-case code/ and shared/ prefixes anymore — must be declared via overrideActorContext', async () => {
|
|
362
|
-
const result = await
|
|
428
|
+
const result = await changedActorsFor({
|
|
363
429
|
filepathsChanged: ['code/some/code.ts'],
|
|
364
430
|
actorConfigs: [miniActor],
|
|
365
|
-
|
|
431
|
+
range,
|
|
366
432
|
});
|
|
367
433
|
expect(result).toEqual([miniActor]);
|
|
368
434
|
});
|
|
369
435
|
it('ignores code/.eslintrc when "code" is declared via overrideActorContext', async () => {
|
|
370
|
-
const result = await
|
|
436
|
+
const result = await changedActorsFor({
|
|
371
437
|
filepathsChanged: ['code/.eslintrc'],
|
|
372
438
|
actorConfigs: [amazonActor],
|
|
373
|
-
|
|
439
|
+
range,
|
|
374
440
|
});
|
|
375
441
|
expect(result).toEqual([]);
|
|
376
442
|
});
|
|
377
443
|
it('shared/Dockerfile declared via overrideActorContext is functional', async () => {
|
|
378
|
-
const result = await
|
|
444
|
+
const result = await changedActorsFor({
|
|
379
445
|
filepathsChanged: ['shared/Dockerfile'],
|
|
380
446
|
actorConfigs: [amazonActor],
|
|
381
|
-
|
|
447
|
+
range,
|
|
382
448
|
});
|
|
383
449
|
expect(result).toEqual([amazonActor]);
|
|
384
450
|
});
|
|
385
451
|
it('code/README.md declared via overrideActorContext is ignored (outside actor folder)', async () => {
|
|
386
|
-
const result = await
|
|
452
|
+
const result = await changedActorsFor({
|
|
387
453
|
filepathsChanged: ['code/README.md'],
|
|
388
454
|
actorConfigs: [amazonActor],
|
|
389
|
-
|
|
455
|
+
range,
|
|
390
456
|
isLatest: true,
|
|
391
457
|
});
|
|
392
458
|
expect(result).toEqual([]);
|
|
@@ -396,15 +462,17 @@ describe('getChangedActors logging', () => {
|
|
|
396
462
|
beforeEach(() => {
|
|
397
463
|
vi.spyOn(DiffJsonSchema, 'isCosmeticOnlyJsonSchemaChange').mockResolvedValue(false);
|
|
398
464
|
vi.spyOn(logger, 'info').mockImplementation(() => undefined);
|
|
465
|
+
vi.spyOn(logger, 'warn').mockImplementation(() => undefined);
|
|
399
466
|
});
|
|
400
467
|
it('logs a single "specific" group for a single actor with one functional file', async () => {
|
|
401
468
|
await getChangedActors({
|
|
402
469
|
filepathsChanged: ['actors/foo_bar/src/main.ts'],
|
|
403
470
|
actorConfigs: [miniActor],
|
|
404
|
-
|
|
471
|
+
range,
|
|
405
472
|
});
|
|
406
473
|
expect(logger.info).toHaveBeenCalledWith('[DIFF]: Changes specific to actor foo/bar: actors/foo_bar/src/main.ts');
|
|
407
|
-
expect(logger.info).toHaveBeenCalledWith('[DIFF]: Actors
|
|
474
|
+
expect(logger.info).toHaveBeenCalledWith('[DIFF]: Actors with functional changes: foo/bar');
|
|
475
|
+
expect(logger.info).toHaveBeenCalledWith('[DIFF]: Actors with only cosmetic changes: none');
|
|
408
476
|
});
|
|
409
477
|
it('logs a single "shared" group when two actors are triggered by the exact same file', async () => {
|
|
410
478
|
const actorA = actorConfig('team/actor-a', 'actors/a', 'APIFY_TOKEN_TEAM', '', ['', 'shared']);
|
|
@@ -412,11 +480,11 @@ describe('getChangedActors logging', () => {
|
|
|
412
480
|
await getChangedActors({
|
|
413
481
|
filepathsChanged: ['shared/shared.ts'],
|
|
414
482
|
actorConfigs: [actorA, actorB],
|
|
415
|
-
|
|
483
|
+
range,
|
|
416
484
|
});
|
|
417
485
|
expect(logger.info).toHaveBeenCalledWith('[DIFF]: Shared changes for actors team/actor-a, team/actor-b: shared/shared.ts');
|
|
418
486
|
expect(logger.info).not.toHaveBeenCalledWith(expect.stringContaining('Changes specific to actor'));
|
|
419
|
-
expect(logger.info).toHaveBeenCalledWith('[DIFF]: Actors
|
|
487
|
+
expect(logger.info).toHaveBeenCalledWith('[DIFF]: Actors with functional changes: team/actor-a, team/actor-b');
|
|
420
488
|
});
|
|
421
489
|
it('logs shared and specific groups in descending-size order for partial overlap across actors', async () => {
|
|
422
490
|
const actorA = actorConfig('team/actor-a', 'actors/a', 'APIFY_TOKEN_TEAM', '', ['']);
|
|
@@ -424,25 +492,77 @@ describe('getChangedActors logging', () => {
|
|
|
424
492
|
await getChangedActors({
|
|
425
493
|
filepathsChanged: ['shared.ts', 'actors/a/a-only.ts', 'actors/b/b-only.ts'],
|
|
426
494
|
actorConfigs: [actorA, actorB],
|
|
427
|
-
|
|
495
|
+
range,
|
|
428
496
|
});
|
|
429
497
|
const errorCalls = vi.mocked(logger.info).mock.calls.map((call) => call[0]);
|
|
430
498
|
expect(errorCalls).toEqual([
|
|
431
499
|
'[DIFF]: Shared changes for actors team/actor-a, team/actor-b: shared.ts',
|
|
432
500
|
'[DIFF]: Changes specific to actor team/actor-a: actors/a/a-only.ts',
|
|
433
501
|
'[DIFF]: Changes specific to actor team/actor-b: actors/b/b-only.ts',
|
|
434
|
-
'[DIFF]: Actors
|
|
502
|
+
'[DIFF]: Actors with functional changes: team/actor-a, team/actor-b',
|
|
503
|
+
'[DIFF]: Actors with only cosmetic changes: none',
|
|
435
504
|
]);
|
|
436
505
|
});
|
|
506
|
+
const outsideContextWarning = (testFile) => `[DIFF]: Test file ${testFile} is outside every Actor's context, so changing only it builds and tests nothing. ` +
|
|
507
|
+
'Add its folder to "overrideActorContext" of the Actors it tests.';
|
|
508
|
+
it('warns about a changed test file outside every Actor context', async () => {
|
|
509
|
+
await getChangedActors({
|
|
510
|
+
filepathsChanged: ['test/platform/standalone.test.ts'],
|
|
511
|
+
actorConfigs: [standaloneActor],
|
|
512
|
+
range,
|
|
513
|
+
testFilesGlob: 'test/platform/**',
|
|
514
|
+
});
|
|
515
|
+
expect(logger.warn).toHaveBeenCalledWith(outsideContextWarning('test/platform/standalone.test.ts'));
|
|
516
|
+
});
|
|
517
|
+
it('still warns when the same push also rebuilds an Actor', async () => {
|
|
518
|
+
const result = await changedActorsFor({
|
|
519
|
+
filepathsChanged: ['test/platform/standalone.test.ts', 'standalone-actors/standalone/src/main.ts'],
|
|
520
|
+
actorConfigs: [standaloneActor],
|
|
521
|
+
range,
|
|
522
|
+
testFilesGlob: 'test/platform/**',
|
|
523
|
+
});
|
|
524
|
+
expect(result).toEqual([standaloneActor]);
|
|
525
|
+
expect(logger.warn).toHaveBeenCalledWith(outsideContextWarning('test/platform/standalone.test.ts'));
|
|
526
|
+
});
|
|
527
|
+
it('does not warn about test files inside an Actor context, even cosmetic ones', async () => {
|
|
528
|
+
await getChangedActors({
|
|
529
|
+
filepathsChanged: ['test/platform/foo.test.ts', 'test/platform/README.md', 'test/platform/CHANGELOG.md'],
|
|
530
|
+
actorConfigs: [miniActor],
|
|
531
|
+
range,
|
|
532
|
+
testFilesGlob: 'test/platform/**',
|
|
533
|
+
});
|
|
534
|
+
expect(logger.warn).not.toHaveBeenCalled();
|
|
535
|
+
});
|
|
437
536
|
it('logs no group lines when zero actors changed', async () => {
|
|
438
537
|
await getChangedActors({
|
|
439
538
|
filepathsChanged: ['.gitignore', '.prettierrc'],
|
|
440
539
|
actorConfigs,
|
|
441
|
-
|
|
540
|
+
range,
|
|
442
541
|
});
|
|
443
542
|
expect(logger.info).not.toHaveBeenCalledWith(expect.stringContaining('Shared changes'));
|
|
444
543
|
expect(logger.info).not.toHaveBeenCalledWith(expect.stringContaining('Changes specific to'));
|
|
445
|
-
expect(logger.info).toHaveBeenCalledWith('[DIFF]:
|
|
544
|
+
expect(logger.info).toHaveBeenCalledWith('[DIFF]: Actors with functional changes: none');
|
|
545
|
+
expect(logger.info).toHaveBeenCalledWith('[DIFF]: Actors with only cosmetic changes: none');
|
|
546
|
+
});
|
|
547
|
+
});
|
|
548
|
+
describe('getChangedActors split by impact', () => {
|
|
549
|
+
beforeEach(() => {
|
|
550
|
+
vi.spyOn(DiffJsonSchema, 'isCosmeticOnlyJsonSchemaChange').mockResolvedValue(false);
|
|
551
|
+
});
|
|
552
|
+
it('lists an Actor as functional when it has any functional change, and as cosmetic only otherwise', async () => {
|
|
553
|
+
const result = await getChangedActors({
|
|
554
|
+
filepathsChanged: [
|
|
555
|
+
'actors/foo_bar/README.md',
|
|
556
|
+
'standalone-actors/standalone/README.md',
|
|
557
|
+
'actors/foo_bar/src/main.ts',
|
|
558
|
+
],
|
|
559
|
+
actorConfigs,
|
|
560
|
+
range,
|
|
561
|
+
});
|
|
562
|
+
expect(result).toStrictEqual({ functional: [miniActor], cosmetic: [standaloneActor] });
|
|
563
|
+
});
|
|
564
|
+
it('returns empty lists when nothing relevant changed', async () => {
|
|
565
|
+
expect(await getChangedActors({ filepathsChanged: ['.vscode/settings.json'], actorConfigs, range })).toStrictEqual({ functional: [], cosmetic: [] });
|
|
446
566
|
});
|
|
447
567
|
});
|
|
448
568
|
//# sourceMappingURL=diff-changes.test.js.map
|