How can I test gitlab-ci.yml?

Gitlab Ci

Gitlab Ci Problem Overview


I've finally manage to make it work so that when you push to a branch job would launch, but I keep waiting for it to launch around 3min and then I've got errors which I need to fix and then commit again, and then waiting again. How can I just ssh to that public runner and test .gitlab-ci.yml "script" part just in the bash?

Gitlab Ci Solutions


Solution 1 - Gitlab Ci

For the record: You can also copy paste your gitlab-ci.yml into the linter-form provided by gitlab:

enter image description here

Depending on which IDE you are using you might be able to find plugins that check for validity. For example in VS Code you can use a plugin called gitlab-vscode-extension which can validate your .gitlab-ci.yml file.

In case you want to programatically validate your .gitlab-ci.yml, gitlab provides an API which allows you to POST your yml to /ci/lint, e.g.:

curl --header "Content-Type: application/json" https://gitlab.example.com/api/v4/ci/lint --data '{"content": "{ \"image\": \"ruby:2.6\", \"services\": [\"postgres\"], \"before_script\": [\"bundle install\", \"bundle exec rake db:create\"], \"variables\": {\"DB_NAME\": \"postgres\"}, \"types\": [\"test\", \"deploy\", \"notify\"], \"rspec\": { \"script\": \"rake spec\", \"tags\": [\"ruby\", \"postgres\"], \"only\": [\"branches\"]}}"}'

Solution 2 - Gitlab Ci

If you want to go beyond mere linting and actually run your CI script, you can do so using gitlab-runner. Here's how to do it.

Install gitlab-runner

OS=darwin
#OS=linux # Uncomment on linux
sudo curl --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-${OS}-amd64
sudo chmod +x /usr/local/bin/gitlab-runner

Official gitlab-runner docs here

Create a command

The following .gitlab-ci.yml file defines a task named build:

build:
  script:
    - echo "Hello World"

Run the command locally (limitations apply!)

gitlab-runner exec shell build

When I run the above locally, I get the following output:

Running with gitlab-runner 11.3.1~beta.4.g0aa5179e (0aa5179e)
Using Shell executor...
Running on cory-klein.local...
Cloning repository...
Cloning into '/Users/coryklein/code/prometheus-redis-exporter/builds/0/project-0'...
done.
Checking out 66fff899 as master...
Skipping Git submodules setup
$ echo "Hello World"
Hello World
Job succeeded

Solution 3 - Gitlab Ci

You can run builds locally (if you control the runner that is) by using the gitlab-runner exec command as described in the official docs here.

Make sure you also check the limitations of testing jobs this way.

Solution 4 - Gitlab Ci

The correct answer is that you cannot test your build pipeline without committing source code to your repository. You can only test one job - most likely the first job - of your build pipeline with gitlab-runner exec.

Since you cannot run multiple jobs you cannot chain any prepare or build steps with anything else. There is no way to stop gitlab-runner from creating a clean checkout and destroying your prepare/build steps.

The best/only way to test is to create a branch and keep force pushing changes to .gitlab-ci.yml to it.

Solution 5 - Gitlab Ci

See if GitLab 13.3 (August 2020) could help:

> ## Better linting for .gitlab-ci.yml files > > When reviewing your CI definitions, you can now use our CI linter to go deeper into pipeline processing to validate the correctness of your .gitlab-ci.yml. > > The CI linter provides feedback not only for syntax validation, but it also validates other kinds of logical errors and invalid configurations by simulating the pipeline as if you were running on master (without actually running anything).
> > This helps you produce a properly configured pipeline faster and helps you avoid situations where a pipeline passed the linter but still could not run. > > See Documentation and Issue.

And, still with GitLab 13.3 (August 2020)

> ## CI linter now can provide warnings in addition to errors > > The CI linter can now provide warnings in addition to error messages when validating your .gitlab-ci.yml file. > > This gives us the opportunity to provide more guidance when evaluating your pipelines, thereby making it easier to avoid more kinds of mistakes by catching them earlier. > > Our initial iteration is to provide a warning when the when:always rule is used without workflow:rules; this scenario causes duplicate pipelines when an MR is created and has also been a source of confusion.
And in addition to displaying this new warning message on the linter page, it will also appear on the pipeline view and run pipeline page to help you improve your CI configurations. > > See Documentation and Issue.


