apify-test-tools 0.10.2-beta.0 → 0.10.2-beta.2
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 +13 -29
- package/.github/cli/apify-test-tools.mjs +362 -0
- package/.github/scripts/run-with-apify-tokens.mjs +2 -2
- 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.yaml +1 -1
- package/.github/workflows/public_pr-build-test.yaml +5 -28
- package/.github/workflows/public_push-build-latest.yaml +2 -2
- package/.husky/pre-commit +5 -0
- package/.prettierignore +3 -0
- package/CHANGELOG.md +5 -0
- package/CONTRIBUTING.md +8 -18
- package/README.md +40 -42
- package/bin/build-from-local.ts +47 -13
- package/bin/build.ts +35 -19
- package/bin/diff-changes.ts +24 -3
- package/bin/main.ts +35 -7
- package/bin/slack.ts +28 -6
- package/bin/test-report.ts +6 -9
- package/bin/types.ts +10 -0
- package/dist/bin/build-from-local.d.ts +10 -2
- package/dist/bin/build-from-local.d.ts.map +1 -1
- package/dist/bin/build-from-local.js +29 -11
- package/dist/bin/build-from-local.js.map +1 -1
- package/dist/bin/build.d.ts +15 -5
- package/dist/bin/build.d.ts.map +1 -1
- package/dist/bin/build.js +24 -15
- package/dist/bin/build.js.map +1 -1
- package/dist/bin/diff-changes.d.ts +2 -1
- package/dist/bin/diff-changes.d.ts.map +1 -1
- package/dist/bin/diff-changes.js +16 -5
- package/dist/bin/diff-changes.js.map +1 -1
- package/dist/bin/main.js +32 -6
- package/dist/bin/main.js.map +1 -1
- package/dist/bin/slack.d.ts +8 -1
- package/dist/bin/slack.d.ts.map +1 -1
- package/dist/bin/slack.js +26 -5
- package/dist/bin/slack.js.map +1 -1
- 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 +9 -0
- package/dist/bin/types.d.ts.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 +162 -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 +172 -0
- package/dist/test/e2e/cli-bundle.e2e.test.js.map +1 -0
- package/dist/test/unit/bin/build-from-local.test.js +53 -1
- package/dist/test/unit/bin/build-from-local.test.js.map +1 -1
- package/dist/test/unit/bin/build.test.js +113 -3
- package/dist/test/unit/bin/build.test.js.map +1 -1
- package/dist/test/unit/bin/diff-changes.test.js +91 -0
- package/dist/test/unit/bin/diff-changes.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 +54 -0
- package/dist/test/unit/bin/slack.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +15 -3
- package/test/bundle/cli-bundle.test.ts +192 -0
- package/test/e2e/cli-bundle.e2e.test.ts +237 -0
- package/test/unit/bin/build-from-local.test.ts +55 -0
- package/test/unit/bin/build.test.ts +135 -3
- package/test/unit/bin/diff-changes.test.ts +106 -0
- package/test/unit/bin/slack.test.ts +65 -0
- package/.github/scripts/check-package-version-bump.mjs +0 -74
- package/.github/workflows-package-version +0 -1
package/dist/bin/slack.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../../bin/slack.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../../bin/slack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAGzC,KAAK,oBAAoB,GAAG;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,GAAU,aAAa,MAAM,EAAE,QAAQ,OAAO,KAAG,OAAO,CAAC,SAAS,CAW5F,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,QAAQ,OAAO,uCAAkD,CAAC;AAK/F,eAAO,MAAM,aAAa,GAAU,4GASjC,oBAAoB,kBAgDtB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAU,OAAO,SAAS,EAAE,SAAS,MAAM,EAAE,MAAM,MAAM,EAAE,QAAQ,MAAM,EAAE,kBASvG,CAAC"}
|
package/dist/bin/slack.js
CHANGED
|
@@ -1,19 +1,41 @@
|
|
|
1
1
|
import { WebClient } from '@slack/web-api';
|
|
2
2
|
import { logger } from './logger.js';
|
|
3
3
|
import { getEnvVar } from './utils.js';
|
|
4
|
+
/**
|
|
5
|
+
* Creates the client the real run posts with. A dry run posts nothing but still requires the token and checks
|
|
6
|
+
* Slack accepts it (`auth.test` is read-only), so it fails wherever the real run would.
|
|
7
|
+
*/
|
|
8
|
+
export const getSlackClient = async (tokenEnvVar, dryRun) => {
|
|
9
|
+
const slack = new WebClient(getEnvVar(tokenEnvVar));
|
|
10
|
+
if (dryRun) {
|
|
11
|
+
try {
|
|
12
|
+
await slack.auth.test();
|
|
13
|
+
}
|
|
14
|
+
catch (err) {
|
|
15
|
+
throw new Error(`${tokenEnvVar} was rejected by Slack: ${err.message}`);
|
|
16
|
+
}
|
|
17
|
+
logger.info(`[DRY RUN] ${tokenEnvVar} is valid`);
|
|
18
|
+
}
|
|
19
|
+
return slack;
|
|
20
|
+
};
|
|
21
|
+
export const sendingLabel = (dryRun) => (dryRun ? '[DRY RUN] Would send' : 'Sending');
|
|
4
22
|
// Git authors come as "Name<email>", Slack only needs the name
|
|
5
23
|
const displayName = (author) => author.replace(/\s*<[^>]*>$/, '');
|
|
6
24
|
export const notifyToSlack = async ({ changedFiles, commits, changelog, repository, dryRun, author, releaseSlackChannel, reportSlackChannel, }) => {
|
|
7
|
-
const slack = new WebClient(getEnvVar('SLACK_TOKEN_RELEASES_BOT'));
|
|
8
25
|
if (!changelog) {
|
|
9
26
|
logger.warn('No new changelog entries found, did you forget to update it?');
|
|
10
27
|
}
|
|
28
|
+
if (!releaseSlackChannel && !reportSlackChannel) {
|
|
29
|
+
logger.info('Skipping slack notification, no --release-slack-channel or --report-slack-channel passed');
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
const slack = await getSlackClient('SLACK_TOKEN_RELEASES_BOT', dryRun);
|
|
11
33
|
let shortMessage = `*${repository}* – New release (by ${displayName(author)}):\n\n`;
|
|
12
34
|
// This one is just for broader public that only cares about public facing changes
|
|
13
35
|
if (changelog && releaseSlackChannel) {
|
|
14
36
|
shortMessage += `*Additions to the changelog*:\n\n${changelog}\n`;
|
|
15
37
|
logger.info(`=========================================`);
|
|
16
|
-
logger.info(
|
|
38
|
+
logger.info(`**${sendingLabel(dryRun)} slack message to channel**: ${releaseSlackChannel}.\n\n${shortMessage}`);
|
|
17
39
|
logger.info(`=========================================`);
|
|
18
40
|
if (!dryRun) {
|
|
19
41
|
await slack.chat.postMessage({
|
|
@@ -30,7 +52,7 @@ export const notifyToSlack = async ({ changedFiles, commits, changelog, reposito
|
|
|
30
52
|
// This one is for devs and project managers that need to know more details
|
|
31
53
|
if (reportSlackChannel) {
|
|
32
54
|
logger.info(`=========================================`);
|
|
33
|
-
logger.info(
|
|
55
|
+
logger.info(`${sendingLabel(dryRun)} slack message to channel: ${reportSlackChannel}.\n\n${longMessage}`);
|
|
34
56
|
logger.info(`=========================================`);
|
|
35
57
|
if (!dryRun) {
|
|
36
58
|
await slack.chat.postMessage({
|
|
@@ -40,8 +62,7 @@ export const notifyToSlack = async ({ changedFiles, commits, changelog, reposito
|
|
|
40
62
|
}
|
|
41
63
|
}
|
|
42
64
|
};
|
|
43
|
-
export const sendSlackMessage = async (channel, text, blocks
|
|
44
|
-
const slack = new WebClient(token);
|
|
65
|
+
export const sendSlackMessage = async (slack, channel, text, blocks) => {
|
|
45
66
|
const { ts } = await slack.chat.postMessage({ text, channel });
|
|
46
67
|
if (blocks.length > 0 && ts) {
|
|
47
68
|
await slack.chat.postMessage({
|
package/dist/bin/slack.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slack.js","sourceRoot":"","sources":["../../bin/slack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAavC,+DAA+D;AAC/D,MAAM,WAAW,GAAG,CAAC,MAAc,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;AAE1E,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAAE,EAChC,YAAY,EACZ,OAAO,EACP,SAAS,EACT,UAAU,EACV,MAAM,EACN,MAAM,EACN,mBAAmB,EACnB,kBAAkB,GACC,EAAE,EAAE;IACvB,
|
|
1
|
+
{"version":3,"file":"slack.js","sourceRoot":"","sources":["../../bin/slack.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-report.d.ts","sourceRoot":"","sources":["../../bin/test-report.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"test-report.d.ts","sourceRoot":"","sources":["../../bin/test-report.ts"],"names":[],"mappings":"AAKA,UAAU,wBAAwB;IAC9B,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,eAAO,MAAM,iBAAiB,GAAU,oFAMrC,wBAAwB,kBAsF1B,CAAC"}
|
package/dist/bin/test-report.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
import { logger } from './logger.js';
|
|
3
|
-
import { sendSlackMessage } from './slack.js';
|
|
4
|
-
import { getEnvVar } from './utils.js';
|
|
3
|
+
import { getSlackClient, sendingLabel, sendSlackMessage } from './slack.js';
|
|
5
4
|
export const reportTestResults = async ({ dryRun, reportSlackChannel, reportFile: jsonResultsPath, jobUrl, workflowName, }) => {
|
|
6
5
|
const results = JSON.parse((await fs.readFile(jsonResultsPath)).toString());
|
|
7
6
|
const passed = [];
|
|
@@ -56,6 +55,9 @@ export const reportTestResults = async ({ dryRun, reportSlackChannel, reportFile
|
|
|
56
55
|
logger.info(`Skipping slack notification. If you want to enable it, add --report-slack-channel flag and make sure SLACK_TOKEN_TESTS_BOT env variable is set.`);
|
|
57
56
|
return;
|
|
58
57
|
}
|
|
58
|
+
// Checked before knowing if there's anything to send, so a broken token shows up on a green run
|
|
59
|
+
// (and in dry runs) rather than on the day tests fail
|
|
60
|
+
const slack = await getSlackClient('SLACK_TOKEN_TESTS_BOT', dryRun);
|
|
59
61
|
if (failedAssertions.length === 0) {
|
|
60
62
|
return;
|
|
61
63
|
}
|
|
@@ -68,14 +70,10 @@ export const reportTestResults = async ({ dryRun, reportSlackChannel, reportFile
|
|
|
68
70
|
const blocks = failedAssertions
|
|
69
71
|
.slice(1)
|
|
70
72
|
.map(({ message, runLink, actorId }) => `• ${message} --- <${runLink}|${actorId}>`);
|
|
71
|
-
logger.info(
|
|
73
|
+
logger.info(`${sendingLabel(dryRun)} slack message to channel ${reportSlackChannel}:`, slackMessage);
|
|
72
74
|
logger.info('\tblocks:', blocks.join('\n\t\t'));
|
|
73
|
-
if (!reportSlackChannel) {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
75
|
if (!dryRun) {
|
|
77
|
-
|
|
78
|
-
await sendSlackMessage(reportSlackChannel, slackMessage, blocks, slackToken);
|
|
76
|
+
await sendSlackMessage(slack, reportSlackChannel, slackMessage, blocks);
|
|
79
77
|
}
|
|
80
78
|
};
|
|
81
79
|
//# sourceMappingURL=test-report.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-report.js","sourceRoot":"","sources":["../../bin/test-report.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAElC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"test-report.js","sourceRoot":"","sources":["../../bin/test-report.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAElC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAU5E,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EAAE,EACpC,MAAM,EACN,kBAAkB,EAClB,UAAU,EAAE,eAAe,EAC3B,MAAM,EACN,YAAY,GACW,EAAE,EAAE;IAC3B,MAAM,OAAO,GAAoB,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7F,MAAM,MAAM,GAA0B,EAAE,CAAC;IACzC,MAAM,MAAM,GAA0B,EAAE,CAAC;IAEzC,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QACvC,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC7B,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAC;YACxC,SAAS;QACb,CAAC;QACD,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,gBAAgB,EAAE,CAAC;YAC5C,IAAI,OAAO,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;gBAC9B,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACzB,CAAC;iBAAM,CAAC;gBACJ,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACzB,CAAC;QACL,CAAC;IACL,CAAC;IAED,MAAM,gBAAgB,GAA4D,EAAE,CAAC;IAErF,MAAM,CAAC,IAAI,EAAE,CAAC;IACd,MAAM,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,MAAM,aAAa,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAClE,MAAM,CAAC,IAAI,EAAE,CAAC;IACd,MAAM,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;IAClE,MAAM,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;IAClE,MAAM,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;IAClE,MAAM,CAAC,IAAI,EAAE,CAAC;IACd,KAAK,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;QAC1C,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;QAC7B,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,QAAQ,QAAQ,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QACjE,MAAM,CAAC,IAAI,EAAE,CAAC;IAClB,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;IAClE,MAAM,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;IAClE,MAAM,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;IAClE,MAAM,CAAC,IAAI,EAAE,CAAC;IACd,KAAK,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC;QAC1C,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;QACpD,IAAI,eAAe,EAAE,CAAC;YAClB,gBAAgB,CAAC,IAAI,CACjB,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBACjC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBACjC,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,OAAO,EAAE,IAAI,CAAC,OAAO;aACxB,CAAC,CAAC,CACN,CAAC;QACN,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,QAAQ,QAAQ,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QACzD,MAAM,CAAC,IAAI,EAAE,CAAC;IAClB,CAAC;IACD,MAAM,CAAC,IAAI,EAAE,CAAC;IACd,MAAM,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,MAAM,aAAa,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAClE,MAAM,CAAC,IAAI,EAAE,CAAC;IAEd,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACtB,MAAM,CAAC,IAAI,CACP,iJAAiJ,CACpJ,CAAC;QACF,OAAO;IACX,CAAC;IACD,gGAAgG;IAChG,sDAAsD;IACtD,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAAC;IAEpE,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO;IACX,CAAC;IAED,2BAA2B;IAC3B,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC5C,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,MAAM,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5D,IAAI,YAAY,GAAG,KAAK,YAAY,IAAI,GAAG,IAAI,CAAC;IAChD,YAAY,IAAI,SAAS,gBAAgB,CAAC,MAAM,4CAA4C,MAAM,CAAC,MAAM,IAAI,KAAK,IAAI,OAAO,EAAE,CAAC;IAChI,YAAY,IAAI,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC,OAAO,SAAS,gBAAgB,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,gBAAgB,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC;IACzH,MAAM,MAAM,GAAG,gBAAgB;SAC1B,KAAK,CAAC,CAAC,CAAC;SACR,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,KAAK,OAAO,SAAS,OAAO,IAAI,OAAO,GAAG,CAAC,CAAC;IAExF,MAAM,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC,6BAA6B,kBAAkB,GAAG,EAAE,YAAY,CAAC,CAAC;IACrG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEhD,IAAI,CAAC,MAAM,EAAE,CAAC;QACV,MAAM,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;IAC5E,CAAC;AACL,CAAC,CAAC"}
|
package/dist/bin/types.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export interface Config {
|
|
|
6
6
|
baseCommit?: string;
|
|
7
7
|
actors: string[];
|
|
8
8
|
ignore: string[];
|
|
9
|
+
testFilesGlob?: string;
|
|
9
10
|
}
|
|
10
11
|
export type Commit = {
|
|
11
12
|
sha: string;
|
|
@@ -19,6 +20,14 @@ export interface BuildData {
|
|
|
19
20
|
actorFullName: string;
|
|
20
21
|
buildNumber: string;
|
|
21
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* What a dry run writes to stdout instead of the command's real result. It's an object, not an array, so
|
|
25
|
+
* it can't be mistaken for real builds: `ACTOR_BUILDS` rejects it before any test runs.
|
|
26
|
+
*/
|
|
27
|
+
export interface DryRunPlan<T> {
|
|
28
|
+
dryRun: true;
|
|
29
|
+
builds: T[];
|
|
30
|
+
}
|
|
22
31
|
export interface ActorConfig {
|
|
23
32
|
actorFullName: string;
|
|
24
33
|
folder: ExistingDir;
|
package/dist/bin/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../bin/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAE9E,MAAM,WAAW,MAAM;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../bin/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAE9E,MAAM,WAAW,MAAM;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,MAAM,GAAG;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,WAAW,SAAS;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU,CAAC,CAAC;IACzB,MAAM,EAAE,IAAI,CAAC;IACb,MAAM,EAAE,CAAC,EAAE,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,WAAW,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,cAAc,CAAC;IAC1B,gBAAgB,EAAE,WAAW,CAAC;IAC9B,YAAY,EAAE,WAAW,EAAE,CAAC;CAC/B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-bundle.test.d.ts","sourceRoot":"","sources":["../../../test/bundle/cli-bundle.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { execFileSync, spawnSync } from 'node:child_process';
|
|
2
|
+
import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import process from 'node:process';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
|
8
|
+
// Runs the committed bundle the composite action ships, not the sources, so these catch anything
|
|
9
|
+
// that only breaks once bundled (a dependency loading code at runtime, a missing shim). Everything
|
|
10
|
+
// here works without tokens or network: read-only commands, dry runs that end up with nothing to
|
|
11
|
+
// build, and the missing-token error. The `CLI bundle` check keeps the bundle in sync with bin/.
|
|
12
|
+
const bundlePath = fileURLToPath(new URL('../../.github/cli/apify-test-tools.mjs', import.meta.url));
|
|
13
|
+
// Only what node and git need, so no Apify or Slack token from the developer's shell leaks in.
|
|
14
|
+
const cliEnv = { PATH: process.env.PATH ?? '', HOME: os.tmpdir() };
|
|
15
|
+
const gitEnv = {
|
|
16
|
+
...cliEnv,
|
|
17
|
+
GIT_AUTHOR_NAME: 'Tester',
|
|
18
|
+
GIT_AUTHOR_EMAIL: 'tester@example.com',
|
|
19
|
+
GIT_COMMITTER_NAME: 'Tester',
|
|
20
|
+
GIT_COMMITTER_EMAIL: 'tester@example.com',
|
|
21
|
+
};
|
|
22
|
+
let repoDir;
|
|
23
|
+
let baseSha;
|
|
24
|
+
let headSha;
|
|
25
|
+
const git = (...args) => execFileSync('git', args, { cwd: repoDir, env: gitEnv, encoding: 'utf8' }).trim();
|
|
26
|
+
const writeRepoFile = async (file, content) => {
|
|
27
|
+
await mkdir(path.dirname(path.join(repoDir, file)), { recursive: true });
|
|
28
|
+
await writeFile(path.join(repoDir, file), content);
|
|
29
|
+
};
|
|
30
|
+
const runCli = (...args) => {
|
|
31
|
+
const result = spawnSync(process.execPath, [bundlePath, ...args], { cwd: repoDir, env: cliEnv, encoding: 'utf8' });
|
|
32
|
+
return { status: result.status, stdout: result.stdout, stderr: result.stderr };
|
|
33
|
+
};
|
|
34
|
+
const gitRange = ['--source-branch', 'feature', '--target-branch', 'main'];
|
|
35
|
+
describe('CLI bundle', () => {
|
|
36
|
+
// Two Actors on `main`; `feature` changes only tester/foo and the root README.
|
|
37
|
+
beforeAll(async () => {
|
|
38
|
+
repoDir = await mkdtemp(path.join(os.tmpdir(), 'apify-cli-bundle-'));
|
|
39
|
+
git('init', '-q', '-b', 'main');
|
|
40
|
+
git('remote', 'add', 'origin', 'https://github.com/apify/fixture-repo.git');
|
|
41
|
+
for (const name of ['foo', 'bar']) {
|
|
42
|
+
await writeRepoFile(`actors/${name}/.actor/actor.json`, JSON.stringify({ actorSpecification: 1, name, version: '0.1' }));
|
|
43
|
+
}
|
|
44
|
+
await writeRepoFile('apify-test-tools.config.json', JSON.stringify({
|
|
45
|
+
actors: [
|
|
46
|
+
{ folder: 'actors/foo', actorFullName: 'tester/foo', tokenEnvVar: 'FOO_TOKEN' },
|
|
47
|
+
{ folder: 'actors/bar', actorFullName: 'tester/bar', tokenEnvVar: 'BAR_TOKEN' },
|
|
48
|
+
],
|
|
49
|
+
}));
|
|
50
|
+
git('add', '-A');
|
|
51
|
+
git('commit', '-q', '-m', 'chore: init');
|
|
52
|
+
baseSha = git('rev-parse', 'HEAD');
|
|
53
|
+
git('checkout', '-q', '-b', 'feature');
|
|
54
|
+
await writeRepoFile('actors/foo/main.js', 'console.log("changed");\n');
|
|
55
|
+
git('add', '-A');
|
|
56
|
+
git('commit', '-q', '-m', 'fix(foo): change foo');
|
|
57
|
+
await writeRepoFile('README.md', 'readme\n');
|
|
58
|
+
git('add', '-A');
|
|
59
|
+
git('commit', '-q', '-m', 'docs: readme');
|
|
60
|
+
headSha = git('rev-parse', 'HEAD');
|
|
61
|
+
});
|
|
62
|
+
afterAll(async () => {
|
|
63
|
+
if (repoDir)
|
|
64
|
+
await rm(repoDir, { recursive: true, force: true });
|
|
65
|
+
});
|
|
66
|
+
it('lists every command in --help', () => {
|
|
67
|
+
const { status, stdout } = runCli('--help');
|
|
68
|
+
expect(status).toBe(0);
|
|
69
|
+
for (const command of [
|
|
70
|
+
'get-commits',
|
|
71
|
+
'get-latest-commit',
|
|
72
|
+
'get-changed-files',
|
|
73
|
+
'get-actor-configs',
|
|
74
|
+
'get-affected-actors',
|
|
75
|
+
'report-tests',
|
|
76
|
+
'build',
|
|
77
|
+
'release',
|
|
78
|
+
'build-from-local',
|
|
79
|
+
'delete-old-builds',
|
|
80
|
+
]) {
|
|
81
|
+
expect(stdout).toContain(command);
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
it('get-commits returns the commits on the source branch', () => {
|
|
85
|
+
const { status, stdout, stderr } = runCli('get-commits', ...gitRange);
|
|
86
|
+
expect(status, stderr).toBe(0);
|
|
87
|
+
expect(JSON.parse(stdout).map((commit) => commit.message)).toEqual([
|
|
88
|
+
'fix(foo): change foo',
|
|
89
|
+
'docs: readme',
|
|
90
|
+
]);
|
|
91
|
+
});
|
|
92
|
+
it('get-latest-commit returns the head of the source branch', () => {
|
|
93
|
+
const { status, stdout, stderr } = runCli('get-latest-commit', ...gitRange);
|
|
94
|
+
expect(status, stderr).toBe(0);
|
|
95
|
+
expect(JSON.parse(stdout)).toMatchObject({ sha: headSha, message: 'docs: readme' });
|
|
96
|
+
});
|
|
97
|
+
it('get-changed-files returns the files changed on the source branch', () => {
|
|
98
|
+
const { status, stdout, stderr } = runCli('get-changed-files', ...gitRange);
|
|
99
|
+
expect(status, stderr).toBe(0);
|
|
100
|
+
expect(JSON.parse(stdout)).toEqual(['README.md', 'actors/foo/main.js']);
|
|
101
|
+
});
|
|
102
|
+
it('get-actor-configs reads both Actors from the config file', () => {
|
|
103
|
+
const { status, stdout, stderr } = runCli('get-actor-configs');
|
|
104
|
+
expect(status, stderr).toBe(0);
|
|
105
|
+
expect(JSON.parse(stdout).map((actor) => actor.actorFullName)).toEqual([
|
|
106
|
+
'tester/foo',
|
|
107
|
+
'tester/bar',
|
|
108
|
+
]);
|
|
109
|
+
});
|
|
110
|
+
it('get-affected-actors returns only the Actor whose files changed', () => {
|
|
111
|
+
const { status, stdout, stderr } = runCli('get-affected-actors', ...gitRange);
|
|
112
|
+
expect(status, stderr).toBe(0);
|
|
113
|
+
expect(JSON.parse(stdout)).toMatchObject([{ actorFullName: 'tester/foo', folder: 'actors/foo' }]);
|
|
114
|
+
});
|
|
115
|
+
it('build --dry-run with nothing to build needs no token', () => {
|
|
116
|
+
const { status, stdout, stderr } = runCli('build', ...gitRange, '--actors', 'tester/bar', '--dry-run');
|
|
117
|
+
expect(status, stderr).toBe(0);
|
|
118
|
+
expect(JSON.parse(stdout)).toEqual({ dryRun: true, builds: [] });
|
|
119
|
+
});
|
|
120
|
+
it('build --dry-run fails cleanly when the Actor token is missing', () => {
|
|
121
|
+
const { status, stderr } = runCli('build', ...gitRange, '--dry-run');
|
|
122
|
+
expect(status).toBe(1);
|
|
123
|
+
expect(stderr).toContain('Env var FOO_TOKEN is not set (needed for actor "tester/foo")');
|
|
124
|
+
});
|
|
125
|
+
it('release --dry-run stops when HEAD is the base commit', () => {
|
|
126
|
+
const { status, stderr } = runCli('release', '--base-commit', headSha, '--dry-run');
|
|
127
|
+
expect(status, stderr).toBe(0);
|
|
128
|
+
expect(stderr).toContain(`HEAD is the base commit ${headSha}, there is nothing new to release`);
|
|
129
|
+
});
|
|
130
|
+
it('release --dry-run with nothing to build skips Slack without a token', () => {
|
|
131
|
+
const { status, stderr } = runCli('release', '--base-commit', baseSha, '--actors', 'tester/bar', '--dry-run');
|
|
132
|
+
expect(status, stderr).toBe(0);
|
|
133
|
+
expect(stderr).toContain('{"dryRun":true,"builds":[]}');
|
|
134
|
+
expect(stderr).toContain('Skipping slack notification');
|
|
135
|
+
});
|
|
136
|
+
it('report-tests summarizes a vitest JSON report', async () => {
|
|
137
|
+
const assertion = (title, status, runId) => ({
|
|
138
|
+
ancestorTitles: [],
|
|
139
|
+
fullName: `foo ${title}`,
|
|
140
|
+
title,
|
|
141
|
+
status,
|
|
142
|
+
failureMessages: status === 'failed' ? ['AssertionError: expected 1 to be 2\n at foo.test.ts:1:1'] : [],
|
|
143
|
+
meta: { runId, runLink: `https://console.apify.com/view/runs/${runId}`, actorId: 'tester/foo' },
|
|
144
|
+
});
|
|
145
|
+
await writeRepoFile('test-output.json', JSON.stringify({
|
|
146
|
+
success: false,
|
|
147
|
+
testResults: [
|
|
148
|
+
{
|
|
149
|
+
name: 'test/platform/foo.test.ts',
|
|
150
|
+
status: 'failed',
|
|
151
|
+
assertionResults: [assertion('works', 'passed', 'run1'), assertion('fails', 'failed', 'run2')],
|
|
152
|
+
},
|
|
153
|
+
],
|
|
154
|
+
}));
|
|
155
|
+
const { status, stderr } = runCli('report-tests', '--report-file', 'test-output.json', '--dry-run');
|
|
156
|
+
expect(status, stderr).toBe(0);
|
|
157
|
+
expect(stderr).toContain('PASSED: 1, FAILED: 1');
|
|
158
|
+
expect(stderr).toContain('1) foo fails ... https://console.apify.com/view/runs/run2');
|
|
159
|
+
expect(stderr).toContain('Skipping slack notification');
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
//# sourceMappingURL=cli-bundle.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-bundle.test.js","sourceRoot":"","sources":["../../../test/bundle/cli-bundle.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-bundle.e2e.test.d.ts","sourceRoot":"","sources":["../../../test/e2e/cli-bundle.e2e.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { execFileSync, spawnSync } from 'node:child_process';
|
|
2
|
+
import { mkdir, mkdtemp, readFile, rm, symlink, writeFile } from 'node:fs/promises';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import process from 'node:process';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
import { ApifyClient } from 'apify-client';
|
|
8
|
+
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
|
|
9
|
+
// End-to-end run of the shipped CLI bundle against two dummy Actors in an isolated sandbox account:
|
|
10
|
+
// dry-run plans read the real Actors, `build-from-local` really builds them, the lib runs them
|
|
11
|
+
// through `testActor` on exactly those builds (the ACTOR_BUILDS handoff), `report-tests` reads the
|
|
12
|
+
// result, and `delete-old-builds` cleans up. Git builds (`build`/`release` without --dry-run) are
|
|
13
|
+
// not covered: the Apify builder would have to clone the fixture repo, which only exists locally.
|
|
14
|
+
//
|
|
15
|
+
// Runs with `npm run test:e2e`, kept out of `npm test`. Skipped without the token, e.g. on fork PRs.
|
|
16
|
+
const TOKEN_ENV_VAR = 'E2E_TEST_APIFY_TOKEN_DBYPODOIHUZABNQTR';
|
|
17
|
+
const token = process.env[TOKEN_ENV_VAR];
|
|
18
|
+
const ACTORS = ['test-tools-testing-sandbox/dummy-for-testing-1', 'test-tools-testing-sandbox/dummy-for-testing-2'];
|
|
19
|
+
// Only used as the source URL in dry-run plans; nothing is cloned from it.
|
|
20
|
+
const REPO_URL = 'https://github.com/apify/apify-test-tools-e2e-fixture';
|
|
21
|
+
const projectRoot = fileURLToPath(new URL('../../', import.meta.url));
|
|
22
|
+
const bundlePath = path.join(projectRoot, '.github/cli/apify-test-tools.mjs');
|
|
23
|
+
const vitestPath = path.join(projectRoot, 'node_modules/vitest/vitest.mjs');
|
|
24
|
+
// Proxy and CA settings pass through so the API is reachable behind a proxy; no other variable does.
|
|
25
|
+
const networkEnv = Object.fromEntries(['HTTPS_PROXY', 'https_proxy', 'HTTP_PROXY', 'http_proxy', 'NO_PROXY', 'no_proxy', 'NODE_EXTRA_CA_CERTS']
|
|
26
|
+
.filter((name) => process.env[name] !== undefined)
|
|
27
|
+
.map((name) => [name, process.env[name]]));
|
|
28
|
+
const baseEnv = { PATH: process.env.PATH ?? '', HOME: os.tmpdir() };
|
|
29
|
+
// The CLI gets only the sandbox token, under the name the fixture config points at.
|
|
30
|
+
const cliEnv = { ...baseEnv, ...networkEnv, [TOKEN_ENV_VAR]: token ?? '' };
|
|
31
|
+
const gitEnv = {
|
|
32
|
+
...baseEnv,
|
|
33
|
+
GIT_AUTHOR_NAME: 'Tester',
|
|
34
|
+
GIT_AUTHOR_EMAIL: 'tester@example.com',
|
|
35
|
+
GIT_COMMITTER_NAME: 'Tester',
|
|
36
|
+
GIT_COMMITTER_EMAIL: 'tester@example.com',
|
|
37
|
+
};
|
|
38
|
+
let repoDir;
|
|
39
|
+
let baseSha;
|
|
40
|
+
const git = (...args) => execFileSync('git', args, { cwd: repoDir, env: gitEnv, encoding: 'utf8' }).trim();
|
|
41
|
+
const writeRepoFile = async (file, content) => {
|
|
42
|
+
await mkdir(path.dirname(path.join(repoDir, file)), { recursive: true });
|
|
43
|
+
await writeFile(path.join(repoDir, file), content);
|
|
44
|
+
};
|
|
45
|
+
// Spawned processes are blocking, so vitest's own timeouts can't stop one that hangs. apify-client
|
|
46
|
+
// retries an unreachable API for minutes, so a hang is killed here and fails with a clear error.
|
|
47
|
+
const PROCESS_TIMEOUT_MS = 8 * 60_000;
|
|
48
|
+
const runCli = (...args) => {
|
|
49
|
+
const result = spawnSync(process.execPath, [bundlePath, ...args], {
|
|
50
|
+
cwd: repoDir,
|
|
51
|
+
env: cliEnv,
|
|
52
|
+
encoding: 'utf8',
|
|
53
|
+
timeout: PROCESS_TIMEOUT_MS,
|
|
54
|
+
});
|
|
55
|
+
const error = result.error ? `\n${result.error.message}` : '';
|
|
56
|
+
return { status: result.status, stdout: result.stdout, stderr: result.stderr + error };
|
|
57
|
+
};
|
|
58
|
+
describe.runIf(token)('CLI bundle against real Actors', { timeout: 2 * 60_000 }, () => {
|
|
59
|
+
let builds;
|
|
60
|
+
// Both Actors on `main`; `feature` changes only dummy-for-testing-1.
|
|
61
|
+
beforeAll(async () => {
|
|
62
|
+
repoDir = await mkdtemp(path.join(os.tmpdir(), 'apify-cli-e2e-'));
|
|
63
|
+
git('init', '-q', '-b', 'main');
|
|
64
|
+
git('remote', 'add', 'origin', `${REPO_URL}.git`);
|
|
65
|
+
const actors = [];
|
|
66
|
+
for (const [i, actorFullName] of ACTORS.entries()) {
|
|
67
|
+
const folder = `actors/dummy-${i + 1}`;
|
|
68
|
+
await writeRepoFile(`${folder}/.actor/actor.json`, JSON.stringify({
|
|
69
|
+
actorSpecification: 1,
|
|
70
|
+
name: actorFullName.split('/')[1],
|
|
71
|
+
version: '0.0',
|
|
72
|
+
dockerfile: '../Dockerfile',
|
|
73
|
+
}));
|
|
74
|
+
await writeRepoFile(`${folder}/Dockerfile`, 'FROM apify/actor-node:22\nCOPY . ./\nCMD ["node", "main.js"]\n');
|
|
75
|
+
await writeRepoFile(`${folder}/main.js`, `console.log('dummy ${i + 1}');\n`);
|
|
76
|
+
actors.push({ folder, actorFullName, tokenEnvVar: TOKEN_ENV_VAR });
|
|
77
|
+
}
|
|
78
|
+
await writeRepoFile('apify-test-tools.config.json', JSON.stringify({ actors }));
|
|
79
|
+
git('add', '-A');
|
|
80
|
+
git('commit', '-q', '-m', 'chore: init');
|
|
81
|
+
baseSha = git('rev-parse', 'HEAD');
|
|
82
|
+
git('checkout', '-q', '-b', 'feature');
|
|
83
|
+
await writeRepoFile('actors/dummy-1/main.js', "console.log('dummy 1 changed');\n");
|
|
84
|
+
git('add', '-A');
|
|
85
|
+
git('commit', '-q', '-m', 'fix(dummy-1): change');
|
|
86
|
+
});
|
|
87
|
+
afterAll(async () => {
|
|
88
|
+
if (repoDir)
|
|
89
|
+
await rm(repoDir, { recursive: true, force: true });
|
|
90
|
+
});
|
|
91
|
+
it('build --dry-run plans a test build of the changed Actor only', () => {
|
|
92
|
+
const { status, stdout, stderr } = runCli('build', '--source-branch', 'feature', '--target-branch', 'main', '--repo-url', REPO_URL, '--dry-run');
|
|
93
|
+
expect(status, stderr).toBe(0);
|
|
94
|
+
expect(JSON.parse(stdout)).toEqual({
|
|
95
|
+
dryRun: true,
|
|
96
|
+
builds: [
|
|
97
|
+
{
|
|
98
|
+
actorFullName: ACTORS[0],
|
|
99
|
+
versionNumber: '0.99',
|
|
100
|
+
gitRepoUrl: `${REPO_URL}#feature:actors/dummy-1`,
|
|
101
|
+
useDockerCache: false,
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
it('release --dry-run plans a build of the default version and tag', () => {
|
|
107
|
+
const { status, stderr } = runCli('release', '--base-commit', baseSha, '--repo-url', REPO_URL, '--dry-run');
|
|
108
|
+
expect(status, stderr).toBe(0);
|
|
109
|
+
expect(stderr).toContain(`[DRY RUN] Would build:\n ${ACTORS[0]} (0.0) from ${REPO_URL}#feature:actors/dummy-1`);
|
|
110
|
+
expect(stderr).toContain('Skipping slack notification');
|
|
111
|
+
});
|
|
112
|
+
it('build-from-local --dry-run plans both Actors from the working tree', () => {
|
|
113
|
+
const { status, stdout, stderr } = runCli('build-from-local', '--dry-run');
|
|
114
|
+
expect(status, stderr).toBe(0);
|
|
115
|
+
expect(JSON.parse(stdout)).toMatchObject({
|
|
116
|
+
dryRun: true,
|
|
117
|
+
builds: ACTORS.map((actorFullName) => ({ actorFullName, versionNumber: '0.98', fileCount: 3 })),
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
it('build-from-local builds both Actors', { timeout: 10 * 60_000 }, () => {
|
|
121
|
+
const { status, stdout, stderr } = runCli('build-from-local');
|
|
122
|
+
expect(status, stderr).toBe(0);
|
|
123
|
+
builds = JSON.parse(stdout);
|
|
124
|
+
expect(builds.map((build) => build.actorFullName)).toEqual(ACTORS);
|
|
125
|
+
for (const build of builds)
|
|
126
|
+
expect(build.buildNumber).toMatch(/^0\.98\.\d+$/);
|
|
127
|
+
});
|
|
128
|
+
it('runs the builds through testActor and reports the results', { timeout: 10 * 60_000 }, async () => {
|
|
129
|
+
expect(builds, 'needs the builds from the previous test').toBeDefined();
|
|
130
|
+
// A consumer's platform test, importing the lib from this checkout. The symlink lets it
|
|
131
|
+
// resolve vitest and the lib's dependencies the way an installed package would.
|
|
132
|
+
await symlink(path.join(projectRoot, 'node_modules'), path.join(repoDir, 'node_modules'), 'dir');
|
|
133
|
+
const libPath = path.join(projectRoot, 'index.ts');
|
|
134
|
+
const actorTests = ACTORS.map((actorId) => `
|
|
135
|
+
testActor(${JSON.stringify(actorId)}, 'finishes', async ({ expect, run }) => {
|
|
136
|
+
const result = await run({ input: {} });
|
|
137
|
+
expect(result.status).toBe('SUCCEEDED');
|
|
138
|
+
});`).join('\n');
|
|
139
|
+
await writeRepoFile('test/platform/dummies.test.ts', `import { describe, testActor } from ${JSON.stringify(libPath)};
|
|
140
|
+
|
|
141
|
+
describe('sandbox dummies', () => {${actorTests}
|
|
142
|
+
});
|
|
143
|
+
`);
|
|
144
|
+
const vitest = spawnSync(process.execPath, [vitestPath, 'run', 'test/platform', '--reporter=json', '--outputFile=./test-output.json'], {
|
|
145
|
+
cwd: repoDir,
|
|
146
|
+
encoding: 'utf8',
|
|
147
|
+
timeout: PROCESS_TIMEOUT_MS,
|
|
148
|
+
env: { ...cliEnv, TESTER_APIFY_TOKEN: token, ACTOR_BUILDS: JSON.stringify(builds) },
|
|
149
|
+
});
|
|
150
|
+
expect(vitest.status, `${vitest.stdout}\n${vitest.stderr}${vitest.error ? `\n${vitest.error.message}` : ''}`).toBe(0);
|
|
151
|
+
// Each run used the build from ACTOR_BUILDS, not the Actor's default build.
|
|
152
|
+
const report = JSON.parse(await readFile(path.join(repoDir, 'test-output.json'), 'utf8'));
|
|
153
|
+
const assertions = report.testResults.flatMap((file) => file.assertionResults);
|
|
154
|
+
expect(assertions).toHaveLength(ACTORS.length);
|
|
155
|
+
const client = new ApifyClient({ token });
|
|
156
|
+
const runBuildIds = await Promise.all(assertions.map(async ({ meta }) => (await client.run(meta.runId).get())?.buildId));
|
|
157
|
+
expect(runBuildIds.sort()).toEqual(builds.map((build) => build.buildId).sort());
|
|
158
|
+
const { status, stderr } = runCli('report-tests', '--report-file', 'test-output.json', '--dry-run');
|
|
159
|
+
expect(status, stderr).toBe(0);
|
|
160
|
+
expect(stderr).toContain(`PASSED: ${ACTORS.length}, FAILED: 0`);
|
|
161
|
+
expect(stderr).toContain('https://console.apify.com/view/runs/');
|
|
162
|
+
});
|
|
163
|
+
// Last, so builds from earlier runs of this suite don't pile up in the sandbox.
|
|
164
|
+
it('delete-old-builds keeps the default builds', () => {
|
|
165
|
+
const { status, stderr } = runCli('delete-old-builds');
|
|
166
|
+
expect(status, stderr).toBe(0);
|
|
167
|
+
for (const actorFullName of ACTORS) {
|
|
168
|
+
expect(stderr).toContain(`[DELETE OLD BUILDS][${actorFullName}]: Skipping default build`);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
//# sourceMappingURL=cli-bundle.e2e.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-bundle.e2e.test.js","sourceRoot":"","sources":["../../../test/e2e/cli-bundle.e2e.test.ts"],"names":[],"mappings":"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"}
|