Search code examples
dockerdockerfiledocker-entrypointgithub-actions

How to run multiple commands in one Github Actions Docker


What is the right way for running multiple commands in one action?

For example:

I want to run a python script as action. Before running this script I need to install the requirements.txt.

I can think of several options:

  • Create a Dockerfile with the command RUN pip install -r requirements.txt in it.
  • Use the python:3 image, and run the pip install -r requirements.txt in the entrypoint.sh file before running the arguments from args in main.workflow.
  • use both pip install and python myscript.py as args

Another example:

I want to run a script that exists in my repository, then compare 2 files (its output and a file that already exists).

This is a process that includes two commands, whereas in the first example, the pip install command can be considered a building command rather than a test command.

the question:

Can I create another Docker for another command, which will contain the output of the previous Docker?

I'm looking for guidelines for the location of the command in Dockerfile, in entrypoint or in args.


Solution

  • You can run multiple commands using a pipe | on the run attribute. Check this out:

    name: My Workflow
    
    on: [push]
    
    jobs:
      runMultipleCommands:
        runs-on: ubuntu-latest
        steps:
         - uses: actions/checkout@v1
         - run: |
            echo "A initial message"
            pip install -r requirements.txt
            echo "Another message or command"
            python myscript.py
            bash some-shell-script-file.sh -xe
         - run: echo "One last message"
    

    On my tests, running a shell script like ./myscript.sh returns a ``. But running it like bash myscript.sh -xe worked like expected.

    My workflow file | Results

    If you want to run this inside the docker machine, an option could be run some like this on you run clause:

    docker exec -it pseudoName /bin/bash -c "cd myproject; pip install -r requirements.txt;"
    

    Regard to the "create another Docker for another command, which will contain the output of the previous Docker", you could use multistage-builds on your dockerfile. Some like:

    ## First stage (named "builder")
    ## Will run your command (using add git as sample) and store the result on "output" file
    FROM alpine:latest as builder
    RUN apk add git > ./output.log
    
    ## Second stage
    ## Will copy the "output" file from first stage
    FROM alpine:latest
    COPY --from=builder ./output.log .
    RUN cat output.log
    # RUN your checks
    CMD []
    

    This way the apk add git result was saved to a file, and this file was copied to the second stage, that can run any check on the results.