With GitLab 13.8 (January 2021), you can check its validity:

> ## CI/CD configuration validation in Pipeline Editor > > Previously, to validate your CI/CD configuration, you had to navigate to the CI lint page or commit your changes and look for any errors. > > In this release, we’ve added verification in the pipeline editor itself. > > It continuously checks your pipeline configuration before writing your .gitlab-ci.yml file and provides you with an indicator that your configuration is valid.
This saves you time and effort that could otherwise be spent optimizing your pipeline. > > https://about.gitlab.com/images/13_8/config_val.png -- CI/CD configuration validation in Pipeline Editor > > See Documentation and Issue.


See also GitLab 13.12 (May 2021)

> ## Pipeline status widget in the pipeline editor > > Previously, after committing changes using the pipeline editor, you had to navigate to a different page to know the real time status of your pipeline. > > In this release, we added a pipeline status widget to the pipeline editor so that you can monitor the status of your pipeline without leaving the comfort of the editor. > > https://about.gitlab.com/images/13_12/status.png -- Pipeline status widget in the pipeline editor > > See Documentation and Issue.

Solution 6 - Gitlab Ci

Use scripting and gitlab's API

My strategy consists on a bash script which is commanded to run via git's pre-commit hook. Of course it can run on demand, it's an script.

> It's dificult to simulate a pipeline locally, specially for shared runners, but it isn't to lint the yaml configuration file to avoid fiddling.

It uses two gitlab's API endpoints to lint the .gitlab-ci.yml:

Both API calls depend on an API_KEY, which I setup within my $HOME at ~/.gitlab.env. The script sources that file to load the key on its environment.

The project based endpoint also requires the project ID. It could be extracted from git remote -v and the like, but for simplicity it's just declared on the script, which is source-controlled within project's respository.

cat script/lint-ci
#!/usr/bin/env bash
# vim:sw=2:ts=2:et:ft=sh
# Written by lorenzogrv. Feel free to share and reuse.

set -Eeuo pipefail

cd "$(dirname "${BASH_SOURCE[0]}")/.."

fail () {
  echo "$@" >&2
  false
}

PROJECT_ID=XXXXXXXX

main () {
  # shellcheck disable=SC1090
  test -f ~/.gitlab.env && source ~/.gitlab.env

  test -v API_KEY || fail "API_KEY not defined"
  test -n "$API_KEY" || fail "API_KEY is empty"

  local filename="${1:-".gitlab-ci.yml"}"
  local response

  response="$(
    jq --null-input --arg yaml "$(<"$filename")" '{ content: $yaml }' \
    | http --check-status \
      POST https://gitlab.com/api/v4/ci/lint \
      "PRIVATE-TOKEN: $API_KEY"
  )"

  if ! test "$(jq '.status' <<<"$response")" != "valid"
  then
    echo "$filename is invalid CI/CD config!"
    jq <<<"$response"
    false
  else
    echo "$filename is valid CI/CD config"
    true
  fi >&2

  response="$(
    jq --null-input --arg yaml "$(<"$filename")" '{ content: $yaml }' \
    | http --check-status \
      POST https://gitlab.com/api/v4/projects/$PROJECT_ID/ci/lint \
      "PRIVATE-TOKEN: $API_KEY"
  )"

  if jq 'if .valid then empty else ("" | halt_error(1)) end' <<<"$response"
  then
    echo "Project's CI/CD config is valid"
    true
  else
    echo "Project's CI/CD config is not valid"
    jq <<<"$response" .errors
    jq <<<"$response" .warnings
    false
  fi >&2
}

main "$@"

Please note the script has some dependencies:

Posible enhacements

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
QuestionholmsView Question on Stackoverflow
Solution 1 - Gitlab CiFelix K.View Answer on Stackoverflow
Solution 2 - Gitlab CiCory KleinView Answer on Stackoverflow
Solution 3 - Gitlab CiStefan van GastelView Answer on Stackoverflow
Solution 4 - Gitlab CichugadieView Answer on Stackoverflow
Solution 5 - Gitlab CiVonCView Answer on Stackoverflow
Solution 6 - Gitlab CilaconbassView Answer on Stackoverflow