Repository navigation
feat: support flexible secret passing methods in workflows - #225
Conversation
…e workflows
`secrets: inherit` only works within the same org or enterprise, so the build and test workflows
got no secrets when called from anywhere else. They now declare their secrets and accept them
three ways, which can be mixed:
- by name, with the Actor tokens packed into APIFY_ACTOR_TOKENS, a JSON object keyed by the
`tokenEnvVar` names from apify-test-tools.config.json (the names differ per repo, so they
cannot be declared one by one)
- everything at once as `ALL_SECRETS: ${{ toJSON(secrets) }}`
- `secrets: inherit`, unchanged for repos in the apify org
The setup action registers every value inside the two JSON secrets as a mask, since the runner
only masks the blob as a whole. The README now shows passing by name and mentions the other two.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wf2reqEVbnQV3vmZ7fjekm
Moves the masking jq out of the setup action into .github/scripts/mask-packed-secrets.sh so it can be tested, and makes it reject non-object JSON like the wrapper does (jq's to_entries accepts arrays too). The tests cover the three ways of passing Actor tokens, which source wins, the missing-token warning, and that malformed packed secrets fail without printing their value. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wf2reqEVbnQV3vmZ7fjekm
There was a problem hiding this comment.
tl;dr: if its mentioned on apify-test-tools.config.json it should be passed through ALL_SECRETS (but with a different name). If not, we should state them explicitly. And these two should not mix.
I'd split these, known secrets used explicitly on the workflow or on the CLI should be explicitly stated as part of the secrets. Whereas user-defined stuff like token env vars to be read (stated on their config file) should be passed in through the secrets hack.
I see no reason for the NPM_TOKEN to be passed through ALL_SECRETS. Also, its not all secrets, but secrets taken from the test tools config the ones we want to pass in.
secrets: inherit should be a fallback for the ALL_SECRETS lookup
There was a problem hiding this comment.
Done in ae574d6. Fixed secrets are declared and passed by name only. Config-defined secrets go in CONFIG_SECRETS (renamed from APIFY_ACTOR_TOKENS so it isn't tied to Actor tokens if the config grows). The wrapper checks CONFIG_SECRETS first, then inherited secrets. ALL_SECRETS and the fromJSON fallbacks are gone. Callers who don't want to list the names can still pass CONFIG_SECRETS: ${{ toJSON(secrets) }}; only the names the config declares get through.
Generated by Claude Code
…_SECRETS Per review: a secret a workflow always reads (NPM_TOKEN, TESTER_APIFY_TOKEN, the Slack tokens) is now only taken by name, and the secrets apify-test-tools.config.json names go in one packed secret, CONFIG_SECRETS (was APIFY_ACTOR_TOKENS). The two no longer mix. - Drops the ALL_SECRETS secret and the `fromJSON(secrets.ALL_SECRETS ...)` fallbacks in every step. Callers who don't want to list config secrets can pass `toJSON(secrets)` as CONFIG_SECRETS; the wrapper still only uses the names the config declares. - The wrapper looks a token up in CONFIG_SECRETS, then among inherited secrets. - Renames the wrapper's step variable to WORKFLOW_SECRETS so it isn't mistaken for a secret callers pass, and the masking script to mask-config-secrets.sh. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wf2reqEVbnQV3vmZ7fjekm
… when it's empty public_platform-tests always runs the tests, so it now declares TESTER_APIFY_TOKEN as required. public_pr-build-test keeps it optional, since `skip-platform-tests` runs no tests. `required` only checks that the caller lists the secret, not that it has a value: the repo may not have it, and PRs from forks never get secrets. Both workflows now check for an empty token right after setup and fail with a clear message, instead of an Apify API error deep inside vitest (and, in the PR workflow, after the Actors were already built). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wf2reqEVbnQV3vmZ7fjekm
…d3vw # Conflicts: # README.md
…g, revert before merging Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Wf2reqEVbnQV3vmZ7fjekm
…r testing, revert before merging" This reverts commit e3ed14f.
|
tested on live repo, all seems good |
I checked it briefly; this is still up for discussion. It is quite ugly but we don't have many good options.
Closes #205
Summary
This PR refactors how secrets are passed to reusable workflows, replacing the single
secrets: inheritapproach with three flexible methods: passing secrets by name, usingALL_SECRETSfor bulk passing, or usingsecrets: inheritwithin the Apify org. This improves security by allowing explicit secret declaration and works across organization boundaries.Key Changes
Updated README documentation with comprehensive guidance on three secret-passing methods:
ALL_SECRETS: bulk passing viatoJSON(secrets)without maintaining a listsecrets: inherit: org-restricted but convenient for Apify reposModified workflow files to declare accepted secrets and use fallback logic:
public_pr-build-test.yaml: Added secret declarations and fallback expressions using||operatorpublic_platform-tests.yaml: Added secret declarations and fallback expressionspublic_push-build-latest.yaml: Added secret declarations and fallback expressionspublic_platform-tests-claude-investigate-and-fix.yaml: Updated example comments to show explicit secret passingEnhanced
run-with-apify-tokens.mjsscript:unpack()helper function to safely parse JSON secretsAPIFY_ACTOR_TOKENS→ top-level secrets →ALL_SECRETSAdded masking support in
checkout-restore-dependenciesaction:all-secretsandapify-actor-tokensinputsUpdated example workflows in README to show explicit secret passing instead of
secrets: inheritNotable Implementation Details
ALL_SECRETS, allowing callers to overridejqto extract and register individual values from JSON secrets before any step can use themfromJSON(secrets.ALL_SECRETS || '{}')to safely handle missing secretsAPIFY_ACTOR_TOKENSJSON object since each repo names its own tokenshttps://claude.ai/code/session_01Wf2reqEVbnQV3vmZ7fjekm