Skip to content

GitLab CI YAML: before_script doesn't accept single string or nested strings

Summary

The before_script of .gitlab-ci.yml cannot be a single string. The documentation states that it can be. Also script of a job can be a single string, so this is inconsistent.

after_script behaves in the same way.

Steps to reproduce

Example of what should be a valid .gitlab-ci.yml

before_script: |
  do_stuff

my_job:
  script: |
    do_stuff

What is the current bug behavior?

This will be rejected by the linter.

Notice that my_job is accepted.

What is the expected correct behavior?

Everything should be ok

Relevant logs and/or screenshots

Linter output:

Status: syntax is incorrect
Error: before_script config should be an array of strings

Results of GitLab environment info

Checked using self hosted version 10.4.2 and current Gitlab.com

Workaround

Its possible to workaround the issue pretty easily

before_script:
  - |
    do_stuff

Technical proposal

diff --git a/lib/gitlab/ci/config/entry/job.rb b/lib/gitlab/ci/config/entry/job.rb
index a20b802be58..e580e42d374 100644
--- a/lib/gitlab/ci/config/entry/job.rb
+++ b/lib/gitlab/ci/config/entry/job.rb
@@ -48,7 +48,7 @@ class Job < ::Gitlab::Config::Entry::Node
             end
           end
 
-          entry :before_script, Entry::Script,
+          entry :before_script, Entry::Commands,
             description: 'Global before script overridden in this job.',
             inherit: true
 
@@ -60,7 +60,7 @@ class Job < ::Gitlab::Config::Entry::Node
             description: 'Deprecated: stage this job will be executed into.',
             inherit: false
 
-          entry :after_script, Entry::Script,
+          entry :after_script, Entry::Commands,
             description: 'Commands that will be executed when finishing job.',
             inherit: true
 
diff --git a/lib/gitlab/ci/config/entry/root.rb b/lib/gitlab/ci/config/entry/root.rb
index 54ef84b965a..622dbb857d0 100644
--- a/lib/gitlab/ci/config/entry/root.rb
+++ b/lib/gitlab/ci/config/entry/root.rb
@@ -32,7 +32,7 @@ class Root < ::Gitlab::Config::Entry::Node
             description: 'List of external YAML files to include.',
             reserved: true
 
-          entry :before_script, Entry::Script,
+          entry :before_script, Entry::Commands,
             description: 'Script that will be executed before each job.',
             reserved: true
 
@@ -44,7 +44,7 @@ class Root < ::Gitlab::Config::Entry::Node
             description: 'Docker images that will be linked to the container.',
             reserved: true
 
-          entry :after_script, Entry::Script,
+          entry :after_script, Entry::Commands,
             description: 'Script that will be executed after each job.',
             reserved: true

This will make before_script and after_script behave exactly like script:

  • accept single string
  • flatten arrays up to 10 levels deep to work with nested !reference calls.
Edited by Marius Bobin