Skip to content

apify push: select which Actors to push in a repository with several #1499

Description

@DaveHanns

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:

  • --all pushes 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-info does not detect CI) with neither flag, a multi-select prompt on stderr asks which Actors to push (useMultiSelectFromList, wrapped by stdinCheckWrapper).
  • Otherwise the listing goes to stderr with Choose what to push: --all, or --actor-dir <path> for each Actor. and the command exits with NoFilesToPush (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 --json envelope {ok, operation, actor, build, error?, exitCode?}.
  • A root without Actors below it, or an --actor-dir value without a readable .actor/actor.json, fails with exit 4 before the login check and before any upload.
  • A non-interactive run without --all or --actor-dir lists the Actors, exits 4, and calls no API.
  • The positional actorId is 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, --json prints one document, {ok, operation: "push", results: [{dir, ...single push result}], exitCode?}, with dir relative to the root using /, even for one Actor; nothing else reaches stdout.
  • apify/push-actor-action needs no change: one Actor per step, or a job matrix over working-directory.

Design notes

  • The selection layer wraps the single-Actor path instead of changing it, so the dockerContextDir work (Make apify push work for monorepo Actors that set dockerContextDir #595) and the local Actor runtime branch (feat: Add local Actor runtime (apify runtime) #1496), which rewrites the same region of push.ts, merge cleanly.
  • The command framework rejects a repeated flag today (Flag --actor-dir can only be specified once.), so Flags.string gains a multiple option that keeps every value.
  • Build the multi-select on @inquirer/core like src/lib/utils/inquirer/confirmImpl.ts, or add a checkbox prompt dependency after measuring its install size per CLAUDE.md.

Out of scope

How it's tested

  • New test/local/commands/push-select.test.ts, modeled on push-git-source.test.ts: the criteria above, --version and --build-tag reaching each version payload, one FAILED build among SUCCEEDED ones (exit 1, per-entry exitCode), and a mocked prompt (an empty selection pushes nothing).
  • New test/local/lib/find-actor-dirs.test.ts for the new discovery helper (for example src/lib/find-actor-dirs.ts): skipped folders, no descent below an Actor, sort order, / separators on Windows.
  • New test/e2e/commands/push-select.test.ts through dist/apify.js, like invalid-config.test.ts: the listing and exit 4 without a token; --actor-dir to a non-Actor folder, exit 4.
  • test/api/commands/push.test.ts: one [api] case pushing two single-folder Actors with --all --json, asserting two SUCCEEDED entries (needs TEST_USER_TOKEN).
  • pnpm run update-docs for the new flags.

Links

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

t-buildersIssues owned by the Builders team.

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions