Search code examples
earthly

How to COPY files from outside of the Earthfile's directory?


Suppose I have a monorepo. Apps (app1, app2) use a Gradle as a build system and share some build-logic with includeBuild("../shared-build-logic") which is outside of the root of each app.

├── shared-build-logic
│   └── src/...
└── app1
    ├── Earthfile
    ├── build.gradle
    ├── src/...
└── app2
    ├── Earthfile
    ├── build.gradle
    ├── src/...

Is it possible for Earthfile to access the files from outside of its root folder or Earthly has the same restrictions as Dockerfile?

I get the following error on attempt to COPY ../shared-build-logic ./:

============================ ❌ FAILURE [2. Build 🔧] ============================

Repeating the output of the command that caused the failure
            +compile *failed* | --> COPY ../shared-build-logic ./
            +compile *failed* | [no output]
            +compile *failed* | ERROR Earthfile line 22:4
            +compile *failed* |       The command
            +compile *failed* |           COPY ../shared-build-logic ./
            +compile *failed* |       failed: "/shared-build-logic": not found

I would also like to perform integration testing with the docker-compose.yaml file located one level above the Eartfile root, but facing the similar problem:

integration-tests:
    FROM earthly/dind:alpine
    COPY ../docker-compose.yaml ./ # <------- does not work
    WITH DOCKER --compose docker-compose.yaml --load build-setup=+compile --allow-privileged
        RUN docker run -e SPRING_DATA_MONGODB_URI=mongodb://mongodb:27017/test-db --network=default_dev-local build-setup ./gradlew test
    END

Is my the only solution to the problem to move Earthfile itself one level upper?


Solution

  • While you can't directly access targets outside of your Earthfile directory you can reference targets.

    This allows you to write a target in an Earthfile under shared-build-logic that saves an artifact containing those files

    You can expose the files you need by using a target.

    shared-build-logic/Earthfile

    files:
        WORKDIR files
        # Copy all of files you want to share
        SAVE ARTIFACT ./*
    

    app/Earthfile

    use-files:
        COPY ../shared-build-logic+files/* .
        # do stuff
    

    You should be able to do something similar with you integration-test target.

    Earthfile

    files:
        WORKDIR files
        SAVE ARTIFACT docker-compose.yaml
    

    folder-with-integration-tests/Earthfile

    integration-tests:
        FROM earthly/dind:alpine
        COPY ../+files/docker-compose.yaml ./
        WITH DOCKER --compose docker-compose.yaml --load build-setup=+compile --allow-privileged
        RUN docker run -e SPRING_DATA_MONGODB_URI=mongodb://mongodb:27017/test-db --network=default_dev-local build-setup ./gradlew test
    END