summaryrefslogtreecommitdiff
path: root/doc/development/rake_tasks.md
blob: cd7f8cba39b4284462fe287fdac4c5e33fbb1a66 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments
---

# Rake tasks for developers

Rake tasks are available for developers and others contributing to GitLab.

## Set up database with developer seeds

If your database user does not have advanced privileges, you must create the database manually before running this command.

```shell
bundle exec rake setup
```

The `setup` task is an alias for `gitlab:setup`.
This tasks calls `db:reset` to create the database, and calls `db:seed_fu` to seed the database.
`db:setup` calls `db:seed` but this does nothing.

### Environment variables

**MASS_INSERT**: Create millions of users (2m), projects (5m) and its
relations. It's highly recommended to run the seed with it to catch slow queries
while developing. Expect the process to take up to 20 extra minutes.

See also [Mass inserting Rails models](mass_insert.md).

**LARGE_PROJECTS**: Create large projects (through import) from a predefined set of URLs.

### Seeding issues for all or a given project

You can seed issues for all or a given project with the `gitlab:seed:issues`
task:

```shell
# All projects
bin/rake gitlab:seed:issues

# A specific project
bin/rake "gitlab:seed:issues[group-path/project-path]"
```

By default, this seeds an average of 2 issues per week for the last 5 weeks per
project.

#### Seeding issues for Insights charts **(ULTIMATE)**

You can seed issues specifically for working with the
[Insights charts](../user/group/insights/index.md) with the
`gitlab:seed:insights:issues` task:

```shell
# All projects
bin/rake gitlab:seed:insights:issues

# A specific project
bin/rake "gitlab:seed:insights:issues[group-path/project-path]"
```

By default, this seeds an average of 10 issues per week for the last 52 weeks
per project. All issues are also randomly labeled with team, type, severity,
and priority.

#### Seeding groups with subgroups

You can seed groups with subgroups that contain milestones/projects/issues
with the `gitlab:seed:group_seed` task:

```shell
bin/rake "gitlab:seed:group_seed[subgroup_depth, username]"
```

Group are additionally seeded with epics if GitLab instance has epics feature available.

#### Seeding a runner fleet test environment

Use the `gitlab:seed:runner_fleet` task to seed a full runner fleet, specifically groups with subgroups and projects that contain runners and pipelines:

```shell
bin/rake "gitlab:seed:runner_fleet[username, registration_prefix, runner_count, job_count]"
```

By default, the Rake task uses the `root` username to create 40 runners and 400 jobs.

```mermaid
graph TD
    G1[Top level group 1] --> G11
    G2[Top level group 2] --> G21
    G11[Group 1.1] --> G111
    G11[Group 1.1] --> G112
    G111[Group 1.1.1] --> P1111
    G112[Group 1.1.2] --> P1121
    G21[Group 2.1] --> P211

    P1111[Project 1.1.1.1<br><i>70% of jobs, sent to first 5 runners</i>]
    P1121[Project 1.1.2.1<br><i>15% of jobs, sent to first 5 runners</i>]
    P211[Project 2.1.1<br><i>15% of jobs, sent to first 5 runners</i>]

    IR1[Instance runner]
    P1111R1[Shared runner]
    P1111R[Project 1.1.1.1 runners<br>20% total runners]
    P1121R[Project 1.1.2.1 runners<br>49% total runners]
    G111R[Group 1.1.1 runners<br>30% total runners<br><i>remaining jobs</i>]
    G21R[Group 2.1 runners<br>1% total runners]

    P1111 --> P1111R1
    P1111 --> G111R
    P1111 --> IR1
    P1111 --> P1111R
    P1121 --> P1111R1
    P1121 --> IR1
    P1121 --> P1121R
    P211 --> P1111R1
    P211 --> G21R
    P211 --> IR1

    classDef groups fill:#09f6,color:#000000,stroke:#333,stroke-width:3px;
    classDef projects fill:#f96a,color:#000000,stroke:#333,stroke-width:2px;
    class G1,G2,G11,G111,G112,G21 groups
    class P1111,P1121,P211 projects
```

