115

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.

baruchiro
  • 5,088
  • 5
  • 44
  • 66

1 Answers1

197

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.

Tiago Gouvêa
  • 15,036
  • 4
  • 75
  • 81
  • 4
    If you run into a weird error, verify the whitespace. Delete it and use tabs to indent again. – Stan Apr 02 '20 at 19:06
  • 1
    Just a note that if you specify `run` twice for the same `name` heading, you get an error: "The workflow is not valid ... 'run' is already defined". Though your example doesn't use the `name` key under `steps`. – Daniel Stevens Nov 22 '21 at 14:48
  • I had issues with this, it was ignoring whitespace even after using the `|`. Eventually, I got it to work simply by using semicolons at the end of each line which, when the action ignores whitespace, is a valid bash command. – Seth May 25 '22 at 19:05
  • @Seth I didn't find any reference on this.. maybe you should create a new question here, with your script, to make easy to find a solution. You can send me the question link here if you want. – Tiago Gouvêa May 26 '22 at 09:47