Feature Request: short-circuit CI pipelines based on files changed since the previous passed pipeline

Everyone can contribute. Help move this issue forward while earning points, leveling up and collecting rewards.

Currently we waste a lot of resources running ruby unit tests when unrelated changes have been made (CSS, JS, documentation changes, etc). I believe we can improve on this by exposing more context-based configuration options within .gitlab-ci.yml.

What if we could do the following:

  1. Pipeline is created.
  2. Find SHA for the most recent ancestor with a passing build.
  3. Generate a diff between the pipeline's commit SHA and the most recent successful ancestor.
  4. Run configured rules to determine which tests to run.

Some example rules:

IF no file matching /**/.eslintrc or /**/*.js has changed, THEN skip the eslint build step.
IF no file matching /**/*.rb has been changed, THEN skip rspec unit tests. (feature tests still run)
IF no file matching /**/.rubocop.yml or /**/*.rb has been changed, THEN skip rubocop linter

This could go into the .gitlab-ci.yml like so:

# ...

lint:javascript:
  <<: *dedicated-runner
  cache:
    paths:
      - node_modules/
  stage: test
  if_changed:
    - "/**/.eslintrc"
    - "/**/*.js"
  image: "node:7.1"
  before_script:
    - npm install
  script:
    - npm --silent run eslint

# ...

Practical applications

Save on build time for certain types of merge requests:

Table of builds to run (using GitLab CE's pipeline config as an example)

| | rubocop | rspec | rake db:migrate | rake haml_lint | rake scss_lint | lint:javascript | teaspoon | lint-doc | |-----|-----|-----|-----|-----|-----|-----|-----|-----|-----| | Markdown File Change | no | no | no | no | no | no | no | yes | | JavaScript Changes | no | feature tests only | no | no | no | yes | yes | no | | SCSS Changes | no | feature tests only | no | no | yes | no | yes | no | | Haml Changes | yes | feature tests only | no | yes | no | no | yes | no | | Ruby Changes (not in /db/*or /config/*) | yes | yes | no | no | no | no | yes | no | | Ruby Changes (/db/migrate/foo.rb) | yes | yes | yes | no | no | no | yes | no |

Edited by 🤖 GitLab Bot 🤖