# Gitlab::Dangerfiles

The goal of this gem is to centralize Danger plugins and rules that to be used by multiple GitLab projects.

## Installation

Add this line to your application's Gemfile:

```ruby
gem 'gitlab-dangerfiles', require: false
```

And then execute:

```sh
$ bundle install
```

Or install it yourself as:

```sh
$ gem install gitlab-dangerfiles
```

## Usage

### Importing plugins and rules

In your project's `Dangerfile`, add the following to import the plugins and rules from this gem:

```ruby
require 'gitlab-dangerfiles'

Gitlab::Dangerfiles.for_project(self) do |dangerfiles|
  # Import all plugins from the gem
  dangerfiles.import_plugins

  # Import all rules from the gem
  dangerfiles.import_dangerfiles

  # Or import only a subset of rules
  dangerfiles.import_dangerfiles(only: %w[changes_size])

  # Or import all rules except a subset of rules
  dangerfiles.import_dangerfiles(except: %w[commit_messages])

  # Or import only a subset of rules, except a subset of rules
  dangerfiles.import_dangerfiles(only: %w[changes_size], except: %w[commit_messages])
end
```

For simple projects such as libraries, you can use the convenience method `import_defaults`:

```ruby
Gitlab::Dangerfiles.for_project(self) do |dangerfiles|
  # Imports all plugins, rules and the default reviewer roulette
  dangerfiles.import_defaults
end
```

You may optionally pass a project name; by default, `ENV['CI_PROJECT_NAME']` will be used:

```ruby
Gitlab::Dangerfiles.for_project(self, 'my-project') do |dangerfiles|
  # Imports all plugins, rules and the default reviewer roulette
  dangerfiles.import_defaults
end
```

Note that your custom plugins and rules (unless you exclude them with `except`) are automatically imported by the gem.

### Plugins

Danger plugins are located under `lib/danger/plugins`.

- `Danger::Helper` available in `Dangerfile`s as `helper`
- `Danger::Changelog` available in `Dangerfile`s as `changelog`
- `Danger::Roulette` available in `Dangerfile`s as `roulette`

For the full documentation about the plugins, please see https://www.rubydoc.info/gems/gitlab-dangerfiles.

### Configuration

Default configuration can be overriden in the form `helper.config.CONFIG_NAME = NEW_VALUE` (`CONFIG_NAME` being a value configuration key).

Alternatively, you can also get/set configuration on the engine directly via `Gitlab::Dangerfiles::Engine#config`.

#### Available general configurations

- `project_root`: The project root path. You shouldn't have to override it.
- `project_name`: The project name. Currently used by the Roulette plugin to fetch relevant
  reviewers/maintainers based on the project name. Default to `ENV["CI_PROJECT_NAME"]`.
- `ci_only_rules`: A list of rules that cannot run locally.
- `files_to_category`: A hash of the form `{ filename_regex => categories, [filename_regex, changes_regex] => categories }`.
  `filename_regex` is the regex pattern to match file names. `changes_regex` is the regex pattern to
  match changed lines in files that match `filename_regex`. Used in `helper.changes_by_category`, `helper.changes`, and `helper.categories_for_file`.

### Rules

Danger rules are located under `lib/danger/rules`.

#### `changelog`

This rule ensures the merge request follows our [Changelog guidelines](https://docs.gitlab.com/ee/development/changelog.html#changelog-entries).

#### `changes_size`

##### Available configurations

- `code_size_thresholds`: A hash of the form `{ high: 42, medium: 12 }` where
  `:high` is the lines changed threshold which triggers an error, and
  `:medium` is the lines changed threshold which triggers a warning.

#### `commit_messages`

##### Available configurations

- `max_commits_count`: The maximum number of allowed non-squashed/non-fixup commits for a given MR.
   A warning is triggered if the MR has more commits.

#### `simple_roulette`

The library includes a simplified default reviewer roulette that you can use in your
project. To use it in your project, perform the following steps:

1. If not yet done, create a `Dangerfile` at the top-level of your project. Refer to [Usage](#usage) to
   see how to set it up.
1. When using the default roulette, use `import_defaults` or import it manually when setting
   up the gitlab-dangerfiles instance:
   ```ruby
   Gitlab::Dangerfiles.for_project(self) do |dangerfiles|
     dangerfiles.import_dangerfiles(only: %w[simple_roulette])
   end
   ```

#### `type_label`

This rule warns when the merge request is missing a [type label](https://about.gitlab.com/handbook/engineering/metrics/#work-type-classification).

If the `DANGER_ERROR_WHEN_TYPE_LABEL_IS_MISSING` environment variable evaluates to `true`, Danger will error when a type label is missing.

If the `changelog` plugin is available, it also tries to infer a type label from the `Changelog` trailer of the MR.

#### `z_add_labels`

This rule adds labels set from other rules (via `helper.labels_to_add`), with a single API request.

#### `z_retry_link`

This rule adds a retry link to the job where Danger ran at the end of the Danger message, only if there's any other message to post.

### CI configuration

In order to run `danger` on GitLab CI, perform the following steps:

1. If not yet done, create a `Dangerfile` at the top-level of your project. Refer to [Usage](#usage) to
   see how to set it up.
2. In `.gitlab-ci.yml`, include [CI configuration](https://gitlab.com/gitlab-org/quality/pipeline-common/-/blob/master/ci/danger-review.yml)
   which defines `danger-review` [CI job](https://docs.gitlab.com/ee/ci/jobs/):

```yaml
include:
  - project: 'gitlab-org/quality/pipeline-common'
    file:
      - '/ci/danger-review.yml'
```

3. Create a [Project or group access token](https://docs.gitlab.com/ee/user/project/settings/project_access_tokens.html)
   with scope `api` and role `Developer`.
4. Add a [CI/CD variable](https://docs.gitlab.com/ee/ci/variables/#add-a-cicd-variable-to-a-project)
   `DANGER_GITLAB_API_TOKEN` (`Masked` but not `Protected`) and use Project access token as value.

See a [real world example](https://gitlab.com/gitlab-org/ruby/gems/gitlab-styles/-/merge_requests/105).

## Rake tasks

You can import this gem's Rake tasks by adding the following to your project's `Rakefile`:

```ruby
require 'gitlab-dangerfiles'

Gitlab::Dangerfiles.load_tasks
```

That will add the `danger_local` Rake task that allows to run Danger locally.

## Documentation

Latest documentation can be found at <https://www.rubydoc.info/gems/gitlab-dangerfiles>.

## Development

After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).

## Contributing

Bug reports and merge requests are welcome at https://gitlab.com/gitlab-org/gitlab-dangerfiles. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://gitlab.com/gitlab-org/gitlab-dangerfiles/blob/master/CODE_OF_CONDUCT.md).

## License

The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).

## Code of Conduct

Everyone interacting in the Gitlab::Danger project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://gitlab.com/gitlab-org/gitlab-dangerfiles/blob/master/CODE_OF_CONDUCT.md).