Repository navigation
Conversation
…of mutating the shared one
…as the Docker context
…to feat/push-validate-actor-json-paths
…to feat/push-validate-actor-json-paths
…to feat/push-validate-actor-json-paths
push reads through a symlink and uploads the content at the link's own path, so a link to a file outside the upload root builds on the platform. The realpath escape rule refused it; the uploaded files rule already rejects anything push does not send.
The worker copies inputSchema over input and outputSchema over output before resolving, so a schema path under the alias was never checked.
The worker treats an empty string as an unset field, so an empty value was wrongly reported as the .actor folder being a directory. A backslash passes path.resolve on Windows but is a filename character on the Linux worker, so it is refused before any resolution.
The lib test now builds its fixture through useTempPath, as the other lib tests do, adds a changelog file so the case-insensitive match is checked for all three listed fields, and covers the reason given when the uploaded file differs only in case. The command test restores the real process.exitCode next to the mocked copy.
checkActorPaths resolves the roots and builds the posix set of uploaded files once and hands them to every field, instead of each field recomputing them.
apify-factory
left a comment
Contributor
There was a problem hiding this comment.
Looks good, nothing blocking.
🏭 Factory review — ℹ️ not auto-approved
This change was reviewed but cannot be auto-approved: a gate failed, so the review cannot end in an approval.
| check | result |
|---|---|
| Static gates | ❌ 14/16 — base-branch, max-lines |
| Review findings | ✅ none |
| Reviewer escalation | ❌ The new check makes apify push fail on paths that used to push fine, based on platform worker rules this repo can't confirm (for example, a missing readme or dockerfile used to fall back to the default). |
Juror 1 — claude-sonnet-5-5, adversarial |
⏭️ skipped — a gate failed |
Why it was not auto-approved
Failed gates:
base-branch: base is feat/push-monorepo-preflight, required mastermax-lines: 646 changed lines (+644/-2), limit 200
The comments above are the review itself; this section only explains the approval decision. Push a change and request @apify-factory again to re-run it, or ask a human to review.
Reviewed e3edc7960 · workflow run
apify-factory
left a comment
Contributor
There was a problem hiding this comment.
Looks good, nothing blocking.
…to feat/push-validate-actor-json-paths
…to feat/push-validate-actor-json-paths
3 tasks
…actor-json-paths # Conflicts: # src/commands/actors/push.ts # src/lib/docker-context.ts
l2ysho
reviewed
Oct 28, 2026
l2ysho
reviewed
Oct 28, 2026
l2ysho
requested changes
Oct 28, 2026
Contributor
|
one preexisting problem I found -> with inputSchema: "./custom_input.json":
we should resolve also this in followup issue. |
This was referenced Oct 29, 2026
…ult README or CHANGELOG
…ngs in apify push
… does An absolute or escaping readme or changelog fails the build even with a backslash in it, so it stays an error. A default Dockerfile that push does not upload is skipped, as the platform never sees it.
A broken Actor now fails with the same error and exit code with or without a login.
Contributor
Author
|
Thanks for checking the templates.
Ready for another look. |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
apify pushchecks none of the file-path fields in.actor/actor.json. The platform resolves them after the upload: a missing schema fails the build, a missingdockerfilesilently falls back to a Dockerfile the user did not choose, and a missingreadmeorchangelogfalls back to the default README or CHANGELOG. This PR applies the worker's rules in the CLI before the login check and before the Actor is looked up or written. Problems that would fail the build or build the wrong image stop the push; areadmeorchangelogthe platform recovers from only prints a warning.Closes #1500. Part of apify/apify-core#28685. Builds on #1502 (merged): the check runs after the
dockerContextDirresolver.Changes
src/lib/actor-paths.ts:checkActorPathsreturns one problem (field, value, resolved path, reason, severity) per failing field.formatActorPathProblemsbuilds the message for one severity, with a header that says what happens.push.tsprints warnings to stderr and continues, and prints errors and exits with code 5 (InvalidActorJson) when any exist. The login check now runs after these local checks, so a broken Actor fails the same way with or without a login.dockerfile,readme,changelog,input,output,webServerSchema, thestoragesschemas, plusinputSchemaandoutputSchema. The worker copies a set alias overinputoroutput, so the alias wins and the base key is skipped. Inline objects and empty strings (unset on the worker) are skipped..actor/and inside the upload root, no backslash (the platform resolves paths with forward slashes), an existing file, and among the files push uploads. The first rule reads the value as the Linux worker does, where a backslash is part of a name, so an absolute or escaping path stays an error even with a backslash in it.dockerfile,readme, andchangelogmatch case-insensitively, as the worker finds them by a directory listing; schemas match exactly.readmeandchangelog, a missing file (a dangling symlink included), a file push does not upload, a case mismatch with the uploaded file, and a backslash are warnings. An absolute path, a path outside the upload root, and a directory stay errors, as the worker fails the build on them.dockerfileand schema references are errors in every case.dockerContextDirpoints inside the Actor folder,dockerfilemust lie inside that context: the worker runs BuildKit with--local dockerfile=<context dir>andfilename=<Dockerfile relative to the context>, so a Dockerfile outside it cannot be read by the build.dockerfileand with a Docker context, the CLI applies the worker's default lookup:.actor/Dockerfile, thenDockerfilein the Actor folder, by any case, among the files push uploads. A default that.gitignoreor.actorignoredrops is skipped, as the platform never sees it. A found default must pass the same rules as a setdockerfile, so a default outside the context stops the push. With no default and a context other than the Actor folder, push stops too: the platform would build that context with its built-in Node.js Dockerfile. A context that is the Actor folder itself, or no context, keeps the built-in Dockerfile as before.Tests
test/local/lib/actor-paths.test.ts: every rule, the aliases, empty strings, backslashes, symlinks (a dangling one and a symlinked Actor folder included), the case mismatch reason, the severity of eachreadmeandchangelogreason, a backslash in an absolute or escapingreadme, the default Dockerfile lookup in every context (an ignored default included), and the message for each severity.test/local/commands/push-actor-paths.test.ts: errors stop push with exit code 5 before the login check and any Actor read or write; a default Dockerfile outside../dockerand the built-in Dockerfile in../dockerstop it; no Dockerfile withdockerContextDir..or without a context pushes; a default.actor/Dockerfilein the context pushes; the js-cypress shape and a missing changelog print a warning and push, with stdout clean under--json; an absolute readme, a readme outside the upload root, a missingdockerfile, and a missing schema stop it.test/local/commands/push-monorepo.test.ts: the context within the Actor folder now has a Dockerfile of its own.update-docs(no change), andtest:localpass, except the two[python]fixture tests that need a newer Python.Notes for reviewers
"dockerContextDir": "../docker"and aDockerfilein the Actor folder, the build failed onopen ../Dockerfile; without it, the platform builtdocker/with its built-in Dockerfile and ignoreddocker/Dockerfile. Both now stop push and name the Dockerfile the platform would use.readmeorchangelogit cannot find and falls back to its default lookup (.actor/ACTOR.md,.actor/README.md, thenREADME.mdorREADMEin the Actor folder, and likewise for the changelog), so the build succeeds. Failing the push there would block Actors that build fine today. A missingdockerfilefalls back as well, but to a Dockerfile the user did not choose, so it stays an error."readme": "./README.md"withREADME.mdin the Actor folder and none in.actor/. It now pushes with a warning instead of failing; fixing the template is a separate follow-up inapify/actor-templates.uploadRoot.--diris not mistaken for an escape.🤖 Generated with Claude Code