dependabot / dependabot-core

🤖 Dependabot's core logic for creating update PRs.
https://docs.github.com/en/code-security/dependabot
MIT License
4.52k stars 945 forks source link

Add global ARG support for Dockerfiles #2057

Open ffscl opened 4 years ago

ffscl commented 4 years ago

Feature request: Dependabot to support ARG with default values in any FROM statement when resolving dependencies.

Docker supports ARG instructions before the first FROM instruction. (https://docs.docker.com/engine/reference/builder/#understand-how-arg-and-from-interact). The ARG instruction should be easy to parse and evaluate.

Example:

ARG REGISTRY=docker.io
FROM ${REGISTRY}/ubuntu:18.04@sha256:2695d3e10e69cc500a16eae6d6629c803c43ab075fa5ce60813a0fc49c47e859

Before checking for new versions, the FROM instruction should be evaluated as:

FROM docker.io/ubuntu:18.04@sha256:2695d3e10e69cc500a16eae6d6629c803c43ab075fa5ce60813a0fc49c47e859

Use case: Using a registry mirror that dependabot doesn't have access to. With this feature in your CI you could override the registry as follows without breaking dependabot:

docker build --build-arg REGISTRY=hub.mirror.example.com .
ruffsl commented 3 years ago

Another example where this would helpful is when the ARG directive is used FROM multistage Dockerfiles:

ARG FROM_IMAGE=osrf/ros2:testing-20210605003201

# multi-stage for caching
FROM $FROM_IMAGE AS cacher
...

# multi-stage for building
FROM $FROM_IMAGE AS builder
...
joebowbeer commented 1 year ago

Another example where this would helpful is when the ARG defines the version:

ARG NODE_VERSION=14.20

FROM node:${NODE_VERSION}-alpine as code
ruffsl commented 1 year ago

@joebowbeer , I'd assume that it'd be tricky to support that kind of partial variable substitution compared to a basic complete substitution, given the reversed parsing of Dockerfile to determine the line charges to commit into an automated PR.

I suppose it'd be simple to detect an outdated tag, but harder to derive a satisfactory commit to bump the influencing args when arbitrary sub-string formatting is used.

joebowbeer commented 1 year ago

@ruffsl thanks for the reality check. I realize that renovate doesn't handle that directly either.

I'll simplify my test case to:

ARG NODE_BASE=node:14.19-alpine

FROM ${NODE_BASE} as code

I would like dependabot to create one PR updating to node:14.20-alpine and another updating to node:18.10-alpine

georgeseifada commented 1 year ago

Any update on this issue?

ralftar commented 1 year ago

How about doing something like this:

ARG ARCHITECTURE
FROM eclipse-mosquitto:2.0.14-openssl AS amd64
FROM arm64v8/eclipse-mosquitto:2.0.14-openssl AS arm64
FROM ${ARCHITECTURE} AS final

Does the trick for me. Bumps both architectures.

georgeseifada commented 1 year ago

How about doing something like this:

ARG ARCHITECTURE
FROM eclipse-mosquitto:2.0.14-openssl AS amd64
FROM arm64v8/eclipse-mosquitto:2.0.14-openssl AS arm64
FROM ${ARCHITECTURE} AS final

Does the trick for me. Bumps both architectures.

This was super helpful. Works well!

georgeseifada commented 1 year ago

How about doing something like this:

ARG ARCHITECTURE
FROM eclipse-mosquitto:2.0.14-openssl AS amd64
FROM arm64v8/eclipse-mosquitto:2.0.14-openssl AS arm64
FROM ${ARCHITECTURE} AS final

Does the trick for me. Bumps both architectures.

This was super helpful. Works well!

Actually, looks like it doesn't work precisely for my use case. I have something like below:

ARG BASE_IMAGE_TARGET=dev
FROM 482568942567.dkr.ecr.us-east-1.amazonaws.com/my-image:1.0.5 AS dev
FROM 587463598343.dkr.ecr.us-east-1.amazonaws.com/my-image:1.0.5 AS prod
FROM ${BASE_IMAGE_TARGET} AS final

For some reason, dependabot will only trigger an update for the first one, e.g. 482568942567.dkr.ecr.us-east-1.amazonaws.com/my-image:1.0.5. However, if I flip the order of lines 2 & 3 about, it will trigger for only 587463598343.dkr.ecr.us-east-1.amazonaws.com/my-image:1.0.5

ruffsl commented 1 year ago

For some reason, dependabot will only trigger an update for the first one

I don't know much golang, but I'd suspect the FROM regex used here only applies to the first matching pattern in the Dockerfile:

https://github.com/dependabot/dependabot-core/blob/05d11aa4cf521b92c377dc34682483ab20f02de4/docker/lib/dependabot/docker/file_updater.rb#L71-L80

A alternative would be to update over all matching groups of found substrings within the Dockerfile. E.g. like the difference between processing over the return values of the match() vs search() functions in the Python regex library:

https://docs.python.org/3/howto/regex.html#match-versus-search