apify-test-tools 0.10.2-beta.1 → 0.10.2-beta.10

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.
Files changed (187) hide show
  1. package/.gitattributes +2 -0
  2. package/.github/actions/checkout-restore-dependencies/action.yaml +64 -27
  3. package/.github/cli/apify-test-tools.mjs +360 -0
  4. package/.github/scripts/check-major-tag-refs.mjs +1 -1
  5. package/.github/scripts/mask-config-secrets.sh +17 -0
  6. package/.github/scripts/run-with-apify-tokens.mjs +37 -12
  7. package/.github/workflows/_check_code.yaml +25 -0
  8. package/.github/workflows/_move_major_tag.yaml +3 -81
  9. package/.github/workflows/_tests.yaml +34 -0
  10. package/.github/workflows/_update_release_metadata.yaml +0 -12
  11. package/.github/workflows/manual_move_major_tag.yaml +3 -3
  12. package/.github/workflows/manual_release_stable.yaml +3 -13
  13. package/.github/workflows/on_master.yaml +9 -5
  14. package/.github/workflows/on_pull_request.yaml +3 -48
  15. package/.github/workflows/public_platform-tests-claude-investigate-and-fix.yaml +13 -2
  16. package/.github/workflows/public_platform-tests.yaml +24 -1
  17. package/.github/workflows/public_pr-build-test.yaml +61 -25
  18. package/.github/workflows/public_push-build-latest.yaml +41 -8
  19. package/.husky/pre-commit +5 -0
  20. package/.prettierignore +3 -0
  21. package/CHANGELOG.md +16 -0
  22. package/CONTRIBUTING.md +105 -21
  23. package/README.md +218 -600
  24. package/bin/affected-actors.ts +198 -0
  25. package/bin/build-from-local.ts +65 -13
  26. package/bin/build.ts +123 -41
  27. package/bin/diff-changes.ts +32 -23
  28. package/bin/diff-json-schema.ts +5 -6
  29. package/bin/git.ts +69 -99
  30. package/bin/main.ts +96 -135
  31. package/bin/slack.ts +43 -10
  32. package/bin/stdin-input.ts +65 -0
  33. package/bin/test-report.ts +6 -9
  34. package/bin/types.ts +15 -0
  35. package/dist/bin/affected-actors.d.ts +46 -0
  36. package/dist/bin/affected-actors.d.ts.map +1 -0
  37. package/dist/bin/affected-actors.js +135 -0
  38. package/dist/bin/affected-actors.js.map +1 -0
  39. package/dist/bin/build-from-local.d.ts +12 -3
  40. package/dist/bin/build-from-local.d.ts.map +1 -1
  41. package/dist/bin/build-from-local.js +34 -12
  42. package/dist/bin/build-from-local.js.map +1 -1
  43. package/dist/bin/build.d.ts +30 -7
  44. package/dist/bin/build.d.ts.map +1 -1
  45. package/dist/bin/build.js +85 -26
  46. package/dist/bin/build.js.map +1 -1
  47. package/dist/bin/diff-changes.d.ts +11 -4
  48. package/dist/bin/diff-changes.d.ts.map +1 -1
  49. package/dist/bin/diff-changes.js +19 -19
  50. package/dist/bin/diff-changes.js.map +1 -1
  51. package/dist/bin/diff-json-schema.d.ts +2 -2
  52. package/dist/bin/diff-json-schema.d.ts.map +1 -1
  53. package/dist/bin/diff-json-schema.js +1 -4
  54. package/dist/bin/diff-json-schema.js.map +1 -1
  55. package/dist/bin/git.d.ts +23 -21
  56. package/dist/bin/git.d.ts.map +1 -1
  57. package/dist/bin/git.js +60 -83
  58. package/dist/bin/git.js.map +1 -1
  59. package/dist/bin/main.js +82 -105
  60. package/dist/bin/main.js.map +1 -1
  61. package/dist/bin/slack.d.ts +14 -4
  62. package/dist/bin/slack.d.ts.map +1 -1
  63. package/dist/bin/slack.js +39 -6
  64. package/dist/bin/slack.js.map +1 -1
  65. package/dist/bin/stdin-input.d.ts +17 -0
  66. package/dist/bin/stdin-input.d.ts.map +1 -0
  67. package/dist/bin/stdin-input.js +54 -0
  68. package/dist/bin/stdin-input.js.map +1 -0
  69. package/dist/bin/test-report.d.ts.map +1 -1
  70. package/dist/bin/test-report.js +6 -8
  71. package/dist/bin/test-report.js.map +1 -1
  72. package/dist/bin/types.d.ts +13 -0
  73. package/dist/bin/types.d.ts.map +1 -1
  74. package/dist/lib/extend-expect.d.ts.map +1 -1
  75. package/dist/lib/extend-expect.js +37 -218
  76. package/dist/lib/extend-expect.js.map +1 -1
  77. package/dist/lib/lib.d.ts +1 -2
  78. package/dist/lib/lib.d.ts.map +1 -1
  79. package/dist/lib/lib.js +15 -22
  80. package/dist/lib/lib.js.map +1 -1
  81. package/dist/lib/run-checks.d.ts +14 -0
  82. package/dist/lib/run-checks.d.ts.map +1 -0
  83. package/dist/lib/run-checks.js +82 -0
  84. package/dist/lib/run-checks.js.map +1 -0
  85. package/dist/lib/run-test-result.d.ts +3 -6
  86. package/dist/lib/run-test-result.d.ts.map +1 -1
  87. package/dist/lib/run-test-result.js +41 -54
  88. package/dist/lib/run-test-result.js.map +1 -1
  89. package/dist/test/bundle/cli-bundle.test.d.ts +2 -0
  90. package/dist/test/bundle/cli-bundle.test.d.ts.map +1 -0
  91. package/dist/test/bundle/cli-bundle.test.js +190 -0
  92. package/dist/test/bundle/cli-bundle.test.js.map +1 -0
  93. package/dist/test/e2e/cli-bundle.e2e.test.d.ts +2 -0
  94. package/dist/test/e2e/cli-bundle.e2e.test.d.ts.map +1 -0
  95. package/dist/test/e2e/cli-bundle.e2e.test.js +138 -0
  96. package/dist/test/e2e/cli-bundle.e2e.test.js.map +1 -0
  97. package/dist/test/e2e/git-build-release.e2e.test.d.ts +2 -0
  98. package/dist/test/e2e/git-build-release.e2e.test.d.ts.map +1 -0
  99. package/dist/test/e2e/git-build-release.e2e.test.js +87 -0
  100. package/dist/test/e2e/git-build-release.e2e.test.js.map +1 -0
  101. package/dist/test/e2e/helpers.d.ts +37 -0
  102. package/dist/test/e2e/helpers.d.ts.map +1 -0
  103. package/dist/test/e2e/helpers.js +57 -0
  104. package/dist/test/e2e/helpers.js.map +1 -0
  105. package/dist/test/unit/bin/affected-actors-cli.test.d.ts +2 -0
  106. package/dist/test/unit/bin/affected-actors-cli.test.d.ts.map +1 -0
  107. package/dist/test/unit/bin/affected-actors-cli.test.js +167 -0
  108. package/dist/test/unit/bin/affected-actors-cli.test.js.map +1 -0
  109. package/dist/test/unit/bin/affected-actors.test.d.ts +2 -0
  110. package/dist/test/unit/bin/affected-actors.test.d.ts.map +1 -0
  111. package/dist/test/unit/bin/affected-actors.test.js +141 -0
  112. package/dist/test/unit/bin/affected-actors.test.js.map +1 -0
  113. package/dist/test/unit/bin/build-cli.test.d.ts +2 -0
  114. package/dist/test/unit/bin/build-cli.test.d.ts.map +1 -0
  115. package/dist/test/unit/bin/build-cli.test.js +44 -0
  116. package/dist/test/unit/bin/build-cli.test.js.map +1 -0
  117. package/dist/test/unit/bin/build-from-local.test.js +65 -1
  118. package/dist/test/unit/bin/build-from-local.test.js.map +1 -1
  119. package/dist/test/unit/bin/build.test.js +223 -3
  120. package/dist/test/unit/bin/build.test.js.map +1 -1
  121. package/dist/test/unit/bin/compiled-cli.d.ts +6 -0
  122. package/dist/test/unit/bin/compiled-cli.d.ts.map +1 -0
  123. package/dist/test/unit/bin/compiled-cli.js +16 -0
  124. package/dist/test/unit/bin/compiled-cli.js.map +1 -0
  125. package/dist/test/unit/bin/diff-changes.test.js +130 -101
  126. package/dist/test/unit/bin/diff-changes.test.js.map +1 -1
  127. package/dist/test/unit/bin/diff.test.js +25 -28
  128. package/dist/test/unit/bin/diff.test.js.map +1 -1
  129. package/dist/test/unit/bin/git.test.js +69 -152
  130. package/dist/test/unit/bin/git.test.js.map +1 -1
  131. package/dist/test/unit/bin/slack.test.d.ts +2 -0
  132. package/dist/test/unit/bin/slack.test.d.ts.map +1 -0
  133. package/dist/test/unit/bin/slack.test.js +71 -0
  134. package/dist/test/unit/bin/slack.test.js.map +1 -0
  135. package/dist/test/unit/bin/stdin-input.test.d.ts +2 -0
  136. package/dist/test/unit/bin/stdin-input.test.d.ts.map +1 -0
  137. package/dist/test/unit/bin/stdin-input.test.js +50 -0
  138. package/dist/test/unit/bin/stdin-input.test.js.map +1 -0
  139. package/dist/test/unit/github-scripts/mask-config-secrets.test.d.ts +2 -0
  140. package/dist/test/unit/github-scripts/mask-config-secrets.test.d.ts.map +1 -0
  141. package/dist/test/unit/github-scripts/mask-config-secrets.test.js +50 -0
  142. package/dist/test/unit/github-scripts/mask-config-secrets.test.js.map +1 -0
  143. package/dist/test/unit/github-scripts/run-with-apify-tokens.test.d.ts +2 -0
  144. package/dist/test/unit/github-scripts/run-with-apify-tokens.test.d.ts.map +1 -0
  145. package/dist/test/unit/github-scripts/run-with-apify-tokens.test.js +102 -0
  146. package/dist/test/unit/github-scripts/run-with-apify-tokens.test.js.map +1 -0
  147. package/dist/test/unit/run-checks.test.d.ts +2 -0
  148. package/dist/test/unit/run-checks.test.d.ts.map +1 -0
  149. package/dist/test/unit/run-checks.test.js +62 -0
  150. package/dist/test/unit/run-checks.test.js.map +1 -0
  151. package/dist/test/unit/run-test-result.test.d.ts +2 -0
  152. package/dist/test/unit/run-test-result.test.d.ts.map +1 -0
  153. package/dist/test/unit/run-test-result.test.js +34 -0
  154. package/dist/test/unit/run-test-result.test.js.map +1 -0
  155. package/dist/test/unit/should-built-and-test.test.js +41 -38
  156. package/dist/test/unit/should-built-and-test.test.js.map +1 -1
  157. package/dist/tsconfig.tsbuildinfo +1 -1
  158. package/docs/cli.md +373 -0
  159. package/docs/lib.md +271 -0
  160. package/docs/workflows.md +367 -0
  161. package/lib/extend-expect.ts +48 -258
  162. package/lib/lib.ts +24 -28
  163. package/lib/run-checks.ts +101 -0
  164. package/lib/run-test-result.ts +45 -55
  165. package/package.json +13 -3
  166. package/test/bundle/cli-bundle.test.ts +235 -0
  167. package/test/e2e/cli-bundle.e2e.test.ts +207 -0
  168. package/test/e2e/git-build-release.e2e.test.ts +113 -0
  169. package/test/e2e/helpers.ts +82 -0
  170. package/test/unit/bin/affected-actors-cli.test.ts +201 -0
  171. package/test/unit/bin/affected-actors.test.ts +182 -0
  172. package/test/unit/bin/build-cli.test.ts +55 -0
  173. package/test/unit/bin/build-from-local.test.ts +71 -0
  174. package/test/unit/bin/build.test.ts +279 -3
  175. package/test/unit/bin/compiled-cli.ts +17 -0
  176. package/test/unit/bin/diff-changes.test.ts +139 -101
  177. package/test/unit/bin/diff.test.ts +25 -28
  178. package/test/unit/bin/git.test.ts +85 -176
  179. package/test/unit/bin/slack.test.ts +84 -0
  180. package/test/unit/bin/stdin-input.test.ts +61 -0
  181. package/test/unit/github-scripts/mask-config-secrets.test.ts +61 -0
  182. package/test/unit/github-scripts/run-with-apify-tokens.test.ts +115 -0
  183. package/test/unit/run-checks.test.ts +76 -0
  184. package/test/unit/run-test-result.test.ts +44 -0
  185. package/test/unit/should-built-and-test.test.ts +46 -39
  186. package/.github/scripts/check-package-version-bump.mjs +0 -74
  187. package/.github/workflows-package-version +0 -1
