gitlab-org/gitlab
Development workflow
The mechanics of writing, testing, and shipping a change to GitLab.
Branching
The default branch is master. Branch names should:
- Be lowercased with hyphens.
- Include the issue number when applicable:
123456-fix-pipeline-cache. - Avoid
wip/prefixes — use the MR's "Mark as draft" toggle instead.
The .ai/git.md file (loaded by AI assistants) lists the project's git conventions.
Commit hygiene
- Each commit should be self-contained, build, and pass lint locally.
- Subject line ≤ 72 characters.
- Squashing on merge is the default; commits within an MR may be exploratory.
Pre-commit checks via Lefthook
The repo uses Lefthook for git hooks (lefthook.yml, ~17K lines of config). After installing GDK or running lefthook install, a pre-push hook runs the relevant linters on the files you changed:
- RuboCop on
*.rb - HAML-Lint on
*.haml - ESLint on
*.js/*.vue - Stylelint on
*.scss - Prettier
- Markdownlint
- gettext-lint
Hooks can be skipped with LEFTHOOK=0 git push, but this is discouraged.
Local CI scripts
Several helper scripts in scripts/ reproduce CI locally:
scripts/run-fast-specs.sh— RSpec subset that runs in seconds.scripts/static-analysis— runs RuboCop, ESLint, Stylelint, etc.scripts/lint-doc.sh— full doc lint suite.scripts/regenerate-schema— re-dumpdb/structure.sqlafter a migration.scripts/verify-tff-mapping— validates the test-file-finder mapping for selective test execution.
Working with feature flags
New code that's not 100% ready for production is gated behind a feature flag. The flow is:
- Create the flag YAML:
config/feature_flags/development/<flag_name>.yml(orgitlab_com_derisk/,beta/,experiment/,wip/,ops/depending on lifecycle). - Wrap code with
Feature.enabled?(:flag_name, actor)fromlib/feature.rb. - Spec the flag both on and off.
- Roll out by chatops, then promote to GA with a clean-up MR removing the flag.
See Feature flags.
Adding a database migration
Use the generator:
bin/rails generate migration AddFooToBars foo:stringMigrations are constrained:
- Forward migrations live in
db/migrate/. - Post-deploy migrations (data backfills, index drops) live in
db/post_migrate/. - Long-running data work uses
Gitlab::BackgroundMigration(lib/gitlab/background_migration/). - Time-based partitions use
lib/gitlab/database/partitioning/. - Strict rules in
lib/gitlab/database/migration_helpers.rband themigration_style_guidedoc.
After writing the migration, regenerate the structure:
bin/rake db:migrate
scripts/regenerate-schemaSchema validators in scripts/validate_* and scripts/migration_schema_validator.rb will block CI if you forget.
Adding a controller / endpoint
For a UI page:
- Add a route in
config/routes/<area>.rb. - Create the controller under
app/controllers/<area>/. - Add a feature category at the top:
feature_category :foo. - Add a Devise/Doorkeeper auth guard.
- Defer business logic to a service in
app/services/<bounded_context>/<verb>_service.rb.
For a REST endpoint:
- Add a Grape file under
lib/api/<area>.rb. - Mount it in
lib/api/api.rb. - Use
present,not_found!, and the helper modules inlib/api/helpers/.
For a GraphQL field:
- Add a type under
app/graphql/types/. - For mutations, add to
app/graphql/mutations/<area>/. - For queries with N+1 concerns, use a
BatchLoader.
Adding a worker (Sidekiq job)
Create
app/workers/<area>/<verb>_worker.rb.Include
ApplicationWorkerand declare:class MyWorker include ApplicationWorker idempotent! feature_category :my_category urgency :low deduplicate :until_executed endAdd the queue to
config/sidekiq_queues.ymlif it's a new namespace.Run
bin/rake gitlab:sidekiq:all_queues_yaml:generateto refreshapp/workers/all_queues.yml.
See Sidekiq jobs for the full pattern.
Pushing and opening the MR
When you're ready:
git push -u origin <branch>The push response includes a "Create merge request" URL. The MR template prompts you for:
- Description ("What does this MR do and why?").
- Screenshots / screen recordings for UI changes.
- Required action checklist.
- Database review request when migrations or schema changes are present.
After merge
A merged MR triggers:
- An auto-deployment cycle: code rolls out to
staging, thencanary, thenproduction(GitLab.com). - Inclusion in the next monthly release tag (the 22nd of each month).
- A changelog entry generated by
scripts/release_environment/.
If your change introduces a regression, the release tools provide a backport process; scripts/backport_fix_to_stable_branch automates much of it.
Related
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.