Skip to content

Validate actor.json paths before push #1500

Description

@DaveHanns

Problem

apify push reads .actor/actor.json with plain JSON.parse and checks none of its path fields. The platform resolves dockerfile, readme, changelog, and every string-valued schema reference (input, output, webServerSchema, storages.*) relative to .actor/, and each must stay inside the uploaded source. The CLI resolves the schema references it reads that way (src/lib/input_schema.ts) and never reads the other three.

  • A wrong dockerfile, readme, or changelog path builds anyway: the worker logs the miss only internally, falls back to .actor/Dockerfile, Dockerfile, then its built-in default (Dockerfile not found, using the default one.), and the build goes green with the wrong image or README. A missing schema file fails the build (Schema property "input": File "..." does not exist!).
  • A path that leaves the uploaded folder fails only after the upload: File: "<path>" is outside of Actor root directory! for a schema reference. Every push from an Actor folder of apify/actor-monorepo-example ends with the context error first; dockerContextDir itself is validated by the resolver of the push sub-issue (Make apify push work for monorepo Actors that set dockerContextDir #595, stage 1), and this helper covers the file fields.

What we want

A CLI pre-flight that applies the worker's path rules before any Actor write. It needs no platform change.

  • After reading the config and before the Actor is looked up or created, apify push checks every file-path field of .actor/actor.json: relative to .actor/, not absolute, inside the upload root after symlinks are resolved, existing, and among the files push uploads (a CLI-only rule that catches a Dockerfile excluded by .gitignore or .actorignore). The name matches case-insensitively for dockerfile, readme, and changelog, as the worker finds those by directory listing, and exactly otherwise. Object-valued schema fields are skipped.
  • A failing check names the field, its value, and the resolved path, and exits with CommandExitCodes.InvalidActorJson (5). A valid dockerContextDir above the upload root keeps the exit 255 (NotImplemented) and the stage 1 message of the push sub-issue (Make apify push work for monorepo Actors that set dockerContextDir #595) until its stage 2 ships.
  • The check is one helper, src/lib/actor-paths.ts, with the upload root as a parameter: push passes the Actor folder today; monorepo push (Make apify push work for monorepo Actors that set dockerContextDir #595) passes its upload root (the Git repository root, or the Docker context root outside Git) and additionally requires dockerfile inside the Docker context.

Design notes

The local Actor runtime branch (#1496) already calls resolveDockerContext in push.ts right after the config read: exit 5 for a dockerContextDir that is not a string, does not contain the Actor, or is missing or outside the Git repository; exit 255 against the platform for a valid context above the Actor folder. Stage 1 of the push sub-issue lifts that resolver to master as src/lib/docker-context.ts, and master is merged into actor-runtime afterward (never rebased); this helper lands after it and hooks in right after the resolver.

The ACTOR_PATH_IN_DOCKER_CONTEXT build arg has no documented value for an Actor at the context root: the worker computes path.relative(buildContextDir, actorSourcePath), which is "", the production value since the arg was introduced, while its unit tests set "." by hand. The value stays ""; the platform field sub-issue (apify-core) pins it in a worker test.

The worker only warns internally for a missing user-specified dockerfile, readme, or changelog and falls back; its code carries a TODO that calls the error a breaking change. That is why the check runs in the CLI.

Out of scope

How it's tested

  • Unit, new test/local/lib/actor-paths.test.ts: ./x and ../x inside the root pass; ../../x, /x, a missing file, a directory for a file field, and a file excluded by .actorignore fail; a wrong-case dockerfile passes and a wrong-case input fails; object-valued fields are skipped; no path fields is a no-op.
  • Command, after test/local/commands/push-git-source.test.ts (mocked client): a wrong dockerfile stops push with exit code 5 and no Actor read or write.

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