Is it possible to use a here-document from within a multiline command in .gitlab-ci.yml?

Is it possible to use a here-document from within a multiline command in .gitlab-ci.yml

I am having difficulty using a here-document within a command that expands multiple lines in a .gitlab-ci.yml job. For example I have created a short test job below, that uses a here-document to assign a multiline string to an environment variable PAYLOAD that is then used in a curl request to POST data to a url:

example:
  image: node:12-stretch-slim
  stage: mystage
  script:
    - >
      PAYLOAD=$(cat << 'JSON'
      '{
        "branch": "master",
        "commit_message": "some commit message",
        "actions": [
          {
            "action": "create",
            "file_path": "foo/bar",
            "content": "some content"
          }
        ]
      }'
      JSON
      )
    - >
      curl -X POST https://requestbin.io/1f84by61
      --header 'Content-Type: application/json; charset=utf-8'
      --data-binary "$PAYLOAD"
  when: manual
  only:
    - /^release-.*$/

The following script fails with the following message on gitlab.com CI server:

$ PAYLOAD=$(cat << 'JSON' '{ # collapsed multi-line command

[551](<private url>) /bin/bash: line 140: warning: here-document at line 140 delimited by end-of-file (wanted `JSON')

[552](<private url>) /bin/bash: line 139: warning: here-document at line 139 delimited by end-of-file (wanted `JSON')

[553](<private url>) cat: '{'$'\n'' "branch": "master",'$'\n'' "commit_message": "some commit message",'$'\n'' "actions": ['$'\n'' {'$'\n'' "action": "create",'$'\n'' "file_path": "foo/bar",'$'\n'' "content": "some content"'$'\n'' }'$'\n'' ]'$'\n''}': No such file or directory

[554](<private url>) cat: JSON: No such file or directory

Can anyone help?

1 Like

Solved it after reading this

Using |- preserves newlines within the command and does not append a newline at the end of the command string. Beforehand I was using > which replaces newlines in the command string with spaces.

release:
  image: node:12-stretch-slim
  stage: release
  before_script:
    - apt-get update && apt-get install -y curl git jq
  script:
    - |-
      PAYLOAD=$(cat << JSON
      {
        "branch": "master",
        "commit_message": "some commit message",
        "actions": [
          {
            "action": "create",
            "file_path": "foo/bar",
            "content": "some content"
          }
        ]
      }
      JSON
      )
    - >
      curl -X POST https://requestbin.io/1f84by61
      --header 'Content-Type: application/json; charset=utf-8'
      --data-binary "$PAYLOAD"
  when: manual
  only:
    - /^release-.*$/
3 Likes