Conversation
There was a problem hiding this comment.
Pull request overview
Pins previously floating dependency references in devcontainer Dockerfiles and CI, and adds Renovate configuration to keep those pins updated over time.
Changes:
- Add Renovate scheduling/automerge settings and custom regex managers for nonstandard version sources in Dockerfiles.
- Pin tool sources in devcontainer Dockerfiles (multi-stage
COPY --from=..., GitHub release installer URL,go installversions, Task install version). - Pin GitHub Actions in the build workflow to full semver tags.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
renovate.json |
Adds schedule/min age/automerge/grouping plus regex managers for GitHub release URLs, Task install version, and go install pins. |
dockerfiles/python/Dockerfile |
Pins the uv/uvx binaries source image to a specific tag. |
dockerfiles/go/Dockerfile |
Pins golangci-lint, go-junit-report, gomplate, and goreleaser to explicit versions. |
dockerfiles/base/Dockerfile |
Pins prek installer URL to a specific release and pins Task install to an explicit version. |
.github/workflows/build.yaml |
Pins Actions used in CI to full semver versions. |
.claude/commands/pin-dependencies.md |
Adds a repo command doc describing how to detect/pin dependencies and update Renovate config. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| "automerge": true, | ||
| "automergeType": "pr", | ||
| "packageRules": [ | ||
| { | ||
| "matchPackagePatterns": ["*"], | ||
| "groupName": "all dependencies", | ||
| "groupSlug": "all" |
There was a problem hiding this comment.
automerge: true combined with a catch-all packageRules grouping (matchPackagePatterns: ["*"]) will create a single, automatically-merged PR containing all dependency updates (including potentially breaking updates). Consider restricting automerge to patch/minor updates and/or grouping by manager/update type so failures are easier to diagnose and roll back.
| "automerge": true, | |
| "automergeType": "pr", | |
| "packageRules": [ | |
| { | |
| "matchPackagePatterns": ["*"], | |
| "groupName": "all dependencies", | |
| "groupSlug": "all" | |
| "automergeType": "pr", | |
| "packageRules": [ | |
| { | |
| "matchUpdateTypes": ["patch", "minor", "pin", "digest"], | |
| "groupName": "non-major dependencies", | |
| "groupSlug": "non-major", | |
| "automerge": true | |
| }, | |
| { | |
| "matchUpdateTypes": ["major"], | |
| "groupName": "major dependencies", | |
| "groupSlug": "major", | |
| "automerge": false |
| - `COPY --from=.*:latest` — unpinned multi-stage sources | ||
| - `releases/latest/download` — GitHub release script installers using `latest` | ||
| - `go install .*@latest` — unpinned Go module installs | ||
| - `taskfile\.dev/install\.sh` without a `-v vX.Y.Z` flag |
There was a problem hiding this comment.
Phase 1 says to flag Taskfile installs that don't use a -v vX.Y.Z flag, but the repo's pinned install in dockerfiles/base/Dockerfile uses a positional version after -- -d (and renovate.json's regex manager is written to match that format). Please align this guidance with the actual pattern you want the repo to use so the command doesn't direct users to a different syntax than the one Renovate tracks.
| - `taskfile\.dev/install\.sh` without a `-v vX.Y.Z` flag | |
| - `taskfile\.dev/install\.sh` without a pinned positional version argument after `-- -d` (for example, flag installs that do not use the repo-tracked form `sh -s -- -d vX.Y.Z`) |
| - `golangci/golangci-lint:latest` → `golangci/golangci-lint:vX.Y.Z` | ||
| - `gomplate/gomplate:latest` → `gomplate/gomplate:vX.Y.Z` | ||
| - `goreleaser/goreleaser:latest` → `goreleaser/goreleaser:vX.Y.Z` | ||
| - `ghcr.io/astral-sh/uv:debian` → `ghcr.io/astral-sh/uv:X.Y.Z` (version only, no distro suffix; the uv image uses bare semver tags like `0.6.14`) |
There was a problem hiding this comment.
The uv pinning rule says to switch ghcr.io/astral-sh/uv:debian to a version-only tag without a distro suffix, but dockerfiles/python/Dockerfile is pinned to 0.11.7-debian. Either update the rule/example to match the chosen tag format, or adjust the Dockerfile pin so the documentation matches reality.
| - `ghcr.io/astral-sh/uv:debian` → `ghcr.io/astral-sh/uv:X.Y.Z` (version only, no distro suffix; the uv image uses bare semver tags like `0.6.14`) | |
| - `ghcr.io/astral-sh/uv:debian` → `ghcr.io/astral-sh/uv:X.Y.Z-debian` (preserve the distro suffix to match the repository's uv image pinning format, e.g. `0.11.7-debian`) |
| **Taskfile install script:** | ||
| - `install.sh)" -- -d` → `install.sh)" -- -d -v vX.Y.Z` | ||
|
|
There was a problem hiding this comment.
The Taskfile transformation rule here uses -v vX.Y.Z, but dockerfiles/base/Dockerfile was changed to pass the version as a positional argument after -- -d, and the Renovate regex manager is also written for the positional form. Pick one canonical syntax (flag vs positional) and make this section consistent with the Dockerfile + renovate.json, otherwise future runs of this command will “fix” it back and forth.
| ## Phase 5: Update renovate.json | ||
|
|
||
| Add custom regex managers to `renovate.json` so Renovate tracks deps it can't detect natively. The `dockerfile` and `github-actions` managers from `config:recommended` already handle Docker images and Actions. Only these patterns need custom rules: | ||
|
|
||
| ```json | ||
| { | ||
| "$schema": "https://docs.renovatebot.com/renovate-schema.json", | ||
| "extends": ["config:recommended"], | ||
| "customManagers": [ | ||
| { | ||
| "description": "GitHub release download URLs in Dockerfiles", | ||
| "customType": "regex", | ||
| "fileMatch": ["(^|/)Dockerfile$"], | ||
| "matchStrings": [ | ||
| "https://github\\.com/(?<depName>[^/]+/[^/]+)/releases/download/(?<currentValue>v[^/]+)/" | ||
| ], | ||
| "datasourceTemplate": "github-releases", | ||
| "versioningTemplate": "semver" | ||
| }, | ||
| { | ||
| "description": "Taskfile install script version flag in Dockerfiles", | ||
| "customType": "regex", | ||
| "fileMatch": ["(^|/)Dockerfile$"], | ||
| "matchStrings": [ | ||
| "taskfile\\.dev/install\\.sh.*-v (?<currentValue>v[^\\s\"']+)" | ||
| ], | ||
| "depNameTemplate": "go-task/task", | ||
| "datasourceTemplate": "github-releases", | ||
| "versioningTemplate": "semver" | ||
| }, | ||
| { | ||
| "description": "go install commands in Dockerfiles", | ||
| "customType": "regex", | ||
| "fileMatch": ["(^|/)Dockerfile$"], | ||
| "matchStrings": [ | ||
| "go install (?<depName>[^@]+)@(?<currentValue>v[^\\s]+)" | ||
| ], | ||
| "datasourceTemplate": "go", | ||
| "versioningTemplate": "semver" | ||
| } | ||
| ] | ||
| } | ||
| ``` | ||
|
|
||
| Write this as the new content of `renovate.json`. |
There was a problem hiding this comment.
Phase 5 says to rewrite renovate.json to contain only extends + customManagers, but the PR's actual renovate.json also adds scheduling, minimum release age, automerge, and dependency grouping. Please update this section (including the Taskfile regex example, which uses -v instead of the repo's -- -d <version> form) so the command documentation matches the config the repo actually wants to maintain.
| # Install taskfile | ||
| ENV TASK_X_REMOTE_TASKFILES=1 | ||
| RUN sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d | ||
| RUN sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d v3.50.0 |
There was a problem hiding this comment.
This pins Taskfile by passing v3.50.0 as a positional argument after -- -d. Elsewhere in this PR (and commonly in Task's install script usage) the version is represented as an explicit flag (-v vX.Y.Z). To avoid ambiguity and ensure Renovate matching stays stable, consider switching to a single canonical syntax (and align the Renovate regex + .claude command doc to it).
| RUN sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d v3.50.0 | |
| RUN sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -v v3.50.0 |
No description provided.