apify-test-tools 0.10.2-beta.2 → 0.10.2-beta.21
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 +1 -0
- package/.github/actionlint.yaml +11 -0
- package/.github/actions/checkout-restore-dependencies/action.yaml +58 -6
- package/.github/cli/apify-test-tools.mjs +135 -142
- package/.github/scripts/mask-config-secrets.sh +17 -0
- package/.github/scripts/run-with-apify-tokens.mjs +63 -103
- package/.github/workflows/_check_code.yaml +5 -21
- package/.github/workflows/_move_major_tag.yaml +2 -2
- package/.github/workflows/public_platform-tests-claude-investigate-and-fix.yaml +89 -8
- package/.github/workflows/public_platform-tests.yaml +68 -30
- package/.github/workflows/public_pr-build-test.yaml +77 -38
- package/.github/workflows/public_push-build-latest.yaml +49 -11
- package/.github/workflows/public_review.yaml +5 -4
- package/.github/workflows/public_stale-issues.yaml +51 -0
- package/.husky/pre-commit +4 -4
- package/.prettierignore +2 -1
- package/CHANGELOG.md +23 -0
- package/CONTRIBUTING.md +117 -17
- package/README.md +221 -595
- package/bin/actor-ids.ts +41 -0
- package/bin/affected-actors.ts +211 -0
- package/bin/build-from-local.ts +19 -1
- package/bin/build.ts +105 -39
- package/bin/diff-changes.ts +69 -36
- package/bin/diff-json-schema.ts +5 -6
- package/bin/git.ts +73 -175
- package/bin/main.ts +142 -189
- package/bin/notify.ts +198 -0
- package/bin/run-tests.ts +182 -0
- package/bin/slack.ts +16 -76
- package/bin/stdin-input.ts +156 -0
- package/bin/test-files-glob.ts +126 -0
- package/bin/test-report.ts +141 -140
- package/bin/types.ts +4 -7
- package/bin/utils/config/load-config.ts +20 -2
- package/bin/utils/config/parser.ts +40 -8
- package/bin/utils/config/structures/grouped.ts +2 -2
- package/bin/utils/config/structures/legacy.ts +1 -1
- package/dist/bin/actor-ids.d.ts +15 -0
- package/dist/bin/actor-ids.d.ts.map +1 -0
- package/dist/bin/actor-ids.js +30 -0
- package/dist/bin/actor-ids.js.map +1 -0
- package/dist/bin/affected-actors.d.ts +55 -0
- package/dist/bin/affected-actors.d.ts.map +1 -0
- package/dist/bin/affected-actors.js +142 -0
- package/dist/bin/affected-actors.js.map +1 -0
- package/dist/bin/build-from-local.d.ts +2 -1
- package/dist/bin/build-from-local.d.ts.map +1 -1
- package/dist/bin/build-from-local.js +6 -2
- package/dist/bin/build-from-local.js.map +1 -1
- package/dist/bin/build.d.ts +18 -5
- package/dist/bin/build.d.ts.map +1 -1
- package/dist/bin/build.js +74 -24
- package/dist/bin/build.js.map +1 -1
- package/dist/bin/diff-changes.d.ts +21 -5
- package/dist/bin/diff-changes.d.ts.map +1 -1
- package/dist/bin/diff-changes.js +41 -28
- 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 +26 -34
- package/dist/bin/git.d.ts.map +1 -1
- package/dist/bin/git.js +60 -143
- package/dist/bin/git.js.map +1 -1
- package/dist/bin/main.js +126 -140
- package/dist/bin/main.js.map +1 -1
- package/dist/bin/notify.d.ts +35 -0
- package/dist/bin/notify.d.ts.map +1 -0
- package/dist/bin/notify.js +131 -0
- package/dist/bin/notify.js.map +1 -0
- package/dist/bin/run-tests.d.ts +21 -0
- package/dist/bin/run-tests.d.ts.map +1 -0
- package/dist/bin/run-tests.js +149 -0
- package/dist/bin/run-tests.js.map +1 -0
- package/dist/bin/slack.d.ts +2 -14
- package/dist/bin/slack.d.ts.map +1 -1
- package/dist/bin/slack.js +17 -46
- package/dist/bin/slack.js.map +1 -1
- package/dist/bin/stdin-input.d.ts +79 -0
- package/dist/bin/stdin-input.d.ts.map +1 -0
- package/dist/bin/stdin-input.js +124 -0
- package/dist/bin/stdin-input.js.map +1 -0
- package/dist/bin/test-files-glob.d.ts +18 -0
- package/dist/bin/test-files-glob.d.ts.map +1 -0
- package/dist/bin/test-files-glob.js +108 -0
- package/dist/bin/test-files-glob.js.map +1 -0
- package/dist/bin/test-report.d.ts +69 -8
- package/dist/bin/test-report.d.ts.map +1 -1
- package/dist/bin/test-report.js +76 -67
- package/dist/bin/test-report.js.map +1 -1
- package/dist/bin/types.d.ts +4 -7
- package/dist/bin/types.d.ts.map +1 -1
- package/dist/bin/utils/config/load-config.d.ts +8 -0
- package/dist/bin/utils/config/load-config.d.ts.map +1 -1
- package/dist/bin/utils/config/load-config.js +14 -1
- package/dist/bin/utils/config/load-config.js.map +1 -1
- package/dist/bin/utils/config/parser.d.ts +15 -2
- package/dist/bin/utils/config/parser.d.ts.map +1 -1
- package/dist/bin/utils/config/parser.js +29 -8
- package/dist/bin/utils/config/parser.js.map +1 -1
- package/dist/bin/utils/config/structures/grouped.js +2 -2
- package/dist/bin/utils/config/structures/grouped.js.map +1 -1
- package/dist/bin/utils/config/structures/legacy.js +1 -1
- package/dist/bin/utils/config/structures/legacy.js.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 -5
- package/dist/lib/lib.d.ts.map +1 -1
- package/dist/lib/lib.js +19 -31
- 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.js +76 -56
- package/dist/test/bundle/cli-bundle.test.js.map +1 -1
- package/dist/test/bundle/token-wrapper.test.d.ts +2 -0
- package/dist/test/bundle/token-wrapper.test.d.ts.map +1 -0
- package/dist/test/bundle/token-wrapper.test.js +80 -0
- package/dist/test/bundle/token-wrapper.test.js.map +1 -0
- package/dist/test/e2e/cli-bundle.e2e.test.js +33 -68
- package/dist/test/e2e/cli-bundle.e2e.test.js.map +1 -1
- 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/actor-filtering.test.js +7 -0
- package/dist/test/unit/bin/actor-filtering.test.js.map +1 -1
- package/dist/test/unit/bin/actor-ids.test.d.ts +2 -0
- package/dist/test/unit/bin/actor-ids.test.d.ts.map +1 -0
- package/dist/test/unit/bin/actor-ids.test.js +40 -0
- package/dist/test/unit/bin/actor-ids.test.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 +224 -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 +153 -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 +49 -0
- package/dist/test/unit/bin/build-cli.test.js.map +1 -0
- package/dist/test/unit/bin/build-from-local.test.js +12 -0
- package/dist/test/unit/bin/build-from-local.test.js.map +1 -1
- package/dist/test/unit/bin/build.test.js +116 -6
- 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 +23 -0
- package/dist/test/unit/bin/compiled-cli.js.map +1 -0
- package/dist/test/unit/bin/diff-changes.test.js +168 -114
- 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 +67 -288
- package/dist/test/unit/bin/git.test.js.map +1 -1
- package/dist/test/unit/bin/notify.test.d.ts +2 -0
- package/dist/test/unit/bin/notify.test.d.ts.map +1 -0
- package/dist/test/unit/bin/notify.test.js +222 -0
- package/dist/test/unit/bin/notify.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 +92 -0
- package/dist/test/unit/bin/stdin-input.test.js.map +1 -0
- package/dist/test/unit/bin/test-cli.test.d.ts +2 -0
- package/dist/test/unit/bin/test-cli.test.d.ts.map +1 -0
- package/dist/test/unit/bin/test-cli.test.js +165 -0
- package/dist/test/unit/bin/test-cli.test.js.map +1 -0
- package/dist/test/unit/bin/test-files-glob.test.d.ts +2 -0
- package/dist/test/unit/bin/test-files-glob.test.d.ts.map +1 -0
- package/dist/test/unit/bin/test-files-glob.test.js +102 -0
- package/dist/test/unit/bin/test-files-glob.test.js.map +1 -0
- package/dist/test/unit/bin/test-report.test.d.ts +2 -0
- package/dist/test/unit/bin/test-report.test.d.ts.map +1 -0
- package/dist/test/unit/bin/test-report.test.js +100 -0
- package/dist/test/unit/bin/test-report.test.js.map +1 -0
- package/dist/test/unit/bin/utils/config/load-config.test.js +19 -1
- package/dist/test/unit/bin/utils/config/load-config.test.js.map +1 -1
- package/dist/test/unit/bin/utils/config/parser.test.js +36 -4
- package/dist/test/unit/bin/utils/config/parser.test.js.map +1 -1
- package/dist/test/unit/bin/utils/config/structures/grouped.test.js +6 -0
- package/dist/test/unit/bin/utils/config/structures/grouped.test.js.map +1 -1
- package/dist/test/unit/bin/utils/config/structures/legacy.test.js +1 -0
- package/dist/test/unit/bin/utils/config/structures/legacy.test.js.map +1 -1
- 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/dist/workflow-scripts-src/run-with-apify-tokens.d.ts +3 -0
- package/dist/workflow-scripts-src/run-with-apify-tokens.d.ts.map +1 -0
- package/dist/workflow-scripts-src/run-with-apify-tokens.js +100 -0
- package/dist/workflow-scripts-src/run-with-apify-tokens.js.map +1 -0
- package/docs/cli.md +473 -0
- package/docs/lib.md +276 -0
- package/docs/workflows.md +455 -0
- package/eslint.config.mjs +10 -1
- package/lib/extend-expect.ts +48 -258
- package/lib/lib.ts +25 -34
- package/lib/run-checks.ts +101 -0
- package/lib/run-test-result.ts +45 -55
- package/package.json +4 -2
- package/platform-tests-investigate-and-fix/skills/assess-impact/SKILL.md +42 -0
- package/platform-tests-investigate-and-fix/skills/measure-flakiness/SKILL.md +4 -2
- package/test/bundle/cli-bundle.test.ts +97 -67
- package/test/bundle/token-wrapper.test.ts +110 -0
- package/test/e2e/cli-bundle.e2e.test.ts +60 -93
- package/test/e2e/git-build-release.e2e.test.ts +113 -0
- package/test/e2e/helpers.ts +82 -0
- package/test/unit/bin/actor-filtering.test.ts +8 -0
- package/test/unit/bin/actor-ids.test.ts +47 -0
- package/test/unit/bin/affected-actors-cli.test.ts +271 -0
- package/test/unit/bin/affected-actors.test.ts +221 -0
- package/test/unit/bin/build-cli.test.ts +61 -0
- package/test/unit/bin/build-from-local.test.ts +16 -0
- package/test/unit/bin/build.test.ts +149 -5
- package/test/unit/bin/compiled-cli.ts +23 -0
- package/test/unit/bin/diff-changes.test.ts +181 -114
- package/test/unit/bin/diff.test.ts +25 -28
- package/test/unit/bin/git.test.ts +76 -361
- package/test/unit/bin/notify.test.ts +299 -0
- package/test/unit/bin/stdin-input.test.ts +120 -0
- package/test/unit/bin/test-cli.test.ts +207 -0
- package/test/unit/bin/test-files-glob.test.ts +118 -0
- package/test/unit/bin/test-report.test.ts +118 -0
- package/test/unit/bin/utils/config/load-config.test.ts +26 -1
- package/test/unit/bin/utils/config/parser.test.ts +46 -5
- package/test/unit/bin/utils/config/structures/grouped.test.ts +12 -0
- package/test/unit/bin/utils/config/structures/legacy.test.ts +1 -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/tsconfig.json +1 -1
- package/vitest.config.ts +9 -0
- package/workflow-scripts-src/run-with-apify-tokens.ts +112 -0
- package/.github/scripts/check-major-tag-refs.mjs +0 -72
- package/dist/test/unit/bin/logging.test.d.ts +0 -2
- package/dist/test/unit/bin/logging.test.d.ts.map +0 -1
- package/dist/test/unit/bin/logging.test.js +0 -43
- package/dist/test/unit/bin/logging.test.js.map +0 -1
- package/dist/test/unit/bin/slack.test.d.ts +0 -2
- package/dist/test/unit/bin/slack.test.d.ts.map +0 -1
- package/dist/test/unit/bin/slack.test.js +0 -54
- package/dist/test/unit/bin/slack.test.js.map +0 -1
- package/test/unit/bin/logging.test.ts +0 -52
- package/test/unit/bin/slack.test.ts +0 -65
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import type { MockInstance } from 'vitest';
|
|
2
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
+
|
|
4
|
+
import { getAffectedActors } from '../../../bin/affected-actors.js';
|
|
5
|
+
import * as DiffChanges from '../../../bin/diff-changes.js';
|
|
6
|
+
import * as Git from '../../../bin/git.js';
|
|
7
|
+
import type { ActorConfig, Commit } from '../../../bin/types.js';
|
|
8
|
+
import * as LoadConfig from '../../../bin/utils/config/load-config.js';
|
|
9
|
+
|
|
10
|
+
// Everything that reads the configs is mocked, so only the identity and name of an Actor matter here
|
|
11
|
+
const actorA = { actorFullName: 'owner/a' } as ActorConfig;
|
|
12
|
+
const actorB = { actorFullName: 'owner/b' } as ActorConfig;
|
|
13
|
+
|
|
14
|
+
const headSha = 'f'.repeat(40);
|
|
15
|
+
const sinceSha = '5'.repeat(40);
|
|
16
|
+
const commit = (sha: string): Commit => ({ sha, author: 'Dev<dev@example.com>', date: 'Date', message: 'msg' });
|
|
17
|
+
const commits = [commit('1'.repeat(40)), commit('2'.repeat(40))];
|
|
18
|
+
const changedFiles = ['src/main.ts', 'CHANGELOG.md'];
|
|
19
|
+
|
|
20
|
+
const selection = { actors: [], ignore: [] };
|
|
21
|
+
|
|
22
|
+
describe('getAffectedActors', () => {
|
|
23
|
+
let changedActorsSpy: MockInstance;
|
|
24
|
+
|
|
25
|
+
beforeEach(() => {
|
|
26
|
+
vi.spyOn(LoadConfig, 'readConfigFile').mockResolvedValue([actorA, actorB]);
|
|
27
|
+
vi.spyOn(LoadConfig, 'readRepoSettings').mockResolvedValue({ platformTestsGlob: 'test/platform/**' });
|
|
28
|
+
changedActorsSpy = vi
|
|
29
|
+
.spyOn(DiffChanges, 'getChangedActors')
|
|
30
|
+
.mockResolvedValue({ functional: [actorA], cosmetic: [actorB], test: [] });
|
|
31
|
+
vi.spyOn(Git, 'resolveCommitSha').mockResolvedValue(headSha);
|
|
32
|
+
vi.spyOn(Git, 'getChangedFilesBetween').mockResolvedValue(changedFiles);
|
|
33
|
+
vi.spyOn(Git, 'getChangelogAdditions').mockResolvedValue('- Added foo');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('requires --base or --since', async () => {
|
|
37
|
+
const options = { ...selection };
|
|
38
|
+
await expect(getAffectedActors(options)).rejects.toThrow('Pass --base, --since, or both');
|
|
39
|
+
// An empty --since (e.g. from an empty cache file) counts as not passed
|
|
40
|
+
await expect(getAffectedActors({ ...options, since: '' })).rejects.toThrow('Pass --base, --since, or both');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
describe('with --base', () => {
|
|
44
|
+
const mergeBaseSha = 'b'.repeat(40);
|
|
45
|
+
let commitsBetweenSpy: MockInstance;
|
|
46
|
+
|
|
47
|
+
beforeEach(() => {
|
|
48
|
+
vi.spyOn(Git, 'getMergeBase').mockResolvedValue(mergeBaseSha);
|
|
49
|
+
commitsBetweenSpy = vi.spyOn(Git, 'getCommitsBetween').mockResolvedValue(commits);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("inspects the branch's own changes, from where it forked from or last merged --base", async () => {
|
|
53
|
+
const findCommitSpy = vi.spyOn(Git, 'findCommitSha');
|
|
54
|
+
|
|
55
|
+
const result = await getAffectedActors({ base: 'origin/master', ...selection });
|
|
56
|
+
|
|
57
|
+
expect(result).toStrictEqual({
|
|
58
|
+
version: 1,
|
|
59
|
+
head: headSha,
|
|
60
|
+
commits,
|
|
61
|
+
changedFiles,
|
|
62
|
+
changelog: '- Added foo',
|
|
63
|
+
// Only the names, the config file stays the source of truth for the rest
|
|
64
|
+
functionallyChangedActors: [{ actorFullName: 'owner/a' }],
|
|
65
|
+
cosmeticallyChangedActors: [{ actorFullName: 'owner/b' }],
|
|
66
|
+
testChangedActors: [],
|
|
67
|
+
});
|
|
68
|
+
expect(Git.getMergeBase).toHaveBeenCalledWith('origin/master', 'HEAD');
|
|
69
|
+
expect(Git.getChangedFilesBetween).toHaveBeenCalledWith(mergeBaseSha, headSha);
|
|
70
|
+
expect(Git.getChangelogAdditions).toHaveBeenCalledWith(mergeBaseSha, headSha, changedFiles);
|
|
71
|
+
expect(commitsBetweenSpy).toHaveBeenCalledWith(mergeBaseSha, headSha);
|
|
72
|
+
expect(changedActorsSpy).toHaveBeenCalledWith({
|
|
73
|
+
filepathsChanged: changedFiles,
|
|
74
|
+
actorConfigs: [actorA, actorB],
|
|
75
|
+
range: { fromRef: mergeBaseSha, toRef: headSha },
|
|
76
|
+
platformTestsGlob: 'test/platform/**',
|
|
77
|
+
});
|
|
78
|
+
expect(findCommitSpy).not.toHaveBeenCalled();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe('and --since', () => {
|
|
82
|
+
const sinceFiles = ['README.md'];
|
|
83
|
+
|
|
84
|
+
beforeEach(() => {
|
|
85
|
+
vi.spyOn(Git, 'findCommitSha').mockResolvedValue(sinceSha);
|
|
86
|
+
vi.spyOn(Git, 'getChangedFilesBetween').mockImplementation(async (fromRef) =>
|
|
87
|
+
fromRef === sinceSha ? sinceFiles : changedFiles,
|
|
88
|
+
);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
const getNarrowed = async (
|
|
92
|
+
branch: DiffChanges.ChangedActors,
|
|
93
|
+
sinceValidated: DiffChanges.ChangedActors,
|
|
94
|
+
) => {
|
|
95
|
+
changedActorsSpy.mockImplementation(async ({ range }) =>
|
|
96
|
+
range.fromRef === sinceSha ? sinceValidated : branch,
|
|
97
|
+
);
|
|
98
|
+
const result = await getAffectedActors({ base: 'origin/master', since: sinceSha, ...selection });
|
|
99
|
+
return {
|
|
100
|
+
functional: result.functionallyChangedActors.map(({ actorFullName }) => actorFullName),
|
|
101
|
+
cosmetic: result.cosmeticallyChangedActors.map(({ actorFullName }) => actorFullName),
|
|
102
|
+
test: result.testChangedActors.map(({ actorFullName }) => actorFullName),
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
it('classifies the changes since --since separately', async () => {
|
|
107
|
+
await getNarrowed(
|
|
108
|
+
{ functional: [actorA], cosmetic: [], test: [] },
|
|
109
|
+
{ functional: [actorA], cosmetic: [], test: [] },
|
|
110
|
+
);
|
|
111
|
+
expect(changedActorsSpy).toHaveBeenCalledWith({
|
|
112
|
+
filepathsChanged: sinceFiles,
|
|
113
|
+
actorConfigs: [actorA, actorB],
|
|
114
|
+
range: { fromRef: sinceSha, toRef: headSha },
|
|
115
|
+
platformTestsGlob: 'test/platform/**',
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('still describes the whole branch', async () => {
|
|
120
|
+
const result = await getAffectedActors({ base: 'origin/master', since: sinceSha, ...selection });
|
|
121
|
+
expect(result.commits).toStrictEqual(commits);
|
|
122
|
+
expect(result.changedFiles).toStrictEqual(changedFiles);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('retests an Actor whose validated change meets a new functional change', async () => {
|
|
126
|
+
await expect(
|
|
127
|
+
getNarrowed(
|
|
128
|
+
{ functional: [actorA], cosmetic: [], test: [] },
|
|
129
|
+
{ functional: [actorA], cosmetic: [], test: [] },
|
|
130
|
+
),
|
|
131
|
+
).resolves.toStrictEqual({ functional: ['owner/a'], cosmetic: [], test: [] });
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it('leaves out Actors that only the branch changed before --since or only --base changed', async () => {
|
|
135
|
+
await expect(
|
|
136
|
+
getNarrowed(
|
|
137
|
+
{ functional: [actorA], cosmetic: [], test: [] },
|
|
138
|
+
{ functional: [actorB], cosmetic: [], test: [] },
|
|
139
|
+
),
|
|
140
|
+
).resolves.toStrictEqual({ functional: [], cosmetic: [], test: [] });
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('takes the less impactful change when the two disagree', async () => {
|
|
144
|
+
// A validated functional change, then only cosmetic changes (e.g. a README merged in from base)
|
|
145
|
+
await expect(
|
|
146
|
+
getNarrowed(
|
|
147
|
+
{ functional: [actorA], cosmetic: [], test: [] },
|
|
148
|
+
{ functional: [], cosmetic: [actorA], test: [] },
|
|
149
|
+
),
|
|
150
|
+
).resolves.toStrictEqual({ functional: [], cosmetic: ['owner/a'], test: [] });
|
|
151
|
+
// A functional change merged in from base, while the branch only changes the README
|
|
152
|
+
await expect(
|
|
153
|
+
getNarrowed(
|
|
154
|
+
{ functional: [], cosmetic: [actorA], test: [] },
|
|
155
|
+
{ functional: [actorA], cosmetic: [], test: [] },
|
|
156
|
+
),
|
|
157
|
+
).resolves.toStrictEqual({ functional: [], cosmetic: ['owner/a'], test: [] });
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('runs the tests of an Actor whose tests the branch changed and changed again since --since', async () => {
|
|
161
|
+
await expect(
|
|
162
|
+
getNarrowed(
|
|
163
|
+
{ functional: [actorA], cosmetic: [], test: [actorA, actorB] },
|
|
164
|
+
{ functional: [], cosmetic: [], test: [actorA] },
|
|
165
|
+
),
|
|
166
|
+
).resolves.toStrictEqual({ functional: [], cosmetic: [], test: ['owner/a'] });
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
it('leaves out test changes that only --base or only the validated part of the branch has', async () => {
|
|
170
|
+
await expect(
|
|
171
|
+
getNarrowed(
|
|
172
|
+
{ functional: [], cosmetic: [], test: [actorA] },
|
|
173
|
+
{ functional: [], cosmetic: [], test: [actorB] },
|
|
174
|
+
),
|
|
175
|
+
).resolves.toStrictEqual({ functional: [], cosmetic: [], test: [] });
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it.each([
|
|
179
|
+
['is HEAD (a rerun)', headSha],
|
|
180
|
+
['is not in the local history', undefined],
|
|
181
|
+
])('checks the whole branch when --since %s', async (_, found) => {
|
|
182
|
+
vi.spyOn(Git, 'findCommitSha').mockResolvedValue(found);
|
|
183
|
+
const result = await getAffectedActors({ base: 'origin/master', since: sinceSha, ...selection });
|
|
184
|
+
expect(result.functionallyChangedActors).toStrictEqual([{ actorFullName: 'owner/a' }]);
|
|
185
|
+
// With no usable validated commit, the "since" diff falls back to the same range as the
|
|
186
|
+
// base diff, so getChangedActors runs twice for identical ranges instead of once.
|
|
187
|
+
expect(changedActorsSpy).toHaveBeenCalledTimes(2);
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
describe('with --since only', () => {
|
|
193
|
+
let resolveBaseSpy: MockInstance;
|
|
194
|
+
let commitsBetweenSpy: MockInstance;
|
|
195
|
+
|
|
196
|
+
beforeEach(() => {
|
|
197
|
+
resolveBaseSpy = vi.spyOn(Git, 'resolveReleaseBaseCommit').mockResolvedValue(sinceSha);
|
|
198
|
+
commitsBetweenSpy = vi.spyOn(Git, 'getCommitsBetween').mockResolvedValue(commits);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it('inspects everything after --since up to HEAD', async () => {
|
|
202
|
+
const result = await getAffectedActors({ since: 'HEAD~2', ...selection });
|
|
203
|
+
|
|
204
|
+
expect(result).toStrictEqual({
|
|
205
|
+
version: 1,
|
|
206
|
+
head: headSha,
|
|
207
|
+
commits,
|
|
208
|
+
changedFiles,
|
|
209
|
+
changelog: '- Added foo',
|
|
210
|
+
// Only the names, the config file stays the source of truth for the rest
|
|
211
|
+
functionallyChangedActors: [{ actorFullName: 'owner/a' }],
|
|
212
|
+
cosmeticallyChangedActors: [{ actorFullName: 'owner/b' }],
|
|
213
|
+
testChangedActors: [],
|
|
214
|
+
});
|
|
215
|
+
expect(resolveBaseSpy).toHaveBeenCalledWith('HEAD~2');
|
|
216
|
+
expect(commitsBetweenSpy).toHaveBeenCalledWith(sinceSha, headSha);
|
|
217
|
+
expect(Git.getChangedFilesBetween).toHaveBeenCalledWith(sinceSha, headSha);
|
|
218
|
+
expect(Git.getChangelogAdditions).toHaveBeenCalledWith(sinceSha, headSha, changedFiles);
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import process from 'node:process';
|
|
3
|
+
|
|
4
|
+
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
|
5
|
+
|
|
6
|
+
import { compileCli } from './compiled-cli.js';
|
|
7
|
+
|
|
8
|
+
let cliPath: string;
|
|
9
|
+
let cleanup: (() => Promise<void>) | undefined;
|
|
10
|
+
|
|
11
|
+
const run = (command: string[], input: string, env: NodeJS.ProcessEnv = process.env) =>
|
|
12
|
+
spawnSync(cliPath, command, { encoding: 'utf8', input, stdio: ['pipe', 'pipe', 'pipe'], env });
|
|
13
|
+
const runBuild = (input: string, args: string[] = ['--version-number', '0.99']) => run(['build', ...args], input);
|
|
14
|
+
|
|
15
|
+
describe('build and notify CLI', () => {
|
|
16
|
+
beforeAll(async () => {
|
|
17
|
+
({ cliPath, cleanup } = await compileCli());
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
afterAll(async () => {
|
|
21
|
+
await cleanup?.();
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('builds nothing for an empty list and prints an empty build list', () => {
|
|
25
|
+
const result = runBuild('{"actors":[]}');
|
|
26
|
+
expect(result.status, result.stderr).toBe(0);
|
|
27
|
+
expect(JSON.parse(result.stdout)).toStrictEqual([]);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('fails on empty stdin instead of building nothing', () => {
|
|
31
|
+
const result = runBuild('');
|
|
32
|
+
expect(result.status).toBe(1);
|
|
33
|
+
expect(result.stderr).toContain('Expected the Actors to build as JSON on stdin, got nothing');
|
|
34
|
+
expect(result.stdout).toBe('');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('rejects a malformed --version-number', () => {
|
|
38
|
+
const result = runBuild('{"actors":[]}', ['--version-number', 'latest']);
|
|
39
|
+
expect(result.status).toBe(1);
|
|
40
|
+
expect(result.stderr).toContain('--version-number must look like 0.1 or be "default"');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('requires --version-number', () => {
|
|
44
|
+
const result = runBuild('{"actors":[]}', []);
|
|
45
|
+
expect(result.status).toBe(1);
|
|
46
|
+
expect(result.stderr).toContain('Missing required argument: version-number');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('notify takes one channel per call', () => {
|
|
50
|
+
const result = run(['notify', '--slack-channel', '#a', '--slack-channel', '#b'], '{}');
|
|
51
|
+
expect(result.status).toBe(1);
|
|
52
|
+
expect(result.stderr).toContain('--slack-channel takes one channel, call notify once for each channel');
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('notify announces no release when there are no new commits', () => {
|
|
56
|
+
const document = { commits: [], changedFiles: [], changelog: null, functionallyChangedActors: [] };
|
|
57
|
+
const result = run(['notify', '--slack-channel', '#notif'], JSON.stringify(document));
|
|
58
|
+
expect(result.status, result.stderr).toBe(0);
|
|
59
|
+
expect(result.stderr).toContain('No new commits, so there is no release to announce');
|
|
60
|
+
});
|
|
61
|
+
});
|
|
@@ -289,5 +289,21 @@ describe('build-from-local helpers', () => {
|
|
|
289
289
|
// Only the read-only lookup ran: builders for uploads and builds are created after the dry-run cutoff
|
|
290
290
|
expect(fromActorConfig).toHaveBeenCalledTimes(1);
|
|
291
291
|
});
|
|
292
|
+
|
|
293
|
+
it('fails before zipping anything when asked to require env vars in sync and they are not', async () => {
|
|
294
|
+
vi.spyOn(ApifyBuilder, 'fromActorConfig').mockReturnValue({
|
|
295
|
+
getActorInfo: async () => ({
|
|
296
|
+
defaultRunOptions: { build: 'latest' },
|
|
297
|
+
taggedBuilds: { latest: { buildNumber: '0.1.5' } },
|
|
298
|
+
versions: [{ versionNumber: '0.1', sourceType: 'GIT_REPO', envVars: [{ name: 'API_KEY' }] }],
|
|
299
|
+
}),
|
|
300
|
+
} as unknown as ApifyBuilder);
|
|
301
|
+
// Only the name matters, the check runs before the sources are read
|
|
302
|
+
const actorConfig = { actorFullName: 'owner/actor' } as unknown as ActorConfig;
|
|
303
|
+
|
|
304
|
+
await expect(
|
|
305
|
+
runBuildsFromLocal({ actorConfigs: [actorConfig], dryRun: true, requireEnvVarsInSync: true }),
|
|
306
|
+
).rejects.toThrow('Env vars of version 0.98 are out of sync with default version 0.1 (missing API_KEY)');
|
|
307
|
+
});
|
|
292
308
|
});
|
|
293
309
|
});
|
|
@@ -7,11 +7,16 @@ import { ActorSourceType, ApifyClient } from 'apify-client';
|
|
|
7
7
|
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
8
8
|
|
|
9
9
|
import {
|
|
10
|
+
ApifyBuilder,
|
|
11
|
+
assertEnvVarsMatchDefaultVersion,
|
|
10
12
|
assertRepoUrlMatchesDefaultVersion,
|
|
13
|
+
buildActors,
|
|
11
14
|
deleteOldBuilds,
|
|
12
15
|
resolveDefaultVersion,
|
|
13
16
|
runBuilds,
|
|
14
17
|
} from '../../../bin/build.js';
|
|
18
|
+
import * as Git from '../../../bin/git.js';
|
|
19
|
+
import { logger } from '../../../bin/logger.js';
|
|
15
20
|
import type { ActorConfig } from '../../../bin/types.js';
|
|
16
21
|
import { ExistingDir, ExistingFile, RelativeDir } from '../../../bin/utils/path/repo-relative.js';
|
|
17
22
|
|
|
@@ -84,6 +89,119 @@ describe('assertRepoUrlMatchesDefaultVersion', () => {
|
|
|
84
89
|
});
|
|
85
90
|
});
|
|
86
91
|
|
|
92
|
+
describe('runBuilds version number', () => {
|
|
93
|
+
// Only the name and folder of the Actor matter here, the builder is stubbed
|
|
94
|
+
const actorConfig = { actorFullName: ACTOR, folder: { isRoot: () => true } } as unknown as ActorConfig;
|
|
95
|
+
// Restored after each test, so the stub never reaches the tests that run the real builder
|
|
96
|
+
afterEach(() => {
|
|
97
|
+
vi.mocked(ApifyBuilder.fromActorConfig).mockRestore();
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
const dryRunBuild = async (versionNumber: string, actorInfo = makeActorInfo()) => {
|
|
101
|
+
vi.spyOn(ApifyBuilder, 'fromActorConfig').mockReturnValue({
|
|
102
|
+
getActorInfo: async () => actorInfo,
|
|
103
|
+
} as unknown as ApifyBuilder);
|
|
104
|
+
const result = await runBuilds({
|
|
105
|
+
actorConfigs: [actorConfig],
|
|
106
|
+
versionNumber,
|
|
107
|
+
repoUrl: REPO_URL,
|
|
108
|
+
shouldVerifyRepoUrl: false,
|
|
109
|
+
branch: 'master',
|
|
110
|
+
dryRun: true,
|
|
111
|
+
});
|
|
112
|
+
if (Array.isArray(result)) throw new Error('A dry run must return a plan, not builds');
|
|
113
|
+
return result.builds[0].versionNumber;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
it('builds the version it is given', async () => {
|
|
117
|
+
await expect(dryRunBuild('0.99')).resolves.toBe('0.99');
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it("resolves default to the version the Actor's default build tag points to", async () => {
|
|
121
|
+
await expect(dryRunBuild('default')).resolves.toBe('0.1');
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('warns when the default version does not give its builds the default build tag', async () => {
|
|
125
|
+
const warnSpy = vi.spyOn(logger, 'warn').mockImplementation(() => undefined);
|
|
126
|
+
await dryRunBuild('default');
|
|
127
|
+
// The fixture's version 0.1 has no build tag of its own
|
|
128
|
+
expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('users keep running the previous build'));
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('does not warn when the default version gives its builds the default build tag', async () => {
|
|
132
|
+
const warnSpy = vi.spyOn(logger, 'warn').mockImplementation(() => undefined);
|
|
133
|
+
const versions = [{ versionNumber: '0.1', buildTag: 'latest', sourceType: ActorSourceType.GitRepo }];
|
|
134
|
+
await dryRunBuild('default', makeActorInfo({ versions } as Partial<ApifyClientTypes.Actor>));
|
|
135
|
+
expect(warnSpy).not.toHaveBeenCalled();
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
describe('buildActors', () => {
|
|
140
|
+
it('builds nothing and needs no branch or repository when there are no Actors', async () => {
|
|
141
|
+
const branchSpy = vi.spyOn(Git, 'getCurrentBranch');
|
|
142
|
+
const repoSpy = vi.spyOn(Git, 'resolveRepoUrl');
|
|
143
|
+
|
|
144
|
+
await expect(buildActors({ actorConfigs: [], versionNumber: '0.99', dryRun: false })).resolves.toStrictEqual(
|
|
145
|
+
[],
|
|
146
|
+
);
|
|
147
|
+
// A dry run keeps the dry-run shape even with nothing to build
|
|
148
|
+
await expect(buildActors({ actorConfigs: [], versionNumber: '0.99', dryRun: true })).resolves.toStrictEqual({
|
|
149
|
+
dryRun: true,
|
|
150
|
+
builds: [],
|
|
151
|
+
});
|
|
152
|
+
expect(branchSpy).not.toHaveBeenCalled();
|
|
153
|
+
expect(repoSpy).not.toHaveBeenCalled();
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
describe('assertEnvVarsMatchDefaultVersion', () => {
|
|
158
|
+
const makeVersion = (versionNumber: string, names: string[]): ApifyClientTypes.ActorVersion => ({
|
|
159
|
+
versionNumber,
|
|
160
|
+
sourceType: ActorSourceType.GitRepo,
|
|
161
|
+
gitRepoUrl: REPO_URL,
|
|
162
|
+
envVars: names.map((name) => ({ name, isSecret: true })),
|
|
163
|
+
});
|
|
164
|
+
const makeActorInfoWithEnvVars = (defaultNames: string[], testNames?: string[]) =>
|
|
165
|
+
makeActorInfo({
|
|
166
|
+
versions: [makeVersion('0.1', defaultNames), ...(testNames ? [makeVersion('0.99', testNames)] : [])],
|
|
167
|
+
});
|
|
168
|
+
const check = (actorInfo: ApifyClientTypes.Actor, versionNumber = '0.99') =>
|
|
169
|
+
assertEnvVarsMatchDefaultVersion(
|
|
170
|
+
ACTOR,
|
|
171
|
+
actorInfo,
|
|
172
|
+
resolveDefaultVersion(ACTOR, actorInfo).defaultVersion,
|
|
173
|
+
versionNumber,
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
it('should pass when the names match in any order, whatever the values', () => {
|
|
177
|
+
expect(() => check(makeActorInfoWithEnvVars(['A', 'B'], ['B', 'A']))).not.toThrow();
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('should pass for the default version itself', () => {
|
|
181
|
+
expect(() => check(makeActorInfoWithEnvVars(['A']), '0.1')).not.toThrow();
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it('should pass when neither version has env vars', () => {
|
|
185
|
+
expect(() => check(makeActorInfo())).not.toThrow();
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it('should list the missing and extra names', () => {
|
|
189
|
+
expect(() => check(makeActorInfoWithEnvVars(['A', 'B'], ['B', 'C']))).toThrow(
|
|
190
|
+
'Env vars of version 0.99 are out of sync with default version 0.1 (missing A; extra C)',
|
|
191
|
+
);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
it('should ask to create the version when it does not exist yet', () => {
|
|
195
|
+
expect(() => check(makeActorInfoWithEnvVars(['A']))).toThrow("Version 0.99 doesn't exist yet");
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('should throw when the default version no longer exists', () => {
|
|
199
|
+
expect(() => assertEnvVarsMatchDefaultVersion(ACTOR, makeActorInfo(), undefined, '0.99')).toThrow(
|
|
200
|
+
'no longer exists',
|
|
201
|
+
);
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
|
|
87
205
|
describe('dry run', () => {
|
|
88
206
|
const TOKEN_ENV_VAR = 'APIFY_TOKEN_OWNER';
|
|
89
207
|
const originalCwd = process.cwd();
|
|
@@ -118,11 +236,14 @@ describe('dry run', () => {
|
|
|
118
236
|
const createVersion = vi.fn();
|
|
119
237
|
const buildClient = vi.fn(() => ({ delete: deleteBuild }));
|
|
120
238
|
|
|
239
|
+
let actorInfo: ApifyClientTypes.Actor;
|
|
240
|
+
|
|
121
241
|
beforeEach(() => {
|
|
122
242
|
vi.stubEnv(TOKEN_ENV_VAR, 'token');
|
|
243
|
+
actorInfo = makeActorInfo();
|
|
123
244
|
const fakeClient = {
|
|
124
245
|
actor: () => ({
|
|
125
|
-
get: async () =>
|
|
246
|
+
get: async () => actorInfo,
|
|
126
247
|
// Old enough to be deleted, and not the default build 0.1.5
|
|
127
248
|
builds: () => ({
|
|
128
249
|
list: async () => ({ items: [{ id: 'old-build', buildNumber: '0.0.1', startedAt: new Date(0) }] }),
|
|
@@ -143,14 +264,15 @@ describe('dry run', () => {
|
|
|
143
264
|
vi.clearAllMocks();
|
|
144
265
|
});
|
|
145
266
|
|
|
146
|
-
const runDryBuilds = async () =>
|
|
267
|
+
const runDryBuilds = async (requireEnvVarsInSync = false) =>
|
|
147
268
|
runBuilds({
|
|
148
269
|
actorConfigs: [actorConfig],
|
|
149
270
|
repoUrl: REPO_URL,
|
|
150
271
|
shouldVerifyRepoUrl: true,
|
|
151
272
|
branch: 'feature',
|
|
152
273
|
dryRun: true,
|
|
153
|
-
|
|
274
|
+
versionNumber: '0.99',
|
|
275
|
+
requireEnvVarsInSync,
|
|
154
276
|
});
|
|
155
277
|
|
|
156
278
|
it('should return a build plan without creating versions or builds', async () => {
|
|
@@ -161,7 +283,6 @@ describe('dry run', () => {
|
|
|
161
283
|
actorFullName: ACTOR,
|
|
162
284
|
versionNumber: '0.99',
|
|
163
285
|
gitRepoUrl: `${REPO_URL}#feature:actors/a`,
|
|
164
|
-
useDockerCache: false,
|
|
165
286
|
},
|
|
166
287
|
],
|
|
167
288
|
});
|
|
@@ -182,11 +303,34 @@ describe('dry run', () => {
|
|
|
182
303
|
shouldVerifyRepoUrl: true,
|
|
183
304
|
branch: 'feature',
|
|
184
305
|
dryRun: true,
|
|
185
|
-
|
|
306
|
+
versionNumber: '0.99',
|
|
186
307
|
}),
|
|
187
308
|
).rejects.toThrow('Repository mismatch');
|
|
188
309
|
});
|
|
189
310
|
|
|
311
|
+
describe('with the default version holding an env var the test version lacks', () => {
|
|
312
|
+
beforeEach(() => {
|
|
313
|
+
actorInfo = makeActorInfo({
|
|
314
|
+
versions: [
|
|
315
|
+
{
|
|
316
|
+
versionNumber: '0.1',
|
|
317
|
+
sourceType: ActorSourceType.GitRepo,
|
|
318
|
+
gitRepoUrl: REPO_URL,
|
|
319
|
+
envVars: [{ name: 'API_KEY', isSecret: true }],
|
|
320
|
+
},
|
|
321
|
+
],
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
it('should still check the env vars when asked to', async () => {
|
|
326
|
+
await expect(runDryBuilds(true)).rejects.toThrow('missing API_KEY');
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
it('should not check the env vars unless asked to', async () => {
|
|
330
|
+
await expect(runDryBuilds()).resolves.toMatchObject({ dryRun: true });
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
|
|
190
334
|
it('should not delete old builds', async () => {
|
|
191
335
|
await deleteOldBuilds([actorConfig], { dryRun: true });
|
|
192
336
|
expect(deleteBuild).not.toHaveBeenCalled();
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { execFileSync } from 'node:child_process';
|
|
2
|
+
import { chmod, mkdtemp, rm } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import process from 'node:process';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
const projectRoot = fileURLToPath(new URL('../../../', import.meta.url));
|
|
8
|
+
const compilerPath = fileURLToPath(new URL('../../../node_modules/typescript/bin/tsc', import.meta.url));
|
|
9
|
+
|
|
10
|
+
/** Compiles the CLI from the sources into a temporary directory, so tests run it the way npm users do. */
|
|
11
|
+
export const compileCli = async () => {
|
|
12
|
+
const buildDir = await mkdtemp(path.join(projectRoot, '.cli-test-'));
|
|
13
|
+
const cleanup = async () => rm(buildDir, { recursive: true, force: true });
|
|
14
|
+
try {
|
|
15
|
+
execFileSync(process.execPath, [compilerPath, '--outDir', buildDir], { cwd: projectRoot });
|
|
16
|
+
const cliPath = path.join(buildDir, 'bin/main.js');
|
|
17
|
+
await chmod(cliPath, 0o755);
|
|
18
|
+
return { cliPath, cleanup };
|
|
19
|
+
} catch (error) {
|
|
20
|
+
await cleanup();
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
};
|