@@ -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:
@@ -24,23 +40,40 @@ jobs:
24
40
  uses: apify/apify-test-tools/.github/actions/checkout-restore-dependencies@workflows-v0
25
41
  with:
26
42
  npm-token: ${{ secrets.NPM_TOKEN }}
43
+ config-secrets: ${{ secrets.CONFIG_SECRETS }}
44
+
45
+ # --since is the last commit that is already released: the push's "before" commit.
46
+ # Everything after it up to HEAD gets released. See the "Releasing Actors" section of docs/cli.md.
47
+ # Needs no tokens, it only reads git and apify-test-tools.config.json.
48
+ - name: Find changes since the last release
49
+ run: |
50
+ apify-test-tools get-affected-actors --since ${{ github.event.before }} > affected.json
27
51
 
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.
52
+ # A release ships cosmetic changes too (README, input schema descriptions), so both lists are built,
53
+ # into each Actor's default version: the one its default build tag points to, which users run.
30
54
  # run-with-apify-tokens.mjs reads the token names from in apify-test-tools.config.json
31
55
  # and hands the build those secrets and nothing else, so the tokens stay in this one command instead of the whole job.
32
56
  # The library never sees secrets it doesn't need
33
- - name: Release Actors and notify
57
+ - name: Build the default versions
58
+ # bash rather than the default shell, for pipefail
59
+ shell: bash
60
+ env:
61
+ WORKFLOW_SECRETS: ${{ toJSON(secrets) }}
62
+ run: |
63
+ jq '{ actors: (.functionallyChangedActors + .cosmeticallyChangedActors) }' affected.json \
64
+ | node "${{ steps.setup.outputs.scripts-path }}/run-with-apify-tokens.mjs" \
65
+ apify-test-tools build --version-number default
66
+
67
+ # Skips the announcement when the push brought no new commits
68
+ - name: Announce the release on Slack
34
69
  env:
