gitlab_clippy 0.1.0

Convert clippy warnings into GitLab Code Quality report
Documentation
image: 'rust:latest'

stages:
  - check
  - lint
  - test
  - deploy

variables:
  CARGO_HOME: $CI_PROJECT_DIR/cargo_cache

.common:
  interruptible: true
  cache:
    key:
      files:
        - Cargo.lock
    paths:
      # https://doc.rust-lang.org/cargo/guide/cargo-home.html#caching-the-cargo-home-in-ci
      - cargo_cache/bin
      - cargo_cache/registry/index
      - cargo_cache/registry/cache
      - cargo_cache/git/db
    policy: pull

.recreate_cache:
  cache:
    policy: pull-push

check:
  stage: check
  needs: []
  extends:
    - .common
    - .recreate_cache
  script:
    - cargo check --workspace

fmt:
  stage: lint
  extends: .common
  needs:
    - job: check
      artifacts: false
  before_script:
    - rustup component add rustfmt
  script:
    - cargo fmt --all -- --check

clippy:
  stage: lint
  extends: .common
  needs:
    - job: check
      artifacts: false
  before_script:
    - rustup component add clippy
  script:
    - cargo clippy
  after_script:
    - cargo clippy --message-format=json &> clippy.txt
    - curl -X POST "https://gitlab-cq-rust.herokuapp.com/clippy" --data-binary @clippy.txt --output report.json
  artifacts:
    reports:
      codequality: report.json
    expire_in: 1 week
  rules:
    - if: '$CODE_QUALITY_DISABLED'
      when: never
    - if: '$CI_PIPELINE_SOURCE == "push"'

test:
  stage: test
  extends: .common
  needs:
    - job: check
      artifacts: false
  script:
    - cargo test --all

coverage:
  image: 'rustlang/rust:nightly'
  stage: test
  extends: .common
  needs:
    - job: check
      artifacts: false
  variables:
    CARGO_INCREMENTAL: 0
    RUSTFLAGS: "-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort"
    RUSTDOCFLAGS: "-Cpanic=abort"
  script:
    - cargo +nightly build
    - cargo +nightly test
    - apt-get update && apt-get install -y --no-install-recommends zip
    - zip -0 ccov.zip `find . -type f \( -name "backend*.gc*" -o -name "gitlab_clippy*.gc*" \) -print`
    - cargo install grcov
    - $CARGO_HOME/bin/grcov ccov.zip -s . -t lcov --llvm --branch --ignore-not-existing --ignore "/*" -o lcov.info
    - bash <(curl -s https://codecov.io/bash) -f lcov.info
    - apt-get update && apt-get install -y --no-install-recommends lcov
    - lcov --summary lcov.info

.heroku:
  image: docker:latest
  services:
    - docker:dind
  variables:
    DOCKER_DRIVER: overlay
  needs:
    - job: test
      artifacts: false
  script:
    - docker build -f Dockerfile --iidfile imageid.txt -t registry.heroku.com/$HEROKU_APP/web .
    - docker login --username=_ --password=$HEROKU_API_KEY registry.heroku.com
    - docker push registry.heroku.com/$HEROKU_APP/web
    - apk add --no-cache curl
    - |-
      curl -X PATCH https://api.heroku.com/apps/$HEROKU_APP/formation \
            -d '{
            "updates": [
              {
                "type": "web",
                "docker_image": "'$(cat imageid.txt)'"
              }
            ]
        }' \
              -H "Content-Type: application/json" \
              -H "Authorization: Bearer ${HEROKU_API_KEY}" \
              -H "Accept: application/vnd.heroku+json; version=3.docker-releases"

staging:
  stage: deploy
  extends: .heroku
  variables:
    HEROKU_API_KEY: $HEROKU_STAGING_API_KEY
    HEROKU_APP: "gitlab-cq-rust-staging"
  environment:
    name: staging
    url: https://gitlab-cq-rust-staging.herokuapp.com
  rules:
    - if: '$CI_PIPELINE_SOURCE == "push"'
      when: manual
      allow_failure: true
    - if: '$CI_PIPELINE_SOURCE == "schedule"'

production:
  stage: deploy
  extends: .heroku
  variables:
    HEROKU_API_KEY: $HEROKU_PRODUCTION_API_KEY
    HEROKU_APP: "gitlab-cq-rust"
  environment:
    name: production
    url: https://gitlab-cq-rust.herokuapp.com
  rules:
    - if: '$CI_COMMIT_TAG =~ /^v\d+.\d+.\d+/'

crates.io:
  stage: deploy
  needs:
    - job: test
      artifacts: false
  variables:
    CRATES_IO_TOKEN: $CRATES_IO_TOKEN
  script:
    - cargo publish --dry-run
    - cargo login $CRATES_IO_TOKEN
    - cargo publish
  rules:
    - if: '$CI_COMMIT_TAG =~ /^v\d+.\d+.\d+/'