#### Seeding custom metrics for the monitoring dashboard

A lot of different types of metrics are supported in the monitoring dashboard.

To import these metrics, you can run:

```shell
bundle exec rake 'gitlab:seed:development_metrics[your_project_id]'
```

#### Seed a project with vulnerabilities

You can seed a project with [security vulnerabilities](../user/application_security/vulnerabilities/index.md).

```shell
# Seed all projects
bin/rake 'gitlab:seed:vulnerabilities'

# Seed a specific project
bin/rake 'gitlab:seed:vulnerabilities[group-path/project-path]'
```

### Automation

If you're very sure that you want to **wipe the current database** and refill
seeds, you can set the `FORCE` environment variable to `yes`:

```shell
FORCE=yes bundle exec rake setup
```

This skips the action confirmation/safety check, saving you from answering
`yes` manually.

### Discard `stdout`

Since the script would print a lot of information, it could be slowing down
your terminal, and it would generate more than 20G logs if you just redirect
it to a file. If we don't care about the output, we could just redirect it to
`/dev/null`:

```shell
echo 'yes' | bundle exec rake setup > /dev/null
```

Because you can't see the questions from `stdout`, you might just want
to `echo 'yes'` to keep it running. It would still print the errors on `stderr`
so no worries about missing errors.

### Extra Project seed options

There are a few environment flags you can pass to change how projects are seeded

- `SIZE`: defaults to `8`, max: `32`. Amount of projects to create.
- `LARGE_PROJECTS`: defaults to false. If set, clones 6 large projects to help with testing.
- `FORK`: defaults to false. If set to `true`, forks `torvalds/linux` five times. Can also be set to an existing project `full_path` to fork that instead.

## Run tests

To run the test you can use the following commands:

- `bin/rake spec` to run the RSpec suite
- `bin/rake spec:unit` to run only the unit tests
- `bin/rake spec:integration` to run only the integration tests
- `bin/rake spec:system` to run only the system tests

`bin/rake spec` takes significant time to pass.
Instead of running the full test suite locally, you can save a lot of time by running
a single test or directory related to your changes. After you submit a merge request,
CI runs full test suite for you. Green CI status in the merge request means
full test suite is passed.

You can't run `rspec .` since this tries to run all the `_spec.rb`
files it can find, also the ones in `/tmp`

You can pass RSpec command line options to the `spec:unit`,
`spec:integration`, and `spec:system` tasks. For example, `bin/rake "spec:unit[--tag ~geo --dry-run]"`.

For an RSpec test, to run a single test file you can run:

```shell
bin/rspec spec/controllers/commit_controller_spec.rb
```

To run several tests inside one directory:

- `bin/rspec spec/requests/api/` for the RSpec tests if you want to test API only

### Run RSpec tests which failed in Merge Request pipeline on your machine

If your Merge Request pipeline failed with RSpec test failures,
you can run all the failed tests on your machine with the following Rake task:

```shell
bin/rake spec:merge_request_rspec_failure
```

There are a few caveats for this Rake task:

- You need to be on the same branch on your machine as the source branch of the Merge Request.
- The pipeline must have been completed.
- You may need to wait for the test report to be parsed and retry again.

This Rake task depends on the [unit test reports](../ci/testing/unit_test_reports.md) feature,
which only gets parsed when it is requested for the first time.

### Speed up tests, Rake tasks, and migrations

