Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Artifacts of intermediate targets not stored #4100

Closed
idsvandermolen opened this issue May 8, 2024 · 8 comments
Closed

Artifacts of intermediate targets not stored #4100

idsvandermolen opened this issue May 8, 2024 · 8 comments
Labels
type:bug Something isn't working

Comments

@idsvandermolen
Copy link

What went wrong?

It seems SAVE ARTIFACT and SAVE IMAGE are only effective when you directly call the target that has the statement.

Test 1

If you have this Earthfile:

VERSION 0.8

docker:
    FROM ubuntu:22.04
    SAVE IMAGE earthly-test:latest

build:
    FROM +docker
    COPY --dir input ./
    SAVE ARTIFACT input AS LOCAL output

all:
    BUILD +build

There are a few issues here, when calling some commands.

command image created? output directory created?
earthly +all no yes
earthly +build no yes
earthly +docker yes no

Note that the output directory is also created when calling +all

Test 2

If we add another intermediate target like this:

VERSION 0.8

docker:
    FROM ubuntu:22.04
    SAVE IMAGE earthly-test:latest

build:
    FROM +docker
    COPY --dir input ./
    SAVE ARTIFACT input AS LOCAL output

tests:
    FROM +build

all:
    BUILD +tests

Then we get this:

command image created? output directory created?
earthly +all no no
earthly +tests no no
earthly +build no yes
earthly +docker yes no

Note that the output directory is not created when calling +tests or +all, which did work in previous test.

Running earthly with --no-cache yields the same result.

What should have happened?

The expected outcome would be that Earthly creates the artifacts also consistently when there is a target in a "chain" with a SAVE statement.

What earthly version?

earthly version v0.8.9 a2fc61e darwin/arm64; macOS 14.1 homebrew

Buildkit Logs

No response

Other Helpful Information

Of course it is still possible we misunderstand Earthly behaviour or are misreading the documentation.

@idsvandermolen idsvandermolen added the type:bug Something isn't working label May 8, 2024
@eliottwiener-gridunity
Copy link

eliottwiener-gridunity commented May 8, 2024

I believe this is the expected behavior.

Here is where the docs explain this:

https://docs.earthly.dev/docs/earthfile#save-image

As of VERSION 0.6, images are only saved if they are connected to the initial target through a chain of BUILD commands.

https://docs.earthly.dev/docs/earthfile#save-artifact

As of VERSION 0.6, local artifacts are only saved if they are connected to the initial target through a chain of BUILD commands.

So the explanation is that BUILD will cause images and artifacts to be saved in the sub-target, whereas FROM will not. In other words, only BUILD forms links of the "chain".

I ran into this same point of confusion not too long ago. I also had assumed that a FROM would lead to images and artifacts being saved. I find the way this works to be a bit counter-intuitive, although I'm guessing there is a good reason for it.

@idsvandermolen
Copy link
Author

Perhaps. Note that the url linked in the docs "if they are connected to the initial target through a chain of BUILD commands" is broken and apparently needs to point at the section in the BUILD command.
I'll read that section and try to figure out if it makes sense. However, at first glance as "Test 2" shows, just adding another intermediate target (tests) changes the behaviour in (IMO) unexpected ways

@idsvandermolen
Copy link
Author

idsvandermolen commented May 8, 2024

I think this section in FROM probably makes it clearer:

The FROM command does not mark any saved images or artifacts of the referenced target for output, nor does it mark any push commands of the referenced target for pushing. For that, please use BUILD.

Though the examples there still use FROM and SAVE ARTIFACT in on target, suggesting it still would work correctly.

@idsvandermolen
Copy link
Author

Actually the docs still don't make it clear to me how to adjust the tests described above to make it work and have both outputs. What I expect is to setup a chain of dependencies and (just like using a Makefile) when one of the targets inputs (either a dependent target or input from COPY) change, the corresponding outputs would be re-generated.

@idsvandermolen
Copy link
Author

Changing the Earthfile to this seems to work:

VERSION 0.8

docker:
    FROM ubuntu:22.04
    SAVE IMAGE earthly-test:latest

build:
    BUILD +docker
    FROM +docker
    COPY --dir input ./
    SAVE ARTIFACT input AS LOCAL output

tests:
    BUILD +build

all:
    BUILD +tests

Which generates all outputs when invoking targets build,tests and all. Though it is not really clear to me if this is the way one should implement it. First I tried to have only a BUILD +docker in build target, but then you get this error:

copy classical: the first command has to be FROM, FROM DOCKERFILE, LOCALLY, ARG, BUILD or IMPORT

@alexcb
Copy link
Collaborator

alexcb commented May 15, 2024

Note that the url linked in the docs "if they are connected to the initial target through a chain of BUILD commands" is broken and apparently needs to point at the section in the BUILD command.

I had a look to see if this could be fixed, but unfortunately the anchor has disappeared. The docs are hosted via gitbook, which makes it difficult to fix these sorts of issues which come from bugs (or feature changes) in gitbook.

@alexcb
Copy link
Collaborator

alexcb commented May 15, 2024

Though the examples there still use FROM and SAVE ARTIFACT in on target, suggesting it still would work correctly.

The SAVE ARTIFACT is required here to allow for a COPY to reference it; Note that SAVE ARTIFACT <path> is different from SAVE ARTIFACT <PATH> AS LOCAL <output>. It's only the AS LOCAL <output> portion that requires chaining of BUILD commands.

@alexcb
Copy link
Collaborator

alexcb commented May 15, 2024

Though it is not really clear to me if this is the way one should implement it

build:
    BUILD +docker
    FROM +docker

is how it's intended to be used. The BUILD +docker occurs asyncronously and doesn't affect the target where it is defined.

If you really want to get into the weeds, you can also create a function to do both, e.g.

VERSION 0.8

BUILD_AND_FROM:
    FUNCTION
	ARG target
	BUILD --pass-args $target
	FROM --pass-args $target

docker:
    FROM ubuntu:22.04
    SAVE IMAGE earthly-test:latest

build:
    DO +BUILD_AND_FROM --target=+docker
    COPY --dir input ./
    SAVE ARTIFACT input AS LOCAL output

tests:
    BUILD +build

all:
    BUILD +tests

@alexcb alexcb closed this as completed May 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type:bug Something isn't working
Projects
Status: Done
Development

No branches or pull requests

3 participants