apify-test-tools 0.10.2-beta.2 → 0.10.2-beta.20
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 +22 -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 +167 -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 +138 -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 +146 -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 +469 -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 +175 -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
|
@@ -26,22 +26,6 @@ jobs:
|
|
|
26
26
|
# - name: Check spelling with typos
|
|
27
27
|
# uses: crate-ci/typos@v1
|
|
28
28
|
|
|
29
|
-
major_tag_refs:
|
|
30
|
-
name: Major tag refs
|
|
31
|
-
runs-on: ubuntu-latest
|
|
32
|
-
steps:
|
|
33
|
-
- name: Checkout repository
|
|
34
|
-
uses: actions/checkout@v6
|
|
35
|
-
- name: Use Node.js
|
|
36
|
-
uses: actions/setup-node@v6
|
|
37
|
-
with:
|
|
38
|
-
node-version: 24
|
|
39
|
-
# `uses:` takes no expressions, so the major tag is repeated in every ref into this repo.
|
|
40
|
-
# Missing one during a bump is silent while both tags exist: the new workflows quietly
|
|
41
|
-
# run the old composite action.
|
|
42
|
-
- name: Check refs match MAJOR_TAG
|
|
43
|
-
run: node .github/scripts/check-major-tag-refs.mjs
|
|
44
|
-
|
|
45
29
|
lint_check:
|
|
46
30
|
name: Lint check
|
|
47
31
|
runs-on: ubuntu-latest
|
|
@@ -93,10 +77,10 @@ jobs:
|
|
|
93
77
|
- name: Build
|
|
94
78
|
run: npm run build
|
|
95
79
|
|
|
96
|
-
# The composite action runs the CLI
|
|
97
|
-
#
|
|
80
|
+
# The composite action runs the CLI and workflow helper bundles, which the pre-commit hook rebuilds.
|
|
81
|
+
# This catches commits that skipped the hook, so stale bundles never ship.
|
|
98
82
|
cli_bundle:
|
|
99
|
-
name: CLI
|
|
83
|
+
name: CLI and workflow bundles
|
|
100
84
|
runs-on: ubuntu-latest
|
|
101
85
|
steps:
|
|
102
86
|
- name: Checkout repository
|
|
@@ -112,8 +96,8 @@ jobs:
|
|
|
112
96
|
- name: Check the bundle is up to date
|
|
113
97
|
run: |
|
|
114
98
|
npm run bundle
|
|
115
|
-
if ! git diff --quiet -- .github/cli
|
|
116
|
-
echo "::error
|
|
99
|
+
if ! git diff --quiet -- .github/cli/ .github/scripts/run-with-apify-tokens.mjs; then
|
|
100
|
+
echo "::error::A CLI or workflow script bundle is out of date. Run \`npm run bundle\` and commit the result."
|
|
117
101
|
exit 1
|
|
118
102
|
fi
|
|
119
103
|
node .github/cli/apify-test-tools.mjs --help > /dev/null
|
|
@@ -42,8 +42,8 @@ jobs:
|
|
|
42
42
|
# it. Depending on a regex in another repo to keep releases working is not a dependency
|
|
43
43
|
# worth having, and `v1` beside a package `v1.0.0` would be worse still.
|
|
44
44
|
#
|
|
45
|
-
#
|
|
46
|
-
#
|
|
45
|
+
# The workflows load this repo with `$/`, so they never name the tag. Only the usage
|
|
46
|
+
# examples in the workflows, README and docs do: update them by hand when bumping it.
|
|
47
47
|
MAJOR_TAG: workflows-v0
|
|
48
48
|
steps:
|
|
49
49
|
- name: Checkout repository
|
|
@@ -22,14 +22,19 @@ name: 'Platform tests: Claude failure investigation and fix'
|
|
|
22
22
|
# platformTestsCore:
|
|
23
23
|
# uses: apify/apify-test-tools/.github/workflows/public_platform-tests.yaml@workflows-v0
|
|
24
24
|
# with:
|
|
25
|
-
#
|
|
26
|
-
#
|
|
25
|
+
# test-files-glob: 'test/platform/hourly/**'
|
|
26
|
+
# report-slack-channel: '#notif-my-repo'
|
|
27
|
+
# secrets:
|
|
28
|
+
# TESTER_APIFY_TOKEN: ${{ secrets.TESTER_APIFY_TOKEN }}
|
|
29
|
+
# SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
|
|
27
30
|
#
|
|
28
31
|
# handle-failure:
|
|
29
32
|
# needs: platformTestsCore
|
|
30
33
|
# if: ${{ failure() }}
|
|
31
34
|
# uses: apify/apify-test-tools/.github/workflows/public_platform-tests-claude-investigate-and-fix.yaml@workflows-v0
|
|
32
|
-
# secrets:
|
|
35
|
+
# secrets:
|
|
36
|
+
# ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
37
|
+
# TESTER_APIFY_TOKEN: ${{ secrets.TESTER_APIFY_TOKEN }}
|
|
33
38
|
|
|
34
39
|
on:
|
|
35
40
|
workflow_call:
|
|
@@ -39,6 +44,11 @@ on:
|
|
|
39
44
|
type: string
|
|
40
45
|
default: sonnet
|
|
41
46
|
description: Claude model to use for investigation and fix
|
|
47
|
+
effort:
|
|
48
|
+
required: false
|
|
49
|
+
type: string
|
|
50
|
+
default: ''
|
|
51
|
+
description: Claude effort level (low, medium, high, xhigh, max) to use for investigation and fix. Uses the Claude Code default when empty.
|
|
42
52
|
max_flakiness_runs:
|
|
43
53
|
required: false
|
|
44
54
|
type: number
|
|
@@ -59,14 +69,34 @@ on:
|
|
|
59
69
|
|
|
60
70
|
Before you create a new issue, check whether the `platform-tests-investigate-and-fix:measure-flakiness` skill applies, and follow it if it does.
|
|
61
71
|
|
|
72
|
+
At the end of your investigation, before you create a new issue, follow the `platform-tests-investigate-and-fix:assess-impact` skill.
|
|
73
|
+
|
|
62
74
|
When you create the issue, write it like an incident postmortem: a short summary and impact up top for anyone skimming, full technical detail below for whoever fixes it. Don't water down the engineering detail to make the top readable.
|
|
63
75
|
- Title: short and clean, describing the actual problem in plain terms — no dates, run numbers, or other noise. Prefix it with a conventional-commit-style type, e.g. "fix: blocking issue on detail endpoint".
|
|
64
|
-
- Body, section 1 ("## Summary"): one line stating what's broken plus its impact, in plain language a PM can understand at a glance — no jargon, internal field names, or stack traces (e.g. "Scraping product detail pages fails when a listing has no reviews
|
|
76
|
+
- Body, section 1 ("## Summary"): one line stating what's broken plus its impact, in plain language a PM can understand at a glance — no jargon, internal field names, or stack traces (e.g. "Scraping product detail pages fails when a listing has no reviews").
|
|
65
77
|
- If you measured flakiness, a "## Flakiness" section right after the Summary, as the `measure-flakiness` skill describes.
|
|
78
|
+
- An "## Impact" section under the Flakiness section (or under the Summary if there's none), as the `assess-impact` skill describes.
|
|
66
79
|
- A `---` divider, then section 2 ("## Details"): the engineering bug report — root cause, relevant log lines, links to the failing run, and any other internals an engineer needs. If a single item/request failed among otherwise-good ones, show or link that specific one (e.g. the dataset item index/id, or its matching debug snapshot) rather than just describing the run as failed.
|
|
67
80
|
|
|
68
81
|
If you create a new issue, you MUST write its issue number (just the number, nothing else) to $GITHUB_WORKSPACE/issue-number.txt as the very last thing you do. If you skip creating one because a duplicate already exists, do not create the file.
|
|
69
82
|
description: Prompt given to Claude for the investigation phase. Override to customize how issues are investigated, titled, and described.
|
|
83
|
+
priority_prompt:
|
|
84
|
+
required: false
|
|
85
|
+
type: string
|
|
86
|
+
# The prio prompt here is purposefully vague; you can adjust it to
|
|
87
|
+
# use custom thresholds based on measured impact metrics.
|
|
88
|
+
default: |
|
|
89
|
+
After you create a new issue and before you write its issue number to $GITHUB_WORKSPACE/issue-number.txt, set its Priority field from the failure's impact and flakiness:
|
|
90
|
+
|
|
91
|
+
To do so, exercise your best judgement. Issues marked with higher priority will be reacted to first.
|
|
92
|
+
Here are guidelines:
|
|
93
|
+
- Determine priority based on combined severity and revenue actually at risk: a less severe bug can outrank a more severe one if much more revenue is actually at risk, and vice versa.
|
|
94
|
+
- If the Impact section considers the bug from several points of view, each in its own sub-section, base the priority on the most impactful one.
|
|
95
|
+
- If it helps you, you can base your assessment off priorities of already existing bugs in the repo.
|
|
96
|
+
- Invisible to the user or Test severity always receives lowest priority.
|
|
97
|
+
|
|
98
|
+
Priority is an organization-level issue field. If the revenue actually at risk can't be determined, e.g. the Impact section says "Cannot be determined", leave Priority unset, unless the relative severity is Invisible to the user or Test.
|
|
99
|
+
description: Prompt given to Claude for setting a new issue's Priority field from its impact and flakiness. Override to customize how priority is judged, e.g. to set revenue thresholds.
|
|
70
100
|
secrets:
|
|
71
101
|
ANTHROPIC_API_KEY:
|
|
72
102
|
required: true
|
|
@@ -77,6 +107,12 @@ on:
|
|
|
77
107
|
NPM_TOKEN:
|
|
78
108
|
required: false
|
|
79
109
|
description: Read-only token for installing private npm packages before Claude runs.
|
|
110
|
+
REDASH_API_KEY:
|
|
111
|
+
required: false
|
|
112
|
+
description: Redash API key for measuring the failure's impact — affected runs, high-touch customers and revenue — from Snowflake.
|
|
113
|
+
AGENT_SKILLS_INTERNAL_GITHUB_TOKEN:
|
|
114
|
+
required: false
|
|
115
|
+
description: GitHub token with read access to apify/agent-skills-internal, for installing its redash-analyst plugin.
|
|
80
116
|
|
|
81
117
|
jobs:
|
|
82
118
|
investigate:
|
|
@@ -92,29 +128,71 @@ jobs:
|
|
|
92
128
|
- name: Checkout repository
|
|
93
129
|
uses: actions/checkout@v5
|
|
94
130
|
|
|
131
|
+
- name: Check which optional secrets are set
|
|
132
|
+
id: optional-secrets
|
|
133
|
+
run: |
|
|
134
|
+
echo "agent-skills-token=${{ secrets.AGENT_SKILLS_INTERNAL_GITHUB_TOKEN != '' }}" >> "$GITHUB_OUTPUT"
|
|
135
|
+
echo "redash-api-key=${{ secrets.REDASH_API_KEY != '' }}" >> "$GITHUB_OUTPUT"
|
|
136
|
+
|
|
137
|
+
- name: Checkout internal agent skills
|
|
138
|
+
id: agent-skills-internal
|
|
139
|
+
if: steps.optional-secrets.outputs.agent-skills-token == 'true'
|
|
140
|
+
continue-on-error: true
|
|
141
|
+
uses: actions/checkout@v5
|
|
142
|
+
with:
|
|
143
|
+
repository: apify/agent-skills-internal
|
|
144
|
+
token: ${{ secrets.AGENT_SKILLS_INTERNAL_GITHUB_TOKEN }}
|
|
145
|
+
path: .agent-skills-internal
|
|
146
|
+
sparse-checkout: |
|
|
147
|
+
.claude-plugin
|
|
148
|
+
skills/redash-analyst
|
|
149
|
+
persist-credentials: false
|
|
150
|
+
|
|
151
|
+
- uses: actions/setup-node@v6
|
|
152
|
+
if: steps.optional-secrets.outputs.redash-api-key == 'true'
|
|
153
|
+
with:
|
|
154
|
+
node-version: 24
|
|
155
|
+
|
|
156
|
+
- name: Install Redash MCP server
|
|
157
|
+
if: steps.optional-secrets.outputs.redash-api-key == 'true'
|
|
158
|
+
continue-on-error: true
|
|
159
|
+
working-directory: ${{ runner.temp }}
|
|
160
|
+
run: npm install --prefix redash-mcp --ignore-scripts --no-audit --no-fund @suthio/redash-mcp@0.1.0
|
|
161
|
+
|
|
95
162
|
- name: Run Claude Code
|
|
96
163
|
id: claude
|
|
97
164
|
uses: anthropics/claude-code-action@8251c103ac8c1d761882c86aba1412c7f583c844 # v1.0.213
|
|
98
165
|
env:
|
|
99
166
|
TESTER_APIFY_TOKEN: ${{ secrets.TESTER_APIFY_TOKEN }}
|
|
167
|
+
REDASH_API_KEY: ${{ secrets.REDASH_API_KEY }}
|
|
100
168
|
MAX_FLAKINESS_RUNS: ${{ inputs.max_flakiness_runs }}
|
|
101
169
|
with:
|
|
102
170
|
prompt: |
|
|
103
171
|
The failing E2E platform test ran in workflow run ${{ github.run_id }} of this repo.
|
|
104
172
|
|
|
105
173
|
${{ inputs.investigate_prompt }}
|
|
174
|
+
|
|
175
|
+
${{ inputs.priority_prompt }}
|
|
106
176
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
107
177
|
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
108
|
-
plugin_marketplaces:
|
|
109
|
-
|
|
178
|
+
plugin_marketplaces: |
|
|
179
|
+
https://github.com/apify/apify-test-tools.git
|
|
180
|
+
${{ steps.agent-skills-internal.outcome == 'success' && format('{0}/.agent-skills-internal', github.workspace) || '' }}
|
|
181
|
+
plugins: |
|
|
182
|
+
platform-tests-investigate-and-fix@apify-test-tools
|
|
183
|
+
${{ steps.agent-skills-internal.outcome == 'success' && 'redash-analyst@apify-agent-skills-internal' || '' }}
|
|
110
184
|
# The `tools` query parameter below selects which tools the Apify MCP server
|
|
111
185
|
# exposes: reading an Actor run — its status, exit code, storage ids and log — and
|
|
112
186
|
# reading that run's dataset items and its key-value store keys and records, e.g.
|
|
113
187
|
# INPUT, OUTPUT and error snapshots. WARN: the server adds `abort-actor-run` on top
|
|
114
188
|
# even when not listed here, see https://github.com/apify/apify-mcp-server
|
|
189
|
+
# `--disallowedTools` removes the Redash MCP server's tools that change Redash: creating,
|
|
190
|
+
# editing, sharing or deleting queries, visualizations, dashboards, widgets, alerts and snippets.
|
|
115
191
|
claude_args: |
|
|
116
|
-
--mcp-config '{"mcpServers":{"apify":{"type":"http","url":"https://mcp.apify.com/?tools=get-actor-run,get-actor-run-log,get-dataset-list,get-dataset,get-dataset-items,get-key-value-store-list,get-key-value-store,get-key-value-store-keys,get-key-value-store-record","headers":{"Authorization":"Bearer ${TESTER_APIFY_TOKEN}"}}}}'
|
|
192
|
+
--mcp-config '{"mcpServers":{"apify":{"type":"http","url":"https://mcp.apify.com/?tools=get-actor-run,get-actor-run-log,get-dataset-list,get-dataset,get-dataset-items,get-key-value-store-list,get-key-value-store,get-key-value-store-keys,get-key-value-store-record","headers":{"Authorization":"Bearer ${TESTER_APIFY_TOKEN}"}},"redash":{"type":"stdio","command":"${{ runner.temp }}/redash-mcp/node_modules/.bin/redash-mcp","env":{"REDASH_URL":"https://charts.apify.com/","REDASH_API_KEY":"${REDASH_API_KEY}"}}}}'
|
|
193
|
+
--disallowedTools mcp__redash__create_query,mcp__redash__update_query,mcp__redash__update_query_parameters,mcp__redash__archive_query,mcp__redash__fork_query,mcp__redash__add_query_favorite,mcp__redash__remove_query_favorite,mcp__redash__create_visualization,mcp__redash__update_visualization,mcp__redash__update_chart_visualization,mcp__redash__delete_visualization,mcp__redash__create_dashboard,mcp__redash__update_dashboard,mcp__redash__update_dashboard_parameters,mcp__redash__archive_dashboard,mcp__redash__fork_dashboard,mcp__redash__share_dashboard,mcp__redash__unshare_dashboard,mcp__redash__add_dashboard_favorite,mcp__redash__remove_dashboard_favorite,mcp__redash__create_alert,mcp__redash__update_alert,mcp__redash__delete_alert,mcp__redash__mute_alert,mcp__redash__add_alert_subscription,mcp__redash__remove_alert_subscription,mcp__redash__create_widget,mcp__redash__update_widget,mcp__redash__update_widget_layout,mcp__redash__update_dashboard_layout,mcp__redash__update_widget_parameter_mappings,mcp__redash__delete_widget,mcp__redash__create_query_snippet,mcp__redash__update_query_snippet,mcp__redash__delete_query_snippet
|
|
117
194
|
--model ${{ inputs.model }}
|
|
195
|
+
${{ inputs.effort && format('--effort {0}', inputs.effort) || '' }}
|
|
118
196
|
--dangerously-skip-permissions
|
|
119
197
|
|
|
120
198
|
- name: Upload Claude output (for debugging)
|
|
@@ -177,7 +255,9 @@ jobs:
|
|
|
177
255
|
actions: read
|
|
178
256
|
steps:
|
|
179
257
|
- name: Setup repository and dependencies
|
|
180
|
-
|
|
258
|
+
# `$/` loads the action from this repo at the commit this workflow was called at, so a caller
|
|
259
|
+
# pinned to a SHA or a branch gets that commit's action and CLI, not whatever the major tag is on.
|
|
260
|
+
uses: $/.github/actions/checkout-restore-dependencies
|
|
181
261
|
with:
|
|
182
262
|
npm-token: ${{ secrets.NPM_TOKEN }}
|
|
183
263
|
|
|
@@ -190,6 +270,7 @@ jobs:
|
|
|
190
270
|
prompt: 'Open a pull request to address GitHub issue #${{ needs.investigate.outputs.issue_number }}. Use `gh issue view ${{ needs.investigate.outputs.issue_number }}` to read the issue details first, then implement the fix and create a PR.'
|
|
191
271
|
claude_args: |
|
|
192
272
|
--model ${{ inputs.model }}
|
|
273
|
+
${{ inputs.effort && format('--effort {0}', inputs.effort) || '' }}
|
|
193
274
|
--dangerously-skip-permissions
|
|
194
275
|
|
|
195
276
|
- name: Upload Claude output (for debugging)
|
|
@@ -3,21 +3,27 @@ name: Platform tests
|
|
|
3
3
|
on:
|
|
4
4
|
workflow_call:
|
|
5
5
|
inputs:
|
|
6
|
-
#
|
|
7
|
-
subtest:
|
|
8
|
-
type: string
|
|
9
|
-
default: ''
|
|
10
|
-
required: false
|
|
11
|
-
# Specify what tests you want to run, relative to `test/platform`
|
|
6
|
+
# Glob of the test files to run, from the repo root, e.g. `test/platform/{hourly,hourly-without-pr}/**`
|
|
12
7
|
test-files-glob:
|
|
13
8
|
type: string
|
|
14
|
-
default: ''
|
|
9
|
+
default: 'test/platform/**'
|
|
15
10
|
required: false
|
|
16
|
-
#
|
|
11
|
+
# Slack channel for failed tests. Empty skips Slack.
|
|
17
12
|
report-slack-channel:
|
|
18
13
|
type: string
|
|
19
14
|
default: ''
|
|
20
15
|
required: false
|
|
16
|
+
# Only TESTER_APIFY_TOKEN is required, every test needs it. See the Secrets section of docs/workflows.md.
|
|
17
|
+
secrets:
|
|
18
|
+
NPM_TOKEN:
|
|
19
|
+
required: false
|
|
20
|
+
description: Read-only token for installing private npm packages.
|
|
21
|
+
TESTER_APIFY_TOKEN:
|
|
22
|
+
required: true
|
|
23
|
+
description: Apify token the platform tests run Actors with.
|
|
24
|
+
SLACK_BOT_TOKEN:
|
|
25
|
+
required: false
|
|
26
|
+
description: Slack token for reporting test results.
|
|
21
27
|
|
|
22
28
|
jobs:
|
|
23
29
|
scheduledPlatformTests:
|
|
@@ -26,37 +32,69 @@ jobs:
|
|
|
26
32
|
runs-on: ubuntu-latest
|
|
27
33
|
steps:
|
|
28
34
|
- name: Setup repository and dependencies
|
|
29
|
-
#
|
|
30
|
-
|
|
35
|
+
# `$/` loads the action from this repo at the commit this workflow was called at, so a caller
|
|
36
|
+
# pinned to a SHA or a branch gets that commit's action and CLI, not whatever the major tag is on.
|
|
37
|
+
uses: $/.github/actions/checkout-restore-dependencies
|
|
31
38
|
with:
|
|
32
39
|
npm-token: ${{ secrets.NPM_TOKEN }}
|
|
33
40
|
|
|
41
|
+
# Fails here with a clear message rather than deep in vitest. `required: true` alone doesn't
|
|
42
|
+
# catch it: a caller can list the secret while the repo doesn't have it, and PRs from forks
|
|
43
|
+
# never get secrets.
|
|
44
|
+
- name: Check TESTER_APIFY_TOKEN
|
|
45
|
+
env:
|
|
46
|
+
TESTER_APIFY_TOKEN: ${{ secrets.TESTER_APIFY_TOKEN }}
|
|
47
|
+
run: |
|
|
48
|
+
if [ -z "$TESTER_APIFY_TOKEN" ]; then
|
|
49
|
+
echo "::error::TESTER_APIFY_TOKEN is empty. Pass it in the secrets: block of the job that calls this workflow."
|
|
50
|
+
exit 1
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# Runs the repo's test code and its whole import graph, so it gets the tester token only.
|
|
54
|
+
# Fails on failing tests, but writes the report anyway for the notification below.
|
|
55
|
+
# Every Actor in the config, on its default build: the one users run
|
|
34
56
|
- name: Test
|
|
57
|
+
id: test
|
|
58
|
+
# bash rather than the default shell, for pipefail
|
|
59
|
+
shell: bash
|
|
35
60
|
env:
|
|
36
61
|
TESTER_APIFY_TOKEN: ${{ secrets.TESTER_APIFY_TOKEN }}
|
|
37
|
-
|
|
62
|
+
# Passed through the environment and quoted, so the shell doesn't expand the glob itself
|
|
63
|
+
# An empty input, e.g. from an expression that picks the glob, runs everything, like the default
|
|
64
|
+
TEST_FILES_GLOB: ${{ inputs.test-files-glob || 'test/platform/**' }}
|
|
65
|
+
run: |
|
|
66
|
+
apify-test-tools get-actor-configs \
|
|
67
|
+
| apify-test-tools test --test-files-glob "$TEST_FILES_GLOB" \
|
|
68
|
+
--reporter github-actions --vitest-output-file ./test-output.json > test-report.json
|
|
69
|
+
|
|
70
|
+
# Posts only when the tests failed, but checks the Slack token on every run that has a channel. Runs
|
|
71
|
+
# whenever the tests did, also after a failure, but not when the token check stopped the job before them.
|
|
72
|
+
- name: Notify
|
|
73
|
+
if: ${{ !cancelled() && steps.test.outcome != 'skipped' }}
|
|
74
|
+
env:
|
|
75
|
+
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
|
|
76
|
+
# Passed through the environment, so a quote in the workflow name can't break the command
|
|
77
|
+
WORKFLOW_NAME: ${{ github.workflow }}
|
|
78
|
+
JOB_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
|
|
79
|
+
# Empty makes notify skip Slack
|
|
80
|
+
SLACK_CHANNEL: ${{ inputs.report-slack-channel }}
|
|
38
81
|
run: |
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
--
|
|
46
|
-
--
|
|
47
|
-
--
|
|
48
|
-
|
|
49
|
-
return_code=$?
|
|
50
|
-
apify-test-tools report-tests \
|
|
51
|
-
--report-file ./test-output.json \
|
|
52
|
-
--workflow-name "${{ github.workflow }}" \
|
|
53
|
-
--job-url "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
|
|
54
|
-
--report-slack-channel "${{ inputs.report-slack-channel || format('#notif-{0}', github.event.repository.name) }}"
|
|
55
|
-
exit $return_code
|
|
82
|
+
# Empty when `test` itself failed before running vitest, its error is in the Test step
|
|
83
|
+
if [ ! -s test-report.json ]; then
|
|
84
|
+
echo "No test report, so there is nothing to notify about"
|
|
85
|
+
exit 0
|
|
86
|
+
fi
|
|
87
|
+
apify-test-tools notify \
|
|
88
|
+
--slack-channel "$SLACK_CHANNEL" \
|
|
89
|
+
--title "$WORKFLOW_NAME" \
|
|
90
|
+
--job-url "$JOB_URL" \
|
|
91
|
+
< test-report.json
|
|
56
92
|
|
|
57
|
-
- name: Upload
|
|
93
|
+
- name: Upload test reports
|
|
58
94
|
uses: actions/upload-artifact@v6
|
|
59
95
|
if: always()
|
|
60
96
|
with:
|
|
61
97
|
name: vitest-results
|
|
62
|
-
path:
|
|
98
|
+
path: |
|
|
99
|
+
./test-output.json
|
|
100
|
+
./test-report.json
|
|
@@ -7,11 +7,33 @@ on:
|
|
|
7
7
|
type: boolean
|
|
8
8
|
default: false
|
|
9
9
|
required: false
|
|
10
|
-
#
|
|
10
|
+
# Glob of the test files to run, from the repo root, e.g. `test/platform/{daily,hourly}/**`. Which changed
|
|
11
|
+
# files count as test changes is `platformTestsGlob` in apify-test-tools.config.json, not this.
|
|
11
12
|
test-files-glob:
|
|
12
13
|
type: string
|
|
13
|
-
default: ''
|
|
14
|
+
default: 'test/platform/**'
|
|
14
15
|
required: false
|
|
16
|
+
# Fail the build unless the env var names of version 0.99 match the default version's
|
|
17
|
+
require-env-vars-in-sync:
|
|
18
|
+
type: boolean
|
|
19
|
+
default: true
|
|
20
|
+
required: false
|
|
21
|
+
# Every secret is optional. The ones this workflow reads are declared by name. The secrets that
|
|
22
|
+
# apify-test-tools.config.json names (e.g. each Actor's `tokenEnvVar`) differ per repo, so they
|
|
23
|
+
# come packed in CONFIG_SECRETS. See the Secrets section of docs/workflows.md.
|
|
24
|
+
secrets:
|
|
25
|
+
NPM_TOKEN:
|
|
26
|
+
required: false
|
|
27
|
+
description: Read-only token for installing private npm packages.
|
|
28
|
+
TESTER_APIFY_TOKEN:
|
|
29
|
+
required: false
|
|
30
|
+
description: Apify token the platform tests run Actors with.
|
|
31
|
+
CONFIG_SECRETS:
|
|
32
|
+
required: false
|
|
33
|
+
description: >-
|
|
34
|
+
JSON object of the secrets apify-test-tools.config.json names, secret name -> value.
|
|
35
|
+
Today that is each Actor's `tokenEnvVar`. Passing `toJSON(secrets)` works too, only
|
|
36
|
+
the names the config declares are used.
|
|
15
37
|
|
|
16
38
|
concurrency:
|
|
17
39
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
@@ -24,11 +46,25 @@ jobs:
|
|
|
24
46
|
steps:
|
|
25
47
|
- name: Setup repository and dependencies
|
|
26
48
|
id: setup
|
|
27
|
-
#
|
|
28
|
-
|
|
49
|
+
# `$/` loads the action from this repo at the commit this workflow was called at, so a caller
|
|
50
|
+
# pinned to a SHA or a branch gets that commit's action and CLI, not whatever the major tag is on.
|
|
51
|
+
uses: $/.github/actions/checkout-restore-dependencies
|
|
29
52
|
with:
|
|
30
53
|
# Some repos use private npm packages, they need to pass NPM_TOKEN secret to this workflow
|
|
31
54
|
npm-token: ${{ secrets.NPM_TOKEN }}
|
|
55
|
+
config-secrets: ${{ secrets.CONFIG_SECRETS }}
|
|
56
|
+
|
|
57
|
+
# Fails here with a clear message rather than deep in vitest. `required: true` alone doesn't
|
|
58
|
+
# catch it: a caller can list the secret while the repo doesn't have it, and PRs from forks
|
|
59
|
+
# never get secrets.
|
|
60
|
+
- name: Check TESTER_APIFY_TOKEN
|
|
61
|
+
env:
|
|
62
|
+
TESTER_APIFY_TOKEN: ${{ secrets.TESTER_APIFY_TOKEN }}
|
|
63
|
+
run: |
|
|
64
|
+
if [ -z "$TESTER_APIFY_TOKEN" ]; then
|
|
65
|
+
echo "::error::TESTER_APIFY_TOKEN is empty. Pass it in the secrets: block of the job that calls this workflow."
|
|
66
|
+
exit 1
|
|
67
|
+
fi
|
|
32
68
|
|
|
33
69
|
- name: Pick last validated commit from cache
|
|
34
70
|
id: base_commit
|
|
@@ -41,54 +77,56 @@ jobs:
|
|
|
41
77
|
# This is needed to force overriding the cache with new entry at the end
|
|
42
78
|
restore-keys: base_commit-
|
|
43
79
|
|
|
44
|
-
#
|
|
45
|
-
#
|
|
46
|
-
|
|
47
|
-
- name: Build
|
|
48
|
-
id: build
|
|
80
|
+
# Needs no tokens, it only reads git and apify-test-tools.config.json. The setup action checks out
|
|
81
|
+
# the PR branch itself (not GitHub's merge commit), so the range ends at the branch's HEAD.
|
|
82
|
+
- name: Find affected Actors
|
|
49
83
|
env:
|
|
50
|
-
ALL_SECRETS: ${{ toJSON(secrets) }}
|
|
51
84
|
# Branch names are attacker-controlled on fork PRs, so they reach the script as
|
|
52
85
|
# environment variables rather than being interpolated into it.
|
|
53
|
-
HEAD_REF: ${{ github.head_ref }}
|
|
54
86
|
BASE_REF: ${{ github.base_ref }}
|
|
55
|
-
SCRIPTS_PATH: ${{ steps.setup.outputs.scripts-path }}
|
|
56
87
|
run: |
|
|
57
88
|
base_commit=$(cat base_commit.txt 2>/dev/null || echo "")
|
|
58
89
|
echo "Last validated (base) commit to be used for build & test: $base_commit"
|
|
59
|
-
args=(
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
90
|
+
args=(--base "origin/$BASE_REF")
|
|
91
|
+
[ -n "$base_commit" ] && args+=(--since "$base_commit")
|
|
92
|
+
apify-test-tools get-affected-actors "${args[@]}" > affected.json
|
|
93
|
+
|
|
94
|
+
# Cosmetic-only changes need no tests, so only the Actors with functional or platform test changes are
|
|
95
|
+
# built, into the test version 0.99 that users never run.
|
|
96
|
+
# run-with-apify-tokens.mjs reads the token names from in apify-test-tools.config.json
|
|
97
|
+
# and hands the build those secrets and nothing else, so the tokens stay in this one command instead of the whole job.
|
|
98
|
+
# The library never sees secrets it doesn't need
|
|
99
|
+
- name: Build
|
|
100
|
+
# bash rather than the default shell, for pipefail
|
|
101
|
+
shell: bash
|
|
102
|
+
env:
|
|
103
|
+
WORKFLOW_SECRETS: ${{ toJSON(secrets) }}
|
|
104
|
+
SCRIPTS_PATH: ${{ steps.setup.outputs.scripts-path }}
|
|
105
|
+
REQUIRE_ENV_VARS_IN_SYNC: ${{ inputs.require-env-vars-in-sync }}
|
|
106
|
+
run: |
|
|
107
|
+
jq '{ actors: (.functionallyChangedActors + .testChangedActors) }' affected.json \
|
|
108
|
+
| node "$SCRIPTS_PATH/run-with-apify-tokens.mjs" apify-test-tools build --version-number 0.99 \
|
|
109
|
+
--require-env-vars-in-sync="$REQUIRE_ENV_VARS_IN_SYNC" \
|
|
110
|
+
| tee builds.json
|
|
70
111
|
|
|
71
112
|
# Runs the repo's test code and its whole import graph, so it gets the tester token only.
|
|
72
113
|
- name: Test
|
|
73
114
|
env:
|
|
74
|
-
ACTOR_BUILDS: ${{ steps.build.outputs.actor_builds }}
|
|
75
115
|
TESTER_APIFY_TOKEN: ${{ secrets.TESTER_APIFY_TOKEN }}
|
|
76
|
-
|
|
116
|
+
# Passed through the environment and quoted, so the shell doesn't expand the glob itself
|
|
117
|
+
# An empty input, e.g. from an expression that picks the glob, runs everything, like the default
|
|
118
|
+
TEST_FILES_GLOB: ${{ inputs.test-files-glob || 'test/platform/**' }}
|
|
119
|
+
# The github-actions reporter annotates the PR with the failing tests
|
|
120
|
+
run: |
|
|
121
|
+
apify-test-tools test --test-files-glob "$TEST_FILES_GLOB" --reporter github-actions \
|
|
122
|
+
< builds.json > test-report.json
|
|
77
123
|
|
|
78
124
|
# NOTE: This is an optimization that if we did functional changes and later only cosmetic changes (e.g. dev readme), we will compare changes files only for the last commit. This must run after tests because we want to cache the latest commit only if the tests are successful
|
|
79
125
|
- name: Store last validated commit to cache
|
|
80
|
-
env:
|
|
81
|
-
HEAD_REF: ${{ github.head_ref }}
|
|
82
|
-
BASE_REF: ${{ github.base_ref }}
|
|
83
126
|
run: |
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
--source-branch "origin/$HEAD_REF"
|
|
88
|
-
--target-branch "origin/$BASE_REF"
|
|
89
|
-
)
|
|
90
|
-
[ -n "$base_commit" ] && args+=(--base-commit "$base_commit")
|
|
91
|
-
apify-test-tools get-latest-commit "${args[@]}" > ./base_commit.txt
|
|
127
|
+
echo "Old last validated (base) commit: $(cat base_commit.txt 2>/dev/null || echo "")"
|
|
128
|
+
# The HEAD that was just built and tested
|
|
129
|
+
jq -r .head affected.json > base_commit.txt
|
|
92
130
|
echo "New last validated (base) commit: $(cat base_commit.txt)"
|
|
93
131
|
|
|
94
132
|
# Pure static checks against the repo. Needs no Apify or Slack credentials, only the npm
|
|
@@ -98,8 +136,9 @@ jobs:
|
|
|
98
136
|
runs-on: ubuntu-latest
|
|
99
137
|
steps:
|
|
100
138
|
- name: Setup repository and dependencies
|
|
101
|
-
#
|
|
102
|
-
|
|
139
|
+
# `$/` loads the action from this repo at the commit this workflow was called at, so a caller
|
|
140
|
+
# pinned to a SHA or a branch gets that commit's action and CLI, not whatever the major tag is on.
|
|
141
|
+
uses: $/.github/actions/checkout-restore-dependencies
|
|
103
142
|
with:
|
|
104
143
|
npm-token: ${{ secrets.NPM_TOKEN }}
|
|
105
144
|
|
|
@@ -3,11 +3,27 @@ name: Build latest and report to slack
|
|
|
3
3
|
on:
|
|
4
4
|
workflow_call:
|
|
5
5
|
inputs:
|
|
6
|
-
#
|
|
6
|
+
# Slack channel for release announcements. Empty skips Slack.
|
|
7
7
|
report-slack-channel:
|
|
8
8
|
type: string
|
|
9
9
|
default: ''
|
|
10
10
|
required: false
|
|
11
|
+
# Every secret is optional. The ones this workflow reads are declared by name. The secrets that
|
|
12
|
+
# apify-test-tools.config.json names (e.g. each Actor's `tokenEnvVar`) differ per repo, so they
|
|
13
|
+
# come packed in CONFIG_SECRETS. See the Secrets section of docs/workflows.md.
|
|
14
|
+
secrets:
|
|
15
|
+
NPM_TOKEN:
|
|
16
|
+
required: false
|
|
17
|
+
description: Read-only token for installing private npm packages.
|
|
18
|
+
SLACK_BOT_TOKEN:
|
|
19
|
+
required: false
|
|
20
|
+
description: Slack token for announcing releases.
|
|
21
|
+
CONFIG_SECRETS:
|
|
22
|
+
required: false
|
|
23
|
+
description: >-
|
|
24
|
+
JSON object of the secrets apify-test-tools.config.json names, secret name -> value.
|
|
25
|
+
Today that is each Actor's `tokenEnvVar`. Passing `toJSON(secrets)` works too, only
|
|
26
|
+
the names the config declares are used.
|
|
11
27
|
|
|
12
28
|
jobs:
|
|
13
29
|
pushBuildLatest:
|
|
@@ -20,27 +36,49 @@ jobs:
|
|
|
20
36
|
steps:
|
|
21
37
|
- name: Setup repository and dependencies
|
|
22
38
|
id: setup
|
|
23
|
-
#
|
|
24
|
-
|
|
39
|
+
# `$/` loads the action from this repo at the commit this workflow was called at, so a caller
|
|
40
|
+
# pinned to a SHA or a branch gets that commit's action and CLI, not whatever the major tag is on.
|
|
41
|
+
uses: $/.github/actions/checkout-restore-dependencies
|
|
25
42
|
with:
|
|
26
43
|
npm-token: ${{ secrets.NPM_TOKEN }}
|
|
44
|
+
config-secrets: ${{ secrets.CONFIG_SECRETS }}
|
|
45
|
+
|
|
46
|
+
# --since is the last commit that is already released: the push's "before" commit.
|
|
47
|
+
# Everything after it up to HEAD gets released. See the "Releasing Actors" section of docs/cli.md.
|
|
48
|
+
# Needs no tokens, it only reads git and apify-test-tools.config.json.
|
|
49
|
+
- name: Find changes since the last release
|
|
50
|
+
run: |
|
|
51
|
+
apify-test-tools get-affected-actors --since ${{ github.event.before }} > affected.json
|
|
27
52
|
|
|
28
|
-
#
|
|
29
|
-
#
|
|
53
|
+
# A release ships cosmetic changes too (README, input schema descriptions), so both lists are built,
|
|
54
|
+
# into each Actor's default version: the one its default build tag points to, which users run.
|
|
55
|
+
# testChangedActors is left out: a change to platform tests alone needs no release.
|
|
30
56
|
# run-with-apify-tokens.mjs reads the token names from in apify-test-tools.config.json
|
|
31
57
|
# and hands the build those secrets and nothing else, so the tokens stay in this one command instead of the whole job.
|
|
32
58
|
# The library never sees secrets it doesn't need
|
|
33
|
-
- name:
|
|
59
|
+
- name: Build the default versions
|
|
60
|
+
# bash rather than the default shell, for pipefail
|
|
61
|
+
shell: bash
|
|
34
62
|
env:
|
|
35
|
-
|
|
36
|
-
SLACK_TOKEN_RELEASES_BOT: ${{ secrets.SLACK_TOKEN_RELEASES_BOT }}
|
|
63
|
+
WORKFLOW_SECRETS: ${{ toJSON(secrets) }}
|
|
37
64
|
run: |
|
|
38
|
-
|
|
39
|
-
|
|
65
|
+
jq '{ actors: (.functionallyChangedActors + .cosmeticallyChangedActors) }' affected.json \
|
|
66
|
+
| node "${{ steps.setup.outputs.scripts-path }}/run-with-apify-tokens.mjs" \
|
|
67
|
+
apify-test-tools build --version-number default
|
|
68
|
+
|
|
69
|
+
# Skips the announcement when the push brought no new commits, or when no channel is set
|
|
70
|
+
- name: Announce the release on Slack
|
|
71
|
+
env:
|
|
72
|
+
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
|
|
73
|
+
SLACK_CHANNEL: ${{ inputs.report-slack-channel }}
|
|
74
|
+
run: |
|
|
75
|
+
apify-test-tools notify \
|
|
76
|
+
--slack-channel "$SLACK_CHANNEL" \
|
|
77
|
+
< affected.json
|
|
40
78
|
|
|
41
79
|
- name: Delete old builds
|
|
42
80
|
env:
|
|
43
|
-
|
|
81
|
+
WORKFLOW_SECRETS: ${{ toJSON(secrets) }}
|
|
44
82
|
run: |
|
|
45
83
|
node "${{ steps.setup.outputs.scripts-path }}/run-with-apify-tokens.mjs" \
|
|
46
84
|
apify-test-tools delete-old-builds
|