getpopper / popper

Container-native task automation engine.
https://getpopper.io
MIT License
302 stars 61 forks source link

Translate `dir` attribute #983

Closed shumbo closed 3 years ago

shumbo commented 3 years ago

Overview

This PR adds support for dir option for Popper-to-Drone translator and makes it possible to run commands in directories other than the root of the repository.

Now the translator is capable of translating all examples in under /examples πŸŽ‰

Strategy

Changing Directory

Popper's dir corresponds to --workdir on Docker under the hood. However, Drone's runner doesn't support running commands other than the project root.

In this PR, the translator inserts a cd command before running the commands to change the working directory.

Absolute Path Access

dir options are usually given in absolute path.

https://github.com/getpopper/popper/blob/d7f79f18ed2245b3dd61b7092ca61e4fcfeef9ca/examples/cpp/ci.yml#L16

However, because Popper and Drone mount the repository in different locations (/workspace for Popper and /drone/src for Drone), we cannot simply cd into the specified directory and need a workaround.

In this PR, the translator inserts ln -s /drone/src /workspace to make a symbolic link. In this way, the file system will have the same structure and any command that uses an absolute path, including the cd command mentioned above, will work as expected.

Limitations

For the reasons above, we need to execute two commands before running the actual commands. We can use Drone's commands attribute to run multiple commands.

However, in order to use that field, we need to obtain actual commands that will be executed in containers. This is why the translator requires runs attribute to be set when using dir attribute.

In Popper, if runs attribute is not given, it will use the Dockerfile's ENTRYPOINT. Because there is no trivial way to obtain ENTRYPOINT from docker images, Popper steps with dir but without runs cannot be translated. Such translations will fail with an error.

Discussion

While working on this PR, I realized that Popper's host runner (used with uses: sh) doesn't respect the dir option.

For example,

steps:
  - id: relative path
    uses: sh
    runs: [/bin/sh, -c]
    dir: /tmp
    args: ["echo 'hello world' > hello.txt"]

Running this workflow with popper run will create hello.txt in the current directory as opposed to /tmp.

To match the behavior of an original workflow and translated workflow, the translator does nothing for steps with uses: sh.