apify-test-tools 0.9.1-beta.9 → 0.10.1-beta.0
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/.github/actions/checkout-restore-dependencies/action.yaml +2 -28
- package/.github/workflows/_move_major_tag.yaml +40 -6
- package/.github/workflows/manual_release_stable.yaml +1 -0
- package/.github/workflows/public_platform-tests.yaml +0 -12
- package/.github/workflows/public_pr-build-test.yaml +2 -24
- package/.github/workflows/public_push-build-latest.yaml +3 -14
- package/.github/workflows/public_review.yaml +0 -7
- package/.github/workflows-package-version +1 -1
- package/CHANGELOG.md +12 -2
- package/CONTRIBUTING.md +2 -4
- package/README.md +147 -36
- package/bin/build-from-local.ts +15 -11
- package/bin/build.ts +127 -67
- package/bin/git.ts +140 -0
- package/bin/main.ts +128 -91
- package/bin/slack.ts +5 -2
- package/bin/types.ts +0 -73
- package/bin/utils/config/parser.ts +6 -5
- package/bin/utils/config/structures/base.ts +5 -1
- package/bin/utils/config/structures/grouped.ts +40 -0
- package/bin/utils/config/structures/legacy.ts +3 -1
- package/bin/utils.ts +7 -15
- package/dist/bin/build-from-local.d.ts +2 -2
- package/dist/bin/build-from-local.d.ts.map +1 -1
- package/dist/bin/build-from-local.js +11 -6
- package/dist/bin/build-from-local.js.map +1 -1
- package/dist/bin/build.d.ts +26 -4
- package/dist/bin/build.d.ts.map +1 -1
- package/dist/bin/build.js +90 -47
- package/dist/bin/build.js.map +1 -1
- package/dist/bin/git.d.ts +40 -0
- package/dist/bin/git.d.ts.map +1 -1
- package/dist/bin/git.js +118 -0
- package/dist/bin/git.js.map +1 -1
- package/dist/bin/main.d.ts +1 -20
- package/dist/bin/main.d.ts.map +1 -1
- package/dist/bin/main.js +65 -62
- package/dist/bin/main.js.map +1 -1
- package/dist/bin/slack.d.ts.map +1 -1
- package/dist/bin/slack.js +4 -2
- package/dist/bin/slack.js.map +1 -1
- package/dist/bin/types.d.ts +0 -64
- package/dist/bin/types.d.ts.map +1 -1
- package/dist/bin/utils/config/parser.d.ts.map +1 -1
- package/dist/bin/utils/config/parser.js +6 -5
- package/dist/bin/utils/config/parser.js.map +1 -1
- package/dist/bin/utils/config/structures/base.d.ts +3 -2
- package/dist/bin/utils/config/structures/base.d.ts.map +1 -1
- package/dist/bin/utils/config/structures/base.js +1 -0
- package/dist/bin/utils/config/structures/base.js.map +1 -1
- package/dist/bin/utils/config/structures/grouped.d.ts +6 -0
- package/dist/bin/utils/config/structures/grouped.d.ts.map +1 -0
- package/dist/bin/utils/config/structures/grouped.js +29 -0
- package/dist/bin/utils/config/structures/grouped.js.map +1 -0
- package/dist/bin/utils/config/structures/legacy.d.ts +1 -1
- package/dist/bin/utils/config/structures/legacy.d.ts.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/bin/utils.d.ts +5 -2
- package/dist/bin/utils.d.ts.map +1 -1
- package/dist/bin/utils.js +6 -12
- package/dist/bin/utils.js.map +1 -1
- package/dist/test/unit/bin/build.test.d.ts +2 -0
- package/dist/test/unit/bin/build.test.d.ts.map +1 -0
- package/dist/test/unit/bin/build.test.js +46 -0
- package/dist/test/unit/bin/build.test.js.map +1 -0
- package/dist/test/unit/bin/git.test.js +104 -1
- package/dist/test/unit/bin/git.test.js.map +1 -1
- package/dist/test/unit/bin/utils/config/load-config.test.js +1 -0
- package/dist/test/unit/bin/utils/config/load-config.test.js.map +1 -1
- package/dist/test/unit/bin/utils/config/parser.test.js +23 -5
- package/dist/test/unit/bin/utils/config/parser.test.js.map +1 -1
- package/dist/test/unit/bin/utils/config/structures/grouped.test.d.ts +2 -0
- package/dist/test/unit/bin/utils/config/structures/grouped.test.d.ts.map +1 -0
- package/dist/test/unit/bin/utils/config/structures/grouped.test.js +75 -0
- package/dist/test/unit/bin/utils/config/structures/grouped.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -2
- package/test/unit/bin/build.test.ts +68 -0
- package/test/unit/bin/git.test.ts +122 -0
- package/test/unit/bin/utils/config/load-config.test.ts +1 -0
- package/test/unit/bin/utils/config/parser.test.ts +26 -5
- package/test/unit/bin/utils/config/structures/grouped.test.ts +90 -0
- package/bin/github.ts +0 -69
- package/dist/bin/github.d.ts +0 -11
- package/dist/bin/github.d.ts.map +0 -1
- package/dist/bin/github.js +0 -59
- package/dist/bin/github.js.map +0 -1
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
name: Checkout and restore dependencies
|
|
2
2
|
description: Checkout and restore dependencies
|
|
3
3
|
inputs:
|
|
4
|
-
working-directory:
|
|
5
|
-
description: Working directory
|
|
6
|
-
required: false
|
|
7
|
-
default: .
|
|
8
|
-
additional-working-directory:
|
|
9
|
-
description: Additional working directory
|
|
10
|
-
required: false
|
|
11
4
|
npm-token:
|
|
12
5
|
description: >-
|
|
13
6
|
Token for installing private npm packages. Exported as both NPM_TOKEN (what a
|
|
@@ -60,30 +53,12 @@ runs:
|
|
|
60
53
|
id: check-dependencies-cache
|
|
61
54
|
uses: actions/cache@v5
|
|
62
55
|
with:
|
|
63
|
-
path:
|
|
64
|
-
key: modules-npm-${{
|
|
65
|
-
|
|
66
|
-
- name: Cache additional dependencies npm
|
|
67
|
-
id: check-additional-dependencies-cache
|
|
68
|
-
if: inputs.additional-working-directory != ''
|
|
69
|
-
uses: actions/cache@v5
|
|
70
|
-
with:
|
|
71
|
-
path: ${{ inputs.additional-working-directory }}/node_modules
|
|
72
|
-
key: modules-npm-${{ inputs.additional-working-directory }}-${{ hashFiles(format('{0}/package-lock.json', inputs.additional-working-directory)) }}
|
|
56
|
+
path: node_modules
|
|
57
|
+
key: modules-npm-${{ hashFiles('package-lock.json') }}
|
|
73
58
|
|
|
74
59
|
- name: install npm dependencies
|
|
75
60
|
if: steps.check-dependencies-cache.outputs.cache-hit != 'true'
|
|
76
61
|
shell: bash
|
|
77
|
-
working-directory: ${{ inputs.working-directory }}
|
|
78
|
-
env:
|
|
79
|
-
NPM_TOKEN: ${{ inputs.npm-token }}
|
|
80
|
-
NODE_AUTH_TOKEN: ${{ inputs.npm-token }}
|
|
81
|
-
run: npm ci
|
|
82
|
-
|
|
83
|
-
- name: install additional npm dependencies
|
|
84
|
-
if: inputs.additional-working-directory != '' && steps.check-additional-dependencies-cache.outputs.cache-hit != 'true'
|
|
85
|
-
shell: bash
|
|
86
|
-
working-directory: ${{ inputs.additional-working-directory }}
|
|
87
62
|
env:
|
|
88
63
|
NPM_TOKEN: ${{ inputs.npm-token }}
|
|
89
64
|
NODE_AUTH_TOKEN: ${{ inputs.npm-token }}
|
|
@@ -96,7 +71,6 @@ runs:
|
|
|
96
71
|
# Needs the npm token too: a repo whose .npmrc routes all traffic through a private
|
|
97
72
|
# registry has to authenticate even for public packages.
|
|
98
73
|
shell: bash
|
|
99
|
-
working-directory: ${{ inputs.working-directory }}
|
|
100
74
|
env:
|
|
101
75
|
NPM_TOKEN: ${{ inputs.npm-token }}
|
|
102
76
|
NODE_AUTH_TOKEN: ${{ inputs.npm-token }}
|
|
@@ -16,6 +16,13 @@ on:
|
|
|
16
16
|
description: Commit to move the tag to. Defaults to the commit that triggered the caller.
|
|
17
17
|
type: string
|
|
18
18
|
default: ''
|
|
19
|
+
wait_for_publish:
|
|
20
|
+
description: >-
|
|
21
|
+
Set by a release that has just published the pinned version. npm accepts a publish
|
|
22
|
+
before the version is readable, so the check waits instead of treating the gap as
|
|
23
|
+
a held tag, and fails if the version never appears.
|
|
24
|
+
type: boolean
|
|
25
|
+
default: false
|
|
19
26
|
|
|
20
27
|
permissions:
|
|
21
28
|
contents: read
|
|
@@ -58,23 +65,50 @@ jobs:
|
|
|
58
65
|
|
|
59
66
|
- name: Check the required package version is published
|
|
60
67
|
id: check
|
|
68
|
+
env:
|
|
69
|
+
# npm accepts a publish and processes it asynchronously ("Your package is being
|
|
70
|
+
# processed and may take a few minutes to become available"). Observed at ~19
|
|
71
|
+
# minutes for a provenance-signed release, so the release path waits well past
|
|
72
|
+
# npm's own estimate rather than shipping a tag consumers cannot install against.
|
|
73
|
+
WAIT_SECONDS: ${{ inputs.wait_for_publish && 2400 || 0 }}
|
|
61
74
|
run: |
|
|
62
75
|
pinned_version=$(cat .github/workflows-package-version)
|
|
63
76
|
echo "pinned_version=$pinned_version" >> "$GITHUB_OUTPUT"
|
|
64
77
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
78
|
+
deadline=$(( $(date +%s) + WAIT_SECONDS ))
|
|
79
|
+
while :; do
|
|
80
|
+
# --prefer-online so a 404 cached from an earlier attempt cannot outlive the
|
|
81
|
+
# publish it was polling for.
|
|
82
|
+
if output=$(npm view "apify-test-tools@$pinned_version" version --prefer-online 2>&1); then
|
|
69
83
|
echo "apify-test-tools@$pinned_version is on npm"
|
|
70
84
|
echo "published=true" >> "$GITHUB_OUTPUT"
|
|
71
85
|
exit 0
|
|
72
86
|
fi
|
|
73
|
-
|
|
74
|
-
|
|
87
|
+
|
|
88
|
+
# Anything that is not "this version does not exist" is a registry, network or
|
|
89
|
+
# auth problem. Sitting in the retry loop would hide it behind a held tag.
|
|
90
|
+
if ! grep -q 'code E404' <<< "$output"; then
|
|
91
|
+
echo "::error::npm view failed for a reason other than the version being absent."
|
|
92
|
+
echo "$output"
|
|
93
|
+
exit 1
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
if [ "$(date +%s)" -ge "$deadline" ]; then
|
|
97
|
+
break
|
|
98
|
+
fi
|
|
99
|
+
echo "apify-test-tools@$pinned_version is not on npm yet, retrying in 30s"
|
|
100
|
+
sleep 30
|
|
75
101
|
done
|
|
102
|
+
|
|
76
103
|
echo "published=false" >> "$GITHUB_OUTPUT"
|
|
77
104
|
|
|
105
|
+
# A release waited for its own publish and never saw it. That is a broken release,
|
|
106
|
+
# not a held tag, and it has to be red so it can be re-run once npm catches up.
|
|
107
|
+
if [ "$WAIT_SECONDS" -gt 0 ]; then
|
|
108
|
+
echo "::error::apify-test-tools@$pinned_version was published by this run but is still not readable after $((WAIT_SECONDS / 60))m. Re-run this job once it appears on npm."
|
|
109
|
+
exit 1
|
|
110
|
+
fi
|
|
111
|
+
|
|
78
112
|
- name: Move tag
|
|
79
113
|
if: steps.check.outputs.published == 'true'
|
|
80
114
|
env:
|
|
@@ -13,13 +13,6 @@ on:
|
|
|
13
13
|
type: string
|
|
14
14
|
default: ''
|
|
15
15
|
required: false
|
|
16
|
-
working-directory:
|
|
17
|
-
type: string
|
|
18
|
-
default: .
|
|
19
|
-
required: false
|
|
20
|
-
additional-working-directory:
|
|
21
|
-
type: string
|
|
22
|
-
required: false
|
|
23
16
|
# Defaults to #notif-<repo-name> when empty, matching the previous behavior.
|
|
24
17
|
report-slack-channel:
|
|
25
18
|
type: string
|
|
@@ -31,16 +24,11 @@ jobs:
|
|
|
31
24
|
name: Scheduled Platform tests
|
|
32
25
|
if: github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main'
|
|
33
26
|
runs-on: ubuntu-latest
|
|
34
|
-
defaults:
|
|
35
|
-
run:
|
|
36
|
-
working-directory: ${{ inputs.working-directory }}
|
|
37
27
|
steps:
|
|
38
28
|
- name: Setup repository and dependencies
|
|
39
29
|
# For testing, you have to temporarily change the branch
|
|
40
30
|
uses: apify/apify-test-tools/.github/actions/checkout-restore-dependencies@workflows-v0
|
|
41
31
|
with:
|
|
42
|
-
working-directory: ${{ inputs.working-directory }}
|
|
43
|
-
additional-working-directory: ${{ inputs.additional-working-directory }}
|
|
44
32
|
npm-token: ${{ secrets.NPM_TOKEN }}
|
|
45
33
|
|
|
46
34
|
- name: Test
|
|
@@ -3,13 +3,6 @@ name: Test
|
|
|
3
3
|
on:
|
|
4
4
|
workflow_call:
|
|
5
5
|
inputs:
|
|
6
|
-
working-directory:
|
|
7
|
-
type: string
|
|
8
|
-
default: .
|
|
9
|
-
required: false
|
|
10
|
-
additional-working-directory:
|
|
11
|
-
type: string
|
|
12
|
-
required: false
|
|
13
6
|
skip-platform-tests:
|
|
14
7
|
type: boolean
|
|
15
8
|
default: false
|
|
@@ -28,17 +21,12 @@ jobs:
|
|
|
28
21
|
platformTest:
|
|
29
22
|
if: ${{ !inputs.skip-platform-tests }}
|
|
30
23
|
runs-on: ubuntu-latest
|
|
31
|
-
defaults:
|
|
32
|
-
run:
|
|
33
|
-
working-directory: ${{ inputs.working-directory }}
|
|
34
24
|
steps:
|
|
35
25
|
- name: Setup repository and dependencies
|
|
36
26
|
id: setup
|
|
37
27
|
# For testing, you have to temporarily change the branch
|
|
38
28
|
uses: apify/apify-test-tools/.github/actions/checkout-restore-dependencies@workflows-v0
|
|
39
29
|
with:
|
|
40
|
-
working-directory: ${{ inputs.working-directory }}
|
|
41
|
-
additional-working-directory: ${{ inputs.additional-working-directory }}
|
|
42
30
|
# Some repos use private npm packages, they need to pass NPM_TOKEN secret to this workflow
|
|
43
31
|
npm-token: ${{ secrets.NPM_TOKEN }}
|
|
44
32
|
|
|
@@ -87,13 +75,9 @@ jobs:
|
|
|
87
75
|
# environment variables rather than being interpolated into it.
|
|
88
76
|
HEAD_REF: ${{ github.head_ref }}
|
|
89
77
|
BASE_REF: ${{ github.base_ref }}
|
|
90
|
-
WORKING_DIRECTORY: ${{ inputs.working-directory }}
|
|
91
78
|
run: |
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
prefix="${work_dir:+$work_dir/}test/platform/"
|
|
95
|
-
changed=$(git diff --name-only --diff-filter=d "origin/$BASE_REF...HEAD" -- "$prefix" \
|
|
96
|
-
| sed "s|^$prefix|./test/platform/|" | tr '\n' ' ')
|
|
79
|
+
changed=$(git diff --name-only --diff-filter=d "origin/$BASE_REF...HEAD" -- test/platform/ \
|
|
80
|
+
| sed "s|^|./|" | tr '\n' ' ')
|
|
97
81
|
branch_actors=$(npx apify-test-tools get-affected-actors \
|
|
98
82
|
--source-branch "origin/$HEAD_REF" \
|
|
99
83
|
--target-branch "origin/$BASE_REF")
|
|
@@ -135,17 +119,11 @@ jobs:
|
|
|
135
119
|
unitTest:
|
|
136
120
|
# TODO: only run on changes to code
|
|
137
121
|
runs-on: ubuntu-latest
|
|
138
|
-
defaults:
|
|
139
|
-
run:
|
|
140
|
-
working-directory: ${{ inputs.working-directory }}
|
|
141
|
-
|
|
142
122
|
steps:
|
|
143
123
|
- name: Setup repository and dependencies
|
|
144
124
|
# For testing, you have to temporarily change the branch
|
|
145
125
|
uses: apify/apify-test-tools/.github/actions/checkout-restore-dependencies@workflows-v0
|
|
146
126
|
with:
|
|
147
|
-
working-directory: ${{ inputs.working-directory }}
|
|
148
|
-
additional-working-directory: ${{ inputs.additional-working-directory }}
|
|
149
127
|
npm-token: ${{ secrets.NPM_TOKEN }}
|
|
150
128
|
|
|
151
129
|
- name: TypeScript
|
|
@@ -3,13 +3,6 @@ name: Build latest and report to slack
|
|
|
3
3
|
on:
|
|
4
4
|
workflow_call:
|
|
5
5
|
inputs:
|
|
6
|
-
working-directory:
|
|
7
|
-
type: string
|
|
8
|
-
default: .
|
|
9
|
-
required: false
|
|
10
|
-
additional-working-directory:
|
|
11
|
-
type: string
|
|
12
|
-
required: false
|
|
13
6
|
# Defaults to #notif-<repo-name> when empty, matching the previous behavior.
|
|
14
7
|
report-slack-channel:
|
|
15
8
|
type: string
|
|
@@ -24,20 +17,16 @@ jobs:
|
|
|
24
17
|
!contains(github.event.head_commit.message, '[skip platform-test]')
|
|
25
18
|
|
|
26
19
|
runs-on: ubuntu-latest
|
|
27
|
-
defaults:
|
|
28
|
-
run:
|
|
29
|
-
working-directory: ${{ inputs.working-directory }}
|
|
30
|
-
|
|
31
20
|
steps:
|
|
32
21
|
- name: Setup repository and dependencies
|
|
33
22
|
id: setup
|
|
34
23
|
# For testing, you have to temporarily change the branch
|
|
35
24
|
uses: apify/apify-test-tools/.github/actions/checkout-restore-dependencies@workflows-v0
|
|
36
25
|
with:
|
|
37
|
-
working-directory: ${{ inputs.working-directory }}
|
|
38
|
-
additional-working-directory: ${{ inputs.additional-working-directory }}
|
|
39
26
|
npm-token: ${{ secrets.NPM_TOKEN }}
|
|
40
27
|
|
|
28
|
+
# --base-commit is the last commit that is already released: the push's "before" commit.
|
|
29
|
+
# Everything after it up to HEAD gets released. See the "Releasing Actors" section of the README.
|
|
41
30
|
# run-with-apify-tokens.mjs reads the token names from in apify-test-tools.config.json
|
|
42
31
|
# and hands the build those secrets and nothing else, so the tokens stay in this one command instead of the whole job.
|
|
43
32
|
# The library never sees secrets it doesn't need
|
|
@@ -47,7 +36,7 @@ jobs:
|
|
|
47
36
|
SLACK_TOKEN_RELEASES_BOT: ${{ secrets.SLACK_TOKEN_RELEASES_BOT }}
|
|
48
37
|
run: |
|
|
49
38
|
node "${{ steps.setup.outputs.scripts-path }}/run-with-apify-tokens.mjs" \
|
|
50
|
-
npx apify-test-tools release --
|
|
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
|
|
51
40
|
|
|
52
41
|
- name: Delete old builds
|
|
53
42
|
env:
|
|
@@ -26,13 +26,6 @@ on:
|
|
|
26
26
|
type: string
|
|
27
27
|
description: Model to use for Claude Code (best, sonnet, opus, haiku, sonnet[1m], opus[1m], opusplan)
|
|
28
28
|
required: false
|
|
29
|
-
working-directory:
|
|
30
|
-
type: string
|
|
31
|
-
default: .
|
|
32
|
-
required: false
|
|
33
|
-
additional-working-directory:
|
|
34
|
-
type: string
|
|
35
|
-
required: false
|
|
36
29
|
secrets:
|
|
37
30
|
ANTHROPIC_API_KEY:
|
|
38
31
|
required: true
|
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.10.0
|
package/CHANGELOG.md
CHANGED
|
@@ -3,23 +3,33 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
5
|
<!-- git-cliff-unreleased-start -->
|
|
6
|
-
## 0.
|
|
6
|
+
## 0.10.1 - **not yet released**
|
|
7
|
+
|
|
8
|
+
### 🐛 Bug Fixes
|
|
9
|
+
|
|
10
|
+
- **internal-workflows:** Wait out npm's async publish before holding the major tag ([#160](https://github.com/apify/apify-test-tools/pull/160)) ([78434f0](https://github.com/apify/apify-test-tools/commit/78434f03d288ecbd383d55d56a1610f06ded298f)) by [@metalwarrior665](https://github.com/metalwarrior665)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
<!-- git-cliff-unreleased-end -->
|
|
14
|
+
## [0.10.0](https://github.com/apify/apify-test-tools/releases/tag/v0.10.0) (2026-09-30)
|
|
7
15
|
|
|
8
16
|
### 🚀 Features
|
|
9
17
|
|
|
10
18
|
- **config/modes:** Lay groundwork for multiple configuration structures ([#142](https://github.com/apify/apify-test-tools/pull/142)) ([7e18638](https://github.com/apify/apify-test-tools/commit/7e18638a8d3523154dbe819312c2b16b54c548ff)) by [@JuanGalilea](https://github.com/JuanGalilea)
|
|
11
19
|
- **workflows:** Host the reusable GitHub workflows in this repo ([#120](https://github.com/apify/apify-test-tools/pull/120)) ([10f089d](https://github.com/apify/apify-test-tools/commit/10f089d85146ceb7cdae964cfa1fc2577df43a37)) by [@metalwarrior665](https://github.com/metalwarrior665)
|
|
20
|
+
- **mode:** Add grouped config mode ([#143](https://github.com/apify/apify-test-tools/pull/143)) ([9d0b93e](https://github.com/apify/apify-test-tools/commit/9d0b93e194a2cd810a31bcef4ca9457fd9ebfb9b)) by [@JuanGalilea](https://github.com/JuanGalilea)
|
|
12
21
|
|
|
13
22
|
### 🐛 Bug Fixes
|
|
14
23
|
|
|
15
24
|
- Apply default actor timeout to runs ([#134](https://github.com/apify/apify-test-tools/pull/134)) ([82f5f7d](https://github.com/apify/apify-test-tools/commit/82f5f7d4de990db7ad8edf940c19ffd6b20bad13)) by [@Patai5](https://github.com/Patai5)
|
|
25
|
+
- Copy cli to zip to KV store local builds ([#151](https://github.com/apify/apify-test-tools/pull/151)) ([ecdda58](https://github.com/apify/apify-test-tools/commit/ecdda58b68a8c7173a023e3a92689bc4fa0ce53c)) by [@gytelio](https://github.com/gytelio), closes [#140](https://github.com/apify/apify-test-tools/issues/140)
|
|
16
26
|
|
|
17
27
|
### 🚜 Refactor
|
|
18
28
|
|
|
19
29
|
- **workflows:** [**breaking**] Rename the floating tag to workflows-v0 ([#146](https://github.com/apify/apify-test-tools/pull/146)) ([c48fb22](https://github.com/apify/apify-test-tools/commit/c48fb223c885c4e5de7e5f64d8c14f6d03fcc7de)) by [@metalwarrior665](https://github.com/metalwarrior665)
|
|
30
|
+
- **bin:** [**breaking**] Remove GitHub event dependency from release command ([#153](https://github.com/apify/apify-test-tools/pull/153)) ([e6953aa](https://github.com/apify/apify-test-tools/commit/e6953aa095d1a92638c6d72441e1b312d9f835c3)) by [@metalwarrior665](https://github.com/metalwarrior665), closes [#131](https://github.com/apify/apify-test-tools/issues/131)
|
|
20
31
|
|
|
21
32
|
|
|
22
|
-
<!-- git-cliff-unreleased-end -->
|
|
23
33
|
## [0.9.0](https://github.com/apify/apify-test-tools/releases/tag/v0.9.0) (2026-08-11)
|
|
24
34
|
|
|
25
35
|
### 🚀 Features
|
package/CONTRIBUTING.md
CHANGED
|
@@ -10,7 +10,6 @@ The package consists of three parts:
|
|
|
10
10
|
|
|
11
11
|
- `bin/build.ts` actor building
|
|
12
12
|
- `bin/git.ts` git wrappers for getting relevant git commits and changed files
|
|
13
|
-
- `bin/github.ts` github push event parsing
|
|
14
13
|
- `bin/main.ts` entrypoing
|
|
15
14
|
- `bin/slack.ts` sending notifications to slack
|
|
16
15
|
- `bin/test-report.ts` processing vitest's test reports
|
|
@@ -40,12 +39,11 @@ git clone git@github.com:apify-store/testing-repo-for-github-actions.git
|
|
|
40
39
|
|
|
41
40
|
#### Working on the CLI
|
|
42
41
|
|
|
43
|
-
To work on the library,
|
|
42
|
+
To work on the library, point the cli to your repo with `--workspace` (it defaults to the current directory):
|
|
44
43
|
|
|
45
44
|
```sh
|
|
46
|
-
export GITHUB_WORKSPACE=../path/to/testing-repo-for-github-actions # path to the repo
|
|
47
45
|
npx tsx bin/main.ts --help
|
|
48
|
-
npx tsx bin/main.ts get-commits --target-branch master --source-branch feat/testing-feature-branch
|
|
46
|
+
npx tsx bin/main.ts --workspace ../path/to/testing-repo-for-github-actions get-commits --target-branch master --source-branch feat/testing-feature-branch
|
|
49
47
|
```
|
|
50
48
|
|
|
51
49
|
#### Working on the library
|
package/README.md
CHANGED
|
@@ -12,37 +12,15 @@ npm i -D apify-test-tools
|
|
|
12
12
|
|
|
13
13
|
- Requires `vitest` version `3.2.0` or later (uses [annotate](https://vitest.dev/guide/test-context.html#annotate))
|
|
14
14
|
- Make sure `target` and `module` in your `tsconfig.json`'s `compilerOptions` are set to `ES2022`
|
|
15
|
+
- Every Actor must already have at least one build under its default build tag (usually `latest`), built
|
|
16
|
+
from a Git repository version whose URL points to this repository. Build it once manually on the
|
|
17
|
+
platform before CI takes over. See [Repository check](#repository-check).
|
|
15
18
|
|
|
16
19
|
### 2. Create the config file
|
|
17
20
|
|
|
18
|
-
Every repo that uses `apify-test-tools` must have an `apify-test-tools.config.json` file at the root.
|
|
21
|
+
Every repo that uses `apify-test-tools` must have an `apify-test-tools.config.json` file at the root. It lists the actors in the repo, their folders, their full names on the platform, and which env var holds the token to use for each. A top-level `mode` field picks the file's layout; leave it out to use the default `"legacy"` layout.
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
{
|
|
22
|
-
"actors": [
|
|
23
|
-
{
|
|
24
|
-
"folder": "actors/web-scraper",
|
|
25
|
-
"actorFullName": "myteam/web-scraper",
|
|
26
|
-
"tokenEnvVar": "APIFY_TOKEN_MYTEAM"
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
"folder": "actors/email-sender",
|
|
30
|
-
"actorFullName": "myteam/email-sender",
|
|
31
|
-
"tokenEnvVar": "APIFY_TOKEN_MYTEAM",
|
|
32
|
-
"overrideActorContext": ["actors/email-sender", "packages/shared"]
|
|
33
|
-
}
|
|
34
|
-
]
|
|
35
|
-
}
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
Each entry has:
|
|
39
|
-
|
|
40
|
-
| Field | Required | Description |
|
|
41
|
-
| ---------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
42
|
-
| `folder` | yes | Relative path from repo root to the actor's own project directory — the folder that directly contains `.actor/actor.json` (i.e. `<folder>/.actor/actor.json`), the actor's README/CHANGELOG, and its source. Use `"."` for a single-actor repo where `.actor/` is at the root. |
|
|
43
|
-
| `actorFullName` | yes | Full actor identifier in `owner/name` format (e.g. `"apify/web-scraper"`). This is the source of truth for the actor name — the `name` field in `actor.json` is not used. |
|
|
44
|
-
| `tokenEnvVar` | yes | Name of the environment variable holding the Apify API token for this actor. No fallback — if the env var is not set at build time, the build fails. |
|
|
45
|
-
| `overrideActorContext` | no | Array of paths (relative to repo root) that define which files are relevant to this actor. When set, replaces the `dockerContextDir` from `actor.json` for change detection. Useful when an actor depends on shared packages outside its Docker build context. Entries must not be prefixes of one another (e.g. `["", "code"]` or `["actors", "actors/foo"]` are rejected). The actor's own `folder` is always part of its context — if none of the listed entries reach it, it's added automatically. |
|
|
23
|
+
See [Config file](#config-file) for the available modes and every field.
|
|
46
24
|
|
|
47
25
|
### 3. Set up actor folders
|
|
48
26
|
|
|
@@ -97,6 +75,82 @@ mkdir -p test/platform/core
|
|
|
97
75
|
|
|
98
76
|
See the [GitHub workflows](#github-worklows) section below.
|
|
99
77
|
|
|
78
|
+
## Config file
|
|
79
|
+
|
|
80
|
+
`apify-test-tools.config.json` lives at the repo root and tells the tool which actors live in the repo, how to identify them, and which token to use.
|
|
81
|
+
|
|
82
|
+
### Actor fields
|
|
83
|
+
|
|
84
|
+
Every actor in the config is described by these fields, whatever the mode:
|
|
85
|
+
|
|
86
|
+
| Field | Required | Description |
|
|
87
|
+
| ---------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
88
|
+
| `folder` | yes | Relative path from repo root to the actor's own project directory — the folder that directly contains `.actor/actor.json` (i.e. `<folder>/.actor/actor.json`), the actor's README/CHANGELOG, and its source. Use `"."` for a single-actor repo where `.actor/` is at the root. |
|
|
89
|
+
| `actorFullName` | yes | Full actor identifier in `owner/name` format (e.g. `"apify/web-scraper"`). This is the source of truth for the actor name — the `name` field in `actor.json` is not used. |
|
|
90
|
+
| `tokenEnvVar` | yes | Name of the environment variable holding the Apify API token for this actor. In [grouped mode](#grouped-mode) it's inherited from the group unless the actor sets its own. No fallback — if the env var is not set at build time, the build fails. |
|
|
91
|
+
| `overrideActorContext` | no | Array of paths (relative to repo root) that define which files are relevant to this actor. When set, replaces the `dockerContextDir` from `actor.json` for change detection. Useful when an actor depends on shared packages outside its Docker build context. Entries must not be prefixes of one another (e.g. `["", "code"]` or `["actors", "actors/foo"]` are rejected). The actor's own `folder` is always part of its context — if none of the listed entries reach it, it's added automatically. |
|
|
92
|
+
|
|
93
|
+
### Modes
|
|
94
|
+
|
|
95
|
+
The file's layout is picked by the top-level `mode` field. Each mode is a different way of writing the same thing: every mode resolves to a list of actors with the fields above, and the same rules apply to all of them — no two actors may share a `folder`, and no two entries may point at the same `actorFullName`. If `mode` is left out, [`"legacy"`](#legacy-mode) is used, so existing config files keep working unchanged.
|
|
96
|
+
|
|
97
|
+
### Legacy mode
|
|
98
|
+
|
|
99
|
+
The default. A flat `actors` array where every entry carries all of its settings. Good for repos with a few actors, or where every actor has different settings.
|
|
100
|
+
|
|
101
|
+
```json
|
|
102
|
+
{
|
|
103
|
+
"mode": "legacy",
|
|
104
|
+
"actors": [
|
|
105
|
+
{
|
|
106
|
+
"folder": "actors/web-scraper",
|
|
107
|
+
"actorFullName": "myteam/web-scraper",
|
|
108
|
+
"tokenEnvVar": "APIFY_TOKEN_MYTEAM"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"folder": "actors/email-sender",
|
|
112
|
+
"actorFullName": "myteam/email-sender",
|
|
113
|
+
"tokenEnvVar": "APIFY_TOKEN_MYTEAM",
|
|
114
|
+
"overrideActorContext": ["actors/email-sender", "packages/shared"]
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`actors` must hold at least one entry. Every entry takes all the [actor fields](#actor-fields) directly, and `tokenEnvVar` is required on each one.
|
|
121
|
+
|
|
122
|
+
### Grouped mode
|
|
123
|
+
|
|
124
|
+
Actors are organized into `groups`, and each group sets `tokenEnvVar` and `overrideActorContext` once for all of its actors. Good for repos where many actors share the same token or context.
|
|
125
|
+
|
|
126
|
+
```json
|
|
127
|
+
{
|
|
128
|
+
"mode": "grouped",
|
|
129
|
+
"groups": {
|
|
130
|
+
"myteam": {
|
|
131
|
+
"tokenEnvVar": "APIFY_TOKEN_MYTEAM",
|
|
132
|
+
"overrideActorContext": ["packages/shared"],
|
|
133
|
+
"actors": [
|
|
134
|
+
{ "folder": "actors/web-scraper", "actorFullName": "myteam/web-scraper" },
|
|
135
|
+
{
|
|
136
|
+
"folder": "actors/email-sender",
|
|
137
|
+
"actorFullName": "myteam/email-sender",
|
|
138
|
+
"overrideActorContext": ["actors/email-sender", "packages/mailer"]
|
|
139
|
+
}
|
|
140
|
+
]
|
|
141
|
+
},
|
|
142
|
+
"partner": {
|
|
143
|
+
"tokenEnvVar": "APIFY_TOKEN_PARTNER",
|
|
144
|
+
"actors": [{ "folder": "actors/partner-crawler", "actorFullName": "partner/crawler" }]
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
`groups` is an object with at least one group. The group key (`myteam`, `partner` above) is only a label for readability; it has no effect on the result, and it does not need to match any folder or username. Each group needs a `tokenEnvVar` and at least one actor, and can optionally set `overrideActorContext`.
|
|
151
|
+
|
|
152
|
+
An actor inside a group can set its own `tokenEnvVar` or `overrideActorContext`, and that value replaces the group's for that actor only. Values are replaced, not merged: in the example above, `myteam/email-sender` gets `["actors/email-sender", "packages/mailer"]`, not `packages/shared` as well.
|
|
153
|
+
|
|
100
154
|
## Github worklows
|
|
101
155
|
|
|
102
156
|
The reusable workflows live in this repo, alongside the package they call. They are the
|
|
@@ -172,6 +226,10 @@ jobs:
|
|
|
172
226
|
secrets: inherit
|
|
173
227
|
```
|
|
174
228
|
|
|
229
|
+
This workflow runs `apify-test-tools release --base-commit ${{ github.event.before }}`. See
|
|
230
|
+
[Releasing Actors](#releasing-actors-release) for how the released range is determined and what to
|
|
231
|
+
pass if you call the CLI from somewhere else.
|
|
232
|
+
|
|
175
233
|
### `claude-review.yaml`
|
|
176
234
|
|
|
177
235
|
Optional. Reviews a PR against the shared guidelines when you add the trigger label, and again on
|
|
@@ -537,7 +595,7 @@ The main local flow is:
|
|
|
537
595
|
4. Build Actors on Apify (with your new code)
|
|
538
596
|
5. Run tests against those builds. You can change tests and run on the same builds.
|
|
539
597
|
|
|
540
|
-
|
|
598
|
+
Run every command from the root of the actor repository you want to work with (or point `--workspace` at it).
|
|
541
599
|
|
|
542
600
|
#### 4. Build affected Actors
|
|
543
601
|
|
|
@@ -547,7 +605,6 @@ Requires `APIFY_TOKEN_<USERNAME>` for all Apify users that own your Actors (e.g.
|
|
|
547
605
|
|
|
548
606
|
```bash
|
|
549
607
|
APIFY_TOKEN_JOHN_DOE=<token> \
|
|
550
|
-
GITHUB_WORKSPACE=. \
|
|
551
608
|
npx apify-test-tools build \
|
|
552
609
|
--target-branch origin/master \
|
|
553
610
|
--source-branch origin/my-dummy-branch \
|
|
@@ -562,11 +619,10 @@ Remove `--dry-run` to actually trigger builds and update the branch names/ The c
|
|
|
562
619
|
|
|
563
620
|
#### Build from local source (no push needed)
|
|
564
621
|
|
|
565
|
-
If you don't want to push a dummy branch just to test a change and wait for all the tests to finish, `build-from-local` builds Actors directly from your local files (zipped and
|
|
622
|
+
If you don't want to push a dummy branch just to test a change and wait for all the tests to finish, `build-from-local` builds Actors directly from your local files (zipped into the Actor's `actor-<id>-source` key-value store and built as `TARBALL`, like `apify push`), skipping steps 1-4 above.
|
|
566
623
|
|
|
567
624
|
```bash
|
|
568
625
|
APIFY_TOKEN_JOHN_DOE=<token> \
|
|
569
|
-
GITHUB_WORKSPACE=. \
|
|
570
626
|
npx apify-test-tools build-from-local --actors john.doe/my-actor
|
|
571
627
|
```
|
|
572
628
|
|
|
@@ -575,8 +631,7 @@ Pass a hardcoded actor name via `--actors` to build only that Actor (comma-separ
|
|
|
575
631
|
```bash
|
|
576
632
|
# Build from local source and capture output
|
|
577
633
|
BUILDS=$(APIFY_TOKEN_JOHN_DOE=apify_api_xxx \
|
|
578
|
-
|
|
579
|
-
npx apify-test-tools build-from-local --actors apify/my-actor)
|
|
634
|
+
npx apify-test-tools build-from-local --actors apify/my-actor)
|
|
580
635
|
```
|
|
581
636
|
|
|
582
637
|
Since you already scoped the build to just the Actor(s) you care about, point vitest at a specific test file (or a `-t` name filter) instead of the whole `test/platform` directory — you get feedback on that one test without waiting for the full suite to run.
|
|
@@ -598,8 +653,7 @@ TESTER_APIFY_TOKEN=<token> \
|
|
|
598
653
|
```bash
|
|
599
654
|
# Build and capture output
|
|
600
655
|
BUILDS=$(APIFY_TOKEN_JOHN_DOE=apify_api_xxx \
|
|
601
|
-
|
|
602
|
-
npx apify-test-tools build \
|
|
656
|
+
npx apify-test-tools build \
|
|
603
657
|
--target-branch origin/master \
|
|
604
658
|
--source-branch origin/my-dummy-branch)
|
|
605
659
|
|
|
@@ -609,10 +663,67 @@ TESTER_APIFY_TOKEN=apify_api_yyy \
|
|
|
609
663
|
npx vitest --run --maxConcurrency 20 --fileParallelism=true --maxWorkers 100 test/platform
|
|
610
664
|
```
|
|
611
665
|
|
|
666
|
+
### Releasing Actors (`release`)
|
|
667
|
+
|
|
668
|
+
`release` builds the `latest` (default) version of every Actor changed since the last release and
|
|
669
|
+
posts release notes to Slack. It reads everything else from git: the branch from the checked-out
|
|
670
|
+
`HEAD`, the commits and changed files from the range `<base-commit>..HEAD`, and the repository from
|
|
671
|
+
the `origin` remote.
|
|
672
|
+
|
|
673
|
+
```bash
|
|
674
|
+
npx apify-test-tools release --base-commit <sha> --release-slack-channel "#releases" --dry-run
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
#### `--base-commit`
|
|
678
|
+
|
|
679
|
+
The last commit that is **already released**. Everything after it, up to `HEAD`, is released. It is
|
|
680
|
+
required: git alone can't tell which commits a push brought, and guessing wrong silently leaves Actors
|
|
681
|
+
on old code.
|
|
682
|
+
|
|
683
|
+
The changed files come from diffing `<base-commit>` and `HEAD` directly, so this works for every
|
|
684
|
+
merge strategy as long as the base commit is the branch tip from **before** the push:
|
|
685
|
+
|
|
686
|
+
| Merge strategy | What lands on the branch | What to pass |
|
|
687
|
+
| ------------------------------ | --------------------------------- | ---------------------------------------------------------------------- |
|
|
688
|
+
| Squash and merge | 1 new commit | the push's "before" commit (`HEAD~1` also works) |
|
|
689
|
+
| Merge commit | the PR's commits + 1 merge commit | the push's "before" commit (`HEAD^1`, the first parent, also works) |
|
|
690
|
+
| Rebase and merge / direct push | N new commits | the push's "before" commit (`HEAD~1` would miss the first N-1 commits) |
|
|
691
|
+
|
|
692
|
+
On GitHub, the push's "before" commit is `${{ github.event.before }}`, which the reusable workflow
|
|
693
|
+
passes for you. On other CIs use the equivalent, e.g. `$CI_COMMIT_BEFORE_SHA` on GitLab. The checkout
|
|
694
|
+
needs the full history (`fetch-depth: 0` in `actions/checkout`) so the base commit is available locally.
|
|
695
|
+
|
|
696
|
+
`release` fails instead of guessing when:
|
|
697
|
+
|
|
698
|
+
- the base commit is all zeros (GitHub sends this for a push that created the branch)
|
|
699
|
+
- the base commit isn't in the local history (shallow checkout) or isn't an ancestor of `HEAD`
|
|
700
|
+
(the branch was force-pushed)
|
|
701
|
+
|
|
702
|
+
In those cases, rerun `release` with a `--base-commit` you pick yourself: an ancestor of `HEAD` from
|
|
703
|
+
before the changes you want to release (for a shallow checkout, fetch the full history instead).
|
|
704
|
+
`--actors` only narrows which of the changed Actors get released; it never forces a build, so on its
|
|
705
|
+
own it doesn't get past these errors.
|
|
706
|
+
If `HEAD` is the base commit, there is nothing to release and the command exits successfully.
|
|
707
|
+
|
|
708
|
+
A failed release isn't retried by the next push: that push's base commit is the failed one's head, so
|
|
709
|
+
its changes are skipped. Re-run the failed workflow run, or release the Actors manually.
|
|
710
|
+
|
|
711
|
+
#### Repository check
|
|
712
|
+
|
|
713
|
+
`release` and `build` point each Actor's version at the `origin` remote. Because a build overwrites the
|
|
714
|
+
version's Git URL, building from a fork or a mirror would repoint the Actor. So, before building, the
|
|
715
|
+
remote is compared with the Git URL of the Actor's default version (the one its default build tag
|
|
716
|
+
points to), and the command fails if they differ or if the default version isn't built from a Git
|
|
717
|
+
repository. The URL form doesn't matter (`https://github.com/org/repo` equals
|
|
718
|
+
`git@github.com:org/repo.git`).
|
|
719
|
+
|
|
720
|
+
To build from a different repository on purpose, e.g. when moving an Actor, pass `--repo-url`. That
|
|
721
|
+
skips the check.
|
|
722
|
+
|
|
612
723
|
#### Dev mode
|
|
613
724
|
|
|
614
725
|
For development on `apify-test-tools` itself, use `tsx` directly:
|
|
615
726
|
|
|
616
727
|
```bash
|
|
617
|
-
|
|
728
|
+
tsx bin/main.ts --workspace local-clone get-actor-configs
|
|
618
729
|
```
|