[Spring](https://github.com/rails/spring) is a Rails application pre-loader. It
speeds up development by keeping your application running in the background so
you don't need to boot it every time you run a test, Rake task or migration.

If you want to use it, you must export the `ENABLE_SPRING` environment
variable to `1`:

```shell
export ENABLE_SPRING=1
```

Alternatively you can use the following on each spec run,

```shell
bundle exec spring rspec some_spec.rb
```

## RuboCop tasks

## Generate initial RuboCop TODO list

One way to generate the initial list is to run the Rake task `rubocop:todo:generate`:

```shell
bundle exec rake rubocop:todo:generate
```

To generate TODO list for specific RuboCop rules, pass them comma-separated as
argument to the Rake task:

```shell
bundle exec rake 'rubocop:todo:generate[Gitlab/NamespacedClass,Lint/Syntax]'
bundle exec rake rubocop:todo:generate\[Gitlab/NamespacedClass,Lint/Syntax\]
```

Some shells require brackets to be escaped or quoted.

See [Resolving RuboCop exceptions](../development/rubocop_development_guide.md#resolving-rubocop-exceptions)
on how to proceed from here.

### Run RuboCop in graceful mode

You can run RuboCop in "graceful mode". This means all enabled cop rules are
silenced which have "grace period" activated (via `Details: grace period`).

Run:

```shell
bundle exec rake 'rubocop:check:graceful'
bundle exec rake 'rubocop:check:graceful[Gitlab/NamespacedClass]'
```

## Compile Frontend Assets

You shouldn't ever need to compile frontend assets manually in development, but
if you ever need to test how the assets get compiled in a production
environment you can do so with the following command:

```shell
RAILS_ENV=production NODE_ENV=production bundle exec rake gitlab:assets:compile
```

This compiles and minifies all JavaScript and CSS assets and copy them along
with all other frontend assets (images, fonts, etc) into `/public/assets` where
they can be easily inspected.

## Emoji tasks

To update the Emoji aliases file (used for Emoji autocomplete), run the
following:

```shell
bundle exec rake tanuki_emoji:aliases
```

To update the Emoji digests file (used for Emoji autocomplete), run the
following:

```shell
bundle exec rake tanuki_emoji:digests
```

This updates the file `fixtures/emojis/digests.json` based on the currently
available Emoji.

To generate a sprite file containing all the Emoji, run:

```shell
bundle exec rake tanuki_emoji:sprite
```

If new emoji are added, the sprite sheet may change size. To compensate for
such changes, first generate the `emoji.png` sprite sheet with the above Rake
task, then check the dimensions of the new sprite sheet and update the
`SPRITESHEET_WIDTH` and `SPRITESHEET_HEIGHT` constants accordingly.

## Update project templates

Starting a project from a template needs this project to be exported. On a
up to date main branch run:

```shell
gdk start
bundle exec rake gitlab:update_project_templates
git checkout -b update-project-templates
git add vendor/project_templates
git commit
git push -u origin update-project-templates
```

Now create a merge request and merge that to main.

To update just a single template instead of all of them, specify the template name
between square brackets. For example, for the `cluster_management` template, run:

```shell
bundle exec rake gitlab:update_project_templates\[cluster_management\]
```

## Generate route lists

To see the full list of API routes, you can run:

```shell
bundle exec rake grape:path_helpers
```

The generated list includes a full list of API endpoints and functional
RESTful API verbs.

For the Rails controllers, run:

```shell
bundle exec rails routes
```

Since these take some time to create, it's often helpful to save the output to
a file for quick reference.

## Show obsolete `ignored_columns`

To see a list of all obsolete `ignored_columns` run:

```shell
bundle exec rake db:obsolete_ignored_columns
```

Feel free to remove their definitions from their `ignored_columns` definitions.

## Validate GraphQL queries

To check the validity of one or more of our front-end GraphQL queries,
run:

```shell
# Validate all queries
bundle exec rake gitlab:graphql:validate
# Validate one query
bundle exec rake gitlab:graphql:validate[path/to/query.graphql]
# Validate a directory
bundle exec rake gitlab:graphql:validate[path/to/queries]
```

This prints out a report with an entry for each query, explaining why
each query is invalid if it fails to pass validation.

We strip out `@client` fields during validation so it is important to mark
client fields with the `@client` directive to avoid false positives.

## Analyze GraphQL queries

Analogous to `ANALYZE` in SQL, we can run `gitlab:graphql:analyze` to
estimate the of the cost of running a query.

Usage:

```shell
# Analyze all queries
bundle exec rake gitlab:graphql:analyze
# Analyze one query
bundle exec rake gitlab:graphql:analyze[path/to/query.graphql]
# Analyze a directory
bundle exec rake gitlab:graphql:analyze[path/to/queries]
```

This prints out a report for each query, including the complexity
of the query if it is valid.

The complexity depends on the arguments in some cases, so the reported
complexity is a best-effort assessment of the upper bound.

## Update GraphQL documentation and schema definitions

To generate GraphQL documentation based on the GitLab schema, run:

```shell
bundle exec rake gitlab:graphql:compile_docs
```

In its current state, the Rake task:

- Generates output for GraphQL objects.
- Places the output at `doc/api/graphql/reference/index.md`.

This uses some features from `graphql-docs` gem like its schema parser and helper methods.
The docs generator code comes from our side giving us more flexibility, like using Haml templates and generating Markdown files.

To edit the content, you may need to edit the following:

- The template. You can edit the template at `tooling/graphql/docs/templates/default.md.haml`.
  The actual renderer is at `Tooling::Graphql::Docs::Renderer`.
- The applicable `description` field in the code, which
  [Updates machine-readable schema files](#update-machine-readable-schema-files),
  which is then used by the `rake` task described earlier.

`@parsed_schema` is an instance variable that the `graphql-docs` gem expects to have available.
`Gitlab::Graphql::Docs::Helper` defines the `object` method we currently use. This is also where you
should implement any new methods for new types you'd like to display.

### Update machine-readable schema files

To generate GraphQL schema files based on the GitLab schema, run:

```shell
bundle exec rake gitlab:graphql:schema:dump
```

This uses GraphQL Ruby's built-in Rake tasks to generate files in both [IDL](https://www.prisma.io/blog/graphql-sdl-schema-definition-language-6755bcb9ce51) and JSON formats.

### Update documentation and schema definitions

The following command combines the intent of [Update GraphQL documentation and schema definitions](#update-graphql-documentation-and-schema-definitions) and [Update machine-readable schema files](#update-machine-readable-schema-files):

```shell
bundle exec rake gitlab:graphql:update_all
```

## Update OpenAPI client for Error Tracking feature

NOTE:
This Rake task needs `docker` to be installed.

To update generated code for OpenAPI client located in
`vendor/gems/error_tracking_open_api` run the following commands:

```shell
# Run rake task
bundle exec rake gems:error_tracking_open_api:generate

# Review and test the changes

# Commit the changes
git commit -m 'Update ErrorTrackingOpenAPI from OpenAPI definition' vendor/gems/error_tracking_open_api
```

## Update banned SSH keys

You can add [banned SSH keys](../security/ssh_keys_restrictions.md#block-banned-or-compromised-keys)
from any Git repository by using the `gitlab:security:update_banned_ssh_keys` Rake task:

1. Find a public remote Git repository containing SSH public keys.
   The public key files must have the `.pub` file extension.
1. Make sure that `/tmp/` directory has enough space to store the remote Git repository.
1. To add the SSH keys to your banned-key list, run this command, replacing
   `GIT_URL` and `OUTPUT_FILE` with appropriate values:

   ```shell
   # @param git_url - Remote Git URL.
   # @param output_file - Update keys to an output file. Default is config/security/banned_ssh_keys.yml.

   bundle exec rake "gitlab:security:update_banned_ssh_keys[GIT_URL, OUTPUT_FILE]"
   ```

This task clones the remote repository, recursively walks the file system looking for files
ending in `.pub`, parses those files as SSH public keys, and then adds the public key fingerprints
to `output_file`. The contents of `config/security/banned_ssh_keys.yml` is read by GitLab and kept
in memory. It is not recommended to increase the size of this file beyond 1 megabyte in size.