Skip to content

feat(push): auto-normalize SemVer versions in actor.json to MAJOR.MINOR#1269

Draft
DaveHanns wants to merge 1 commit into
apify:masterfrom
DaveHanns:push-auto-normalize-semver-version
Draft

feat(push): auto-normalize SemVer versions in actor.json to MAJOR.MINOR#1269
DaveHanns wants to merge 1 commit into
apify:masterfrom
DaveHanns:push-auto-normalize-semver-version

Conversation

@DaveHanns

Copy link
Copy Markdown
Contributor

Summary

The version field in actor.json is frequently copied straight from package.json (or written from muscle memory) as three-part SemVer — 0.0.1, 1.0.0, 1.0.0-beta. The platform requires strict MAJOR.MINOR and rejects everything else during the build admission step, after the source files have already been uploaded and a build slot has been spent. The error surface is a cryptic 400 that the user learns nothing from; every retry burns a build.

#1245 added a strict client-side guard that fails fast on any non-MAJOR.MINOR version. That's an improvement, but the failure still forces a manual round-trip to edit actor.json and re-run push — often on a first-time deploy where the developer (or an agent driving the CLI) doesn't yet know what Apify's version format is.

This change is complementary: before the strict validator runs, detect SemVer-shaped versions we can unambiguously read (MAJOR.MINOR.PATCH, optional pre-release identifiers, optional build metadata) and rewrite them to MAJOR.MINOR for the current upload, with a warning that tells the developer what happened and points at the field to edit for a permanent fix. Non-SemVer garbage (latest, v1, etc.) falls through to the strict validator unchanged, so this doesn't paper over inputs the CLI can't safely interpret.

Behaviour

actor.json version Effect
0.0.1 WARN + auto-normalized to 0.0 for this upload; strict validator sees 0.0 and passes
1.0.0-beta WARN + auto-normalized to 1.0
2.3.4-rc.1+build.7 WARN + auto-normalized to 2.3
0.0 (already valid) no rewrite, no warning
latest, v1 (not SemVer) unchanged; strict validator rejects with a pointed message

Example warning:

WARN: Actor version '0.0.1' is not the strict MAJOR.MINOR format the platform expects;
      auto-normalizing to '0.0' for this upload.
      Update the `version` field in .actor/actor.json to '0.0' to make this permanent.

Rationale

Developers scaffolding an Actor from scratch — especially in Node ecosystems, where npm init writes three-part SemVer by default — trip on this on their very first apify push. The docs mention MAJOR.MINOR but it's buried; without an early-and-friendly CLI translation, the developer learns nothing from a 400 error minutes into the flow. This PR lets push educate + proceed rather than educate + fail.

The strict validator from #1245 is intentionally preserved (behind this normalization step) so we still fail fast on inputs the CLI can't unambiguously interpret.

Test plan

  • apify push with actor.json version: "0.0.1" prints the WARN and completes a successful build against a fresh Actor
  • apify push with actor.json version: "1.0.0-beta" normalizes to 1.0
  • apify push with actor.json version: "0.0" (already valid) prints no warning
  • apify push with actor.json version: "latest" still fails fast at the strict validator with the existing pointed message (regression check for #1245)
  • apify push -v 0.0.1 (flag override) also gets normalized
  • apify push --json still returns the JSON envelope with the normalized versionNumber

Surfaced during an evaluation of Apify surfaces for agent-driven Actor development.

Co-Authored-By: Claude Opus 4.7 noreply@anthropic.com

The `version` field in `actor.json` is frequently copied straight from
`package.json` (or written from muscle memory) as three-part SemVer —
`0.0.1`, `1.0.0`, `1.0.0-beta`. The platform requires strict
MAJOR.MINOR and rejects everything else during the build admission
step, after the source files have already been uploaded and a build
slot has been spent. The error surface is a cryptic 400 that the user
learns nothing from; every retry burns a build.

PR apify#1245 added a strict client-side guard that fails fast on any
non-MAJOR.MINOR version. That's an improvement, but the failure still
forces a manual round-trip to edit `actor.json` and re-run `push` —
often on a first-time deploy where the user (or an agent driving the
CLI) doesn't yet know what Apify's version format is.

This change is complementary: before the strict validator runs, detect
SemVer-shaped versions we can unambiguously read (`MAJOR.MINOR.PATCH`,
optional pre-release identifiers, optional build metadata) and rewrite
them to `MAJOR.MINOR` for the current upload, with a warning that
tells the user what happened and points at the field to edit for a
permanent fix. Non-SemVer garbage (`latest`, `v1`, etc.) falls through
to the strict validator unchanged, so this doesn't paper over inputs
the CLI can't safely interpret.

Behaviour:

  actor.json version "0.0.1"      -> WARN + normalized to "0.0" for
                                     this upload; strict validator
                                     sees "0.0" and passes.
  actor.json version "1.0.0-beta" -> WARN + normalized to "1.0".
  actor.json version "latest"     -> unchanged; strict validator
                                     rejects with a pointed message.

Surfaced during an evaluation of Apify surfaces for agent-driven
Actor development.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants