Authored by Peter Weinert

Validate your .gitlab-ci.yml in a git hook


Are you tired of Gitlab reporting "yaml invalid"? Then you should validate your yaml prior to that...


Copy this snippet into your .git/hooks/pre-commit script in order to lint your .gitlab-ci.yml. Your script pre-commit must be executable (chmod +x .git/hooks/pre-commit). Please note, this script works fine in Windows as git provides Git Bash.
You want to change the code line containing to match your Gitlab URL.



> git add .gitlab-ci.yml
> git commit

If the validation fails, the commit aborts.


  • An invalid .gitlab-ci.yml


> git add .gitlab-ci.yml
> git commit
ERROR: Invalid .gitlab-ci.yml. Lint reports {"status":"invalid","errors":["jobs:clang config can't be blank"]}.
Use the Gitlab Lint ( for more information.
Aborting commit.

and the commit is aborted. You can fix the yaml and try again.

  • A valid .gitlab-ci.yml:
    - ./build-with-clang


> git add .gitlab-ci.yml
> git commit
[test 1c1b986] fine
 1 file changed, 3 insertions(+)

and the commit is accepted.

  • If the connectivity to the Lint API is broken you get
> git add .gitlab-ci.yml
> git commit
WARNING: .gitlab-ci.yml not validated! Curl failed with error code 6
[test f780642] offline
 1 file changed, 1 insertion(+)

but the commit is accepted, so you can continue to work offline.

Implementation notes

When git add is called is was the perfect time to validate. But: The clean filter in attributes is not suitable here, as we do validation not conversion! As a result, pre-commit is used.

The proper .gitlab-ci.yml is taken from index not from the working directory (git checkout-index), as these may differ.

The Gitlab API works as shown (doc):

curl --header "Content-Type: application/json" --data '{"content": "{ \"image\": \"ruby:2.1\", \"services\": [\"postgres\"], \"before_script\": [\"gem install bundler\", \"bundle install\", \"bundle exec rake db:create\"], \"variables\": {\"DB_NAME\": \"postgres\"}, \"types\": [\"test\", \"deploy\", \"notify\"], \"rspec\": { \"script\": \"rake spec\", \"tags\": [\"ruby\", \"postgres\"], \"only\": [\"branches\"]}}"}'

returns {"status":"valid","errors":[]}

curl --header "Content-Type: application/json" --data '{"content": "{ test}"}'

returns {"status":"invalid","errors":["jobs:test config can't be blank"]}


Please leave a comment if you found a bug or an security issue.

Peter Weinert
LRZ Software Engineering

pre-commit 2.42 KB
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment