Github Action: Split Long Command into Multiple Lines

GithubYamlGithub Actions

Github Problem Overview


I have a Github action command that is really long:

name: build

on: [push]

jobs:
    build:
        runs-on: ubuntu-18.04
        steps:
            - uses: actions/checkout@v1
            - name: Install Prerequisites
              run: |
                sudo apt-get update
                sudo apt-get install -y --no-install-recommends "a very very long list of prerequisites"

May I know whether it is possible to split the long command into multiple lines for better readability? I have tried the separator '' but it does not work. Thanks in advance.

Github Solutions


Solution 1 - Github

I have a multi line command using backslash to separate the lines as follows:

- name: Configure functions
  run: |
    firebase functions:config:set \
      some.key1="${{ secrets.SOME_KEY_1 }}" \
      some.key2="${{ secrets.SOME_KEY_2 }}" \
    ...    

Note the preceding '|' character.

Solution 2 - Github

You can use the YAML folded style with > which is supported by GitHub Actions.

For example,

run: >
  xvfb-run
  ./mvnw -f my/pom.xml
  clean verify
  -DskipTests

newlines will be replaced with spaces so the above is equivalent to

run: xvfb-run ./mvnw -f my/pom.xml clean verify -DskipTests

Solution 3 - Github

Going to share this in since it has not been mentioned.

You can use:

  • | called a Literal Block Scalar which preserves new lines and trailing spaces
  • > called a Folded Block Scalar which converts new lines into spaces
  • plain old strings, either unquoted, single-quoted or double-quoted

I found the site yaml-multiline.info useful for understanding how yaml strings are interpreted.

For my use case, I ended up doing the following:

run: >-
  for i in $(find . -type f -name "*.log");
  do
   echo "File: ${i} \n";
   cat $i;
   printf '%*s\n' "${COLUMNS:-$(tput cols)}" '' | tr ' ' -;
  done

Solution 4 - Github

The above answers all had pieces, but this is what worked for me in a github composite action. It should work in a regular workflow too.

As @lorenzo-bettini said, if you want everything to be on one line, use what @Josue Alexander Ibarra called a Folded Block Scalar.

run: >
  xvfb-run
  ./mvnw -f my/pom.xml
  clean verify
  -DskipTests

> newlines will be replaced with spaces so the above is equivalent to

run: xvfb-run ./mvnw -f my/pom.xml clean verify -DskipTests

If you want new lines to be preserved, use what @Josue Alexander Ibarra called a Literal Block Scalar.

run: |
  FILE=./package.json
  if test -f "$FILE"
  then
    echo "$FILE exists."
  else
    echo "File does not exist"
  fi

When you do a multi-line run, though, you have to make sure you indent correctly, otherwise step will think that shell: bash is part of the run: | string.

WRONG:

  steps:
    - run: |
      FILE=./package.json
      if test -f "$FILE"
      then
        echo "$FILE exists."
      else
        echo "File does not exist"
      fi
      shell: run

RIGHT:

  steps:
    - run: |
        FILE=./package.json
        if test -f "$FILE"
        then
          echo "$FILE exists."
        else
          echo "File does not exist"
        fi
      shell: run

Solution 5 - Github

This was not possible using backslashes, earlier. See the accepted answer on how to do it now.


As far as I know, GitHub Actions does not support that.

However, you can use environment variables for that.

For example, this script splits your command in 3 lines of code and executes it as one line.

steps:
  - name: Install Prerequisites
    run: |
      sudo apt-get update
      bash -c "$line1 $line2 $line3"
    env:
    - line1='sudo apt-get install -y --no-install-recommends '
    - line2='a very very long list'
    - line3='of prerequisites'

It creates the environment variables line1, line2 and line3 and concats and executes them in a bash session.

Solution 6 - Github

Note also the join and format functions for expressions:

HELLO_WORLD = ${{ join('Hello', 'world!') }}
HELLO_WORLD = ${{ format('{{Hello {0}}}', 'World') }}

Presumably these could be combined with env variables.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBojian ZhengView Question on Stackoverflow
Solution 1 - GithubMike De MarcoView Answer on Stackoverflow
Solution 2 - Githublorenzo-bettiniView Answer on Stackoverflow
Solution 3 - GithubJosue Alexander IbarraView Answer on Stackoverflow
Solution 4 - GithubMixchangeView Answer on Stackoverflow
Solution 5 - Githubdan1stView Answer on Stackoverflow
Solution 6 - GithubJon PeckView Answer on Stackoverflow