Public
Authored by Peter Weinert

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

Target

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

Installation

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 https://gitlab.lrz.de to match your Gitlab URL.

Usage

Type

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

If the validation fails, the commit aborts.

Results

  • An invalid .gitlab-ci.yml

    clang:

    produces

    > 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 (https://gitlab.lrz.de/ci/lint) for more information.
    Aborting commit.

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

  • A valid .gitlab-ci.yml:

    clang:
    script:
    - ./build-with-clang

    produces

    > 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" https://gitlab.lrz.de/api/v4/ci/lint --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" https://gitlab.lrz.de/api/v4/ci/lint --data '{"content": "{ test}"}'

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

Contribute

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

Peter Weinert
LRZ Software Engineering

Edited
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