35
- ALL_SECRETS: ${{ toJSON(secrets) }}
36
70
  SLACK_TOKEN_RELEASES_BOT: ${{ secrets.SLACK_TOKEN_RELEASES_BOT }}
37
71
  run: |
38
- node "${{ steps.setup.outputs.scripts-path }}/run-with-apify-tokens.mjs" \
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
72
+ 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
73
 
41
74
  - name: Delete old builds
42
75
  env:
43
- ALL_SECRETS: ${{ toJSON(secrets) }}
76
+ WORKFLOW_SECRETS: ${{ toJSON(secrets) }}
44
77
  run: |
45
78
  node "${{ steps.setup.outputs.scripts-path }}/run-with-apify-tokens.mjs" \
46
- npx apify-test-tools delete-old-builds
79
+ apify-test-tools delete-old-builds
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
@@ -8,3 +8,6 @@ CHANGELOG.md
8
8
 
9
9
  # Fixtures must stay byte-exact — several are deliberately malformed or empty
10
10
  test/fixtures
11
+
12
+ # Generated by `npm run bundle`
13
+ .github/cli/
package/CHANGELOG.md CHANGED
@@ -5,10 +5,26 @@ 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&#x27; 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
+
25
+ ### 🚜 Refactor
26
+
27
+ - [**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
28
 
13
29
 
14
30
  <!-- 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,28 +87,14 @@ 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
- It only looks at a single PR, so it won't catch a workflow that starts using a CLI feature merged in
108
- an earlier, still-unreleased PR. That needs someone to land a CLI change and sit on it unreleased;
109
- catching it would mean flagging every workflow edit made while any package change is unreleased.
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.
@@ -115,3 +103,99 @@ pushing workflow changes.
115
103
  reusable workflow runs with the caller's repo checked out and never gets its own. Its `prompt-ref`
116
104
  input defaults to `workflows-v0` so the instructions come from the same release as the workflow — leaving it
117
105
  at `master` would run released workflows against unreleased instructions.
106
+
107
+ ## Versioning and releases
108
+
109
+ The workflows and the npm package live in one repo but ship on their own schedules:
110
+
111
+ | What | Consumers get it through | Ships when |
112
+ | -------------------------------------------- | ------------------------------------------ | ----------------------- |
113
+ | the workflows and the CLI they call | the `@workflows-v0` tag in `uses:` | every master push |
114
+ | the lib (`testActor`, `describe`, matchers…) | `apify-test-tools` in their `package.json` | a stable release on npm |
115
+
116
+ The CLI is bundled with its dependencies into `.github/cli/apify-test-tools.mjs` (`npm run bundle`, run by the
117
+ pre-commit hook and checked in CI), and the setup action runs it from there. Nothing is installed for it, so a tag is
118
+ a complete statement: these workflows and this CLI, with the exact dependency versions from `package-lock.json` at
119
+ that commit. The consumer's own `node_modules` is left alone, so their tests keep the lib version they locked.
120
+
121
+ - **Workflow or CLI change** — merge it. `workflows-v0` moves once checks and tests pass, and it goes live. No
122
+ release needed, even when a workflow starts using a new CLI feature: both are in the same commit.
123
+ - **Lib change** — merge it, then cut a release when you want it out. Consumers pick it up when they update
124
+ `apify-test-tools`.
125
+
126
+ The CLI and the lib in one job can be different versions now, so the formats between them are a contract: the
127
+ `ACTOR_BUILDS` JSON that `build` writes and the lib reads, and the vitest JSON report `report-tests` reads. Add
128
+ fields freely; renaming or removing one needs a new major tag.
129
+
130
+ `workflows-v0` moving on every master push means `@workflows-v0` is as live as `@master` was — there's no staging
131
+ step. What the tag buys you is a `workflows-v1` for breaking workflow changes, so repos migrate one at a time instead
132
+ of all at once, and a way to roll back by pointing the tag at an earlier commit (**Move major version tag**
133
+ workflow). Bump `MAJOR_TAG` in `.github/workflows/_move_major_tag.yaml` to cut the next major; the old tag then
134
+ freezes where it is and keeps working, CLI included, since the bundle is part of the frozen commit.
135
+
136
+ The tag tracks the **workflows'** contract, not the npm package version. They move independently on purpose, so
137
+ `@workflows-v0` is expected to stay `@workflows-v0` after the package reaches 1.0 — bump it when a workflow breaks
138
+ its callers, not when the package does. Because `uses:` cannot take an expression, every ref into this repo repeats
139
+ the tag literally; `check-major-tag-refs.mjs` fails the build if `MAJOR_TAG` and those refs disagree, which is the
140
+ mistake that would otherwise ship silently during a bump.
141
+
142
+ ## Testing workflow changes
143
+
144
+ - Point [testing-repo-for-github-actions](https://github.com/apify-store/testing-repo-for-github-actions) at your
145
+ branch (`uses: ...@your-branch`). It has real attached Actors and tests. The branch carries its own CLI bundle, so
146
+ one branch tests the workflows and the CLI together.
147
+ - To change the composite action itself, repoint the `uses:` refs inside the reusable workflows at your branch as
148
+ well, and change them back before merging.
149
+ - Make sure the shell code actually works on your laptop first.
150
+ - After merging, watch the workflow on a real project before moving on.
151
+
152
+ ## How the workflows scope secrets
153
+
154
+ The public side of this is the [Secrets](./docs/workflows.md#secrets) table.
155
+
156
+ The Actor tokens are the one set that cannot be listed in the workflow, because each Actor names its own token via
157
+ `tokenEnvVar` in `apify-test-tools.config.json`, and a reusable workflow only accepts secrets it declares by name.
158
+ Callers pack them into the `CONFIG_SECRETS` secret. Those steps pass `${{ toJSON(secrets) }}` as `WORKFLOW_SECRETS`
159
+ and run the command through `.github/scripts/run-with-apify-tokens.mjs`, which reads that same config file to decide
160
+ which secrets to pass on. It looks each one up in `CONFIG_SECRETS` first, then among the secrets `secrets: inherit`
161
+ brought:
162
+
163
+ ```yaml
164
+ - name: Build
165
+ shell: bash
166
+ env:
167
+ WORKFLOW_SECRETS: ${{ toJSON(secrets) }}
168
+ run: |
169
+ jq '{ actors: .functionallyChangedActors }' affected.json \
170
+ | node "${{ steps.setup.outputs.scripts-path }}/run-with-apify-tokens.mjs" \
171
+ apify-test-tools build --version-number 0.99
172
+ ```
173
+
174
+ The wrapper passes only the tokens the config declares and drops `WORKFLOW_SECRETS`, so neither the CLI nor anything
175
+ under `node_modules` sees the blob. Nothing is written to `$GITHUB_ENV`, so the tokens stay inside that one command
176
+ rather than leaking into later steps. Reading the same file `apify-test-tools` reads means the two can't drift, and a
177
+ secret that merely looks like an Actor token is not passed just because of its name.
178
+
179
+ A token the config declares but the repo hasn't set is a warning, not a failure: a repo can carry an Actor whose
180
+ token isn't configured and still build fine as long as that Actor never changes, and `apify-test-tools` raises a
181
+ precise error naming the Actor at the point it actually needs the token.
182
+
183
+ The runner masks a secret by its exact value, so it only knows `CONFIG_SECRETS` as a whole blob. The setup action
184
+ runs `.github/scripts/mask-config-secrets.sh` first, which registers each value inside it with `::add-mask::`, so a
185
+ token taken out of the blob is masked too.
186
+
187
+ `scripts-path` comes from the setup action (give the step `id: setup`) and points at this repo's `.github/scripts/`
188
+ directory inside the runner's action checkout, so workflows can run these helpers without checking this repo out
189
+ again. The caller's workspace holds the caller's repo, not this one.
190
+
191
+ Two tidier-looking alternatives don't work, so don't reach for them:
192
+
193
+ - **Exporting to `$GITHUB_ENV`** would let the steps call the CLI directly with no wrapper, but `$GITHUB_ENV`
194
+ applies to every later step in the job. In `pr-build-test` the vitest step runs after the build, so it would
195
+ inherit Actor tokens it has no use for.
196
+ - **Returning the tokens as a step output** would be scoped correctly, but the runner refuses to set an output whose
197
+ value contains a registered secret. It logs `Skip output <name> since it may contain secret` and leaves the output
198
+ empty, so anything reading it downstream gets nothing.
199
+
200
+ The `unitTest` job runs static checks and needs `NPM_TOKEN` only. No job runs `npm ci` or `pnpm install` with Apify
201
+ or Slack credentials in scope, so a postinstall script in the dependency tree cannot read them.