Skip to content

bug: uv hardlink warning and dev dependency installation at container runtime #27

@zkoppert

Description

@zkoppert

Problem

Every time the Docker container runs as a GitHub Action, the logs show:

Downloading mypy (13.0MiB)
Downloading pygments (1.2MiB)
Downloading black (1.7MiB)
 Downloaded black
 Downloaded pygments
 Downloaded mypy
warning: Failed to hardlink files; falling back to full copy. This may lead to degraded performance.
         If the cache and target directories are on different filesystems, hardlinking may not be supported.
         If this is intentional, set `export UV_LINK_MODE=copy` or use `--link-mode=copy` to suppress this warning.
Installed 26 packages in 612ms

There are two issues here:

1. Dev dependencies installed at runtime

The Dockerfile builds with uv sync --frozen --no-dev (line 12), but the entrypoint is uv run --project /action/workspace (line 23) which syncs all dependencies (including dev) before executing the script. This means mypy, black, pygments, and other dev tools are downloaded and installed on every single run - wasting time and bandwidth for packages that are never used at runtime.

2. uv hardlink warning

When running as a GitHub Action, Docker mounts the runner workspace into the container. The uv cache and target .venv directory end up on different filesystems (container overlay vs host mount), so hardlinking fails and uv falls back to a full copy with a noisy warning.

Expected behavior

  • Only production dependencies should be installed (they should already be baked into the image)
  • No hardlink warnings in logs

Suggested fix

Two changes to the Dockerfile:

  1. Add ENV UV_LINK_MODE=copy to suppress the hardlink warning
  2. Add --no-dev to the entrypoint so uv run does not re-install dev dependencies:
ENV UV_LINK_MODE=copy
ENTRYPOINT ["uv", "run", "--no-dev", "--project", "/action/workspace"]

Or alternatively, skip uv run entirely at runtime and use the pre-built venv directly:

ENTRYPOINT ["python3", "-u"]
CMD ["/action/workspace/pr_conflict_detector.py"]

Where this was observed

GitHub Actions workflow run: https://github.com/github/new-user-experience/actions/runs/23080465650/job/67048787353

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions