Skip to content

Playwright bump script ignores base image variants, breaking camoufox e2e #2175

Description

@vdusek

The Update Playwright version workflow bumped the project template's pinned Playwright to 1.62.0 in #2151, but apify/actor-python-playwright-camoufox:3.13-1.62.0 was never published. All nine End-to-end tests (playwright_camoufox, *, *) jobs fail on the generated Actor's image build:

error: failed to solve: apify/actor-python-playwright-camoufox:3.13-1.62.0: not found

Every other check is green, so the bot's auto-merge is blocked and the PR sits open.

Root cause

Camoufox does not support Playwright 1.61+. Camoufox ships its own Firefox build whose Juggler protocol diverged from upstream, so since camoufox 0.5.3 (2026-07-15) the package declares playwright<1.61 and the base image build in apify/apify-actor-docker fails for 1.61 and newer (camoufox 0.5.5 depends on playwright<1.61). The plain, -chrome, -firefox and -webkit images all have a 3.13-1.62.0 tag; camoufox stops at 3.13-1.61.0, and even that one is stale -- built a day before the pin tightened, its rebuild fails in every scheduled run. Upstream: apify/apify-actor-docker#297 and apify/apify-actor-docker#301.

The bump script checks only one of the five image variants. scripts/update_playwright_version.py reads tags from actor-python-playwright alone, but the template feeds that single playwright_version into five base images -- plain, -camoufox, -chrome, -firefox, -webkit (src/crawlee/project_template/{{cookiecutter.project_name}}/Dockerfile:10-22). It picks the highest tag of the plain image and assumes the variants keep pace, producing a FROM line for a tag that was never built.

Possible solutions

1. Decouple camoufox from the shared pin. Give it its own version in the template Dockerfile and resolve each variant against its own Docker Hub repository:

# % set playwright_version = '1.62.0'
# % set camoufox_playwright_version = '1.60.0'

The other four images keep tracking the latest Playwright while camoufox stays on what it supports. Since apify/apify-actor-docker#301 caps camoufox at the range it declares, this divergence is permanent rather than temporary, which argues for making it explicit.

2. Make the script variant-aware, keeping one shared pin. Fetch tags for all five image repositories and pick the highest version present in all of them. Smaller diff and one version to reason about, but it holds every crawler type at 1.60.0 for as long as camoufox lags -- which, per the point above, is indefinitely.

3. Fail loudly instead of silently. Independent of 1 and 2: have the script verify the resolved tag exists for every image the template can emit and exit non-zero when it does not, turning a red e2e job hours later into an immediate workflow failure. Worth doing alongside either option.

Related

RUN pip install --no-deps --force-reinstall "playwright=={{ playwright_version }}" in the template bypasses camoufox's playwright<1.61 constraint, so even once a camoufox image for a newer Playwright exists, this line can silently install a Playwright that camoufox declares incompatible.

Metadata

Metadata

Assignees

No one assigned

    Labels

    t-toolingIssues with this label are in the ownership of the tooling team.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions