Repository navigation
apify push: select which Actors to push in a repository with several #1499
Description
Problem
apify push works on one directory (--dir or the current folder) and never searches for an Actor above or below it. At the root of a repository with Actors in subfolders, such as apify/actor-monorepo-example, it prints an error starting A valid Actor could not be found in the current directory., hints at apify init, and exits with code 4 (NoFilesToPush), so pushing several Actors means one invocation per folder.
What we want
When the resolved directory (the root) has no Actor config that push accepts today (.actor/actor.json, actor.json, or the legacy apify.json) but directories below it do, list them and push what the user chose, one ordinary push per Actor, in sequence. A directory with its own config is pushed as today.
Discovery finds every directory below the root with .actor/actor.json, sorted by path, skipping the hard-coded ignores of getActorLocalFilePaths and anything below a found Actor. The listing shows each path and its name.
Selection:
--allpushes every Actor found.--actor-dir <path>, repeatable and relative to the root, pushes those; exclusive with--all.- In an interactive terminal (stdin is a TTY and
ci-infodoes not detect CI) with neither flag, a multi-select prompt on stderr asks which Actors to push (useMultiSelectFromList, wrapped bystdinCheckWrapper). - Otherwise the listing goes to stderr with
Choose what to push: --all, or --actor-dir <path> for each Actor.and the command exits withNoFilesToPush(4), today's code for a root without an Actor, before the login check, even for one Actor: the command never guesses.
Each selected directory runs through the existing single-Actor push with that directory as cwd, so file collection, the newer-on-platform check, the Git-source prompt, the 3 MB rule, and every flag apply per push unchanged.
Acceptance criteria:
- A directory with its own Actor config behaves as today, including the
--jsonenvelope{ok, operation, actor, build, error?, exitCode?}. - A root without Actors below it, or an
--actor-dirvalue without a readable.actor/actor.json, fails with exit 4 before the login check and before any upload. - A non-interactive run without
--allor--actor-dirlists the Actors, exits 4, and calls no API. - The positional
actorIdis rejected (exit 5,InvalidInput) when more than one Actor is selected. - Pushes run in order; a failed Actor does not stop the rest; the exit code is that of the first failed Actor, 0 when all succeeded.
- Whenever the root has no config of its own,
--jsonprints one document,{ok, operation: "push", results: [{dir, ...single push result}], exitCode?}, withdirrelative to the root using/, even for one Actor; nothing else reaches stdout. -
apify/push-actor-actionneeds no change: one Actor per step, or a job matrix overworking-directory.
Design notes
- The selection layer wraps the single-Actor path instead of changing it, so the
dockerContextDirwork (Makeapify pushwork for monorepo Actors that setdockerContextDir#595) and the local Actor runtime branch (feat: Add local Actor runtime (apify runtime) #1496), which rewrites the same region ofpush.ts, merge cleanly. - The command framework rejects a repeated flag today (
Flag --actor-dir can only be specified once.), soFlags.stringgains amultipleoption that keeps every value. - Build the multi-select on
@inquirer/corelikesrc/lib/utils/inquirer/confirmImpl.ts, or add a checkbox prompt dependency after measuring its install size perCLAUDE.md.
Out of scope
- Workspace detection,
dockerContextDir, and shared code outside the Actor folder (Makeapify pushwork for monorepo Actors that setdockerContextDir#595). - Listing discovered Actors without pushing, parallel builds, and waiting for all builds at once.
- Changes to
apify/push-actor-action, including its README; the CI docs page is the docs sub-issue (Monorepo docs: fix Docker context, build arg, andactor.jsonpath wording apify-docs#3082).
How it's tested
- New
test/local/commands/push-select.test.ts, modeled onpush-git-source.test.ts: the criteria above,--versionand--build-tagreaching each version payload, oneFAILEDbuild amongSUCCEEDEDones (exit 1, per-entryexitCode), and a mocked prompt (an empty selection pushes nothing). - New
test/local/lib/find-actor-dirs.test.tsfor the new discovery helper (for examplesrc/lib/find-actor-dirs.ts): skipped folders, no descent below an Actor, sort order,/separators on Windows. - New
test/e2e/commands/push-select.test.tsthroughdist/apify.js, likeinvalid-config.test.ts: the listing and exit 4 without a token;--actor-dirto a non-Actor folder, exit 4. test/api/commands/push.test.ts: one[api]case pushing two single-folder Actors with--all --json, asserting twoSUCCEEDEDentries (needsTEST_USER_TOKEN).pnpm run update-docsfor the new flags.
Links
- Epic: apify/apify-core#28685, Scope split, CLI line (choosing which Actor(s) to push).
- Monorepo push: Make
apify pushwork for monorepo Actors that setdockerContextDir#595. - Pushing from a folder without an Actor was blocked in fix: prevent running
apify pushfrom non-actor-looking folders #537, closingapify pushworks in any, even empty folder #317. - Deploy action: https://github.com/apify/push-actor-action (
working-directory, one push per step).
Activity