apify-test-tools 0.10.2-beta.1 → 0.10.2-beta.11
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/actionlint.yaml +11 -0
- package/.github/actions/checkout-restore-dependencies/action.yaml +64 -28
- package/.github/cli/apify-test-tools.mjs +360 -0
- package/.github/scripts/mask-config-secrets.sh +17 -0
- package/.github/scripts/run-with-apify-tokens.mjs +37 -12
- package/.github/workflows/_check_code.yaml +25 -16
- package/.github/workflows/_move_major_tag.yaml +5 -83
- package/.github/workflows/_tests.yaml +34 -0
- package/.github/workflows/_update_release_metadata.yaml +0 -12
- package/.github/workflows/manual_move_major_tag.yaml +3 -3
- package/.github/workflows/manual_release_stable.yaml +3 -13
- package/.github/workflows/on_master.yaml +9 -5
- package/.github/workflows/on_pull_request.yaml +3 -48
- package/.github/workflows/public_platform-tests-claude-investigate-and-fix.yaml +16 -3
- package/.github/workflows/public_platform-tests.yaml +27 -3
- package/.github/workflows/public_pr-build-test.yaml +67 -29
- package/.github/workflows/public_push-build-latest.yaml +44 -10
- package/.github/workflows/public_review.yaml +5 -4
- package/.husky/pre-commit +5 -0
- package/.prettierignore +3 -0
- package/CHANGELOG.md +17 -0
- package/CONTRIBUTING.md +112 -24
- package/README.md +218 -600
- package/bin/affected-actors.ts +198 -0
- package/bin/build-from-local.ts +65 -13
- package/bin/build.ts +123 -41
- package/bin/diff-changes.ts +32 -23
- package/bin/diff-json-schema.ts +5 -6
- package/bin/git.ts +69 -99
- package/bin/main.ts +96 -135
- package/bin/slack.ts +43 -10
- package/bin/stdin-input.ts +65 -0
- package/bin/test-report.ts +6 -9
- package/bin/types.ts +15 -0
- package/dist/bin/affected-actors.d.ts +46 -0
- package/dist/bin/affected-actors.d.ts.map +1 -0
- package/dist/bin/affected-actors.js +135 -0
- package/dist/bin/affected-actors.js.map +1 -0
- package/dist/bin/build-from-local.d.ts +12 -3
- package/dist/bin/build-from-local.d.ts.map +1 -1
- package/dist/bin/build-from-local.js +34 -12
- package/dist/bin/build-from-local.js.map +1 -1
- package/dist/bin/build.d.ts +30 -7
- package/dist/bin/build.d.ts.map +1 -1
- package/dist/bin/build.js +85 -26
- package/dist/bin/build.js.map +1 -1
- package/dist/bin/diff-changes.d.ts +11 -4
- package/dist/bin/diff-changes.d.ts.map +1 -1
- package/dist/bin/diff-changes.js +19 -19
- package/dist/bin/diff-changes.js.map +1 -1
- package/dist/bin/diff-json-schema.d.ts +2 -2
- package/dist/bin/diff-json-schema.d.ts.map +1 -1
- package/dist/bin/diff-json-schema.js +1 -4
- package/dist/bin/diff-json-schema.js.map +1 -1
- package/dist/bin/git.d.ts +23 -21
- package/dist/bin/git.d.ts.map +1 -1
- package/dist/bin/git.js +60 -83
- package/dist/bin/git.js.map +1 -1
- package/dist/bin/main.js +82 -105
- package/dist/bin/main.js.map +1 -1
- package/dist/bin/slack.d.ts +14 -4
- package/dist/bin/slack.d.ts.map +1 -1
- package/dist/bin/slack.js +39 -6
- package/dist/bin/slack.js.map +1 -1
- package/dist/bin/stdin-input.d.ts +17 -0
- package/dist/bin/stdin-input.d.ts.map +1 -0
- package/dist/bin/stdin-input.js +54 -0
- package/dist/bin/stdin-input.js.map +1 -0
- package/dist/bin/test-report.d.ts.map +1 -1
- package/dist/bin/test-report.js +6 -8
- package/dist/bin/test-report.js.map +1 -1
- package/dist/bin/types.d.ts +13 -0
- package/dist/bin/types.d.ts.map +1 -1
- package/dist/lib/extend-expect.d.ts.map +1 -1
- package/dist/lib/extend-expect.js +37 -218
- package/dist/lib/extend-expect.js.map +1 -1
- package/dist/lib/lib.d.ts +1 -2
- package/dist/lib/lib.d.ts.map +1 -1
- package/dist/lib/lib.js +15 -22
- package/dist/lib/lib.js.map +1 -1
- package/dist/lib/run-checks.d.ts +14 -0
- package/dist/lib/run-checks.d.ts.map +1 -0
- package/dist/lib/run-checks.js +82 -0
- package/dist/lib/run-checks.js.map +1 -0
- package/dist/lib/run-test-result.d.ts +3 -6
- package/dist/lib/run-test-result.d.ts.map +1 -1
- package/dist/lib/run-test-result.js +41 -54
- package/dist/lib/run-test-result.js.map +1 -1
- package/dist/test/bundle/cli-bundle.test.d.ts +2 -0
- package/dist/test/bundle/cli-bundle.test.d.ts.map +1 -0
- package/dist/test/bundle/cli-bundle.test.js +190 -0
- package/dist/test/bundle/cli-bundle.test.js.map +1 -0
- package/dist/test/e2e/cli-bundle.e2e.test.d.ts +2 -0
- package/dist/test/e2e/cli-bundle.e2e.test.d.ts.map +1 -0
- package/dist/test/e2e/cli-bundle.e2e.test.js +138 -0
- package/dist/test/e2e/cli-bundle.e2e.test.js.map +1 -0
- package/dist/test/e2e/git-build-release.e2e.test.d.ts +2 -0
- package/dist/test/e2e/git-build-release.e2e.test.d.ts.map +1 -0
- package/dist/test/e2e/git-build-release.e2e.test.js +87 -0
- package/dist/test/e2e/git-build-release.e2e.test.js.map +1 -0
- package/dist/test/e2e/helpers.d.ts +37 -0
- package/dist/test/e2e/helpers.d.ts.map +1 -0
- package/dist/test/e2e/helpers.js +57 -0
- package/dist/test/e2e/helpers.js.map +1 -0
- package/dist/test/unit/bin/affected-actors-cli.test.d.ts +2 -0
- package/dist/test/unit/bin/affected-actors-cli.test.d.ts.map +1 -0
- package/dist/test/unit/bin/affected-actors-cli.test.js +167 -0
- package/dist/test/unit/bin/affected-actors-cli.test.js.map +1 -0
- package/dist/test/unit/bin/affected-actors.test.d.ts +2 -0
- package/dist/test/unit/bin/affected-actors.test.d.ts.map +1 -0
- package/dist/test/unit/bin/affected-actors.test.js +141 -0
- package/dist/test/unit/bin/affected-actors.test.js.map +1 -0
- package/dist/test/unit/bin/build-cli.test.d.ts +2 -0
- package/dist/test/unit/bin/build-cli.test.d.ts.map +1 -0
- package/dist/test/unit/bin/build-cli.test.js +44 -0
- package/dist/test/unit/bin/build-cli.test.js.map +1 -0
- package/dist/test/unit/bin/build-from-local.test.js +65 -1
- package/dist/test/unit/bin/build-from-local.test.js.map +1 -1
- package/dist/test/unit/bin/build.test.js +223 -3
- package/dist/test/unit/bin/build.test.js.map +1 -1
- package/dist/test/unit/bin/compiled-cli.d.ts +6 -0
- package/dist/test/unit/bin/compiled-cli.d.ts.map +1 -0
- package/dist/test/unit/bin/compiled-cli.js +16 -0
- package/dist/test/unit/bin/compiled-cli.js.map +1 -0
- package/dist/test/unit/bin/diff-changes.test.js +130 -101
- package/dist/test/unit/bin/diff-changes.test.js.map +1 -1
- package/dist/test/unit/bin/diff.test.js +25 -28
- package/dist/test/unit/bin/diff.test.js.map +1 -1
- package/dist/test/unit/bin/git.test.js +69 -152
- package/dist/test/unit/bin/git.test.js.map +1 -1
- package/dist/test/unit/bin/slack.test.d.ts +2 -0
- package/dist/test/unit/bin/slack.test.d.ts.map +1 -0
- package/dist/test/unit/bin/slack.test.js +71 -0
- package/dist/test/unit/bin/slack.test.js.map +1 -0
- package/dist/test/unit/bin/stdin-input.test.d.ts +2 -0
- package/dist/test/unit/bin/stdin-input.test.d.ts.map +1 -0
- package/dist/test/unit/bin/stdin-input.test.js +50 -0
- package/dist/test/unit/bin/stdin-input.test.js.map +1 -0
- package/dist/test/unit/github-scripts/mask-config-secrets.test.d.ts +2 -0
- package/dist/test/unit/github-scripts/mask-config-secrets.test.d.ts.map +1 -0
- package/dist/test/unit/github-scripts/mask-config-secrets.test.js +50 -0
- package/dist/test/unit/github-scripts/mask-config-secrets.test.js.map +1 -0
- package/dist/test/unit/github-scripts/run-with-apify-tokens.test.d.ts +2 -0
- package/dist/test/unit/github-scripts/run-with-apify-tokens.test.d.ts.map +1 -0
- package/dist/test/unit/github-scripts/run-with-apify-tokens.test.js +102 -0
- package/dist/test/unit/github-scripts/run-with-apify-tokens.test.js.map +1 -0
- package/dist/test/unit/run-checks.test.d.ts +2 -0
- package/dist/test/unit/run-checks.test.d.ts.map +1 -0
- package/dist/test/unit/run-checks.test.js +62 -0
- package/dist/test/unit/run-checks.test.js.map +1 -0
- package/dist/test/unit/run-test-result.test.d.ts +2 -0
- package/dist/test/unit/run-test-result.test.d.ts.map +1 -0
- package/dist/test/unit/run-test-result.test.js +34 -0
- package/dist/test/unit/run-test-result.test.js.map +1 -0
- package/dist/test/unit/should-built-and-test.test.js +41 -38
- package/dist/test/unit/should-built-and-test.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/docs/cli.md +373 -0
- package/docs/lib.md +271 -0
- package/docs/workflows.md +370 -0
- package/lib/extend-expect.ts +48 -258
- package/lib/lib.ts +24 -28
- package/lib/run-checks.ts +101 -0
- package/lib/run-test-result.ts +45 -55
- package/package.json +13 -3
- package/test/bundle/cli-bundle.test.ts +235 -0
- package/test/e2e/cli-bundle.e2e.test.ts +207 -0
- package/test/e2e/git-build-release.e2e.test.ts +113 -0
- package/test/e2e/helpers.ts +82 -0
- package/test/unit/bin/affected-actors-cli.test.ts +201 -0
- package/test/unit/bin/affected-actors.test.ts +182 -0
- package/test/unit/bin/build-cli.test.ts +55 -0
- package/test/unit/bin/build-from-local.test.ts +71 -0
- package/test/unit/bin/build.test.ts +279 -3
- package/test/unit/bin/compiled-cli.ts +17 -0
- package/test/unit/bin/diff-changes.test.ts +139 -101
- package/test/unit/bin/diff.test.ts +25 -28
- package/test/unit/bin/git.test.ts +85 -176
- package/test/unit/bin/slack.test.ts +84 -0
- package/test/unit/bin/stdin-input.test.ts +61 -0
- package/test/unit/github-scripts/mask-config-secrets.test.ts +61 -0
- package/test/unit/github-scripts/run-with-apify-tokens.test.ts +115 -0
- package/test/unit/run-checks.test.ts +76 -0
- package/test/unit/run-test-result.test.ts +44 -0
- package/test/unit/should-built-and-test.test.ts +46 -39
- package/.github/scripts/check-major-tag-refs.mjs +0 -72
- package/.github/scripts/check-package-version-bump.mjs +0 -74
- package/.github/workflows-package-version +0 -1
|
@@ -12,6 +12,27 @@ on:
|
|
|
12
12
|
type: string
|
|
13
13
|
default: ''
|
|
14
14
|
required: false
|
|
15
|
+
# Fail the build unless the env var names of version 0.99 match the default version's
|
|
16
|
+
require-env-vars-in-sync:
|
|
17
|
+
type: boolean
|
|
18
|
+
default: true
|
|
19
|
+
required: false
|
|
20
|
+
# Every secret is optional. The ones this workflow reads are declared by name. The secrets that
|
|
21
|
+
# apify-test-tools.config.json names (e.g. each Actor's `tokenEnvVar`) differ per repo, so they
|
|
22
|
+
# come packed in CONFIG_SECRETS. See the Secrets section of docs/workflows.md.
|
|
23
|
+
secrets:
|
|
24
|
+
NPM_TOKEN:
|
|
25
|
+
required: false
|
|
26
|
+
description: Read-only token for installing private npm packages.
|
|
27
|
+
TESTER_APIFY_TOKEN:
|
|
28
|
+
required: false
|
|
29
|
+
description: Apify token the platform tests run Actors with.
|
|
30
|
+
CONFIG_SECRETS:
|
|
31
|
+
required: false
|
|
32
|
+
description: >-
|
|
33
|
+
JSON object of the secrets apify-test-tools.config.json names, secret name -> value.
|
|
34
|
+
Today that is each Actor's `tokenEnvVar`. Passing `toJSON(secrets)` works too, only
|
|
35
|
+
the names the config declares are used.
|
|
15
36
|
|
|
16
37
|
concurrency:
|
|
17
38
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
@@ -24,11 +45,25 @@ jobs:
|
|
|
24
45
|
steps:
|
|
25
46
|
- name: Setup repository and dependencies
|
|
26
47
|
id: setup
|
|
27
|
-
#
|
|
28
|
-
|
|
48
|
+
# `$/` loads the action from this repo at the commit this workflow was called at, so a caller
|
|
49
|
+
# pinned to a SHA or a branch gets that commit's action and CLI, not whatever the major tag is on.
|
|
50
|
+
uses: $/.github/actions/checkout-restore-dependencies
|
|
29
51
|
with:
|
|
30
52
|
# Some repos use private npm packages, they need to pass NPM_TOKEN secret to this workflow
|
|
31
53
|
npm-token: ${{ secrets.NPM_TOKEN }}
|
|
54
|
+
config-secrets: ${{ secrets.CONFIG_SECRETS }}
|
|
55
|
+
|
|
56
|
+
# Fails here with a clear message rather than deep in vitest. `required: true` alone doesn't
|
|
57
|
+
# catch it: a caller can list the secret while the repo doesn't have it, and PRs from forks
|
|
58
|
+
# never get secrets.
|
|
59
|
+
- name: Check TESTER_APIFY_TOKEN
|
|
60
|
+
env:
|
|
61
|
+
TESTER_APIFY_TOKEN: ${{ secrets.TESTER_APIFY_TOKEN }}
|
|
62
|
+
run: |
|
|
63
|
+
if [ -z "$TESTER_APIFY_TOKEN" ]; then
|
|
64
|
+
echo "::error::TESTER_APIFY_TOKEN is empty. Pass it in the secrets: block of the job that calls this workflow."
|
|
65
|
+
exit 1
|
|
66
|
+
fi
|
|
32
67
|
|
|
33
68
|
- name: Pick last validated commit from cache
|
|
34
69
|
id: base_commit
|
|
@@ -41,31 +76,41 @@ jobs:
|
|
|
41
76
|
# This is needed to force overriding the cache with new entry at the end
|
|
42
77
|
restore-keys: base_commit-
|
|
43
78
|
|
|
44
|
-
#
|
|
45
|
-
#
|
|
46
|
-
|
|
47
|
-
- name: Build
|
|
48
|
-
id: build
|
|
79
|
+
# Needs no tokens, it only reads git and apify-test-tools.config.json. The setup action checks out
|
|
80
|
+
# the PR branch itself (not GitHub's merge commit), so the range ends at the branch's HEAD.
|
|
81
|
+
- name: Find affected Actors
|
|
49
82
|
env:
|
|
50
|
-
ALL_SECRETS: ${{ toJSON(secrets) }}
|
|
51
83
|
# Branch names are attacker-controlled on fork PRs, so they reach the script as
|
|
52
84
|
# environment variables rather than being interpolated into it.
|
|
53
|
-
HEAD_REF: ${{ github.head_ref }}
|
|
54
85
|
BASE_REF: ${{ github.base_ref }}
|
|
55
|
-
SCRIPTS_PATH: ${{ steps.setup.outputs.scripts-path }}
|
|
56
86
|
run: |
|
|
57
87
|
base_commit=$(cat base_commit.txt 2>/dev/null || echo "")
|
|
58
88
|
echo "Last validated (base) commit to be used for build & test: $base_commit"
|
|
59
89
|
args=(
|
|
60
|
-
--
|
|
61
|
-
--target-branch "origin/$BASE_REF"
|
|
90
|
+
--base "origin/$BASE_REF"
|
|
62
91
|
# TODO: Temporary hotfix until build glob matching aligns with Vitest's test selection glob.
|
|
63
92
|
--test-files-glob 'test/platform/**'
|
|
64
|
-
--use-docker-cache
|
|
65
93
|
)
|
|
66
|
-
[ -n "$base_commit" ] && args+=(--
|
|
67
|
-
|
|
68
|
-
|
|
94
|
+
[ -n "$base_commit" ] && args+=(--since "$base_commit")
|
|
95
|
+
apify-test-tools get-affected-actors "${args[@]}" > affected.json
|
|
96
|
+
|
|
97
|
+
# Cosmetic-only changes need no tests, so only the functionally changed Actors are built, into the
|
|
98
|
+
# test version 0.99 that users never run.
|
|
99
|
+
# run-with-apify-tokens.mjs reads the token names from in apify-test-tools.config.json
|
|
100
|
+
# and hands the build those secrets and nothing else, so the tokens stay in this one command instead of the whole job.
|
|
101
|
+
# The library never sees secrets it doesn't need
|
|
102
|
+
- name: Build
|
|
103
|
+
id: build
|
|
104
|
+
# bash rather than the default shell, for pipefail
|
|
105
|
+
shell: bash
|
|
106
|
+
env:
|
|
107
|
+
WORKFLOW_SECRETS: ${{ toJSON(secrets) }}
|
|
108
|
+
SCRIPTS_PATH: ${{ steps.setup.outputs.scripts-path }}
|
|
109
|
+
REQUIRE_ENV_VARS_IN_SYNC: ${{ inputs.require-env-vars-in-sync }}
|
|
110
|
+
run: |
|
|
111
|
+
actor_builds=$(jq '{ actors: .functionallyChangedActors }' affected.json \
|
|
112
|
+
| node "$SCRIPTS_PATH/run-with-apify-tokens.mjs" apify-test-tools build --version-number 0.99 \
|
|
113
|
+
--require-env-vars-in-sync="$REQUIRE_ENV_VARS_IN_SYNC")
|
|
69
114
|
echo "actor_builds=$actor_builds" | tee -a "$GITHUB_OUTPUT"
|
|
70
115
|
|
|
71
116
|
# Runs the repo's test code and its whole import graph, so it gets the tester token only.
|
|
@@ -77,18 +122,10 @@ jobs:
|
|
|
77
122
|
|
|
78
123
|
# 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
124
|
- name: Store last validated commit to cache
|
|
80
|
-
env:
|
|
81
|
-
HEAD_REF: ${{ github.head_ref }}
|
|
82
|
-
BASE_REF: ${{ github.base_ref }}
|
|
83
125
|
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
|
-
npx apify-test-tools get-latest-commit "${args[@]}" > ./base_commit.txt
|
|
126
|
+
echo "Old last validated (base) commit: $(cat base_commit.txt 2>/dev/null || echo "")"
|
|
127
|
+
# The HEAD that was just built and tested
|
|
128
|
+
jq -r .head affected.json > base_commit.txt
|
|
92
129
|
echo "New last validated (base) commit: $(cat base_commit.txt)"
|
|
93
130
|
|
|
94
131
|
# Pure static checks against the repo. Needs no Apify or Slack credentials, only the npm
|
|
@@ -98,8 +135,9 @@ jobs:
|
|
|
98
135
|
runs-on: ubuntu-latest
|
|
99
136
|
steps:
|
|
100
137
|
- name: Setup repository and dependencies
|
|
101
|
-
#
|
|
102
|
-
|
|
138
|
+
# `$/` loads the action from this repo at the commit this workflow was called at, so a caller
|
|
139
|
+
# pinned to a SHA or a branch gets that commit's action and CLI, not whatever the major tag is on.
|
|
140
|
+
uses: $/.github/actions/checkout-restore-dependencies
|
|
103
141
|
with:
|
|
104
142
|
npm-token: ${{ secrets.NPM_TOKEN }}
|
|
105
143
|
|
|
@@ -8,6 +8,22 @@ on:
|
|
|
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_TOKEN_RELEASES_BOT:
|
|
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,45 @@ 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.
|
|
30
55
|
# run-with-apify-tokens.mjs reads the token names from in apify-test-tools.config.json
|
|
31
56
|
# and hands the build those secrets and nothing else, so the tokens stay in this one command instead of the whole job.
|
|
32
57
|
# The library never sees secrets it doesn't need
|
|
33
|
-
- name:
|
|
58
|
+
- name: Build the default versions
|
|
59
|
+
# bash rather than the default shell, for pipefail
|
|
60
|
+
shell: bash
|
|
61
|
+
env:
|
|
62
|
+
WORKFLOW_SECRETS: ${{ toJSON(secrets) }}
|
|
63
|
+
run: |
|
|
64
|
+
jq '{ actors: (.functionallyChangedActors + .cosmeticallyChangedActors) }' affected.json \
|
|
65
|
+
| node "${{ steps.setup.outputs.scripts-path }}/run-with-apify-tokens.mjs" \
|
|
66
|
+
apify-test-tools build --version-number default
|
|
67
|
+
|
|
68
|
+
# Skips the announcement when the push brought no new commits
|
|
69
|
+
- name: Announce the release on Slack
|
|
34
70
|
env:
|
|
35
|
-
ALL_SECRETS: ${{ toJSON(secrets) }}
|
|
36
71
|
SLACK_TOKEN_RELEASES_BOT: ${{ secrets.SLACK_TOKEN_RELEASES_BOT }}
|
|
37
72
|
run: |
|
|
38
|
-
|
|
39
|
-
npx apify-test-tools release --base-commit ${{ github.event.before }} --release-slack-channel "#delivery-public-actors" --report-slack-channel "${{ inputs.report-slack-channel || format('#notif-{0}', github.event.repository.name) }}" --use-docker-cache
|
|
73
|
+
apify-test-tools notify-release --release-slack-channel "#delivery-public-actors" --report-slack-channel "${{ inputs.report-slack-channel || format('#notif-{0}', github.event.repository.name) }}" < affected.json
|
|
40
74
|
|
|
41
75
|
- name: Delete old builds
|
|
42
76
|
env:
|
|
43
|
-
|
|
77
|
+
WORKFLOW_SECRETS: ${{ toJSON(secrets) }}
|
|
44
78
|
run: |
|
|
45
79
|
node "${{ steps.setup.outputs.scripts-path }}/run-with-apify-tokens.mjs" \
|
|
46
|
-
|
|
80
|
+
apify-test-tools delete-old-builds
|
|
@@ -14,12 +14,12 @@ on:
|
|
|
14
14
|
description: Label added after a successful review and never removed. Set to an empty string to disable.
|
|
15
15
|
required: false
|
|
16
16
|
prompt-ref:
|
|
17
|
-
default:
|
|
17
|
+
default: ''
|
|
18
18
|
type: string
|
|
19
19
|
description: >-
|
|
20
20
|
Ref of this repository to fetch the review instructions from. Defaults to the
|
|
21
|
-
|
|
22
|
-
test a prompt change from a branch.
|
|
21
|
+
commit this workflow was called at, so the instructions always match it. Override
|
|
22
|
+
it only to test a prompt change from a branch.
|
|
23
23
|
required: false
|
|
24
24
|
model:
|
|
25
25
|
default: sonnet
|
|
@@ -55,10 +55,11 @@ jobs:
|
|
|
55
55
|
# head_ref must be used for pull_request but for push and schedule events we have to use ref to get the branch name
|
|
56
56
|
ref: ${{ github.head_ref || github.ref }}
|
|
57
57
|
|
|
58
|
+
# job.workflow_* is this reusable workflow's own repo and commit; the github context is the caller's.
|
|
58
59
|
- name: 'Fetch review instructions'
|
|
59
60
|
run: |
|
|
60
61
|
curl -sfL \
|
|
61
|
-
"https://raw.githubusercontent.com
|
|
62
|
+
"https://raw.githubusercontent.com/${{ job.workflow_repository }}/${{ inputs.prompt-ref || job.workflow_sha }}/.github/review-prompt.md" \
|
|
62
63
|
-o "${{ github.workspace }}/.claude-review-prompt.md"
|
|
63
64
|
|
|
64
65
|
- name: 'Review PR against guidelines'
|
package/.husky/pre-commit
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
echo "pre-commit: typechecking, linting, testing, checking code formatting, checking for unused exports & validating schemas"
|
|
2
2
|
|
|
3
3
|
|
|
4
|
+
# The workflows run the CLI from this bundle, so it ships with every commit that changes bin/ or its
|
|
5
|
+
# dependencies. Rebuilding takes well under a second.
|
|
6
|
+
npm run -s bundle
|
|
7
|
+
git add .github/cli/apify-test-tools.mjs
|
|
8
|
+
|
|
4
9
|
npm test
|
|
5
10
|
npm run format:check
|
|
6
11
|
# We typecheck & lint last when we know our code works
|
package/.prettierignore
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -5,10 +5,27 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
<!-- git-cliff-unreleased-start -->
|
|
6
6
|
## 0.10.2 - **not yet released**
|
|
7
7
|
|
|
8
|
+
### 🚀 Features
|
|
9
|
+
|
|
10
|
+
- **ci:** Ship the workflows' CLI as a bundle in the action instead of installing it ([#200](https://github.com/apify/apify-test-tools/pull/200)) ([a0ef975](https://github.com/apify/apify-test-tools/commit/a0ef9756123a30a8210590b080a2a289c6a9c17c)) by [@metalwarrior665](https://github.com/metalwarrior665)
|
|
11
|
+
- [**breaking**] Revamp get-affected-actors to be a core logic command ([#190](https://github.com/apify/apify-test-tools/pull/190)) ([ea5f244](https://github.com/apify/apify-test-tools/commit/ea5f244cfd42bf3fa9ffd38cd2ad499dde2e83f8)) by [@metalwarrior665](https://github.com/metalwarrior665)
|
|
12
|
+
- [**breaking**] Add logic-less build command and use command chaining in workflows ([#193](https://github.com/apify/apify-test-tools/pull/193)) ([e5b0b86](https://github.com/apify/apify-test-tools/commit/e5b0b86ee06fca51d4be0ddc81b0a4a469d31603)) by [@metalwarrior665](https://github.com/metalwarrior665)
|
|
13
|
+
- **get-affected-actors:** Three-dot diff, narrowed per Actor with --since ([#204](https://github.com/apify/apify-test-tools/pull/204)) ([fa9a0e7](https://github.com/apify/apify-test-tools/commit/fa9a0e7518764dd4722ec9ecbf67b2a26a5a062e)) by [@metalwarrior665](https://github.com/metalwarrior665)
|
|
14
|
+
- Add effort input to Claude investigate-and-fix workflow ([#221](https://github.com/apify/apify-test-tools/pull/221)) ([c2ac078](https://github.com/apify/apify-test-tools/commit/c2ac078aec9ef02337af0e5c06db1b947b6c969b)) by [@foxt451](https://github.com/foxt451)
|
|
15
|
+
- **ci:** Support pnpm ([#214](https://github.com/apify/apify-test-tools/pull/214)) ([ee7d734](https://github.com/apify/apify-test-tools/commit/ee7d7340564c5b8657a8a1f0cf920d67b40ae013)) by [@ruocco-l](https://github.com/ruocco-l)
|
|
16
|
+
- Support flexible secret passing methods in workflows ([#225](https://github.com/apify/apify-test-tools/pull/225)) ([22f7e80](https://github.com/apify/apify-test-tools/commit/22f7e807ca3949656c15b79f848a192d71b15946)) by [@metalwarrior665](https://github.com/metalwarrior665), closes [#205](https://github.com/apify/apify-test-tools/issues/205)
|
|
17
|
+
- [**breaking**] Require env vars of test versions in sync with the default version ([#217](https://github.com/apify/apify-test-tools/pull/217)) ([a2481dd](https://github.com/apify/apify-test-tools/commit/a2481ddf09004308cb54e49b783c8b21a25dcbe4)) by [@metalwarrior665](https://github.com/metalwarrior665)
|
|
18
|
+
|
|
8
19
|
### 🐛 Bug Fixes
|
|
9
20
|
|
|
10
21
|
- **toBeObject:** Reject null ([#191](https://github.com/apify/apify-test-tools/pull/191)) ([6bdae49](https://github.com/apify/apify-test-tools/commit/6bdae4905756e0ae8dd6146942e6fc04dbead48e)) by [@JuanGalilea](https://github.com/JuanGalilea), closes [#88](https://github.com/apify/apify-test-tools/issues/88)
|
|
11
22
|
- Build and test on test-only changes even when .dockerignore lists the tests ([#177](https://github.com/apify/apify-test-tools/pull/177)) ([5cb1b5a](https://github.com/apify/apify-test-tools/commit/5cb1b5ab5f6f43ec279f9624b402e73d55a5974a)) by [@artogahr](https://github.com/artogahr), closes [#145](https://github.com/apify/apify-test-tools/issues/145)
|
|
23
|
+
- **git:** List both paths of moved files when detecting changes ([#215](https://github.com/apify/apify-test-tools/pull/215)) ([44ba565](https://github.com/apify/apify-test-tools/commit/44ba565242c1ac3daea281a648acb28712bb4363)) by [@metalwarrior665](https://github.com/metalwarrior665)
|
|
24
|
+
- **workflows:** Load setup action and review prompt from the called commit ([#226](https://github.com/apify/apify-test-tools/pull/226)) ([7524711](https://github.com/apify/apify-test-tools/commit/752471135d4d147f6f6492a26c08af388d7ccf72)) by [@metalwarrior665](https://github.com/metalwarrior665)
|
|
25
|
+
|
|
26
|
+
### 🚜 Refactor
|
|
27
|
+
|
|
28
|
+
- [**breaking**] Remove build-for-test and release composite commands ([#203](https://github.com/apify/apify-test-tools/pull/203)) ([85efc54](https://github.com/apify/apify-test-tools/commit/85efc54697e98208c827c4f450906e00eebcd9ca)) by [@metalwarrior665](https://github.com/metalwarrior665)
|
|
12
29
|
|
|
13
30
|
|
|
14
31
|
<!-- git-cliff-unreleased-end -->
|
package/CONTRIBUTING.md
CHANGED
|
@@ -56,6 +56,8 @@ npx tsx /path/to/apify-test-tools/bin/main.ts --help
|
|
|
56
56
|
npx tsx /path/to/apify-test-tools/bin/main.ts get-commits --target-branch master --source-branch feat/testing-feature-branch
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
+
Or clone a test repo into `local-clone/` inside this repo and run `npm run start:dev -- <command>`.
|
|
60
|
+
|
|
59
61
|
#### Working on the library
|
|
60
62
|
|
|
61
63
|
You need to istall the local version of `apify-test-tools` in your cloned `testing-repo-for-github-actions`:
|
|
@@ -85,33 +87,119 @@ The tag is not semver, so `git-cliff` would abort on it. It is skipped only beca
|
|
|
85
87
|
The action's "Nothing to release" guard resolves to this tag and no longer fires, so an empty stable
|
|
86
88
|
release fails at `npm publish` instead of erroring cleanly.
|
|
87
89
|
|
|
88
|
-
Consumers pin `@workflows-v0`, not `@master`. See
|
|
89
|
-
[Versioning and releases](./README.md#versioning-and-releases) in the README for how the tag and the
|
|
90
|
-
npm release relate — the short version:
|
|
91
|
-
|
|
92
|
-
- changing only a workflow needs no npm release
|
|
93
|
-
- changing only the package needs no workflow change
|
|
94
|
-
- a workflow that calls a **new** CLI feature must set `.github/workflows-package-version` to the
|
|
95
|
-
version that will contain it, in the same PR. The `workflows-v0` tag is then held until that version is on
|
|
96
|
-
npm, so merging can't ship a workflow that calls a CLI that doesn't exist yet.
|
|
97
|
-
|
|
98
|
-
`.github/workflows-package-version` holds one exact version, and the stable release writes it. The
|
|
99
|
-
workflows install exactly it, which is what makes a frozen major tag stay frozen — it keeps the
|
|
100
|
-
library it was tested with instead of following `latest` forever.
|
|
101
|
-
|
|
102
|
-
The `Package version bump needed` check enforces the point above: a PR touching both a `public_`
|
|
103
|
-
workflow (or the composite action) and `bin/`, `lib/` or `index.ts` has to move the pin. When the
|
|
104
|
-
two changes are unrelated and the workflow doesn't need the new code, label the PR
|
|
105
|
-
`no-version-bump-needed`.
|
|
90
|
+
Consumers pin `@workflows-v0`, not `@master`. See [Versioning and releases](#versioning-and-releases) below.
|
|
106
91
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
92
|
+
- `npm test` covers the bundle without network (`test/bundle/`). `npm run test:e2e` runs it against
|
|
93
|
+
dummy Actors in an isolated sandbox account (`test/e2e/`) and skips itself unless
|
|
94
|
+
`E2E_TEST_APIFY_TOKEN_DBYPODOIHUZABNQTR` is set. CI passes that secret only to the `E2E tests` job.
|
|
95
|
+
The git `build` and release pipeline tests clone
|
|
96
|
+
[testing-repo-for-github-actions](https://github.com/apify-store/testing-repo-for-github-actions) and
|
|
97
|
+
use its `e2e/base` and `e2e/feature` branches as fixtures, so never rebase or delete those.
|
|
110
98
|
|
|
111
99
|
`npm run lint` and `actionlint` (via the `Code checks` workflow) both gate master, so run them before
|
|
112
100
|
pushing workflow changes.
|
|
113
101
|
|
|
102
|
+
The reusable workflows load the composite action with `uses: $/.github/actions/checkout-restore-dependencies`, never
|
|
103
|
+
`apify/apify-test-tools/...@workflows-v0`. `$/` is the
|
|
104
|
+
[self-repository syntax](https://github.blog/changelog/2026-07-30-reference-same-repository-actions-with-self-repository-syntax/):
|
|
105
|
+
it resolves to this repo at the commit the workflow was called at. A hardcoded tag would hand a caller pinned to an
|
|
106
|
+
older SHA, or to a branch, the action and CLI from the tag instead of from the commit they asked for.
|
|
107
|
+
|
|
114
108
|
`public_review` is the odd one out: it fetches `.github/review-prompt.md` over HTTP at run time, because a
|
|
115
|
-
reusable workflow runs with the caller's repo checked out and never gets its own.
|
|
116
|
-
|
|
117
|
-
|
|
109
|
+
reusable workflow runs with the caller's repo checked out and never gets its own. With `prompt-ref` left empty it
|
|
110
|
+
fetches from `job.workflow_repository` at `job.workflow_sha`, the commit the workflow itself came from, so the
|
|
111
|
+
instructions always match the workflow.
|
|
112
|
+
|
|
113
|
+
## Versioning and releases
|
|
114
|
+
|
|
115
|
+
The workflows and the npm package live in one repo but ship on their own schedules:
|
|
116
|
+
|
|
117
|
+
| What | Consumers get it through | Ships when |
|
|
118
|
+
| -------------------------------------------- | ------------------------------------------ | ----------------------- |
|
|
119
|
+
| the workflows and the CLI they call | the `@workflows-v0` tag in `uses:` | every master push |
|
|
120
|
+
| the lib (`testActor`, `describe`, matchers…) | `apify-test-tools` in their `package.json` | a stable release on npm |
|
|
121
|
+
|
|
122
|
+
The CLI is bundled with its dependencies into `.github/cli/apify-test-tools.mjs` (`npm run bundle`, run by the
|
|
123
|
+
pre-commit hook and checked in CI), and the setup action runs it from there. Nothing is installed for it, so a tag is
|
|
124
|
+
a complete statement: these workflows and this CLI, with the exact dependency versions from `package-lock.json` at
|
|
125
|
+
that commit. The consumer's own `node_modules` is left alone, so their tests keep the lib version they locked.
|
|
126
|
+
|
|
127
|
+
- **Workflow or CLI change** — merge it. `workflows-v0` moves once checks and tests pass, and it goes live. No
|
|
128
|
+
release needed, even when a workflow starts using a new CLI feature: both are in the same commit.
|
|
129
|
+
- **Lib change** — merge it, then cut a release when you want it out. Consumers pick it up when they update
|
|
130
|
+
`apify-test-tools`.
|
|
131
|
+
|
|
132
|
+
The CLI and the lib in one job can be different versions now, so the formats between them are a contract: the
|
|
133
|
+
`ACTOR_BUILDS` JSON that `build` writes and the lib reads, and the vitest JSON report `report-tests` reads. Add
|
|
134
|
+
fields freely; renaming or removing one needs a new major tag.
|
|
135
|
+
|
|
136
|
+
`workflows-v0` moving on every master push means `@workflows-v0` is as live as `@master` was — there's no staging
|
|
137
|
+
step. What the tag buys you is a `workflows-v1` for breaking workflow changes, so repos migrate one at a time instead
|
|
138
|
+
of all at once, and a way to roll back by pointing the tag at an earlier commit (**Move major version tag**
|
|
139
|
+
workflow). Bump `MAJOR_TAG` in `.github/workflows/_move_major_tag.yaml` to cut the next major; the old tag then
|
|
140
|
+
freezes where it is and keeps working, CLI included, since the bundle is part of the frozen commit.
|
|
141
|
+
|
|
142
|
+
The tag tracks the **workflows'** contract, not the npm package version. They move independently on purpose, so
|
|
143
|
+
`@workflows-v0` is expected to stay `@workflows-v0` after the package reaches 1.0 — bump it when a workflow breaks
|
|
144
|
+
its callers, not when the package does. The usage examples in the workflows, README and docs repeat the tag
|
|
145
|
+
literally, so update them by hand when you bump it.
|
|
146
|
+
|
|
147
|
+
## Testing workflow changes
|
|
148
|
+
|
|
149
|
+
- Point [testing-repo-for-github-actions](https://github.com/apify-store/testing-repo-for-github-actions) at your
|
|
150
|
+
branch (`uses: ...@your-branch`). It has real attached Actors and tests. The workflows load the composite action
|
|
151
|
+
with `$/` and the branch carries its own CLI bundle, so one branch tests the workflows, the action and the CLI
|
|
152
|
+
together, with nothing to repoint.
|
|
153
|
+
- Make sure the shell code actually works on your laptop first.
|
|
154
|
+
- After merging, watch the workflow on a real project before moving on.
|
|
155
|
+
|
|
156
|
+
## How the workflows scope secrets
|
|
157
|
+
|
|
158
|
+
The public side of this is the [Secrets](./docs/workflows.md#secrets) table.
|
|
159
|
+
|
|
160
|
+
The Actor tokens are the one set that cannot be listed in the workflow, because each Actor names its own token via
|
|
161
|
+
`tokenEnvVar` in `apify-test-tools.config.json`, and a reusable workflow only accepts secrets it declares by name.
|
|
162
|
+
Callers pack them into the `CONFIG_SECRETS` secret. Those steps pass `${{ toJSON(secrets) }}` as `WORKFLOW_SECRETS`
|
|
163
|
+
and run the command through `.github/scripts/run-with-apify-tokens.mjs`, which reads that same config file to decide
|
|
164
|
+
which secrets to pass on. It looks each one up in `CONFIG_SECRETS` first, then among the secrets `secrets: inherit`
|
|
165
|
+
brought:
|
|
166
|
+
|
|
167
|
+
```yaml
|
|
168
|
+
- name: Build
|
|
169
|
+
shell: bash
|
|
170
|
+
env:
|
|
171
|
+
WORKFLOW_SECRETS: ${{ toJSON(secrets) }}
|
|
172
|
+
run: |
|
|
173
|
+
jq '{ actors: .functionallyChangedActors }' affected.json \
|
|
174
|
+
| node "${{ steps.setup.outputs.scripts-path }}/run-with-apify-tokens.mjs" \
|
|
175
|
+
apify-test-tools build --version-number 0.99
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
The wrapper passes only the tokens the config declares and drops `WORKFLOW_SECRETS`, so neither the CLI nor anything
|
|
179
|
+
under `node_modules` sees the blob. Nothing is written to `$GITHUB_ENV`, so the tokens stay inside that one command
|
|
180
|
+
rather than leaking into later steps. Reading the same file `apify-test-tools` reads means the two can't drift, and a
|
|
181
|
+
secret that merely looks like an Actor token is not passed just because of its name.
|
|
182
|
+
|
|
183
|
+
A token the config declares but the repo hasn't set is a warning, not a failure: a repo can carry an Actor whose
|
|
184
|
+
token isn't configured and still build fine as long as that Actor never changes, and `apify-test-tools` raises a
|
|
185
|
+
precise error naming the Actor at the point it actually needs the token.
|
|
186
|
+
|
|
187
|
+
The runner masks a secret by its exact value, so it only knows `CONFIG_SECRETS` as a whole blob. The setup action
|
|
188
|
+
runs `.github/scripts/mask-config-secrets.sh` first, which registers each value inside it with `::add-mask::`, so a
|
|
189
|
+
token taken out of the blob is masked too.
|
|
190
|
+
|
|
191
|
+
`scripts-path` comes from the setup action (give the step `id: setup`) and points at this repo's `.github/scripts/`
|
|
192
|
+
directory inside the runner's action checkout, so workflows can run these helpers without checking this repo out
|
|
193
|
+
again. The caller's workspace holds the caller's repo, not this one.
|
|
194
|
+
|
|
195
|
+
Two tidier-looking alternatives don't work, so don't reach for them:
|
|
196
|
+
|
|
197
|
+
- **Exporting to `$GITHUB_ENV`** would let the steps call the CLI directly with no wrapper, but `$GITHUB_ENV`
|
|
198
|
+
applies to every later step in the job. In `pr-build-test` the vitest step runs after the build, so it would
|
|
199
|
+
inherit Actor tokens it has no use for.
|
|
200
|
+
- **Returning the tokens as a step output** would be scoped correctly, but the runner refuses to set an output whose
|
|
201
|
+
value contains a registered secret. It logs `Skip output <name> since it may contain secret` and leaves the output
|
|
202
|
+
empty, so anything reading it downstream gets nothing.
|
|
203
|
+
|
|
204
|
+
The `unitTest` job runs static checks and needs `NPM_TOKEN` only. No job runs `npm ci` or `pnpm install` with Apify
|
|
205
|
+
or Slack credentials in scope, so a postinstall script in the dependency tree cannot read them.
|