/doc/administration/backup_restore/backup_archive_process.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: Git repository backup workflow
accDescr: Sequence diagram showing the repositories sub-task calling gitaly-backup with a list of repositories. For each repository, gitaly-backup uses RPCs to collect refs, create a bundle, and retrieve custom hooks. It then returns success or failure.
box Backup host
participant Repositories sub-task
participant gitaly-backup
end
Repositories sub-task->>+gitaly-backup: List of repositories
loop Each repository
gitaly-backup->>+Gitaly: ListRefs request
Gitaly->>-gitaly-backup: List of Git references
gitaly-backup->>+Gitaly: CreateBundleFromRefList request
Gitaly->>-gitaly-backup: Git bundle file
gitaly-backup->>+Gitaly: GetCustomHooks request
Gitaly->>-gitaly-backup: Custom hooks archive
end
gitaly-backup->>-Repositories sub-task: Success/failure
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: Server-side repository backup workflow
accDescr: Sequence diagram showing server-side backups where the repositories sub-task calls gitaly-backup, which issues a BackupRepository request for each repository. Gitaly uploads files directly to object storage, then reports success or failure for that repository.
box Backup host
participant Repositories sub-task
participant gitaly-backup
end
Repositories sub-task->>+gitaly-backup: List of repositories
loop Each repository
gitaly-backup->>+Gitaly: BackupRepository request
Gitaly->>+Object-storage: Git references file
Object-storage->>-Gitaly: Success/failure
Gitaly->>+Object-storage: Git bundle file
Object-storage->>-Gitaly: Success/failure
Gitaly->>+Object-storage: Custom hooks archive
Object-storage->>-Gitaly: Success/failure
Gitaly->>+Object-storage: Backup manifest file
Object-storage->>-Gitaly: Success/failure
Gitaly->>-gitaly-backup: Success/failure
end
gitaly-backup->>-Repositories sub-task: Success/failure
/doc/administration/cicd/job_artifacts_troubleshooting.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: Direct artifact download flow
accDescr: Runner authenticates, gets redirected to object storage, and downloads artifacts directly.
autonumber
participant C as Runner
participant O as Object Storage
participant W as Workhorse
participant R as Rails
participant P as PostgreSQL
C->>+W: GET /api/v4/jobs/:id/artifacts?direct_download=true
Note over C,W: gitlab-ci-token@<CI_JOB_TOKEN>
W-->+R: GET /api/v4/jobs/:id/artifacts?direct_download=true
Note over W,R: gitlab-ci-token@<CI_JOB_TOKEN>
R->>P: Look up job for CI_JOB_TOKEN
R->>P: Find user who triggered job
R->>R: Does user have :read_build access?
alt Yes
R->>W: Send 302 redirect to object storage presigned URL
R->>C: 302 redirect
C->>O: GET <presigned URL>
else No
R->>W: 401 Unauthorized
W->>C: 401 Unauthorized
end
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: Proxied artifact download flow
accDescr: Runner authenticates, GitLab fetches from object storage, and streams artifacts back.
autonumber
participant C as Runner
participant O as Object Storage
participant W as Workhorse
participant R as Rails
participant P as PostgreSQL
C->>+W: GET /api/v4/jobs/:id/artifacts?direct_download=true
Note over C,W: gitlab-ci-token@<CI_JOB_TOKEN>
W-->+R: GET /api/v4/jobs/:id/artifacts?direct_download=true
Note over W,R: gitlab-ci-token@<CI_JOB_TOKEN>
R->>P: Look up job for CI_JOB_TOKEN
R->>P: Find user who triggered job
R->>R: Does user have :read_build access?
alt Yes
R->>W: SendURL with object storage presigned URL
W->>O: GET <presigned URL>
O->>W: <artifacts data>
W->>C: <artifacts data>
else No
R->>W: 401 Unauthorized
W->>C: 401 Unauthorized
end
/doc/administration/dedicated/create_instance/storage_types.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD
accTitle: Storage allocation for 2,000 users
accDescr: Diagram showing 1 TiB total storage with repository storage on a single Gitaly node and object storage
subgraph A[Total storage size: 1 TiB]
B[Repository storage: 600 GiB]
C[Object storage: 424 GiB]
B --> D[Gitaly node: 600 GiB]
end
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD
accTitle: Storage allocation for 10,000 users
accDescr: Diagram showing 5 TiB total storage with repository storage across 3 Gitaly nodes and object storage
subgraph A[Total storage size: 5 TiB]
B[Repository storage: 2,048 GiB]
C[Object storage: 3,072 GiB]
D[Gitaly node 1: 683 GiB]
E[Gitaly node 2: 683 GiB]
F[Gitaly node 3: 682 GiB]
B --- D
B --- E
B --- F
end
/doc/administration/duo_add_on_seat_management_with_ldap.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: Workflow of GitLab Duo add-on seat management with LDAP
accDescr: Sequence diagram showing automatic GitLab Duo add-on seat management based on LDAP group membership. Users sign in, GitLab authenticates them, then enqueues a background job to sync seat assignment based on their group membership.
participant User
participant GitLab
participant LDAP
participant Background Job
User->>GitLab: Sign in with LDAP credentials
GitLab->>LDAP: Authenticate user
LDAP-->>GitLab: User authenticated
GitLab->>Background Job: Enqueue 'LdapAddOnSeatSyncWorker' seat sync job
GitLab-->>User: Sign-in complete
Background Job->>Background Job: Start
Background Job->>LDAP: Check user's groups against duo_add_on_groups
LDAP-->>Background Job: Return membership of groups
alt User member of any duo_add_on_groups?
Background Job->>GitLab: Assign Duo Add-on seat
else User not in duo_add_on_groups
Background Job->>GitLab: Remove Duo Add-on seat (if assigned)
end
Background Job-->>Background Job: Complete
Note over GitLab, Background Job: Additionally, LdapAllAddOnSeatSyncWorker runs daily at 2 AM to sync all LDAP users
/doc/administration/geo/disaster_recovery/runbooks/planned_failover_multi_node.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD
accTitle: Geo planned-failover topology (multi-node)
accDescr: Multi-node Geo deployment for planned failover with primary and secondary sites. Each site has Rails, PostgreSQL, Gitaly, Redis, and monitoring nodes
subgraph main[Geo multi-node deployment architecture]
subgraph Primary[Primary site, multi-node]
Node_1[Rails node 1]
Node_2[Rails node 2]
Node_3[PostgreSQL node]
Node_4[Gitaly node]
Node_5[Redis node]
Node_6[Monitoring node]
end
subgraph Secondary[Secondary site]
Node_7[Rails node 1]
Node_8[Rails node 2]
Node_9[PostgreSQL node]
Node_10[Gitaly node]
Node_11[Redis node]
Node_12[Monitoring node]
end
end
/doc/administration/geo/disaster_recovery/runbooks/planned_failover_single_node.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD
accTitle: Geo planned-failover topology (single-node)
accDescr: A single-node Geo deployment for planned failover, with one GitLab node at the primary site and one node at the secondary site.
subgraph main[Geo single-node deployment]
subgraph Primary[Primary site]
Node_1[(GitLab node)]
end
subgraph Secondary1[Secondary site]
Node_2[(GitLab node)]
end
end
/doc/administration/geo/glossary.md
Diagram 1
graph TD
subgraph S-Site[Single-node site]
Node_3[GitLab node]
end
Diagram 2
graph TD
subgraph MN-Site[Multi-node site]
Node_1[Application node]
Node_2[Database node]
Node_3[Gitaly node]
end
Diagram 3
graph TD
subgraph Geo deployment
subgraph Primary[Primary site, single-node]
Node_1[GitLab node]
end
subgraph Secondary1[Secondary site 1, single-node]
Node_2[GitLab node]
end
end
Diagram 4
graph TD
subgraph Geo deployment
subgraph Primary[Primary site, multi-node]
Node_1[Application node]
Node_2[Database node]
end
subgraph Secondary1[Secondary site 1, multi-node]
Node_5[Application node]
Node_6[Database node]
end
end
Diagram 5
graph TD
subgraph Geo deployment
subgraph Primary[Primary site, multi-node]
Node_1[Application node]
Node_2[Database node]
Node_3[Gitaly node]
end
subgraph Secondary1[Secondary site 1, multi-node]
Node_5[Application node]
Node_6[Database node]
end
subgraph Secondary2[Secondary site 2, single-node]
Node_7[Single GitLab node]
end
end
/doc/administration/gitaly/_index.md
Diagram 1
flowchart LR
subgraph Gitaly clients
Rails[GitLab Rails]
Workhorse[GitLab Workhorse]
Shell[GitLab Shell]
Zoekt[Zoekt Indexer]
Elasticsearch[Elasticsearch Indexer]
KAS["GitLab Agent for Kubernetes (KAS)"]
end
subgraph Gitaly
GitalyServer[Gitaly server]
end
FS[Local filesystem]
ObjectStorage[Object storage]
Rails -- gRPC --> Gitaly
Workhorse -- gRPC --> Gitaly
Shell -- gRPC --> Gitaly
Zoekt -- gRPC --> Gitaly
Elasticsearch -- gRPC --> Gitaly
KAS -- gRPC --> Gitaly
GitalyServer --> FS
GitalyServer -- TCP --> Workhorse
GitalyServer -- TCP --> ObjectStorage
/doc/administration/gitaly/cgroups.md
Diagram 1
flowchart TB
parent
repos-1
repos-2
repos-3
parent-->repos-1
parent-->repos-2
parent-->repos-3
/doc/administration/gitaly/praefect/configure.md
Diagram 1
sequenceDiagram
autonumber
participant Client as Client
participant LB as TCP Load Balancer
participant Praefect as Praefect
Client->>LB: Establish TLS Session (w/ ALPN Extension)
LB->>Praefect: Establish TLS Session (w/ ALPN Extension)
Client->>LB: Encrypted TCP packets
LB->>Praefect: Encrypted TCP packets
Praefect->>LB: Encrypted Response
LB->>Client: Encrypted Response
Diagram 2
sequenceDiagram
autonumber
participant Client as Client
participant NGINX as NGINX Stream Proxy
participant Praefect as Praefect
Client->>NGINX: Establish TLS Session (w/ ALPN Extension)
NGINX->>Praefect: Establish New TLS Session
Praefect->>NGINX: Connection failed: missing selected ALPN property
/doc/administration/gitlab_duo_self_hosted/configuration_types.md
Diagram 1
%%{init: { "theme": "default", "fontFamily": "GitLab Sans", "sequence": { "actorFontSize": 12, "participantFontSize": 12, "messageFontSize": 12 } }}%%
sequenceDiagram
actor User as User
participant SelfHostedGitLab as Self-hosted GitLab (Your Instance)
participant GitLabAIGateway as GitLab AI gateway (External)
participant GitLabAIVendor as GitLab AI Vendor (External)
User ->> SelfHostedGitLab: Send request
SelfHostedGitLab ->> SelfHostedGitLab: Check if self-hosted model is configured
SelfHostedGitLab ->> GitLabAIGateway: Forward request for AI processing
GitLabAIGateway ->> GitLabAIVendor: Create prompt and send request to AI model server
GitLabAIVendor -->> GitLabAIGateway: Respond to the prompt
GitLabAIGateway -->> SelfHostedGitLab: Forward AI response
SelfHostedGitLab -->> User: Forward AI response
Diagram 2
%%{init: { "theme": "default", "fontFamily": "GitLab Sans", "sequence": { "actorFontSize": 12, "participantFontSize": 12, "messageFontSize": 12 } }}%%
sequenceDiagram
actor User as User
participant SelfHostedGitLab as Self-hosted GitLab
participant SelfHostedAIGateway as Self-hosted AI gateway
participant SelfHostedModel as Self-hosted model
User ->> SelfHostedGitLab: Send request
SelfHostedGitLab ->> SelfHostedGitLab: Check if self-hosted model is configured
SelfHostedGitLab ->> SelfHostedAIGateway: Forward request for AI processing
SelfHostedAIGateway ->> SelfHostedModel: Create prompt and perform request to AI model server
SelfHostedModel -->> SelfHostedAIGateway: Respond to the prompt
SelfHostedAIGateway -->> SelfHostedGitLab: Forward AI response
SelfHostedGitLab -->> User: Forward AI response
Diagram 3
%%{init: { "theme": "default", "fontFamily": "GitLab Sans", "sequence": { "actorFontSize": 12, "participantFontSize": 12, "messageFontSize": 12 } }}%%
sequenceDiagram
participant User as User
participant GitLab as GitLab Instance
participant AI gateway as AI gateway
participant AIModel as AI Model
User->>GitLab: Configure Model
User->>GitLab: Request Access
GitLab->>GitLab: Mint Token
GitLab->>User: Send Token
User->>GitLab: Forward Minted Token
GitLab->>AI gateway: Verify Token
AI gateway->>GitLab: Token Validated
GitLab->>AI gateway: Send Request to Model
AI gateway->>AIModel: Send Request to Model
AIModel->>AIModel: Authenticate using API Key
AIModel->>AI gateway: Process Request
AI gateway->>GitLab: Send Result to GitLab
GitLab->>User: Send Response
/doc/administration/packages/container_registry.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart LR
accTitle: Container registry authentication flow
accDescr: Shows how users authenticate with the container registry with GitLab API to push and pull Docker images
A[User] --->|1: Docker loginon port 443| C{Frontend loadbalancer}
C --->|2: connection attemptwithout token fails| D[Container registry]
C --->|5: connect with token succeeds| D[Container registry]
C --->|3: Dockerrequests token| E[API frontend]
E --->|4:API returnssigned token| C
linkStyle 1 stroke-width:4px,stroke:red
linkStyle 2 stroke-width:4px,stroke:green
/doc/administration/packages/container_registry_metadata_database.md
Diagram 1
flowchart TB
subgraph "Primary site"
P_Rails[GitLab Rails]
P_Reg[Container registry]
P_RegDB[(Registry database)]
P_Obj[(Object storage)]
P_Reg --> P_RegDB
P_RegDB --> P_Obj
end
subgraph "Secondary site"
S_Rails[GitLab Rails]
S_Reg[Container registry]
S_RegDB[(Registry database)]
S_Obj[(Object storage)]
S_Reg --> S_RegDB
S_RegDB --> S_Obj
end
P_Reg -- "Notifications" --> P_Rails
P_Rails -- "Events" --> S_Rails
S_Rails --> S_Reg
classDef primary fill:#d1f7c4
classDef secondary fill:#b8d4ff
class P_Rails,P_Reg,P_MainDB,P_RegDB,P_Obj primary
class S_Rails,S_Reg,S_MainDB,S_RegDB,S_Obj secondary
/doc/administration/pages/troubleshooting.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: GitLab Pages Request Flow
accDescr: Sequence diagram showing how a user request flows through GitLab Pages components to serve static files.
actor User
participant PagesNGINX as Pages NGINX
participant Pages as GitLab Pages
participant GitlabNGINX as GitLab NGINX
participant GitlabAPI as GitLab Rails
participant ObjectStorage as Object Storage
User->>PagesNGINX: Request to Pages
activate PagesNGINX
PagesNGINX->>Pages: Forwarded to Pages
activate Pages
Pages->>GitlabNGINX: Fetch domain info
activate GitlabNGINX
GitlabNGINX->>GitlabAPI: Forwarded to GitLab API
activate GitlabAPI
GitlabAPI->>GitlabNGINX: 200 OK (domain info)
deactivate GitlabAPI
GitlabNGINX->>Pages: 200 OK (domain info)
deactivate GitlabNGINX
Note right of Pages: Domain information cached in Pages
Pages->>ObjectStorage: Fetch static files
activate ObjectStorage
ObjectStorage->>Pages: 200 OK (files)
deactivate ObjectStorage
Pages->>User: 200 OK (static files served)
deactivate Pages
deactivate PagesNGINX
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: GitLab Pages OAuth Flow
accDescr: Sequence diagram showing the OAuth authentication flow between User, GitLab Pages, and GitLab Rails for accessing protected pages sites.
actor User
participant PagesService as GitLab Pages
participant GitlabApp as GitLab Rails
User->>PagesService: GET Request for site
activate PagesService
PagesService-->>User: 302 Redirect to project subdomain https://projects.gitlab.io/auth?state=state1
deactivate PagesService
Note left of User: Cookie state1
User->>PagesService: GET https://projects.gitlab.io/auth?state=state1
activate PagesService
PagesService-->>User: 302 Redirect to gitlab.com/oauth/authorize?state=state1
deactivate PagesService
User->>GitlabApp: GET oauth/authorize?state=state1
activate GitlabApp
GitlabApp-->>User: 200 OK (authorization form)
deactivate GitlabApp
User->>GitlabApp: POST authorization form
activate GitlabApp
GitlabApp-->>User: 302 Redirect to oauth/redirect
deactivate GitlabApp
User->>GitlabApp: GET oauth/redirect?state=state1
activate GitlabApp
GitlabApp-->>User: 200 OK (with auth code)
deactivate GitlabApp
User->>PagesService: GET https://projects.gitlab.io/auth?code=code1&state=state1
activate PagesService
PagesService->>GitlabApp: POST oauth/token with code=code1
activate GitlabApp
GitlabApp-->>PagesService: 200 OK (access token)
deactivate GitlabApp
PagesService-->>User: 302 Redirect to https://[namespace].gitlab.io/auth?code=code2&state=state1
deactivate PagesService
User->>PagesService: GET https://[namespace].gitlab.io/auth?code=code2&state=state1
activate PagesService
PagesService-->>User: 302 Redirect to site
deactivate PagesService
User->>PagesService: GET Request for site
activate PagesService
PagesService-->>User: 200 OK (site content)
deactivate PagesService
/doc/administration/reference_architectures/_index.md
Diagram 1
%%{init: { 'theme': 'base' } }%%
graph TD
L0A(<b>What Reference Architecture should I use?</b>)
L1A(<b>What is your <a href=#expected-load-rps--user-count>expected load</a>?</b>)
L2A("60 RPS / 3,000 users or more?")
L2B("40 RPS / 2,000 users or less?")
L3A("<a href=#do-you-need-high-availability-ha>Do you need HA?</a><br>(or zero-downtime upgrades)")
L3B[Do you have experience with<br/>and want additional resilience<br/>with select components in Kubernetes?]
L4A><b>Recommendation</b><br><br>60 RPS / 3,000 user architecture with HA<br>and supported reductions]
L4B><b>Recommendation</b><br><br>Architecture closest to <a href=#expected-load-rps--user-count>expected load</a> with HA]
L4C><b>Recommendation</b><br><br>Cloud Native Hybrid architecture<br>closest to <a href=#expected-load-rps--user-count>expected load</a>]
L4D>"<b>Recommendation</b><br><br>Standalone 20 RPS / 1,000 user or 40 RPS / 2,000 user<br/>architecture with Backups"]
L0A --> L1A
L1A --> L2A
L1A --> L2B
L2A -->|Yes| L3B
L3B -->|Yes| L4C
L3B -->|No| L4B
L2B --> L3A
L3A -->|Yes| L4A
L3A -->|No| L4D
L5A("<a href=#gitlab-geo-cross-regional-distribution--disaster-recovery>Do you need cross regional distribution</br> or disaster recovery?"</a>) --> |Yes| L6A><b>Additional Recommendation</b><br><br> GitLab Geo]
L4A ~~~ L5A
L4B ~~~ L5A
L4C ~~~ L5A
L4D ~~~ L5A
L5B("Do you have <a href=#large-monorepos>Large Monorepos</a> or expect</br> to have substantial <a href=#additional-workloads>additional workloads</a>?") --> |Yes| L6B><b>Additional Recommendations</b><br><br><a href=#if-in-doubt---start-large-monitor-and-scale-down>Start large, monitor and scale down</a><br><br> Contact GitLab representative or Support]
L4A ~~~ L5B
L4B ~~~ L5B
L4C ~~~ L5B
L4D ~~~ L5B
classDef default fill:#FCA326
linkStyle default fill:none,stroke:#7759C2
/doc/administration/settings/jira_cloud_app.md
Diagram 1
sequenceDiagram
accTitle: Dataflow of the GitLab for Jira Cloud app installed from the Atlassian Marketplace
accDescr: How GitLab.com handles lifecycle events when the GitLab for Jira Cloud app was installed from the Atlassian Marketplace
participant Jira
participant Your instance
participant GitLab.com
Jira->>+GitLab.com: App install/uninstall event
GitLab.com->>-Your instance: App install/uninstall event
Your instance->>Jira: Your development data
/doc/administration/settings/usage_statistics.md
Diagram 1
sequenceDiagram
participant GitLab instance
participant Version Application
GitLab instance->>Version Application: Is there a version update?
Version Application->>GitLab instance: Response (PNG/SVG)
/doc/administration/static_objects_external_storage.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: Request and response flow
accDescr: Describes how requests and responses flow from the user, GitLab, and a CDN.
User->>GitLab: GET /project/-/archive/master.zip
GitLab->>User: 302 Found
Note over User,GitLab: Location: https://cdn.com/project/-/archive/master.zip?token=secure-user-token
User->>CDN: GET /project/-/archive/master.zip?token=secure-user-token
alt object not in cache
CDN->>GitLab: GET /project/-/archive/master.zip
Note over CDN,GitLab: X-Gitlab-External-Storage-Token: secure-cdn-token<br/>X-Gitlab-Static-Object-Token: secure-user-token
GitLab->>CDN: 200 OK
CDN->>User: master.zip
else object in cache
CDN->>GitLab: GET /project/-/archive/master.zip
Note over CDN,GitLab: X-Gitlab-External-Storage-Token: secure-cdn-token<br/>X-Gitlab-Static-Object-Token: secure-user-token<br/>If-None-Match: etag-value
GitLab->>CDN: 304 Not Modified
CDN->>User: master.zip
end
/doc/ci/cloud_services/_index.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: Authorization workflow
accDescr: The flow of authorization requests between GitLab and a cloud provider.
participant GitLab
Note right of Cloud: Create OIDC identity provider
Note right of Cloud: Create role with conditionals
Note left of GitLab: CI/CD job with ID token
GitLab->>+Cloud: Call cloud API with ID token
Note right of Cloud: Decode & verify JWT with public key (https://gitlab.com/oauth/discovery/keys)
Note right of Cloud: Validate audience defined in OIDC
Note right of Cloud: Validate conditional (sub, aud) role
Note right of Cloud: Generate credential or fetch secret
Cloud->>GitLab: Return temporary credential
Note left of GitLab: Perform operation
/doc/ci/jobs/_index.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
stateDiagram-v2
accTitle: CI/CD job state transitions
accDescr: Shows possible state transitions for CI/CD jobs, including cancellation paths.
direction TB
state if_versions <>
[*] --> pending: Job created
pending --> canceled: Cancel requested
canceled --> [*]
pending --> running: Runner picks up job
running --> success: Job succeeds
success --> [*]
running --> failed: Job fails
failed --> [*]
running --> if_versions: Cancel requested
if_versions --> canceling: GitLab 17.0 and later with GitLab Runner 16.10 and later
if_versions --> canceled: GitLab 16.11 and earlier with GitLab Runner 16.9 and earlier
canceling --> canceled: after_script complete
/doc/ci/pipelines/pipeline_architectures.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
accTitle: Basic pipelines
accDescr: Shows a pipeline that runs sequentially through the build, test, and deploy stages.
subgraph deploy stage
deploy --> deploy_a
deploy --> deploy_b
end
subgraph test stage
test --> test_a
test --> test_b
end
subgraph build stage
build --> build_a
build --> build_b
end
build_a -.-> test
build_b -.-> test
test_a -.-> deploy
test_b -.-> deploy
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
accTitle: Pipeline using needs
accDescr: Shows how two jobs can start without waiting for earlier stages to complete
subgraph Pipeline using needs
build_a --> test_a --> deploy_a
build_b --> test_b --> deploy_b
end
Diagram 3
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
accTitle: Parent and child pipelines
accDescr: Shows that a parent pipeline can trigger independent child pipelines
subgraph Parent pipeline
trigger_a -.-> build_a
trigger_b -.-> build_b
subgraph child pipeline B
build_b --> test_b --> deploy_b
end
subgraph child pipeline A
build_a --> test_a --> deploy_a
end
end
/doc/ci/review_apps/_index.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart TD
accTitle: Review app workflow
accDescr: Diagram showing how review apps fit into the GitLab development workflow.
subgraph Development["Development"]
TopicBranch["Create topic branch"]
Commit["Make code changes"]
CreateMR["Create merge request"]
end
subgraph ReviewAppCycle["Review app cycle"]
direction LR
Pipeline["CI/CD pipeline runs"]
ReviewApp["Review app deployed"]
Testing["Review and testing"]
Feedback["Feedback provided"]
NewCommits["Address feedback\nwith new commits"]
end
subgraph Deployment["Deployment"]
Approval["Merge request approved"]
Merge["Merged to default branch"]
Production["Deployed to production"]
end
TopicBranch --> Commit
Commit --> CreateMR
CreateMR --> Pipeline
Pipeline --> ReviewApp
ReviewApp --> Testing
Testing --> Feedback
Feedback --> NewCommits
NewCommits --> Pipeline
Testing --> Approval
Approval --> Merge
Merge --> Production
classDef devNode fill:#e1e1e1,stroke:#666,stroke-width:1px
classDef reviewNode fill:#fff0dd,stroke:#f90,stroke-width:1px
classDef finalNode fill:#d5f5ff,stroke:#0095cd,stroke-width:1px
class TopicBranch,Commit,CreateMR devNode
class Pipeline,ReviewApp,Testing,Feedback,NewCommits reviewNode
class Approval,Merge,Production finalNode
/doc/ci/runners/long_polling.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: Long polling workflow
accDescr: The flow of a single runner getting a job with long polling enabled
autonumber
participant C as Runner
participant W as Workhorse
participant Redis as Redis
participant R as Rails
participant S as Sidekiq
C->>+W: POST /api/v4/jobs/request
W->>+Redis: New job for runner A?
Redis->>+W: Unknown
W->>+R: POST /api/v4/jobs/request
R->>+Redis: Runner A: last_update = X
R->>W: 204 No job, X-GitLab-Last-Update = X
W->>C: 204 No job, X-GitLab-Last-Update = X
C->>W: POST /api/v4/jobs/request, X-GitLab-Last-Update: X
W->>Redis: Notify when last_update change
Note over W: Request held in long poll
Note over S: CI job created
Note over S, Redis: Update all registered runners
S->>Redis: Runner A: last_update = Z
Redis->>W: Runner: last_update changed
Note over W: Request released from long poll
W->>Rails: POST /api/v4/jobs/request
Rails->>W: 201 Job was scheduled
W->>C: 201 Job was scheduled
/doc/ci/secrets/id_token_authentication.md
Diagram 1
sequenceDiagram
participant GitLab as GitLab CI/CD
participant Runner as GitLab Runner
participant Vault as HashiCorp Vault
GitLab->>Runner: Generates an ID token (JWT) for the CI/CD job
Runner->>Vault: Runner authenticates with HashiCorp Vault using the token
Vault->>Vault: HashiCorp Vault verifies the token
Vault->>Vault: HashiCorp Vault checks bounded claims and attaches policies
Vault->>Runner: HashiCorp Vault returns the token
Runner->>Vault: Runner requests secrets from HashiCorp Vault
Vault->>Runner: Returns secrets
/doc/development/ai_features/_index.md
Diagram 1
flowchart TD
A[GitLab frontend] -->B[AiAction GraphQL mutation]
B --> C[Llm::ExecuteMethodService]
C --> D[One of services, for example: Llm::GenerateSummaryService]
D -->|scheduled| E[AI worker:Llm::CompletionWorker]
E -->F[::Gitlab::Llm::Completions::Factory]
F -->G[`::Gitlab::Llm::VertexAi::Completions::...` class using `::Gitlab::Llm::Templates::...` class]
G -->|calling| H[Gitlab::Llm::VertexAi::Client]
H --> |response| I[::Gitlab::Llm::GraphqlSubscriptionResponseService]
I --> J[GraphqlTriggers.ai_completion_response]
J --> K[::GitlabSchema.subscriptions.trigger]
/doc/development/ai_features/availability.md
Diagram 1
flowchart TD
A[Start] --> B{Member of Premium/Ultimate group?}
B -->|No| C[Cannot use GitLab Duo]
B -->|Yes| D{Has Duo Pro/Enterprise license?}
D -->|No| E[Cannot use GitLab Duo]
D -->|Yes| F{Using Duo with specific\ngroup/project resource?}
F -->|No| G[Can use GitLab Duo]
F -->|Yes| H{Group/Project has\nDuo features enabled?}
H -->|No| I[Cannot use Duo with\nthis resource]
H -->|Yes| J[Can use Duo with\nthis resource]
Diagram 2
flowchart TD
A[Start] --> B{Member of Premium/Ultimate group?}
B -->|No| C[Cannot use GitLab Duo]
B -->|Yes| D{Has Duo Pro/Enterprise license?}
D -->|Yes| E[Can use GitLab Duo]
D -->|No| F{Any Premium/Ultimate group has\nDuo Core enabled?}
F -->|No| G[Cannot use GitLab Duo]
F -->|Yes| H{Using Chat or\nCode Suggestions in IDE?}
H -->|No| I[Cannot use GitLab Duo]
H -->|Yes| J{Using Duo with specific\ngroup/project resource?}
J -->|No| K[Can use GitLab Duo]
J -->|Yes| L{Group/Project has\nDuo features enabled?}
L -->|Yes| M[Can use Duo with\nthis resource]
L -->|No| N[Cannot use Duo with\nthis resource]
Diagram 3
flowchart TD
A[Start] --> B{Instance has Duo features\nset to 'Always off'?}
B -->|Yes| C[Cannot use GitLab Duo]
B -->|No| D{Has Duo Pro/Enterprise license?}
D -->|No| E[Cannot use GitLab Duo]
D -->|Yes| F{Using Duo with specific\ngroup/project resource?}
F -->|No| G[Can use GitLab Duo]
F -->|Yes| H{Group/Project has\nDuo features enabled?}
H -->|No| I[Cannot use Duo with\nthis resource]
H -->|Yes| J[Can use Duo with\nthis resource]
Diagram 4
flowchart TD
A[Start] --> B{Instance has Duo features\nset to 'Always off'?}
B -->|Yes| C[Cannot use GitLab Duo]
B -->|No| D{Has Duo Pro/Enterprise license?}
D -->|Yes| E[Can use GitLab Duo]
D -->|No| F{Instance has Duo Core enabled?}
F -->|No| G[Cannot use GitLab Duo]
F -->|Yes| H{Using Chat or\nCode Suggestions in IDE?}
H -->|No| I[Cannot use GitLab Duo]
H -->|Yes| J{Using Duo with specific\ngroup/project resource?}
J -->|No| K[Can use GitLab Duo]
J -->|Yes| L{Group/Project has\nDuo features enabled?}
L -->|Yes| M[Can use Duo with\nthis resource]
L -->|No| N[Cannot use Duo with\nthis resource]
/doc/development/ai_features/duo_agent_platform.md
Diagram 1
graph TD
A[Entry Point] --> B[initDuoAgentsPlatformPage]
B --> C[Extract Namespace Data]
C --> D[Create Router with Namespace]
D --> E[Component Mapping]
E --> F[Namespace-Specific Component]
F --> G[GraphQL Query with Props]
G --> H[Rendered UI]
I[Dataset Properties] --> C
J[Namespace Constant] --> E
K[Component Mappings] --> E
/doc/development/ai_features/embeddings.md
Diagram 1
graph LR
A[database record] --> B[ActiveRecord callback]
B --> C[build embedding reference]
C -->|add to queue| N[queue]
E[cron worker every minute] <-->|pull from queue| N
E --> G[deserialize reference]
G --> H[generate embedding]
H <--> I[AI gateway]
I <--> J[Vertex API]
H --> K[upsert document with embedding]
K --> L[Elasticsearch]
Diagram 2
graph LR
A[cron] --> B{endpoint throttled?}
B -->|no| C[schedule 16 workers]
C ..->|each worker| D{endpoint throttled?}
D -->|no| E[fetch 19 references from queue]
E ..->|each reference| F[increment endpoint]
F --> G{endpoint throttled?}
G -->|no| H[call AI gateway to generate embedding]
/doc/development/ai_features/evaluation_runner/_index.md
Diagram 1
flowchart LR
subgraph EV["Evaluators"]
PL(["PromptLibrary/ELI5"])
DSIN(["Input Dataset"])
end
subgraph ER["EvaluationRunner"]
CI["CI/CD pipelines"]
subgraph GDKS["Remote GDKs"]
subgraph GDKM["GDK-master"]
bl1["Duo features on master branch"]
fi1["fixtures (Issue,MR,etc)"]
end
subgraph GDKF["GDK-feature"]
bl2["Duo features on feature branch"]
fi2["fixtures (Issue,MR,etc)"]
end
end
end
subgraph MR["MergeRequests"]
GRMR["GitLab-Rails MR"]
GRAI["AI Gateway MR"]
end
MR -- [1] trigger --- CI
CI -- [2] spins up --- GDKS
PL -- [3] get responses and evaluate --- GDKS
/doc/development/architecture.md
Diagram 1
%%{init: {"flowchart": { "useMaxWidth": false } }}%%
graph TB
%% Component declarations and formatting
HTTP((HTTP/HTTPS))
SSH((SSH))
GitLabPages(GitLab Pages)
GitLabWorkhorse(GitLab Workhorse)
GitLabShell(GitLab Shell)
Gitaly(Gitaly)
Puma("Puma (Gitlab Rails)")
Sidekiq("Sidekiq (GitLab Rails)")
PostgreSQL(PostgreSQL)
Redis(Redis)
HTTP -- TCP 80,443 --> NGINX
SSH -- TCP 22 --> GitLabShell
NGINX -- TCP 8090 --> GitLabPages
NGINX --> GitLabWorkhorse
GitLabShell --> Gitaly
GitLabShell --> GitLabWorkhorse
GitLabWorkhorse --> Gitaly
GitLabWorkhorse --> Puma
GitLabWorkhorse --> Redis
Sidekiq --> PostgreSQL
Sidekiq --> Redis
Puma --> PostgreSQL
Puma --> Redis
Puma --> Gitaly
Gitaly --> GitLabWorkhorse
Diagram 2
%%{init: {"flowchart": { "useMaxWidth": false } }}%%
graph LR
%% Anchor items in the appropriate subgraph.
%% Link them where the destination* is.
subgraph Clients
Browser((Browser))
Git((Git))
end
%% External Components / Applications
Geo{{GitLab Geo}} -- TCP 80, 443 --> HTTP
Geo -- TCP 22 --> SSH
Geo -- TCP 5432 --> PostgreSQL
Runner{{GitLab Runner}} -- TCP 443 --> HTTP
K8sAgent{{GitLab agent}} -- TCP 443 --> HTTP
%% GitLab Application Suite
subgraph GitLab
subgraph Ingress
HTTP[[HTTP/HTTPS]]
SSH[[SSH]]
NGINX[NGINX]
GitLabShell[GitLab Shell]
%% inbound/internal
Browser -- TCP 80,443 --> HTTP
Git -- TCP 80,443 --> HTTP
Git -- TCP 22 --> SSH
HTTP -- TCP 80, 443 --> NGINX
SSH -- TCP 22 --> GitLabShell
end
subgraph GitLab Services
%% inbound from NGINX
NGINX --> GitLabWorkhorse
NGINX -- TCP 8090 --> GitLabPages
NGINX -- TCP 8150 --> GitLabKas
NGINX --> Registry
%% inbound from GitLabShell
GitLabShell --> GitLabWorkhorse
%% services
Puma["Puma (GitLab Rails)"]
Puma <--> Registry
GitLabWorkhorse[GitLab Workhorse] <--> Puma
GitLabKas[GitLab agent server] --> GitLabWorkhorse
GitLabPages[GitLab Pages] --> GitLabWorkhorse
Mailroom
Sidekiq
end
subgraph Integrated Services
%% Mattermost
Mattermost
Mattermost ---> GitLabWorkhorse
NGINX --> Mattermost
%% Grafana
Grafana
NGINX --> Grafana
end
subgraph Metadata
%% PostgreSQL
PostgreSQL
PostgreSQL --> Consul
%% Consul and inbound
Consul
Puma ---> Consul
Sidekiq ---> Consul
Migrations --> PostgreSQL
%% PgBouncer and inbound
PgBouncer
PgBouncer --> Consul
PgBouncer --> PostgreSQL
Sidekiq --> PgBouncer
Puma --> PgBouncer
end
subgraph State
%% Redis and inbound
Redis
Puma --> Redis
Sidekiq --> Redis
GitLabWorkhorse --> Redis
Mailroom --> Redis
GitLabKas --> Redis
%% Sentinel and inbound
Sentinel <--> Redis
Puma --> Sentinel
Sidekiq --> Sentinel
GitLabWorkhorse --> Sentinel
Mailroom --> Sentinel
GitLabKas --> Sentinel
end
subgraph Git Repositories
%% Gitaly / Praefect
Praefect --> Gitaly
GitLabKas --> Praefect
GitLabShell --> Praefect
GitLabWorkhorse --> Praefect
Puma --> Praefect
Sidekiq --> Praefect
Praefect <--> PraefectPGSQL[PostgreSQL]
%% Gitaly makes API calls
%% Ordered here to ensure placement.
Gitaly --> GitLabWorkhorse
end
subgraph Storage
%% ObjectStorage and inbound traffic
ObjectStorage["Object storage"]
Puma -- TCP 443 --> ObjectStorage
Sidekiq -- TCP 443 --> ObjectStorage
GitLabWorkhorse -- TCP 443 --> ObjectStorage
Registry -- TCP 443 --> ObjectStorage
GitLabPages -- TCP 443 --> ObjectStorage
%% Gitaly can perform repository backups to object storage.
Gitaly --> ObjectStorage
end
subgraph Monitoring
%% Prometheus
Grafana -- TCP 9090 --> Prometheus[Prometheus]
Prometheus -- TCP 80, 443 --> Puma
RedisExporter[Redis Exporter] --> Redis
Prometheus -- TCP 9121 --> RedisExporter
PostgreSQLExporter[PostgreSQL Exporter] --> PostgreSQL
PgBouncerExporter[PgBouncer Exporter] --> PgBouncer
Prometheus -- TCP 9187 --> PostgreSQLExporter
Prometheus -- TCP 9100 --> NodeExporter[Node Exporter]
Prometheus -- TCP 9168 --> GitLabExporter[GitLab Exporter]
Prometheus -- TCP 9127 --> PgBouncerExporter
Prometheus --> Alertmanager
GitLabExporter --> PostgreSQL
GitLabExporter --> GitLabShell
GitLabExporter --> Sidekiq
%% Alertmanager
Alertmanager -- TCP 25 --> SMTP
end
%% end subgraph GitLab
end
subgraph External
subgraph External Services
SMTP[SMTP Gateway]
LDAP
%% Outbound SMTP
Sidekiq -- TCP 25 --> SMTP
Puma -- TCP 25 --> SMTP
Mailroom -- TCP 25 --> SMTP
%% Outbound LDAP
Puma -- TCP 369 --> LDAP
Sidekiq -- TCP 369 --> LDAP
%% Elasticsearch
Elasticsearch
Puma -- TCP 9200 --> Elasticsearch
Sidekiq -- TCP 9200 --> Elasticsearch
Elasticsearch --> Praefect
%% Zoekt
Zoekt --> Praefect
end
subgraph External Monitoring
%% Sentry
Sidekiq -- TCP 80, 443 --> Sentry
Puma -- TCP 80, 443 --> Sentry
%% Jaeger
Jaeger
Sidekiq -- UDP 6831 --> Jaeger
Puma -- UDP 6831 --> Jaeger
Gitaly -- UDP 6831 --> Jaeger
GitLabShell -- UDP 6831 --> Jaeger
GitLabWorkhorse -- UDP 6831 --> Jaeger
end
%% end subgraph External
end
click Alertmanager "#alertmanager"
click Praefect "#praefect"
click Geo "#gitlab-geo"
click NGINX "#nginx"
click Runner "#gitlab-runner"
click Registry "#registry"
click ObjectStorage "#minio"
click Mattermost "#mattermost"
click Gitaly "#gitaly"
click Jaeger "#jaeger"
click GitLabWorkhorse "#gitlab-workhorse"
click LDAP "#ldap-authentication"
click Puma "#puma"
click GitLabShell "#gitlab-shell"
click SSH "#ssh-request-22"
click Sidekiq "#sidekiq"
click Sentry "#sentry"
click GitLabExporter "#gitlab-exporter"
click Elasticsearch "#elasticsearch"
click Migrations "#database-migrations"
click PostgreSQL "#postgresql"
click Consul "#consul"
click PgBouncer "#pgbouncer"
click PgBouncerExporter "#pgbouncer-exporter"
click RedisExporter "#redis-exporter"
click Redis "#redis"
click Prometheus "#prometheus"
click Grafana "#grafana"
click GitLabPages "#gitlab-pages"
click PostgreSQLExporter "#postgresql-exporter"
click SMTP "#outbound-email"
click NodeExporter "#node-exporter"
Diagram 3
sequenceDiagram
participant Git on client
participant NGINX
participant Workhorse
participant Rails
participant Gitaly
participant Git on server
Note left of Git on client: git fetch<br/>info-refs
Git on client->>+Workhorse: GET /info/refs?service=git-upload-pack
Workhorse->>+Rails: GET /info/refs?service=git-upload-pack
Note right of Rails: Auth check
Rails-->>-Workhorse: Gitlab::Workhorse.git_http_ok
Workhorse->>+Gitaly: SmartHTTPService.InfoRefsUploadPack request
Gitaly->>+Git on server: git upload-pack --stateless-rpc --advertise-refs
Git on server-->>-Gitaly: git upload-pack response
Gitaly-->>-Workhorse: SmartHTTPService.InfoRefsUploadPack response
Workhorse-->>-Git on client: 200 OK
Note left of Git on client: git fetch<br/>fetch-pack
Git on client->>+Workhorse: POST /git-upload-pack
Workhorse->>+Rails: POST /git-upload-pack
Note right of Rails: Auth check
Rails-->>-Workhorse: Gitlab::Workhorse.git_http_ok
Workhorse->>+Gitaly: SmartHTTPService.PostUploadPack request
Gitaly->>+Git on server: git upload-pack --stateless-rpc
Git on server-->>-Gitaly: git upload-pack response
Gitaly-->>-Workhorse: SmartHTTPService.PostUploadPack response
Workhorse-->>-Git on client: 200 OK
Diagram 4
sequenceDiagram
participant Git on client
participant SSH server
participant AuthorizedKeysCommand
participant GitLab Shell
participant Rails
participant Gitaly
participant Git on server
Note left of Git on client: git fetch
Git on client->>+SSH server: ssh git fetch-pack request
SSH server->>+AuthorizedKeysCommand: gitlab-shell-authorized-keys-check git AAAA...
AuthorizedKeysCommand->>+Rails: GET /internal/api/authorized_keys?key=AAAA...
Note right of Rails: Lookup key ID
Rails-->>-AuthorizedKeysCommand: 200 OK, command="gitlab-shell upload-pack key_id=1"
AuthorizedKeysCommand-->>-SSH server: command="gitlab-shell upload-pack key_id=1"
SSH server->>+GitLab Shell: gitlab-shell upload-pack key_id=1
GitLab Shell->>+Rails: GET /internal/api/allowed?action=upload_pack&key_id=1
Note right of Rails: Auth check
Rails-->>-GitLab Shell: 200 OK, { gitaly: ... }
GitLab Shell->>+Gitaly: SSHService.SSHUploadPack request
Gitaly->>+Git on server: git upload-pack request
Note over Git on client,Git on server: Bidirectional communication between Git client and server
Git on server-->>-Gitaly: git upload-pack response
Gitaly -->>-GitLab Shell: SSHService.SSHUploadPack response
GitLab Shell-->>-SSH server: gitlab-shell upload-pack response
SSH server-->>-Git on client: ssh git fetch-pack response
/doc/development/bulk_import.md
Diagram 1
flowchart TD
subgraph s1["Main"]
BulkImportWorker -- Enqueue itself --> BulkImportWorker
BulkImportWorker --> BulkImports::ExportRequestWorker
BulkImports::ExportRequestWorker --> BulkImports::EntityWorker
BulkImports::EntityWorker -- Enqueue itself --> BulkImports::EntityWorker
BulkImports::EntityWorker --> BulkImports::PipelineWorker
BulkImports::PipelineWorker -- Enqueue itself --> BulkImports::PipelineWorker
BulkImports::EntityWorker --> BulkImports::PipelineWorkerA["BulkImports::PipelineWorker"]
BulkImports::EntityWorker --> BulkImports::PipelineWorkerA1["..."]
BulkImportWorker --> BulkImports::ExportRequestWorkerB["BulkImports::ExportRequestWorker"]
BulkImports::ExportRequestWorkerB --> BulkImports::PipelineWorkerBB["..."]
end
subgraph s2["Batched pipelines"]
BulkImports::PipelineWorker --> BulkImports::PipelineBatchWorker
BulkImports::PipelineWorker --> BulkImports::PipelineBatchWorkerA["..."]
BulkImports::PipelineBatchWorker --> BulkImports::FinishBatchedPipelineWorker
end
Diagram 2
flowchart TD
subgraph s1["Cron"]
BulkImports::StaleImportWorker
end
Diagram 3
flowchart TD
subgraph s1["Main"]
BulkImports::RelationExportWorker
end
subgraph s2["Batched relations"]
BulkImports::RelationExportWorker --> BulkImports::RelationBatchExportWorker
BulkImports::RelationExportWorker --> BulkImports::RelationBatchExportWorkerA["..."]
BulkImports::RelationBatchExportWorker --> BulkImports::FinishBatchedRelationExportWorker
end
/doc/development/code_intelligence/_index.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: Sequence diagram for LSIF artifact uploads
accDescr: The process of how Runner, Workhorse, Rails, and object storage work together to upload an artifact.
participant Runner
participant Workhorse
participant Rails
participant Object Storage
Runner->>+Workhorse: POST /v4/jobs/:id/artifacts
Workhorse->>+Rails: POST /:id/artifacts/authorize
Rails-->>-Workhorse: Respond with ProcessLsif header
Note right of Workhorse: Process LSIF file
Workhorse->>+Object Storage: Put file
Object Storage-->>-Workhorse: request results
Workhorse->>+Rails: POST /:id/artifacts
Rails-->>-Workhorse: request results
Workhorse-->>-Runner: request results
/doc/development/code_owners/_index.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD
Api::Internal::Base --> Gitlab::GitAccess
Gitlab::GitAccess --> Gitlab::Checks::DiffCheck
Gitlab::Checks::DiffCheck --> Gitlab::Checks::Diffs::CodeOwnersCheck
Gitlab::Checks::Diffs::CodeOwnersCheck --> ProtectedBranch
Gitlab::Checks::Diffs::CodeOwnersCheck --> Gitlab::CodeOwners::Loader
Gitlab::CodeOwners::Loader --> Gitlab::CodeOwners::Entry
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD
Repositories::GitHttpController --> Gitlab::GlRepository
Gitlab::GlRepository --> Gitlab::GitAccessProject
Gitlab::GitAccessProject --> Gitlab::Checks::DiffCheck
Gitlab::Checks::DiffCheck --> Gitlab::Checks::Diffs::CodeOwnersCheck
Gitlab::Checks::Diffs::CodeOwnersCheck --> ProtectedBranch
Gitlab::Checks::Diffs::CodeOwnersCheck --> Gitlab::CodeOwners::Loader
Gitlab::CodeOwners::Loader --> Gitlab::CodeOwners::Entry
Diagram 3
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD
EE::ProtectedBranches::CreateService --> MergeRequest::SyncCodeOwnerApprovalRules
EE::MergeRequestRefreshService --> MergeRequest::SyncCodeOwnerApprovalRules
EE::MergeRequests::ReloadMergeHeadDiffService --> MergeRequest::SyncCodeOwnerApprovalRules
EE::MergeRequests::CreateService --> MergeRequests::SyncCodeOwnerApprovalRulesWorker
EE::MergeRequests::UpdateService --> MergeRequests::SyncCodeOwnerApprovalRulesWorker
MergeRequests::SyncCodeOwnerApprovalRulesWorker --> MergeRequest::SyncCodeOwnerApprovalRules
MergeRequest::SyncCodeOwnerApprovalRules --> id1{delete outdated code owner rules}
MergeRequest::SyncCodeOwnerApprovalRules --> id2{create rule for each code owner entry}
/doc/development/database/ci_mirrored_tables.md
Diagram 1
graph LR
subgraph "Main database (tables)"
A[namespaces] -->|updates| B[namespaces_sync_events]
A -->|deletes| C[loose_foreign_keys_deleted_records]
D[projects] -->|deletes| C
D -->|updates| E[projects_sync_events]
end
B --> F
C --> G
E --> H
subgraph "Sidekiq worker jobs"
F[Namespaces::ProcessSyncEventsWorker]
G[LooseForeignKeys::CleanupWorker]
H[Projects::ProcessSyncEventsWorker]
end
F -->|do update| I
G -->|delete records| I
G -->|delete records| J
H -->|do update| J
subgraph "CI database (tables)"
I[ci_namespace_mirrors]
J[ci_project_mirrors]
end
Diagram 2
graph LR
subgraph CI["CI Tables"]
E[other CI tables]
F{queries with joins allowed}
G[ci_project_mirrors]
H[ci_namespace_mirrors]
E---F
F---G
F---H
end
Main["Main Tables"]---L["⛔ ← Joins are not allowed → ⛔"]
L---CI
subgraph Main["Main Tables"]
A[other main tables]
B{queries with joins allowed}
C[projects]
D[namespaces]
A---B
B---C
B---D
end
/doc/development/database/dbcheck-migrations-job.md
Diagram 1
graph LR
Main((main<br>commit A)) ===> |remove constraint<br>fk_rails_dbebdaa8fe| MainB((main<br>commit B))
Main((main<br>commit A)) --> |checkout<br>dev| DevA((dev<br>commit A)):::dev
DevA((dev<br>commit A)) --> |add column<br>dependency_proxy_size| DevC((dev<br>commit C)):::dev
DevC -.-> |CI pipeline<br>executes| JOB-FAILED((JOB FAILED!)):::error
classDef main fill:#f4f0ff,stroke:#7b58cf
classDef dev fill:#e9f3fc,stroke:#1f75cb
classDef error fill:#f15146,stroke:#d4121a
/doc/development/database/poc_tree_iterator.md
Diagram 1
flowchart TD
A("gitlab-org (9979)") --- B("quality (2750817)")
B --- C("engineering-productivity (16947798)")
B --- D("performance-testing (9453799)")
A --- F("charts (5032027)")
A --- E("ruby (14018648)")
Diagram 2
flowchart TD
A(1) --- B(2)
A --- C(3)
C --- D(4)
/doc/development/documentation/site_architecture/deployment_process.md
Diagram 1
graph LR
A["Default branches<br>of upstream projects"]
B["build:compile_site job"]
C["pages job"]
D([docs.gitlab.com])
A--"Content pulled"-->B
B--"Compiled site"-->C
C--"Deployed with<br>GitLab Pages"-->D
Diagram 2
graph LR
A["build:compile_site job"]
B["build:compile_archive job"]
C["pages job"]
D["pages-archives job"]
E([docs.gitlab.com])
F([docs.gitlab.com/VERSION/])
G([archives.docs.gitlab.com/VERSION/])
A--"Compiled site"-->C
B--"Compiled site"-->D
C--"Deploys upcoming version"-->E
D--"Deploys current stable and two previous versions"-->F
D--"Deploys earlier versions"-->G
/doc/development/documentation/styleguide/_index.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart TD
accTitle: Example diagram title
accDescr: A description of your diagram
A[Start here] -->|action| B[next step]
/doc/development/documentation/workflow.md
Diagram 1
graph TD
A("Feature MR Created (Engineer)") --> |Assign| B("Code Review (reviewer)")
B --> |"Approve / Reassign"| C("Code Review (maintainer)")
C --> |Approve| F("Merge (maintainer)")
A --> D("Docs Added (Engineer)")
D --> |Assign| E("Docs Review (Tech Writer)")
E --> |Approve| F
/doc/development/event_store.md
Diagram 1
graph LR
subgraph ci[CI]
cp[CreatePipelineService]
end
subgraph mr[MergeRequests]
upw[UpdateHeadPipelineWorker]
end
subgraph no[Namespaces::Onboarding]
pow[PipelinesOnboardedWorker]
end
cp -- perform_async --> upw
cp -- perform_async --> pow
Diagram 2
graph LR
subgraph ci[CI]
cp[CreatePipelineService]
cp -- publish --> e[PipelineCreateEvent]
end
subgraph mr[MergeRequests]
upw[UpdateHeadPipelineWorker]
end
subgraph no[Namespaces::Onboarding]
pow[PipelinesOnboardedWorker]
end
upw -. subscribe .-> e
pow -. subscribe .-> e
/doc/development/fe_guide/content_editor.md
Diagram 1
sequenceDiagram
participant A as Editing tools UI
participant B as Tiptap object
A->>B: queries state/dispatches commands
B--)A: notifies state changes
Diagram 2
sequenceDiagram
participant A as rich text editor
participant E as Tiptap object
participant B as Markdown serializer
participant C as Markdown API
participant D as ProseMirror parser
A->>B: deserialize(markdown)
B->>C: render(markdown)
C-->>B: html
B->>D: to document(html)
D-->>A: document
A->>E: setContent(document)
Diagram 3
sequenceDiagram
participant A as rich text editor
participant B as Markdown serializer
participant C as ProseMirror Markdown
A->>B: serialize(document)
B->>C: serialize(document, serializers)
C-->>A: Markdown string
/doc/development/fe_guide/diagrams_net_integration.md
Diagram 1
sequenceDiagram
Diagrams.net->>+GitLab application: message('configure')
GitLab application-->>Diagrams.net: action('configure', config)
Diagram 2
classDiagram
DiagramsnetIntegration ..> EditorFacade
EditorFacade <|-- ContentEditorFacade
EditorFacade <|-- MarkdownEditorFacade
ContentEditorFacade ..> ContentEditor
MarkdownEditorFacade ..> MarkdownEditor
class EditorFacade {
<<Interface>>
+uploadDiagram(filename, diagramSvg)
+insertDiagram(uploadResults)
+updateDiagram(diagramMarkdown, uploadResults)
+getDiagram()
}
/doc/development/fe_guide/pinia.md
Diagram 1
flowchart TD
A[Store]
A --> B[State]
A --> C[Actions]
A --> D[Mutations]
A --> E[Getters]
B --> F[items]
B --> G[isLoadingItems]
B --> H[itemWithActiveForm]
B --> I[isSubmittingForm]
Diagram 2
flowchart TD
A[Items Store]
A --> B[State]
A --> C[Actions]
A --> D[Getters]
B --> E[items]
B --> F[isLoading]
H[Form Store]
H --> I[State]
H --> J[Actions]
H --> K[Getters]
I --> L[activeItem]
I --> M[isSubmitting]
Diagram 3
graph TD
A[Store Alpha] --> Foo(Action Foo)
B[Store Beta] --> Bar(Action Bar)
A -- calls --> Bar
B -- calls --> Foo
Diagram 4
graph TD
A[Store Alpha] --> Foo(Action Foo)
A -- calls --> Bar
B[Store Beta] --> Bar(Action Bar)
B -- calls --> Foo
Diagram 5
graph TD
C[Store Gamma]
A[Store Alpha] --- Bar(Action Bar)
B[Store Beta] --- Foo(Action Foo)
C -- calls --> Bar
C -- calls --> Foo
/doc/development/fe_guide/source_editor.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD;
B[Extension 1]---A[Source Editor]
C[Extension 2]---A[Source Editor]
D[Extension 3]---A[Source Editor]
E[...]---A[Source Editor]
F[Extension N]---A[Source Editor]
A[Source Editor]---Z[Monaco]
/doc/development/feature_flags/_index.md
Diagram 1
flowchart LR
FDOFF(Flag is currently<br>'default: off')
FDON(Flag is currently<br>'default: on')
CDO{Change to<br>'default: on'}
ACF(added / changed / fixed / '...')
RF{Remove flag}
RF2{Remove flag}
RC(removed / changed)
OTHER(other)
FDOFF -->CDO-->ACF
FDOFF -->RF
RF-->|Keep new code?| ACF
RF-->|Keep old code?| OTHER
FDON -->RF2
RF2-->|Keep old code?| RC
RF2-->|Keep new code?| OTHER
/doc/development/geo/proxying.md
Diagram 1
sequenceDiagram
actor client
participant secondary
participant primary
client->>secondary: GET /explore
secondary-->>primary: GET /explore (proxied)
primary-->>secondary: HTTP/1.1 200 OK [..]
secondary->>client: HTTP/1.1 200 OK [..]
Diagram 2
sequenceDiagram
participant W as Workhorse (secondary)
participant API as Internal Rails API
W->API: GET /api/v4/geo/proxy (internal)
loop Poll every 10 seconds
API-->W: {geo_proxy_primary_url, geo_proxy_extra_data}, update config
end
Diagram 3
flowchart LR
A[Client]--->W1["Workhorse (secondary)"]
W1 --> W1C[Serve data locally?]
W1C -- "Yes" ----> W1
W1C -- "No (proxy)" ----> W2["Workhorse (primary)"]
W2 --> W1 ----> A
Diagram 4
sequenceDiagram
autoNumber
participant Client
participant Secondary
participant Primary
Client->>Secondary: `/group/project` request
Secondary->>Primary: proxy /group/project
opt primary not signed in
Primary-->>Secondary: 302 redirect
Secondary-->>Client: proxy 302 redirect
Client->>Secondary: /users/sign_in
Secondary->>Primary: proxy /users/sign_in
Note right of Primary: authentication happens, POST to same URL etc
Primary-->>Secondary: 302 redirect
Secondary-->>Client: proxy 302 redirect
Client->>Secondary: /group/project
Secondary->>Primary: proxy /group/project
end
Primary-->>Secondary: /group/project logged in response (session on primary created)
Secondary-->>Client: proxy full response
Diagram 5
sequenceDiagram
participant C as Git client
participant Wsec as "Workhorse (secondary)"
participant Rsec as "Rails (secondary)"
participant Gsec as "Gitaly (secondary)"
C->>Wsec: GET /foo/bar.git/info/refs/?service=git-upload-pack
Wsec->>Rsec: <internal API check>
note over Rsec: decide that the repo is synced and up to date
Rsec-->>Wsec: 401 Unauthorized
Wsec-->>C: <response>
C->>Wsec: GET /foo/bar.git/info/refs/?service=git-upload-pack
Wsec->>Rsec: <internal API check>
Rsec-->>Wsec: Render Workhorse OK
Wsec-->>C: 200 OK
C->>Wsec: POST /foo/bar.git/git-upload-pack
Wsec->>Rsec: GitHttpController#git_receive_pack
Rsec-->>Wsec: Render Workhorse OK
Wsec->>Gsec: Workhorse gets the connection details from Rails, connects to Gitaly: SmartHTTP Service, UploadPack RPC (check the proto for details)
Gsec-->>Wsec: Return a stream of Proto messages
Wsec-->>C: Pipe messages to the Git client
Diagram 6
sequenceDiagram
participant C as Git client
participant Wsec as "Workhorse (secondary)"
participant Rsec as "Rails (secondary)"
participant W as "Workhorse (primary)"
participant R as "Rails (primary)"
participant G as "Gitaly (primary)"
C->>Wsec: GET /foo/bar.git/info/refs/?service=git-upload-pack
Wsec->>Rsec: <response>
note over Rsec: decide that the repo is out of date
Rsec-->>Wsec: 302 Redirect to /-/from_secondary/2/foo/bar.git/info/refs?service=git-upload-pack
Wsec-->>C: <response>
C->>Wsec: GET /-/from_secondary/2/foo/bar.git/info/refs/?service=git-upload-pack
Wsec->>W: <proxied request>
W->>R: <data>
R-->>W: 401 Unauthorized
W-->>Wsec: <proxied response>
Wsec-->>C: <response>
C->>Wsec: GET /-/from_secondary/2/foo/bar.git/info/refs/?service=git-upload-pack
note over W: proxied
Wsec->>W: <proxied request>
W->>R: <data>
R-->>W: Render Workhorse OK
W-->>Wsec: <proxied response>
Wsec-->>C: <response>
C->>Wsec: POST /-/from_secondary/2/foo/bar.git/git-upload-pack
Wsec->>W: <proxied request>
W->>R: GitHttpController#git_receive_pack
R-->>W: Render Workhorse OK
W->>G: Workhorse gets the connection details from Rails, connects to Gitaly: SmartHTTP Service, UploadPack RPC (check the proto for details)
G-->>W: Return a stream of Proto messages
W-->>Wsec: Pipe messages to the Git client
Wsec-->>C: Return piped messages from Git
Diagram 7
sequenceDiagram
participant C as Git client
participant S as GitLab Shell (secondary)
participant I as Internal API (secondary Rails)
participant G as Gitaly (secondary)
C->>S: git pull
S->>I: SSH key validation (api/v4/internal/authorized_keys?key=..)
I-->>S: HTTP/1.1 200 OK
S->>G: InfoRefs:UploadPack RPC
G-->>S: stream Git response back
S-->>C: stream Git response back
C-->>S: stream Git data to push
S->>G: UploadPack RPC
G-->>S: stream Git response back
S-->>C: stream Git response back
Diagram 8
sequenceDiagram
participant C as Git client
participant S as GitLab Shell (secondary)
participant I as Internal API (secondary Rails)
participant P as Primary API
C->>S: git pull
S->>I: SSH key validation (api/v4/internal/authorized_keys?key=..)
I-->>S: HTTP/1.1 300 (custom action status) with {endpoint, msg, primary_repo}
S->>I: POST /api/v4/geo/proxy_git_ssh/info_refs_upload_pack
I->>P: POST $PRIMARY/foo/bar.git/info/refs/?service=git-upload-pack
P-->>I: HTTP/1.1 200 OK
I-->>S: <response>
S-->>C: return Git response from primary
C-->>S: stream Git data to push
S->>I: POST /api/v4/geo/proxy_git_ssh/upload_pack
I->>P: POST $PRIMARY/foo/bar.git/git-upload-pack
P-->>I: HTTP/1.1 200 OK
I-->>S: <response>
S-->>C: return Git response from primary
Diagram 9
sequenceDiagram
participant C as Git client
participant S as GitLab Shell (secondary)
participant I as Internal API (secondary Rails)
participant P as Primary API
C->>S: git push
S->>I: SSH key validation (api/v4/internal/authorized_keys?key=..)
I-->>S: HTTP/1.1 300 (custom action status) with {endpoint, msg, primary_repo}
S->>I: POST /api/v4/geo/proxy_git_ssh/info_refs_receive_pack
I->>P: POST $PRIMARY/foo/bar.git/info/refs/?service=git-receive-pack
P-->>I: HTTP/1.1 200 OK
I-->>S: <response>
S-->>C: return Git response from primary
C-->>S: stream Git data to push
S->>I: POST /api/v4/geo/proxy_git_ssh/receive_pack
I->>P: POST $PRIMARY/foo/bar.git/git-receive-pack
P-->>I: HTTP/1.1 200 OK
I-->>S: <response>
S-->>C: return Git response from primary
Diagram 10
sequenceDiagram
participant C as Git client
participant Wsec as Workhorse (secondary)
participant W as Workhorse (primary)
participant R as Rails (primary)
participant G as Gitaly (primary)
C->>Wsec: GET /foo/bar.git/info/refs/?service=git-receive-pack
Wsec->>C: 302 Redirect to /-/from_secondary/2/foo/bar.git/info/refs?service=git-receive-pack
C->>Wsec: GET /-/from_secondary/2/foo/bar.git/info/refs/?service=git-receive-pack
Wsec->>W: <proxied request>
W->>R: <data>
R-->>W: 401 Unauthorized
W-->>Wsec: <proxied response>
Wsec-->>C: <response>
C->>Wsec: GET /-/from_secondary/2/foo/bar.git/info/refs/?service=git-receive-pack
Wsec->>W: <proxied request>
W->>R: <data>
R-->>W: Render Workhorse OK
W-->>Wsec: <proxied response>
Wsec-->>C: <response>
C->>Wsec: POST /-/from_secondary/2/foo/bar.git/git-receive-pack
Wsec->>W: <proxied request>
W->>R: GitHttpController:git_receive_pack
R-->>W: Render Workhorse OK
W->>G: Get connection details from Rails and connects to SmartHTTP Service, ReceivePack RPC
G-->>W: Return a stream of Proto messages
W-->>Wsec: Pipe messages to the Git client
Wsec-->>C: Return piped messages from Git
/doc/development/geo.md
Diagram 1
stateDiagram-v2
Pending --> Started
Started --> Synced
Started --> Failed
Synced --> Pending: Mark for resync
Failed --> Pending: Mark for resync
Failed --> Started: Retry
Diagram 2
sequenceDiagram
participant R as Runner
participant P as Puma
participant DB as PostgreSQL
participant SsP as Secondary site PostgreSQL
R->>P: Upload artifact
P->>DB: Insert `ci_job_artifacts` row
P->>DB: Insert `geo_events` row
P->>DB: Insert `geo_event_log` row
DB->>SsP: Replicate rows
Diagram 3
sequenceDiagram
participant DB as PostgreSQL
participant GLC as Geo Log Cursor
participant R as Redis
participant S as Sidekiq
participant TDB as PostgreSQL Tracking DB
participant PP as Primary site Puma
GLC->>DB: Query `geo_event_log`
GLC->>DB: Query `geo_events`
GLC->>R: Enqueue `Geo::EventWorker`
S->>R: Pick up `Geo::EventWorker`
S->>TDB: Insert to `job_artifact_registry`, "starting sync"
S->>PP: GET <primary site internal URL>/geo/retrieve/job_artifact/123
S->>TDB: Update `job_artifact_registry`, "synced"
Diagram 4
sequenceDiagram
participant SC as Sidekiq-cron
participant R as Redis
participant S as Sidekiq
participant DB as PostgreSQL
participant TDB as PostgreSQL Tracking DB
SC->>R: Enqueue `Geo::Secondary::RegistryConsistencyWorker`
S->>R: Pick up `Geo::Secondary::RegistryConsistencyWorker`
S->>DB: Query `ci_job_artifacts`
S->>TDB: Query `job_artifact_registry`
S->>TDB: Insert to `job_artifact_registry`
Diagram 5
sequenceDiagram
participant SC as Sidekiq-cron
participant R as Redis
participant S as Sidekiq
participant DB as PostgreSQL
participant TDB as PostgreSQL Tracking DB
participant PP as Primary site Puma
SC->>R: Enqueue `Geo::RegistrySyncWorker`
S->>R: Pick up `Geo::RegistrySyncWorker`
S->>TDB: Query `*_registry` tables
S->>R: Enqueue `Geo::EventWorker`s
S->>R: Pick up `Geo::EventWorker`
S->>TDB: Insert to `job_artifact_registry`, "starting sync"
S->>PP: GET <primary site internal URL>/geo/retrieve/job_artifact/123
S->>TDB: Update `job_artifact_registry`, "synced"
Diagram 6
sequenceDiagram
participant Ru as Runner
participant P as Puma
participant DB as PostgreSQL
participant SC as Sidekiq-cron
participant Rd as Redis
participant S as Sidekiq
participant F as Filesystem
Ru->>P: Upload artifact
P->>DB: Insert `ci_job_artifacts`
P->>DB: Insert `ci_job_artifact_states`
SC->>Rd: Enqueue `Geo::VerificationCronWorker`
S->>Rd: Pick up `Geo::VerificationCronWorker`
S->>DB: Query `ci_job_artifact_states`
S->>Rd: Enqueue `Geo::VerificationBatchWorker`
S->>Rd: Pick up `Geo::VerificationBatchWorker`
S->>DB: Query `ci_job_artifact_states`
S->>DB: Update `ci_job_artifact_states` row, "started"
S->>F: Checksum file
S->>DB: Update `ci_job_artifact_states` row, "succeeded"
Diagram 7
sequenceDiagram
participant SC as Sidekiq-cron
participant R as Redis
participant S as Sidekiq
participant TDB as PostgreSQL Tracking DB
participant F as Filesystem
participant DB as PostgreSQL
SC->>R: Enqueue `Geo::VerificationCronWorker`
S->>R: Pick up `Geo::VerificationCronWorker`
S->>TDB: Query `job_artifact_registry`
S->>R: Enqueue `Geo::VerificationBatchWorker`
S->>R: Pick up `Geo::VerificationBatchWorker`
S->>TDB: Query `job_artifact_registry`
S->>TDB: Update `job_artifact_registry` row, "started"
S->>F: Checksum file
S->>DB: Query `ci_job_artifact_states`
S->>TDB: Update `job_artifact_registry` row, "succeeded"
Diagram 8
stateDiagram-v2
Pending --> Started
Pending --> Disabled: No primary checksum
Disabled --> Started: Primary checksum succeeded
Started --> Succeeded
Started --> Failed
Succeeded --> Pending: Mark for reverify
Failed --> Pending: Mark for reverify
Failed --> Started: Retry
Diagram 9
flowchart TD;
GET:Geo-->getcg
Provision-->Terraform
Configure-->Ansible
Geo-->Ansible
QA-->gagq
subgraph "omnibus-gitlab-mirror"
GET:Geo
end
subgraph getcg [GitLab-environment-toolkit-configs/Geo]
direction LR
Generate-terraform-config-->Provision
Provision-->Generate-ansible-config
Generate-ansible-config-->Configure
Configure-->Geo
Geo-->QA
QA-->Destroy-geo
end
subgraph get [GitLab Environment Toolkit]
Terraform
Ansible
end
subgraph GitLab QA
gagq[GitLab QA Geo Scenario]
end
/doc/development/gitlab_shell/_index.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
A[Git pull] --> |via SSH| B[gitlab-shell]
B -->|API call| C[gitlab-rails<br>authorization]
C -->|accept or decline| D[Gitaly session]
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
subgraph User initiates
A[Git push] -->|via SSH| B[gitlab-shell]
end
subgraph Gitaly
B -->|establish Gitaly session| C[gitlab-shell pre-receive hook]
C -->|API auth call| D[Gitlab-rails]
D --> E[accept or decline push]
end
Diagram 3
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
a2 --> b2
a2 --> b3
a2 --> b4
b2 --> c1
b3 --> c1
b4 --> c1
c2 --> d1
c2 --> d2
c2 --> d3
d1 --> e1
d2 --> e1
d3 --> e1
a1[Cloudflare] --> a2[TCP<br/> load balancer]
e1[Git]
subgraph HAProxy Fleet
b2[HAProxy]
b3[HAProxy]
b4[HAProxy]
end
subgraph GKE
c1[Internal TCP<br/> load balancer<br/>port 2222] --> c2[GitLab-shell<br/> pods]
end
subgraph Gitaly
d1[Gitaly]
d2[Gitaly]
d3[Gitaly]
end
Diagram 4
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
participant Git on client
participant SSH server
participant AuthorizedKeysCommand
participant GitLab Shell
participant Rails
participant Gitaly
participant Git on server
Note left of Git on client: git fetch
Git on client->>+SSH server: ssh git fetch-pack request
SSH server->>+AuthorizedKeysCommand: gitlab-shell-authorized-keys-check git AAAA...
AuthorizedKeysCommand->>+Rails: GET /internal/api/authorized_keys?key=AAAA...
Note right of Rails: Lookup key ID
Rails-->>-AuthorizedKeysCommand: 200 OK, command="gitlab-shell upload-pack key_id=1"
AuthorizedKeysCommand-->>-SSH server: command="gitlab-shell upload-pack key_id=1"
SSH server->>+GitLab Shell: gitlab-shell upload-pack key_id=1
GitLab Shell->>+Rails: GET /internal/api/allowed?action=upload_pack&key_id=1
Note right of Rails: Auth check
Rails-->>-GitLab Shell: 200 OK, { gitaly: ... }
GitLab Shell->>+Gitaly: SSHService.SSHUploadPack request
Gitaly->>+Git on server: git upload-pack request
Note over Git on client,Git on server: Bidirectional communication between Git client and server
Git on server-->>-Gitaly: git upload-pack response
Gitaly -->>-GitLab Shell: SSHService.SSHUploadPack response
GitLab Shell-->>-SSH server: gitlab-shell upload-pack response
SSH server-->>-Git on client: ssh git fetch-pack response
/doc/development/gitlab_shell/gitlab_sshd.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
participant Git on client
participant GitLab SSHD
participant Rails
participant Gitaly
participant Git on server
Note left of Git on client: git fetch
Git on client->>+GitLab SSHD: ssh git fetch-pack request
GitLab SSHD->>+Rails: GET /internal/api/authorized_keys?key=AAAA...
Note right of Rails: Lookup key ID
Rails-->>-GitLab SSHD: 200 OK, command="gitlab-shell upload-pack key_id=1"
GitLab SSHD->>+Rails: GET /internal/api/allowed?action=upload_pack&key_id=1
Note right of Rails: Auth check
Rails-->>-GitLab SSHD: 200 OK, { gitaly: ... }
GitLab SSHD->>+Gitaly: SSHService.SSHUploadPack request
Gitaly->>+Git on server: git upload-pack request
Note over Git on client,Git on server: Bidirectional communication between Git client and server
Git on server-->>-Gitaly: git upload-pack response
Gitaly -->>-GitLab SSHD: SSHService.SSHUploadPack response
GitLab SSHD-->>-Git on client: ssh git fetch-pack response
/doc/development/image_scaling.md
Diagram 1
sequenceDiagram
Client->>+Workhorse: GET /uploads/-/system/project/avatar/278964/logo-extra-whitespace.png?width=64
Workhorse->>+Rails: forward request
Rails->>+Rails: validate request
Rails->>+Rails: resolve image location
Rails-->>-Workhorse: Gitlab-Workhorse-Send-Data: send-scaled-image
Workhorse->>+Workhorse: invoke image scaler
Workhorse-->>-Client: 200 OK
/doc/development/internal_analytics/_index.md
Diagram 1
flowchart LR;
feature-->track
track-->|send event record - only on gitlab.com|snowplow
track-->|increase metric counts|redis
database-->service_ping
redis-->service_ping
service_ping-->|json with metric values - weekly export|snowflake
snowplow-->|event records - continuous import|snowflake
snowflake-->vis
subgraph glb[Gitlab Application]
feature[Feature Code]
subgraph events[Internal Analytics Code]
track[track_event / trackEvent]
redis[(Redis)]
database[(Database)]
service_ping[\Service Ping Process\]
end
end
snowplow[\Snowplow Pipeline\]
snowflake[(Snowflake Data Warehouse)]
vis[Dashboards in Tableau]
/doc/development/internal_analytics/product_analytics.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart TB
accTitle: Product Analytics flow
accDescr: How data is collected, processed, and visualized in dashboards.
subgraph Event collection
A([SDK]) --Send user data--> B[Snowplow Collector]
B --Pass data--> C[Snowplow Enricher]
end
subgraph Data warehouse
C --Transform and enrich data--> D([ClickHouse])
end
subgraph Data visualization
F([Dashboards with panels/visualizations])
F --Request data--> G[Product Analytics API]
G --Run Cube queries with pre-aggregations--> H[Cube]
H --Get data--> D
D --Return results--> H
H --Transform data to be rendered--> G
G --Return data--> F
end
/doc/development/internal_analytics/service_ping/_index.md
Diagram 1
sequenceDiagram
participant GitLab Instance
participant Versions Application
participant Licenses Application
participant Salesforce
participant GCP Bucket
participant Snowflake DW
participant Tableau Dashboards
GitLab Instance->>Versions Application: Send Service Ping
loop Process usage data
Versions Application->>Versions Application: Parse usage data
Versions Application->>Versions Application: Write to database
Versions Application->>Versions Application: Update license ping time
end
loop Process data for Salesforce
Versions Application-xLicenses Application: Request Zuora subscription id
Licenses Application-xVersions Application: Zuora subscription id
Versions Application-xSalesforce: Request Zuora account id by Zuora subscription id
Salesforce-xVersions Application: Zuora account id
Versions Application-xSalesforce: Usage data for the Zuora account
end
Versions Application->>GCP Bucket: Export Versions database
GCP Bucket->>Snowflake DW: Import data
Snowflake DW->>Snowflake DW: Transform data using dbt
Snowflake DW->>Tableau Dashboards: Data available for querying
Versions Application->>GitLab Instance: DevOps Score (Conversational Development Index)
/doc/development/lfs.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart LR
accTitle: Git pushes with Git LFS
accDescr: Explains how the LFS hook routes new files depending on type
A[Git push] -->B[LFS hook]
B -->C[Pointers]
B -->D[Binary files]
C -->E[Repository]
D -->F[LFS server]
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart LR
accTitle: Git pull using Git LFS
accDescr: Explains how the LFS hook pulls LFS assets from the LFS server, and everything else from the Git repository
A[User] -->|initiates<br>git pull| B[Repository]
B -->|Pull data and<br>LFS transfers| C[LFS hook]
C -->|LFS pointers| D[LFS server]
D -->|Binary<br>files| C
C -->|Pull data and<br>binary files| A
Diagram 3
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
autonumber
alt Over HTTPS
Git client-->>Git client: user-supplied credentials
else Over SSH
Git client->>gitlab-shell: git-lfs-authenticate
activate gitlab-shell
activate GitLab Rails
gitlab-shell->>GitLab Rails: POST /api/v4/internal/lfs_authenticate
GitLab Rails-->>gitlab-shell: token with expiry
deactivate gitlab-shell
deactivate GitLab Rails
end
Diagram 4
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
Note right of Git client: Typical Git clone things happen first
Note right of Git client: Authentication for LFS comes next
activate GitLab Rails
autonumber
Git client->>GitLab Rails: POST project/namespace/info/lfs/objects/batch
GitLab Rails-->>Git client: payload with objects
deactivate GitLab Rails
loop each object in payload
Git client->>GitLab Rails: GET project/namespace/gitlab-lfs/objects/:oid/ (<- This URL is from the payload)
GitLab Rails->>Workhorse: SendfileUpload
Workhorse-->> Git client: Binary data
end
Diagram 5
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
Note right of Git client: Typical Git push things happen first.
Note right of Git client: Authentication for LFS comes next.
autonumber
activate GitLab Rails
Git client ->> GitLab Rails: POST project/namespace/info/lfs/objects/batch
GitLab Rails-->>Git client: payload with objects
deactivate GitLab Rails
loop each object in payload
Git client->>Workhorse: PUT project/namespace/gitlab-lfs/objects/:oid/:size (URL is from payload)
Workhorse->>GitLab Rails: PUT project/namespace/gitlab-lfs/objects/:oid/:size/authorize
GitLab Rails-->>Workhorse: response with where path to upload
Workhorse->>Workhorse: Upload
Workhorse->>GitLab Rails: PUT project/namespace/gitlab-lfs/objects/:oid/:size/finalize
end
Diagram 6
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
autonumber
Client->>+Workhorse: GET /group/project/-/archive/master.zip
Workhorse->>+Rails: GET /group/project/-/archive/master.zip
Rails->>+Workhorse: Gitlab-Workhorse-Send-Data git-archive
Workhorse->>Gitaly: SendArchiveRequest
Gitaly->>Git: git archive master
Git->>Smudge: OID 12345
Smudge->>+Workhorse: GET /internal/api/v4/lfs?oid=12345&gl_repository=project-1234
Workhorse->>+Rails: GET /internal/api/v4/lfs?oid=12345&gl_repository=project-1234
Rails->>+Workhorse: Gitlab-Workhorse-Send-Data send-url
Workhorse->>Smudge: <LFS data>
Smudge->>Git: <LFS data>
Git->>Gitaly: <streamed data>
Gitaly->>Workhorse: <streamed data>
Workhorse->>Client: master.zip
/doc/development/merge_request_concepts/approval_rules.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
erDiagram
accTitle: Approval rules data model
accDescr: Entity relationship diagram of approval rules
Project ||--o{ MergeRequest: " "
Project ||--o{ ApprovalProjectRule: " "
ApprovalProjectRule }o--o{ User: " "
ApprovalProjectRule }o--o{ Group: " "
ApprovalProjectRule }o--o{ ProtectedBranch: " "
MergeRequest ||--|| ApprovalState: " "
ApprovalState ||--o{ ApprovalWrappedRule: " "
MergeRequest ||--o{ Approval: " "
MergeRequest ||--o{ ApprovalMergeRequestRule: " "
ApprovalMergeRequestRule }o--o{ User: " "
ApprovalMergeRequestRule }o--o{ Group: " "
ApprovalMergeRequestRule ||--o| ApprovalProjectRule: " "
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
erDiagram
accTitle: ApprovalState
accDescr: Entity relationship diagram between MergeRequest and ApprovalState
MergeRequest ||--|| ApprovalState: " "
Diagram 3
%%{init: { "fontFamily": "GitLab Sans" }}%%
erDiagram
accTitle: ApprovalProjectRule diagram
accDescr: Entity relationship diagram between projects and ApprovalProjectRule
Project ||--o{ ApprovalProjectRule: " "
ApprovalProjectRule }o--o{ User: " "
ApprovalProjectRule }o--o{ Group: " "
ApprovalProjectRule }o--o{ ProtectedBranch: " "
Diagram 4
%%{init: { "fontFamily": "GitLab Sans" }}%%
erDiagram
accTitle: ApprovalMergeRequestRule diagram
accDescr: Entity relationship diagram between MergeRequest and ApprovalMergeRequestRule
MergeRequest ||--o{ ApprovalMergeRequestRule: " "
ApprovalMergeRequestRule }o--o{ User: " "
ApprovalMergeRequestRule }o--o{ Group: " "
ApprovalMergeRequestRule ||--o| ApprovalProjectRule: " "
Diagram 5
%%{init: { "fontFamily": "GitLab Sans" }}%%
erDiagram
accTitle: ApprovalWrappedRule diagram
accDescr: Entity relationship diagram between ApprovalState and ApprovalWrappedRule
ApprovalState ||--o{ ApprovalWrappedRule: " "
Diagram 6
%%{init: { "fontFamily": "GitLab Sans" }}%%
erDiagram
accTitle: Approval diagram
accDescr: Entity relationship diagram between MergeRequest and Approval
MergeRequest ||--o{ Approval: " "
Diagram 7
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
accTitle: Merge request creation in the UI
accDescr: Flowchart of the creation of a merge request in the web UI, when the merge request contains approval rules
Projects::MergeRequests::CreationsController --> MergeRequests::CreateService
MergeRequests::CreateService --> ApprovalRules::ParamsFilteringService
ApprovalRules::ParamsFilteringService --> MergeRequests::CreateService
MergeRequests::CreateService --> MergeRequest
MergeRequest --> db[(Database)]
MergeRequest --> User
MergeRequest --> Group
MergeRequest --> ApprovalProjectRule
User --> db[(Database)]
Group --> db[(Database)]
ApprovalProjectRule --> db[(Database)]
Diagram 8
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
accTitle: Viewing approval rules on a merge request
accDescr: Flowchart of how the frontend retrieves, then displays, approval rule information on a merge request page
API::MergeRequestApprovals --> MergeRequest
MergeRequest --> ApprovalState
ApprovalState --> id1{approval rules are overridden}
id1{approval rules are overridden} --> |No| ApprovalProjectRule & ApprovalMergeRequestRule
id1{approval rules are overridden} --> |Yes| ApprovalMergeRequestRule
ApprovalState --> ApprovalWrappedRule
ApprovalWrappedRule --> Approval
Diagram 9
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
accTitle: Approval data flowchart
accDescr: Flowchart of how an approval call to the API reaches the database
API::MergeRequestApprovals --> MergeRequests::ApprovalService
MergeRequests::ApprovalService --> Approval
Approval --> db[(Database)]
/doc/development/merge_request_concepts/diffs/development.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
erDiagram
accTitle: Data model of diffs
accDescr: Data model of the four ActiveRecord models used in diffs
MergeRequest ||--|{ MergeRequestDiff: ""
MergeRequestDiff |{--|{ MergeRequestDiffCommit: ""
MergeRequestDiff |{--|| MergeRequestDiffDetail: ""
MergeRequestDiff |{--|{ MergeRequestDiffFile: ""
MergeRequestDiffCommit |{--|| MergeRequestDiffCommitUser: ""
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart TD
accTitle: Flowchart of generating a new diff version
accDescr: High-level flowchart of components used when creating a new diff version, based on a Git push to a branch
A[PostReceive worker] --> B[MergeRequests::RefreshService]
B --> C[Reload diff of merge requests]
C --> D[Create merge request diff]
D --> K[(Database)]
D --> E[Ensure commit SHAs]
E --> L[Gitaly]
E --> F[Set patch-id]
F --> L[Gitaly]
F --> G[Save commits]
G --> L[Gitaly]
G --> K[(Database)]
G --> H[Save diffs]
H --> L[Gitaly]
H --> K[(Database)]
H --> M[(Object Storage)]
H --> I[Keep around commits]
I --> L[Gitaly]
I --> J[Clear highlight and stats cache]
J --> N[(Redis)]
Diagram 3
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: Data flow of building a new diff
accDescr: Detailed model of the data flow through the components that build a new diff version
PostReceive-->>+MergeRequests_RefreshService: execute()
Note over MergeRequests_RefreshService: Reload diff of merge requests
MergeRequests_RefreshService-->>+MergeRequest: reload_diff()
Note over MergeRequests_ReloadDiffsService: Create merge request diff
MergeRequest-->>+MergeRequests_ReloadDiffsService: execute()
MergeRequests_ReloadDiffsService-->>+MergeRequest: create_merge_request_diff()
MergeRequest-->>+MergeRequestDiff: create()
Note over MergeRequestDiff: Ensure commit SHAs
MergeRequestDiff-->>+MergeRequest: source_branch_sha()
MergeRequest-->>+Repository: commit()
Repository-->>+Gitaly: FindCommit RPC
Gitaly-->>-Repository: Gitlab::Git::Commit
Repository-->>+Commit: new()
Commit-->>-Repository: Commit
Repository-->>-MergeRequest: Commit
MergeRequest-->>-MergeRequestDiff: Commit SHA
Note over MergeRequestDiff: Set patch-id
MergeRequestDiff-->>+Repository: get_patch_id()
Repository-->>+Gitaly: GetPatchID RPC
Gitaly-->>-Repository: Patch ID
Repository-->>-MergeRequestDiff: Patch ID
Note over MergeRequestDiff: Save commits
MergeRequestDiff-->>+Gitaly: ListCommits RPC
Gitaly-->>-MergeRequestDiff: Commits
MergeRequestDiff-->>+MergeRequestDiffCommit: create_bulk()
Note over MergeRequestDiff: Save diffs
MergeRequestDiff-->>+Gitaly: ListCommits RPC
Gitaly-->>-MergeRequestDiff: Commits
opt When external diffs is enabled
MergeRequestDiff-->>+ObjectStorage: upload diffs
end
MergeRequestDiff-->>+MergeRequestDiffFile: legacy_bulk_insert()
Note over MergeRequestDiff: Keep around commits
MergeRequestDiff-->>+Repository: keep_around()
Repository-->>+Gitaly: WriteRef RPC
Note over MergeRequests_ReloadDiffsService: Clear highlight and stats cache
MergeRequests_ReloadDiffsService->>+Gitlab_Diff_HighlightCache: clear()
MergeRequests_ReloadDiffsService->>+Gitlab_Diff_StatsCache: clear()
Gitlab_Diff_HighlightCache-->>+Redis: cache
Gitlab_Diff_StatsCache-->>+Redis: cache
Diagram 4
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart TD
accTitle: Generating a HEAD diff (high-level view)
accDescr: High-level flowchart of components used when generating a HEAD diff
A[MergeRequestMergeabilityCheckWorker] --> B[MergeRequests::MergeabilityCheckService]
B --> C[Merge changes to ref]
C --> L[Gitaly]
C --> D[Recreate merge request HEAD diff]
D --> K[(Database)]
D --> E[Ensure commit SHAs]
E --> L[Gitaly]
E --> F[Set patch-id]
F --> L[Gitaly]
F --> G[Save commits]
G --> L[Gitaly]
G --> K[(Database)]
G --> H[Save diffs]
H --> L[Gitaly]
H --> K[(Database)]
H --> M[(Object Storage)]
H --> I[Keep around commits]
I --> L[Gitaly]
Diagram 5
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: Generating a HEAD diff (detail view)
accDescr: Detailed sequence diagram of generating a new HEAD diff
MergeRequestMergeabilityCheckWorker-->>+MergeRequests_MergeabilityCheckService: execute()
Note over MergeRequests_MergeabilityCheckService: Merge changes to ref
MergeRequests_MergeabilityCheckService-->>+MergeRequests_MergeToRefService: execute()
MergeRequests_MergeToRefService-->>+Repository: merge_to_ref()
Repository-->>+Gitaly: UserMergeBranch RPC
Gitaly-->>-Repository: Commit SHA
MergeRequests_MergeToRefService-->>+Repository: commit()
Repository-->>+Gitaly: FindCommit RPC
Gitaly-->>-Repository: Gitlab::Git::Commit
Repository-->>+Commit: new()
Commit-->>-Repository: Commit
Repository-->>-MergeRequests_MergeToRefService: Commit
Note over MergeRequests_MergeabilityCheckService: Recreate merge request HEAD diff
MergeRequests_MergeabilityCheckService-->>+MergeRequests_ReloadMergeHeadDiffService: execute()
MergeRequests_ReloadMergeHeadDiffService-->>+MergeRequest: create_merge_request_diff()
MergeRequest-->>+MergeRequestDiff: create()
Note over MergeRequestDiff: Ensure commit SHAs
MergeRequestDiff-->>+MergeRequest: merge_ref_head()
MergeRequest-->>+Repository: commit()
Repository-->>+Gitaly: FindCommit RPC
Gitaly-->>-Repository: Gitlab::Git::Commit
Repository-->>+Commit: new()
Commit-->>-Repository: Commit
Repository-->>-MergeRequest: Commit
MergeRequest-->>-MergeRequestDiff: Commit SHA
Note over MergeRequestDiff: Set patch-id
MergeRequestDiff-->>+Repository: get_patch_id()
Repository-->>+Gitaly: GetPatchID RPC
Gitaly-->>-Repository: Patch ID
Repository-->>-MergeRequestDiff: Patch ID
Note over MergeRequestDiff: Save commits
MergeRequestDiff-->>+Gitaly: ListCommits RPC
Gitaly-->>-MergeRequestDiff: Commits
MergeRequestDiff-->>+MergeRequestDiffCommit: create_bulk()
Note over MergeRequestDiff: Save diffs
MergeRequestDiff-->>+Gitaly: ListCommits RPC
Gitaly-->>-MergeRequestDiff: Commits
opt When external diffs is enabled
MergeRequestDiff-->>+ObjectStorage: upload diffs
end
MergeRequestDiff-->>+MergeRequestDiffFile: legacy_bulk_insert()
Note over MergeRequestDiff: Keep around commits
MergeRequestDiff-->>+Repository: keep_around()
Repository-->>+Gitaly: WriteRef RPC
Diagram 6
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart TD
accTitle: Viewing a diff
accDescr: High-level flowchart a diffs_batch request, which renders diffs for browser display
A[Frontend] --> B[diffs_batch.json]
B --> C[Preload diffs and ivars]
C -->D[Gitaly]
C -->E[(Database)]
C --> F[Getting diff file collection]
C --> F[Getting diff file collection]
F --> G[Calculate unfoldable diff lines]
G --> E
G --> H{ETag header is not stale}
H --> |Yes| I[Return 304]
H --> |No| J[Serialize diffs]
J --> D
J --> E
J --> K[(Redis)]
J --> L[Return 200 with JSON]
Diagram 7
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: Viewing the most recent diff
accDescr: Sequence diagram showing how a particular diff is chosen for display, first with the HEAD diff, then the latest diff, followed by a specific version if it's requested
Frontend-->>+.#diffs_batch: API call
Note over .#diffs_batch: Preload diffs and ivars
.#diffs_batch-->>+.#define_diff_vars: before_action
.#define_diff_vars-->>+MergeRequest: merge_request_head_diff() or merge_request_diff()
MergeRequest-->>+MergeRequestDiff: find()
MergeRequestDiff-->>-MergeRequest: MergeRequestDiff
MergeRequest-->>-.#define_diff_vars: MergeRequestDiff
.#define_diff_vars-->>-.#diffs_batch: @compare
Note over .#diffs_batch: Getting diff file collection
.#diffs_batch-->>+MergeRequestDiff: diffs_in_batch()
MergeRequestDiff-->>+Gitlab_Diff_FileCollection_MergeRequestDiffBatch: new()
Gitlab_Diff_FileCollection_MergeRequestDiffBatch-->>-MergeRequestDiff: diff file collection
MergeRequestDiff-->>-.#diffs_batch: diff file collection
Note over .#diffs_batch: Calculate unfoldable diff lines
.#diffs_batch-->>+MergeRequest: note_positions_for_paths
MergeRequest-->>+Gitlab_Diff_PositionCollection: new() then unfoldable()
Gitlab_Diff_PositionCollection-->>-MergeRequest: position collection
MergeRequest-->>-.#diffs_batch: unfoldable_positions
break when ETag header is present and is not stale
.#diffs_batch-->>+Frontend: return 304 HTTP
end
.#diffs_batch->>+Gitlab_Diff_FileCollection_MergeRequestDiffBatch: write_cache()
Gitlab_Diff_FileCollection_MergeRequestDiffBatch->>+Gitlab_Diff_HighlightCache: write_if_empty()
Gitlab_Diff_FileCollection_MergeRequestDiffBatch->>+Gitlab_Diff_StatsCache: write_if_empty()
Gitlab_Diff_HighlightCache-->>+Redis: cache
Gitlab_Diff_StatsCache-->>+Redis: cache
Note over .#diffs_batch: Serialize diffs and render JSON
.#diffs_batch-->>+PaginatedDiffSerializer: represent()
PaginatedDiffSerializer-->>+Gitlab_Diff_FileCollection_MergeRequestDiffBatch: diff_files()
Gitlab_Diff_FileCollection_MergeRequestDiffBatch-->>+MergeRequestDiff: raw_diffs()
MergeRequestDiff-->>+MergeRequestDiffFile: Get all associated records
MergeRequestDiffFile-->>-MergeRequestDiff: Gitlab::Git::DiffCollection
MergeRequestDiff-->>-Gitlab_Diff_FileCollection_MergeRequestDiffBatch: diff files
Gitlab_Diff_FileCollection_MergeRequestDiffBatch-->>+Gitlab_Diff_StatsCache: find_by_path()
Gitlab_Diff_StatsCache-->>+Redis: Read data from cache
Gitlab_Diff_FileCollection_MergeRequestDiffBatch-->>+Gitlab_Diff_HighlightCache: decorate()
Gitlab_Diff_HighlightCache-->>+Redis: Read data from cache
Gitlab_Diff_FileCollection_MergeRequestDiffBatch-->>-PaginatedDiffSerializer: diff files
PaginatedDiffSerializer-->>-.#diffs_batch: JSON
.#diffs_batch-->>+Frontend: return 200 HTTP with JSON
Diagram 8
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: Viewing diffs without whitespace changes
accDescr: Sequence diagram showing how a particular diff is chosen for display, if whitespace changes are not requested - first with the HEAD diff, then the latest diff, followed by a specific version if it's requested
Frontend-->>+.#diffs_batch: API call
Note over .#diffs_batch: Preload diffs and ivars
.#diffs_batch-->>+.#define_diff_vars: before_action
.#define_diff_vars-->>+MergeRequest: merge_request_head_diff() or merge_request_diff()
MergeRequest-->>+MergeRequestDiff: find()
MergeRequestDiff-->>-MergeRequest: MergeRequestDiff
MergeRequest-->>-.#define_diff_vars: MergeRequestDiff
.#define_diff_vars-->>-.#diffs_batch: @compare
Note over .#diffs_batch: Getting diff file collection
.#diffs_batch-->>+MergeRequestDiff: diffs_in_batch()
MergeRequestDiff-->>+Gitlab_Diff_FileCollection_Compare: new()
Gitlab_Diff_FileCollection_Compare-->>-MergeRequestDiff: diff file collection
MergeRequestDiff-->>-.#diffs_batch: diff file collection
Note over .#diffs_batch: Calculate unfoldable diff lines
.#diffs_batch-->>+MergeRequest: note_positions_for_paths
MergeRequest-->>+Gitlab_Diff_PositionCollection: new() then unfoldable()
Gitlab_Diff_PositionCollection-->>-MergeRequest: position collection
MergeRequest-->>-.#diffs_batch: unfoldable_positions
break when ETag header is present and is not stale
.#diffs_batch-->>+Frontend: return 304 HTTP
end
opt Cache highlights and stats when viewing HEAD, latest or specific version
.#diffs_batch->>+Gitlab_Diff_FileCollection_MergeRequestDiffBatch: write_cache()
Gitlab_Diff_FileCollection_MergeRequestDiffBatch->>+Gitlab_Diff_HighlightCache: write_if_empty()
Gitlab_Diff_FileCollection_MergeRequestDiffBatch->>+Gitlab_Diff_StatsCache: write_if_empty()
Gitlab_Diff_HighlightCache-->>+Redis: cache
Gitlab_Diff_StatsCache-->>+Redis: cache
end
Note over .#diffs_batch: Serialize diffs and render JSON
.#diffs_batch-->>+PaginatedDiffSerializer: represent()
PaginatedDiffSerializer-->>+Gitlab_Diff_FileCollection_MergeRequestDiffBatch: diff_files()
Gitlab_Diff_FileCollection_MergeRequestDiffBatch-->>+MergeRequestDiff: raw_diffs()
MergeRequestDiff-->>+Repository: diff()
Repository-->>+Gitaly: CommitDiff RPC
Gitaly-->>-Repository: GitalyClient::DiffStitcher
Repository-->>-MergeRequestDiff: Gitlab::Git::DiffCollection
MergeRequestDiff-->>-Gitlab_Diff_FileCollection_MergeRequestDiffBatch: diff files
Gitlab_Diff_FileCollection_MergeRequestDiffBatch-->>+Gitlab_Diff_StatsCache: find_by_path()
Gitlab_Diff_StatsCache-->>+Redis: Read data from cache
Gitlab_Diff_FileCollection_MergeRequestDiffBatch-->>+Gitlab_Diff_HighlightCache: decorate()
Gitlab_Diff_HighlightCache-->>+Redis: Read data from cache
Gitlab_Diff_FileCollection_MergeRequestDiffBatch-->>-PaginatedDiffSerializer: diff files
PaginatedDiffSerializer-->>-.#diffs_batch: JSON
.#diffs_batch-->>+Frontend: return 200 HTTP with JSON
Diagram 9
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: Comparing diffs
accDescr: Sequence diagram of how diffs are compared against each other
Frontend-->>+.#diffs_batch: API call
Note over .#diffs_batch: Preload diffs and ivars
.#diffs_batch-->>+.#define_diff_vars: before_action
.#define_diff_vars-->>+MergeRequestDiff: compare_with(start_sha)
MergeRequestDiff-->>+Compare: new()
Compare-->>-MergeRequestDiff: Compare
MergeRequestDiff-->>-.#define_diff_vars: Compare
.#define_diff_vars-->>-.#diffs_batch: @compare
Note over .#diffs_batch: Getting diff file collection
.#define_diff_vars-->>+Compare: diffs_in_batch()
Compare-->>+Gitlab_Diff_FileCollection_Compare: new()
Gitlab_Diff_FileCollection_Compare-->>-Compare: diff file collection
Compare-->>-.#define_diff_vars: diff file collection
Note over .#diffs_batch: Calculate unfoldable diff lines
.#diffs_batch-->>+MergeRequest: note_positions_for_paths
MergeRequest-->>+Gitlab_Diff_PositionCollection: new() then unfoldable()
Gitlab_Diff_PositionCollection-->>-MergeRequest: position collection
MergeRequest-->>-.#diffs_batch: unfoldable_positions
break when ETag header is present and is not stale
.#diffs_batch-->>+Frontend: return 304 HTTP
end
Note over .#diffs_batch: Serialize diffs and render JSON
.#diffs_batch-->>+PaginatedDiffSerializer: represent()
PaginatedDiffSerializer-->>+Gitlab_Diff_FileCollection_Compare: diff_files()
Gitlab_Diff_FileCollection_Compare-->>+Compare: raw_diffs()
Compare-->>+Repository: diff()
Repository-->>+Gitaly: CommitDiff RPC
Gitaly-->>-Repository: GitalyClient::DiffStitcher
Repository-->>-Compare: Gitlab::Git::DiffCollection
Compare-->>-Gitlab_Diff_FileCollection_Compare: diff files
Gitlab_Diff_FileCollection_Compare-->>-PaginatedDiffSerializer: diff files
PaginatedDiffSerializer-->>-.#diffs_batch: JSON
.#diffs_batch-->>+Frontend: return 200 HTTP with JSON
Diagram 10
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: Viewing commit diff
accDescr: Sequence diagram showing how viewing the diff of a specific commit is different from the default diff view flow
Frontend-->>+.#diffs_batch: API call
Note over .#diffs_batch: Preload diffs and ivars
.#diffs_batch-->>+.#define_diff_vars: before_action
.#define_diff_vars-->>+Repository: commit()
Repository-->>+Gitaly: FindCommit RPC
Gitaly-->>-Repository: Gitlab::Git::Commit
Repository-->>+Commit: new()
Commit-->>-Repository: Commit
Repository-->>-.#define_diff_vars: Commit
.#define_diff_vars-->>-.#diffs_batch: @compare
Note over .#diffs_batch: Getting diff file collection
.#define_diff_vars-->>+Commit: diffs_in_batch()
Commit-->>+Gitlab_Diff_FileCollection_Commit: new()
Gitlab_Diff_FileCollection_Commit-->>-Commit: diff file collection
Commit-->>-.#define_diff_vars: diff file collection
Note over .#diffs_batch: Calculate unfoldable diff lines
.#diffs_batch-->>+MergeRequest: note_positions_for_paths
MergeRequest-->>+Gitlab_Diff_PositionCollection: new() then unfoldable()
Gitlab_Diff_PositionCollection-->>-MergeRequest: position collection
MergeRequest-->>-.#diffs_batch: unfoldable_positions
break when ETag header is present and is not stale
.#diffs_batch-->>+Frontend: return 304 HTTP
end
Note over .#diffs_batch: Serialize diffs and render JSON
.#diffs_batch-->>+PaginatedDiffSerializer: represent()
PaginatedDiffSerializer-->>+Gitlab_Diff_FileCollection_Commit: diff_files()
Gitlab_Diff_FileCollection_Commit-->>+Commit: raw_diffs()
Commit-->>+Gitaly: CommitDiff RPC
Gitaly-->>-Commit: GitalyClient::DiffStitcher
Commit-->>-Gitlab_Diff_FileCollection_Commit: Gitlab::Git::DiffCollection
Gitlab_Diff_FileCollection_Commit-->>-PaginatedDiffSerializer: diff files
PaginatedDiffSerializer-->>-.#diffs_batch: JSON
.#diffs_batch-->>+Frontend: return 200 HTTP with JSON
Diagram 11
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart TD
accTitle: Diff request flow (high level)
accDescr: High-level flowchart of the components used in a diffs request
A[Frontend] --> B[diffs.json]
B --> C[Build merge request]
C --> D[Get diffs]
D --> E[Render view with diffs]
E --> G[Gitaly]
E --> F[Respond with JSON with the rendered view]
Diagram 12
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: Diff request flow (low level)
accDescr: Sequence diagram with a deeper view of the components used in a diffs request
Frontend-->>+.#diffs: API call
Note over .#diffs: Build merge request
.#diffs-->>+MergeRequests_BuildService: execute
MergeRequests_BuildService-->>+Compare: new()
Compare-->>-MergeRequests_BuildService: Compare
MergeRequests_BuildService-->>+Compare: commits()
Compare-->>+Gitaly: ListCommits RPC
Gitaly-->-Compare: Commits
Compare-->>-MergeRequests_BuildService: Commits
MergeRequests_BuildService-->>-.#diffs: MergeRequest
Note over .#diffs: Get diffs
.#diffs-->>+MergeRequest: diffs()
MergeRequest-->>+Compare: diffs()
Compare-->>+Gitlab_Diff_FileCollection_Compare: new()
Gitlab_Diff_FileCollection_Compare-->>-Compare: diff file collection
Compare-->>-MergeRequest: diff file collection
MergeRequest-->>-.#diffs: @diffs =
Note over .#diffs: Render view with diffs
.#diffs-->>+HAML: view_to_html_string('projects/merge_requests/creations/_diffs', diffs: @diffs)
HAML-->>+Gitlab_Diff_FileCollection_Compare: diff_files()
Gitlab_Diff_FileCollection_Compare-->>+Compare: raw_diffs()
Compare-->>+Repository: diff()
Repository-->>+Gitaly: CommitDiff RPC
Gitaly-->>-Repository: GitalyClient::DiffStitcher
Repository-->>-Compare: Gitlab::Git::DiffCollection
Compare-->>-Gitlab_Diff_FileCollection_Compare: diff files
Gitlab_Diff_FileCollection_Compare-->>-HAML: diff files
HAML-->>-.#diffs: rendered view
.#diffs-->>-Frontend: Respond with JSON with rendered view
/doc/development/merge_request_concepts/diffs/frontend.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart TB
accTitle: Component rendering
accDescr: Flowchart of how components are rendered in the GitLab front end
classDef code font-family: monospace;
A["diffs~~app.vue"]
descVirtualScroller(["Virtual Scroller"])
codeForFiles[["v-for(diffFiles)"]]
B["diffs~~diff_file.vue"]
C["diffs~~diff_file_header.vue"]
D["diffs~~diff_stats.vue"]
E["diffs~~diff_content.vue"]
boolFileIsText{isTextFile}
boolOnlyWhitespace{isWhitespaceOnly}
boolNotDiffable{notDiffable}
boolNoPreview{noPreview}
descShowChanges(["Show button to "Show changes""])
%% Non-text changes
dirDiffViewer>"vue_shared~~diff_viewer"]
F["./viewers/not_diffable.vue"]
G["./viewers/no_preview.vue"]
H["./diff_viewer.vue"]
I["diffs~~diff_view.vue"]
boolIsRenamed{isRenamed}
boolIsModeChanged{isModeChanged}
boolFileHasNoPath{hasNewPath}
boolIsImage{isImage}
J["./viewers/renamed.vue"]
K["./viewers/mode_changed.vue"]
descNoViewer(["No viewer is rendered"])
L["./viewers/image_diff_viewer.vue"]
M["./viewers/download.vue"]
N["vue_shared~~download_diff_viewer.vue"]
boolImageIsReplaced{isReplaced}
O["vue_shared~~image_viewer.vue"]
switchImageMode((image_diff_viewer.mode))
P["./viewers/image_diff/onion_skin_viewer.vue"]
Q["./viewers/image_diff/swipe_viewer.vue"]
R["./viewers/image_diff/two_up_viewer.vue"]
S["diffs~~image_diff_overlay.vue"]
codeForImageDiscussions[["v-for(discussions)"]]
T["vue_shared~~design_note_pin.vue"]
U["vue_shared~~user_avatar_link.vue"]
V["diffs~~diff_discussions.vue"]
W["batch_comments~~diff_file_drafts.vue"]
codeForTwoUpDiscussions[["v-for(discussions)"]]
codeForTwoUpDrafts[["v-for(drafts)"]]
X["notes~~notable_discussion.vue"]
%% Text-file changes
codeForDiffLines[["v-for(diffLines)"]]
Y["diffs~~diff_expansion_cell.vue"]
Z["diffs~~diff_row.vue"]
AA["diffs~~diff_line.vue"]
AB["batch_comments~~draft_note.vue"]
AC["diffs~~diff_comment_cell.vue"]
AD["diffs~~diff_gutter_avatars.vue"]
AE["ee-diffs~~inline_findings_gutter_icon_dropdown.vue"]
AF["notes~~noteable_note.vue"]
AG["notes~~note_actions.vue"]
AH["notes~~note_body.vue"]
AI["notes~~note_header.vue"]
AJ["notes~~reply_button.vue"]
AK["notes~~note_awards_list.vue"]
AL["notes~~note_edited_text.vue"]
AM["notes~~note_form.vue"]
AN["vue_shared~~awards_list.vue"]
AO["emoji~~picker.vue"]
AP["emoji~~emoji_list.vue"]
descEmojiVirtualScroll(["Virtual Scroller"])
AQ["emoji~~category.vue"]
AR["emoji~emoji_category.vue"]
AS["vue_shared~~markdown_editor.vue"]
class codeForFiles,codeForImageDiscussions code;
class codeForTwoUpDiscussions,codeForTwoUpDrafts code;
class codeForDiffLines code;
%% Also apply code styling to this switch node
class switchImageMode code;
%% Also apply code styling to these boolean nodes
class boolFileIsText,boolOnlyWhitespace,boolNotDiffable,boolNoPreview code;
class boolIsRenamed,boolIsModeChanged,boolFileHasNoPath,boolIsImage code;
class boolImageIsReplaced code;
A --> descVirtualScroller
A -->|"Virtual Scroller is
disabled when
Find in page search
(Cmd/Ctrl+f) is used."|codeForFiles
descVirtualScroller --> codeForFiles
codeForFiles --> B --> C --> D
B --> E
%% File view flags cascade
E --> boolFileIsText
boolFileIsText --> |yes| I
boolFileIsText --> |no| boolOnlyWhitespace
boolOnlyWhitespace --> |yes| descShowChanges
boolOnlyWhitespace --> |no| dirDiffViewer
dirDiffViewer --> H
H --> boolNotDiffable
boolNotDiffable --> |yes| F
boolNotDiffable --> |no| boolNoPreview
boolNoPreview --> |yes| G
boolNoPreview --> |no| boolIsRenamed
boolIsRenamed --> |yes| J
boolIsRenamed --> |no| boolIsModeChanged
boolIsModeChanged --> |yes| K
boolIsModeChanged --> |no| boolFileHasNoPath
boolFileHasNoPath --> |yes| boolIsImage
boolFileHasNoPath --> |no| descNoViewer
boolIsImage --> |yes| L
boolIsImage --> |no| M
M --> N
%% Image diff viewer
L --> boolImageIsReplaced
boolImageIsReplaced --> |yes| switchImageMode
boolImageIsReplaced --> |no| O
switchImageMode -->|"'twoup' (default)"| R
switchImageMode -->|'onion'| P
switchImageMode -->|'swipe'| Q
P & Q --> S
S --> codeForImageDiscussions
S --> AM
R-->|"Rendered in
note container div"|U & W & V
%% Do not combine this with the "P & Q --> S" statement above
%% The order of these node relationships defines the
%% layout of the graph, and we need it in this order.
R --> S
V --> codeForTwoUpDiscussions
W --> codeForTwoUpDrafts
%% This invisible link forces `noteable_discussion`
%% to render above `design_note_pin`
X ~~~ T
codeForTwoUpDrafts --> AB
codeForImageDiscussions & codeForTwoUpDiscussions & codeForTwoUpDrafts --> T
codeForTwoUpDiscussions --> X
%% Text file diff viewer
I --> codeForDiffLines
codeForDiffLines --> Z
codeForDiffLines -->|"isMatchLine?"| Y
codeForDiffLines -->|"hasCodeQuality?"| AA
codeForDiffLines -->|"hasDraftNote(s)?"| AB
Z -->|"hasCodeQuality?"| AE
Z -->|"hasDiscussions?"| AD
AA --> AC
%% Draft notes
AB --> AF
AF --> AG & AH & AI
AG --> AJ
AH --> AK & AL & AM
AK --> AN --> AO --> AP --> descEmojiVirtualScroll --> AQ --> AR
AM --> AS
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD
accTitle: Formatting diffs
accDescr: A flowchart of steps taken when rendering a diff, including retrieval and display preparations
A[fetchDiffFilesBatch] -->
B[commit SET_DIFF_DATA_BATCH] -->
C[prepareDiffData] -->
D[prepareRawDiffFile] -->
E[ensureBasicDiffFileLines] -->
F[prepareDiffFileLines] -->
G[finalizeDiffFile] -->
H[deduplicateFilesList]
Diagram 3
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD
accTitle: Render queue pipeline
accDescr: Flowchart of the steps in the render queue pipeline
A[startRenderDiffsQueue] -->B
B[commit RENDER_FILE current file index] -->C
C[canRenderNextFile?]
C -->|Yes| D[Render file] -->B
C -->|No| E[Re-run requestIdleCallback] -->C
/doc/development/migration_style_guide.md
Diagram 1
graph LR
A{Schema<br/>changed?}
A -->|Yes| C{Critical to<br/>speed or<br/>behavior?}
A -->|No| D{Is it fast?}
C -->|Yes| H{Is it fast?}
C -->|No| F[Post-deploy migration]
H -->|Yes| E[Regular migration]
H -->|No| I[Post-deploy migration<br/>+ feature flag]
D -->|Yes| F[Post-deploy migration]
D -->|No| G[Background migration]
/doc/development/multi_version_compatibility.md
Diagram 1
sequenceDiagram
Client browser->>Canary node: GET /gitlab-org/gitlab/-/issues/1
Canary node-->>Client browser: HTML page with canary JS
Client browser->>Main node: POST /api/graphql with query including newFieldAddedInCanary
Main node-->>Client browser: Returns error due to unrecognized field
Diagram 2
gantt
title Deployment
dateFormat HH:mm
section Deploy box
Run migrations :done, migr, after schemaA, 2m
Run post-deployment migrations :postmigr, after mcvn , 2m
section Database
Schema A :done, schemaA, 00:00 , 1h
Schema B :crit, schemaB, after migr, 58m
Schema C. : schemaC, after postmigr, 1h
section Machine A
Version N :done, mavn, 00:00 , 75m
Version N+1 : after mavn, 105m
section Machine B
Version N :done, mbvn, 00:00 , 105m
Version N+1 : mbdone, after mbvn, 75m
section Machine C
Version N :done, mcvn, 00:00 , 2h
Version N+1 : mbcdone, after mcvn, 1h
/doc/development/namespaces.md
Diagram 1
graph TD
Namespace -.- Group
Namespace -.- ProjectNamespace
Namespace -.- UserNamespace
Diagram 2
graph TD
Namespace -.- Group
Namespace -.- ProjectNamespace
Namespace -.- UserNamespace
User -- has one --- UserNamespace
Namespace --- Member --- User
Diagram 3
graph TD
Group -- has many --- ProjectNamespace -- has one --- Project
Group -- has many --- Group
Diagram 4
graph TD
classDef active fill:#f00,color:#fff
classDef sel fill:#00f,color:#fff
A --- A.A --- A.A.A
A.A --- A.A.B
A --- A.B --- A.B.A
A.B --- A.B.B
class A.A.B active
class A sel
Diagram 5
graph TD
classDef active fill:#f00,color:#fff
classDef sel fill:#00f,color:#fff
A --- A.A --- A.A.A
A.A --- A.A.B
A --- A.B --- A.B.A
A.B --- A.B.B
class A.A active
class A.A.A,A.A.B sel
Diagram 6
graph TD
classDef active fill:#f00,color:#fff
classDef sel fill:#00f,color:#fff
A --- A.A --- A.A.A
A.A --- A.A.B
A --- A.B --- A.B.A
A.B --- A.B.B
class A.A active
class A sel
Diagram 7
graph TD
classDef active fill:#f00,color:#fff
classDef sel fill:#00f,color:#fff
A --- A.A --- A.A.A
A.A --- A.A.B
A --- A.B --- A.B.A
A.B --- A.B.B
class A.A active
class A,A.A.A,A.A.B sel
Diagram 8
graph TD
classDef active fill:#f00,color:#fff
classDef sel fill:#00f,color:#fff
A --- A.A --- A.A.A
A.A --- A.A.B
A --- A.B --- A.B.A
A.B --- A.B.B
class A.A.B active
Diagram 9
graph TD
classDef active fill:#f00,color:#fff
classDef sel fill:#00f,color:#fff
A --- A.A --- A.A.A
A.A --- A.A.B
A --- A.B --- A.B.A
A.B --- A.B.B
class A,A.A active
class A.A.A,A.A.B,A.B,A.B.A,A.B.B sel
/doc/development/packages/cleanup_policies.md
Diagram 1
flowchart TD
job[Limited capacity job] --> cleanup([ContainerExpirationPolicies::CleanupService])
cleanup --> cleanup_tags([Projects::ContainerRepository::CleanupTagsService])
cleanup_tags --> delete_tags([Projects::ContainerRepository::DeleteTagsService])
/doc/development/packages/debian_repository.md
Diagram 1
sequenceDiagram
autonumber
actor Client
Client->>+DebianProjectPackages: PUT projects/:id/packages/debian/:file_name
Note over DebianProjectPackages: If `.changes` file or distribution param present
DebianProjectPackages->>+CreateTemporaryPackageService: Create temporary package
Note over DebianProjectPackages: Else
DebianProjectPackages->>+FindOrCreateIncomingService: Create "incoming" package
Note over DebianProjectPackages: Finally
DebianProjectPackages->>+CreatePackageFileService: Create "unknown" file
Note over CreatePackageFileService: If `.changes` file or distribution param present
CreatePackageFileService->>+ProcessPackageFileWorker: Schedule worker to process the file
DebianProjectPackages->>+Client: 202 Created
ProcessPackageFileWorker->>+ProcessPackageFileService: Start service
Diagram 2
sequenceDiagram
autonumber
ProcessPackageFileWorker->>+ProcessPackageFileService: Start service
ProcessPackageFileService->>+ExtractChangesMetadataService: Extract changes metadata
ExtractChangesMetadataService->>+ExtractMetadataService: Extract file metadata
ExtractMetadataService->>+ParseDebian822Service: run `dpkg --field` to get control file
ExtractMetadataService->>+ExtractDebMetadataService: If .deb, .udeb or ddeb
ExtractDebMetadataService->>+ParseDebian822Service: run `dpkg --field` to get control file
ParseDebian822Service-->>-ExtractDebMetadataService: Parse String as Debian RFC822 control data format
ExtractDebMetadataService-->>-ExtractMetadataService: Return the parsed control file
ExtractMetadataService->>+ParseDebian822Service: if .dsc, .changes, or buildinfo
ParseDebian822Service-->>-ExtractMetadataService: Parse String as Debian RFC822 control data format
ExtractMetadataService-->>-ExtractChangesMetadataService: Parse Metadata file
ExtractChangesMetadataService-->>-ProcessPackageFileService: Return list of files and hashes from the .changes file
loop process files listed in .changes
ProcessPackageFileService->>+ExtractMetadataService: Process file
ExtractMetadataService->>+ParseDebian822Service: run `dpkg --field` to get control file
ExtractMetadataService->>+ExtractDebMetadataService: If .deb, .udeb or ddeb
ExtractDebMetadataService->>+ParseDebian822Service: run `dpkg --field` to get control file
ParseDebian822Service-->>-ExtractDebMetadataService: Parse String as Debian RFC822 control data format
ExtractDebMetadataService-->>-ExtractMetadataService: Return the parsed control file
ExtractMetadataService->>+ParseDebian822Service: if .dsc, .changes, or buildinfo
ParseDebian822Service-->>-ExtractMetadataService: Parse String as Debian RFC822 control data format
ExtractMetadataService-->>-ProcessPackageFileService: Use parsed metadata to update "unknown" (or known) file
end
ProcessPackageFileService->>+GenerateDistributionWorker: Find distribution and start service
GenerateDistributionWorker->>+GenerateDistributionService: Generate distribution
Diagram 3
sequenceDiagram
autonumber
GenerateDistributionWorker->>+GenerateDistributionService: Generate distribution
GenerateDistributionService->>+GenerateDistributionService: generate component files based on new archs and updates from .changes
GenerateDistributionService->>+GenerateDistributionKeyService: generate GPG key for distribution
GenerateDistributionKeyService-->>-GenerateDistributionService: GPG key
GenerateDistributionService-->>-GenerateDistributionService: Generate distribution file
GenerateDistributionService->>+SignDistributionService: Sign release file with GPG key
SignDistributionService-->>-GenerateDistributionService: Save the signed release file
GenerateDistributionService->>+GenerateDistributionService: destroy no longer used component files
/doc/development/packages/dependency_proxy.md
Diagram 1
flowchart TD
id1([$ docker]) --> id2([GitLab Dependency Proxy])
id2 --> id3([DockerHub])
Diagram 2
sequenceDiagram
Client->>+GitLab: Login? / request token
GitLab->>+Client: JWT
Client->>+GitLab: request a manifest for an image
GitLab->>+ExternalRegistry: request JWT
ExternalRegistry->>+GitLab : JWT
GitLab->>+ExternalRegistry : request manifest
ExternalRegistry->>+GitLab : return manifest
GitLab->>+GitLab : store manifest
GitLab->>+Client : return manifest
loop request image layers
Client->>+GitLab: request a blob from the manifest
GitLab->>+ExternalRegistry: request JWT
ExternalRegistry->>+GitLab : JWT
GitLab->>+ExternalRegistry : request blob
ExternalRegistry->>+GitLab : return blob
GitLab->>+GitLab : store blob
GitLab->>+Client : return blob
end
Diagram 3
sequenceDiagram
autonumber
participant C as Docker CLI
participant R as GitLab (Dependency Proxy)
Note right of C: User tries `docker login gitlab.com` and enters username/password
C->>R: GET /v2/
Note left of R: Check for Authorization header, return 401 if none, return 200 if token exists and is valid
R->>C: 401 Unauthorized with header "WWW-Authenticate": "Bearer realm=\"http://gitlab.com/jwt/auth\",service=\"registry.docker.io\""
Note right of C: Request Oauth token using HTTP Basic Auth
C->>R: GET /jwt/auth
Note left of R: Token is returned
R->>C: 200 OK (with Bearer token included)
Note right of C: original request is tested again
C->>R: GET /v2/ (this time with `Authorization: Bearer [token]` header)
Note right of C: Login Succeeded
R->>C: 200 OK
Diagram 4
graph TD
A[Receive manifest request] --> | We have the manifest cached.| B{Docker manifest HEAD request}
A --> | We do not have manifest cached.| C{Docker manifest GET request}
B --> | Digest matches the one in the DB | D[Fetch manifest from cache]
B --> | HEAD request error, network failure, cannot reach DockerHub | D[Fetch manifest from cache]
B --> | Digest does not match the one in DB | C
C --> E[Save manifest to cache, save digest to database]
D --> F
E --> F[Return manifest]
Diagram 5
sequenceDiagram
Client->>Workhorse: GET /v2/*group_id/dependency_proxy/containers/*image/manifests/*tag
Workhorse->>Rails: GET /v2/*group_id/dependency_proxy/containers/*image/manifests/*tag
Rails->>Rails: Check DB. Is manifest persisted in cache?
alt In Cache
Rails->>Workhorse: Respond with send-url injector
Workhorse->>Client: Send the file to the client
else Not In Cache
Rails->>Rails: Generate auth token and download URL for the manifest in upstream registry
Rails->>Workhorse: Respond with send-dependency injector
Workhorse->>External Registry: Request the manifest
External Registry->>Workhorse: Download the manifest
Workhorse->>Rails: GET /v2/*group_id/dependency_proxy/containers/*image/manifest/*tag/authorize
Rails->>Workhorse: Respond with upload instructions
Workhorse->>Client: Send the manifest file to the client with original headers
Workhorse->>Object Storage: Save the manifest file with some of it's header values
Workhorse->>Rails: Finalize the upload
end
/doc/development/packages/harbor_registry_development.md
Diagram 1
sequenceDiagram
Client->>+GitLab: Request Harbor registry
GitLab->>+Harbor instance: Request repositories data via API
Harbor instance->>+GitLab: Repositories data
GitLab->>+Client: Return repositories data
Client->>+GitLab: Request Harbor registry artifacts
GitLab->>+Harbor instance: Request artifacts data via API
Harbor instance->>+GitLab: Artifacts data
GitLab->>+Client: Return artifacts data
Client->>+GitLab: Request Harbor registry tags
GitLab->>+Harbor instance: Request tags data via API
Harbor instance->>+GitLab: Tags data
GitLab->>+Client: Return tags data
/doc/development/packages/structure.md
Diagram 1
erDiagram
projects }|--|| namespaces : ""
packages_package_files }o--|| packages_packages : ""
packages_package_file_build_infos }o--|| packages_package_files : ""
packages_build_infos }o--|| packages_packages : ""
packages_tags }o--|| packages_packages : ""
packages_packages }|--|| projects : ""
packages_maven_metadata |o--|| packages_packages : ""
packages_nuget_metadata |o--|| packages_packages : ""
packages_composer_metadata |o--|| packages_packages : ""
packages_conan_metadata |o--|| packages_packages : ""
packages_pypi_metadata |o--|| packages_packages : ""
packages_npm_metadata |o--|| packages_packages : ""
package_conan_file_metadatum |o--|| packages_package_files : ""
package_helm_file_metadatum |o--|| packages_package_files : ""
packages_nuget_dependency_link_metadata |o--|| packages_dependency_links: ""
packages_dependencies ||--o| packages_dependency_links: ""
packages_packages ||--o{ packages_dependency_links: ""
namespace_package_settings |o--|| namespaces: ""
Diagram 2
erDiagram
projects }|--|| namespaces : ""
packages_packages }|--|| projects : ""
packages_package_files }o--|| packages_packages : ""
packages_debian_group_architectures }|--|| packages_debian_group_distributions : ""
packages_debian_group_component_files }|--|| packages_debian_group_components : ""
packages_debian_group_component_files }|--|| packages_debian_group_architectures : ""
packages_debian_group_components }|--|| packages_debian_group_distributions : ""
packages_debian_group_distribution_keys }|--|| packages_debian_group_distributions : ""
packages_debian_group_distributions }o--|| namespaces : ""
packages_debian_project_architectures }|--|| packages_debian_project_distributions : ""
packages_debian_project_component_files }|--|| packages_debian_project_components : ""
packages_debian_project_component_files }|--|| packages_debian_project_architectures : ""
packages_debian_project_components }|--|| packages_debian_project_distributions : ""
packages_debian_project_distribution_keys }|--|| packages_debian_project_distributions : ""
packages_debian_project_distributions }o--|| projects : ""
packages_debian_publications }|--|| packages_debian_project_distributions : ""
packages_debian_publications |o--|| packages_packages : ""
packages_debian_project_distributions |o--|| packages_packages : ""
packages_debian_group_distributions |o--|| namespaces : ""
packages_debian_file_metadata |o--|| packages_package_files : ""
Diagram 3
erDiagram
projects }|--|| namespaces : ""
container_repositories }|--|| projects : ""
container_expiration_policy |o--|| projects : ""
Diagram 4
erDiagram
dependency_proxy_blobs }o--|| namespaces : ""
dependency_proxy_manifests }o--|| namespaces : ""
dependency_proxy_image_ttl_group_policies |o--|| namespaces : ""
dependency_proxy_group_settings |o--|| namespaces : ""
/doc/development/pipelines/_index.md
Diagram 1
flowchart LR
subgraph frontend
fe["Frontend code"]--tested with-->jest
end
subgraph backend
be["Backend code"]--tested with-->rspec
end
be--generates-->fixtures["frontend fixtures"]
fixtures--used in-->jest
Diagram 2
graph LR
subgraph "prepare stage";
A["detect-tests"]
end
subgraph "test stage";
B["jest"];
C["rspec migration"];
D["rspec unit"];
E["rspec integration"];
F["rspec system"];
G["rspec fail-fast"];
end
subgraph "post-test stage";
Z["fail-pipeline-early"];
end
A --"artifact: list of test files"--> G
G --"on failure"--> Z
Diagram 3
graph LR
subgraph "prepare stage";
A["detect-previous-failed-tests"]
end
subgraph "test stage";
B["rspec rspec-pg16-rerun-previous-failed-tests"];
C["rspec rspec-ee-pg16-rerun-previous-failed-tests"];
end
A --"artifact: list of test files"--> B & C
Diagram 4
flowchart TD
subgraph "JiHuLab.com"
JH["gitlab-cn/gitlab"]
end
subgraph "GitLab.com"
Mirror["gitlab-org/gitlab-jh-mirrors/gitlab"]
subgraph MR["gitlab-org/gitlab merge request"]
Add["add-jh-files job"]
Prepare["prepare-as-if-jh-branch job"]
Add --"download artifacts"--> Prepare
end
subgraph "gitlab-org-sandbox/gitlab-jh-validation"
Sync["(*optional) sync-as-if-jh-branch job on branch as-if-jh-code-sync"]
Start["start-as-if-jh job on as-if-jh/* branch"]
AsIfJH["as-if-jh pipeline"]
end
Mirror --"pull mirror with master and main-jh"--> gitlab-org-sandbox/gitlab-jh-validation
Mirror --"download JiHu files with ADD_JH_FILES_TOKEN"--> Add
Prepare --"push as-if-jh branches with AS_IF_JH_TOKEN"--> Sync
Sync --"push as-if-jh branches with AS_IF_JH_TOKEN"--> Start
Start --> AsIfJH
end
JH --"pull mirror with corresponding JH branches"--> Mirror
/doc/development/polling.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
Client->>+Rails: GET /projects/5/pipelines
Rails->>+EtagCaching: GET /projects/5/pipelines
EtagCaching->>+Redis: read(key = 'GET <ETag>')
rect rgb(255, 204, 203)
Redis->>+EtagCaching: cache MISS
end
EtagCaching->>+Redis: write('<New ETag>')
EtagCaching->>+Rails: GET /projects/5/pipelines
Rails->>+Client: JSON response with ETag
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
Client->>+Rails: GET /projects/5/pipelines
Rails->>+EtagCaching: GET /projects/5/pipelines
EtagCaching->>+Redis: read(key = 'GET <ETag>')
rect rgb(144, 238, 144)
Redis->>+EtagCaching: cache HIT
end
EtagCaching->>+Client: 304 Not Modified
/doc/development/product_qualified_lead_guide/_index.md
Diagram 1
sequenceDiagram
Trial Frontend Forms ->>TrialsController#create_lead: GitLab.com frontend sends [lead] to backend
TrialsController#create->>CreateLeadService: [lead]
TrialsController#create->>ApplyTrialService: [lead] Apply the trial
CreateLeadService->>SubscriptionPortalClient#generate_trial(sync_to_gl=false): [lead] Creates customer account on CustomersDot
ApplyTrialService->>SubscriptionPortalClient#generate_trial(sync_to_gl=true): [lead] Asks CustomersDot to apply the trial on namespace
SubscriptionPortalClient#generate_trial(sync_to_gl=false)->>CustomersDot|TrialsController#create(sync_to_gl=false): GitLab.com sends [lead] to CustomersDot
SubscriptionPortalClient#generate_trial(sync_to_gl=true)->>CustomersDot|TrialsController#create(sync_to_gl=true): GitLab.com asks CustomersDot to apply the trial
Diagram 2
sequenceDiagram
CustomersDot|TrialsController#create->>HostedPlans|CreateTrialService#execute: Save [lead] to leads table for monitoring purposes
HostedPlans|CreateTrialService#execute->>BaseTrialService#create_account: Creates a customer record in customers table
HostedPlans|CreateTrialService#create_lead->>CreateLeadService: Creates a lead record in customers table
HostedPlans|CreateTrialService#create_lead->>Workato|CreateLeadWorker: Async worker to submit [lead] to Workato
Workato|CreateLeadWorker->>Workato|CreateLeadService: [lead]
Workato|CreateLeadService->>WorkatoApp#create_lead: [lead]
WorkatoApp#create_lead->>Workato: [lead] is sent to Workato
Diagram 3
sequenceDiagram
HostedPlans|CreateTrialService->load_namespace#Gitlab api/namespaces: Load namespace details
HostedPlans|CreateTrialService->create_order#: Creates an order in orders table
HostedPlans|CreateTrialService->create_trial_history#: Creates a record in trial_histories table
Diagram 4
sequenceDiagram
HandRaiseForm Vue Component->>HandRaiseLeadsController#create: GitLab.com frontend sends [lead] to backend
HandRaiseLeadsController#create->>CreateHandRaiseLeadService: [lead]
CreateHandRaiseLeadService->>SubscriptionPortalClient: [lead]
SubscriptionPortalClient->>CustomersDot|TrialsController#create_hand_raise_lead: GitLab.com sends [lead] to CustomersDot
Diagram 5
sequenceDiagram
CustomersDot|TrialsController#create_hand_raise_lead->>CreateLeadService: Save [lead] to leads table for monitoring purposes
CustomersDot|TrialsController#create_hand_raise_lead->>Workato|CreateLeadWorker: Async worker to submit [lead] to Workato
Workato|CreateLeadWorker->>Workato|CreateLeadService: [lead]
Workato|CreateLeadService->>WorkatoApp#create_lead: [lead]
WorkatoApp#create_lead->>Workato: [lead] is sent to Workato
Diagram 6
sequenceDiagram
Workato->>Marketo: [lead]
Marketo->>Salesforce(SFDC): [lead]
/doc/development/push_rules/_index.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD
Repositories::GitHttpController --> Gitlab::GitAccess
Api::Internal::Base --> Gitlab::GitAccess
Gitlab::GitAccess --> Gitlab::Checks::ChangesAccess
Gitlab::Checks::ChangesAccess --> Gitlab::Checks::SingleChangeAccess
Gitlab::Checks::ChangesAccess --> EE::Gitlab::Checks::PushRuleCheck
Gitlab::Checks::SingleChangeAccess --> Gitlab::Checks::DiffCheck
EE::Gitlab::Checks::PushRuleCheck -->|Only if pushing to a tag| EE::Gitlab::Checks::PushRules::TagCheck
EE::Gitlab::Checks::PushRuleCheck -->|Only if pushing to a branch| EE::Gitlab::Checks::PushRules::BranchCheck
Gitlab::Checks::ChangesAccess --> EE::Gitlab::Checks::FileSizeLimitCheck
/doc/development/rake_tasks.md
Diagram 1
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
/doc/development/real_time.md
Diagram 1
sequenceDiagram
participant V as Vue Component
participant AP as Apollo Client
participant P as Rails/GraphQL
participant AC as Action Cable/GraphQL
participant R as Redis PubSub
AP-->>V: injected
AP->>P: HTTP GET /-/cable
AC-->>P: Hijack TCP connection
AC->>+R: SUBSCRIBE(client)
R-->>-AC: channel subscription
AC-->>AP: HTTP 101: Switching Protocols
par
V->>AP: query(gql)
Note over AP,P: Fetch initial data for this view
AP->>+P: HTTP POST /api/graphql (initial query)
P-->>-AP: initial query response
AP->>AP: cache and/or transform response
AP->>V: trigger update
V->>V: re-render
and
Note over AP,AC: Subscribe to future updates for this view
V->>AP: subscribeToMore(event, gql)
AP->>+AC: WS: subscribe(event, query)
AC->>+R: SUBSCRIBE(event)
R-->>-AC: event subscription
AC-->>-AP: confirm_subscription
end
Note over V,R: time passes
P->>+AC: trigger event
AC->>+R: PUBLISH(event)
R-->>-AC: subscriptions
loop For each subscriber
AC->>AC: run GQL query
AC->>+R: PUBLISH(client, query_result)
R-->>-AC: callback
AC->>-AP: WS: push query result
end
AP->>AP: cache and/or transform response
AP->>V: trigger update
V->>V: re-render
/doc/development/repository_storage_moves/_index.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD
A[<code>POST /api/:version/project_repository_storage_moves</code>] --> C
B[<code>POST /api/:version/projects/:id/repository_storage_moves</code>] --> D
C[Schedule move for each project in shard] --> D[Set state to scheduled]
D --> E[<code>after_transition callback</code>]
E --> F{<code>set_repository_read_only!</code>}
F -->|success| H[Schedule repository update worker]
F -->|error| G[Set state to failed]
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD
A[Repository update worker scheduled] --> B{State is scheduled?}
B -->|Yes| C[Set state to started]
B -->|No| D[Return success]
C --> E{Same filesystem?}
E -.-> G[Set project repo to writable]
E -->|Yes| F["Mirror repositories (project, wiki, design, & pool)"]
G --> H[Update repo storage value]
H --> I[Set state to finished]
I --> J[Associate project with new pool repository]
J --> K[Unlink old pool repository]
K --> L[Update project repository storage values]
L --> N[Remove old paths if same filesystem]
N --> M[Set state to finished]
/doc/development/sec/_index.md
Diagram 1
flowchart LR
subgraph G1[Scanning]
Scanner
Analyzer
CI[CI Jobs]
end
subgraph G2[Processing, visualization, and management]
Parsers
Database
Views
Interactions
end
G1 --Report Artifact--> G2
/doc/development/sec/analyzer_development_guide.md
Diagram 1
graph LR
A1[git tag v1.1.0]--> B1(run CI pipeline)
B1 -->|build and tag patch| D1[1.1.0]
B1 -->|tag minor| E1[1.1]
B1 -->|retag major| F1[1]
B1 -->|retag latest| G1[latest]
A2[git tag v1.1.1]--> B2(run CI pipeline)
B2 -->|build and tag patch| D2[1.1.1]
B2 -->|retag minor| E2[1.1]
B2 -->|retag major| F2[1]
B2 -->|retag latest| G2[latest]
A3[push to default branch]--> B3(run CI pipeline)
B3 -->|build and tag edge| D3[edge]
/doc/development/spam_protection_and_captcha/web_ui.md
Diagram 1
sequenceDiagram
participant U as User
participant V as Vue/JS Application
participant A as ApolloLink or Axios Interceptor
participant G as GitLab API
U->>V: Save model
V->>A: Request
A->>G: Request
G--xA: Response with error and spam/CAPTCHA related fields
A->>U: CAPTCHA presented in modal
U->>A: CAPTCHA solved to obtain valid CAPTCHA response
A->>G: Request with valid CAPTCHA response and SpamLog ID in headers
G-->>A: Response with success
A-->>V: Response with success
/doc/development/testing_guide/end_to_end/_index.md
Diagram 1
graph LR
A["x1y1z1 - master HEAD"]
B["d1e1f1 - merged results (CI_COMMIT_SHA)"]
A --> B
B --> C["Merged results pipeline"]
C --> D["E2E tests"]
/doc/development/testing_guide/review_apps.md
Diagram 1
graph TD
A["build-qa-image, compile-production-assets<br/>(canonical default refs only)"];
B1[start-review-app-pipeline];
B[review-build-cng];
C["review-deploy<br><br>Helm deploys the review app using the Cloud<br/>Native images built by the CNG-mirror pipeline.<br><br>Cloud Native images are deployed to the `review-apps`<br>Kubernetes (GKE) cluster, in the GCP `gitlab-review-apps` project."];
D[CNG-mirror];
A --> B1
B1 --> B
B -.->|triggers a CNG-mirror pipeline| D
D -.->|depends on the multi-project pipeline| B
B --> C
subgraph "1. gitlab-org/gitlab parent pipeline"
A
B1
end
subgraph "2. gitlab-org/gitlab child pipeline"
B
C
end
subgraph "CNG-mirror pipeline"
D>Cloud Native images are built];
end
/doc/development/testing_guide/testing_levels.md
Diagram 1
graph RL
plain[Plain JavaScript];
Vue[Vue Components];
feature-flags[Feature flags];
license-checks[License Checks];
plain---Vuex;
plain---GraphQL;
Vue---plain;
Vue---Vuex;
Vue---GraphQL;
browser---plain;
browser---Vue;
plain---backend;
Vuex---backend;
GraphQL---backend;
Vue---backend;
backend---database;
backend---feature-flags;
backend---license-checks;
class plain tested;
class Vuex tested;
classDef node color:#909090,fill:#f0f0f0,stroke-width:2px,stroke:#909090
classDef label stroke-width:0;
classDef tested color:#000000,fill:#a0c0ff,stroke:#6666ff,stroke-width:2px,stroke-dasharray: 5, 5;
subgraph " "
tested;
mocked;
class tested tested;
end
Diagram 2
graph RL
plain[Plain JavaScript];
Vue[Vue Components];
feature-flags[Feature flags];
license-checks[License Checks];
plain---Vuex;
plain---GraphQL;
Vue---plain;
Vue---Vuex;
Vue---GraphQL;
browser---plain;
browser---Vue;
plain---backend;
Vuex---backend;
GraphQL---backend;
Vue---backend;
backend---database;
backend---feature-flags;
backend---license-checks;
class Vue tested;
classDef node color:#909090,fill:#f0f0f0,stroke-width:2px,stroke:#909090
classDef label stroke-width:0;
classDef tested color:#000000,fill:#a0c0ff,stroke:#6666ff,stroke-width:2px,stroke-dasharray: 5, 5;
subgraph " "
tested;
mocked;
class tested tested;
end
Diagram 3
graph RL
plain[Plain JavaScript];
Vue[Vue Components];
feature-flags[Feature flags];
license-checks[License Checks];
plain---Vuex;
plain---GraphQL;
Vue---plain;
Vue---Vuex;
Vue---GraphQL;
browser---plain;
browser---Vue;
plain---backend;
Vuex---backend;
GraphQL---backend;
Vue---backend;
backend---database;
backend---feature-flags;
backend---license-checks;
class plain tested;
class Vue tested;
class Vuex tested;
class GraphQL tested;
class browser tested;
linkStyle 0,1,2,3,4,5,6 stroke:#6666ff,stroke-width:2px,stroke-dasharray: 5, 5;
classDef node color:#909090,fill:#f0f0f0,stroke-width:2px,stroke:#909090
classDef label stroke-width:0;
classDef tested color:#000000,fill:#a0c0ff,stroke:#6666ff,stroke-width:2px,stroke-dasharray: 5, 5;
subgraph " "
tested;
mocked;
class tested tested;
end
Diagram 4
graph RL
plain[Plain JavaScript];
Vue[Vue Components];
feature-flags[Feature flags];
license-checks[License Checks];
plain---Vuex;
plain---GraphQL;
Vue---plain;
Vue---Vuex;
Vue---GraphQL;
browser---plain;
browser---Vue;
plain---backend;
Vuex---backend;
GraphQL---backend;
Vue---backend;
backend---database;
backend---feature-flags;
backend---license-checks;
class backend tested;
class plain tested;
class Vue tested;
class Vuex tested;
class GraphQL tested;
class browser tested;
linkStyle 0,1,2,3,4,5,6,7,8,9,10 stroke:#6666ff,stroke-width:2px,stroke-dasharray: 5, 5;
classDef node color:#909090,fill:#f0f0f0,stroke-width:2px,stroke:#909090
classDef label stroke-width:0;
classDef tested color:#000000,fill:#a0c0ff,stroke:#6666ff,stroke-width:2px,stroke-dasharray: 5, 5;
subgraph " "
tested;
mocked;
class tested tested;
end
/doc/development/uploads/_index.md
Diagram 1
sequenceDiagram
participant c as Client
participant w as Workhorse
participant r as Rails
participant os as Object Storage
activate c
c ->>+w: POST /some/url/upload
w ->>+r: POST /some/url/upload/authorize
Note over w,r: this request has an empty body
r-->>-w: presigned OS URL
w->>+os: PUT file
Note over w,os: file is stored on a temporary location. Rails select the destination
os-->>-w: request result
w->>+r: POST /some/url/upload
Note over w,r: file was replaced with its location<br>and other metadata
r->>+os: move object to final destination
os-->>-r: request result
opt requires async processing
r->>+redis: schedule a job
redis-->>-r: job is scheduled
end
r-->>-c: request result
deactivate c
w->>-w: cleanup
opt requires async processing
activate sidekiq
sidekiq->>+redis: fetch a job
redis-->>-sidekiq: job
sidekiq->>+os: get object
os-->>-sidekiq: file
sidekiq->>sidekiq: process file
deactivate sidekiq
end
/doc/development/user_contribution_mapping.md
Diagram 1
flowchart
%%% nodes
Start{{
Group or project
migration is started
}}
FetchInfo[
Fetch information
about the contribution
]
FetchUserInfo[
Fetch information about
the user who is associated
with the contribution.
]
CheckSourceUser{
Has a user in the destination
instance already accepted being
mapped to the source user?
}
AssignToUser[
Assign contribution to the user
]
PlaceholderLimit{
Namespace reached
the placeholder limit?
}
CreatePlaceholderUser[
Create a placeholder user and
save the details of the source user
]
AssignContributionPlaceholder[
Assign contribution
to placeholder user
]
AssignImportUser[
Assign contributions to the
ImportUser and save source user
details
]
ImportContribution[
Save contribution
into the database
]
PushPlaceholderReference[
Push instance of placeholder
reference to Redis
]
LoadPlaceholderReference(((
Load placeholder references
into the database
)))
%%% connections
Start --> FetchInfo
FetchInfo --> FetchUserInfo
FetchUserInfo --> CheckSourceUser
CheckSourceUser -- Yes --> AssignToUser
CheckSourceUser -- No --> PlaceholderLimit
PlaceholderLimit -- No --> CreatePlaceholderUser
CreatePlaceholderUser --> AssignContributionPlaceholder
PlaceholderLimit -- Yes --> AssignImportUser
AssignToUser-->ImportContribution
AssignContributionPlaceholder-->ImportContribution
AssignImportUser-->ImportContribution
ImportContribution-->PushPlaceholderReference
PushPlaceholderReference-->LoadPlaceholderReference
Diagram 2
flowchart TD
%% Nodes
OwnerAssigns{{
Group owner requests a
source user to be assigned
to a user in the destination
}}
Notification[
Notification is sent
to the user
]
ReceivesNotification[
User receives the notification and
clicks the button to see more details
]
ClickMoreDetails[
The user is redirected to the more details page
]
CheckRequestStatus{
Group owner has cancelled
the request?
}
RequestCancelledPage(((
Shows request cancelled
by the owner message
)))
OwnerCancel(
Group owner chooses to cancel
the assignment request
)
ReassigmentOptions{
Show reassignment options
}
ReassigmentStarts(((
Start the reassignment
of the contributions
)))
ReassigmentRejected(((
Shows request rejected
by the user message
)))
%% Edge connections between nodes
OwnerAssigns --> Notification --> ReceivesNotification --> ClickMoreDetails
OwnerAssigns --> OwnerCancel
ClickMoreDetails --> CheckRequestStatus
CheckRequestStatus -- Yes --> RequestCancelledPage
CheckRequestStatus -- No --> ReassigmentOptions
ReassigmentOptions -- User accepts --> ReassigmentStarts
ReassigmentOptions -- User rejects --> ReassigmentRejected
OwnerCancel-.->CheckRequestStatus
Diagram 3
stateDiagram-v2
[*] --> pending_reassignment
pending_reassignment --> reassignment_in_progress: Reassign user and bypass assignee confirmation
awaiting_approval --> reassignment_in_progress: Accept reassignment
reassignment_in_progress --> completed: Contribution reassignment completed successfully
reassignment_in_progress --> failed: Error reassigning contributions
pending_reassignment --> awaiting_approval: Reassign user
awaiting_approval --> pending_reassignment: Cancel reassignment
awaiting_approval --> rejected: Reject reassignment
rejected --> pending_reassignment: Cancel reassignment
rejected --> keep_as_placeholder: Keep as placeholder
pending_reassignment --> keep_as_placeholder: Keeps as placeholder
Diagram 4
flowchart LR
%% Nodes
OwnerAssigns{{
Administrator or enterprise group owner
requests a source user to be assigned
to a user in the destination
}}
ConfirmAssignmentWithBypass[
Group owner confirms assignment
without assignee confirmation
]
ReassigmentStarts((
Start the reassignment
of the contributions
))
NotifyAssignee(((
Reassigned real user
notified that contributions
have been reassigned
)))
%% Edge connections between nodes
OwnerAssigns --> ConfirmAssignmentWithBypass --> ReassigmentStarts --> NotifyAssignee
/doc/development/value_stream_analytics.md
Diagram 1
graph LR;
IssueCreated --> IssueClosed;
IssueCreated --> IssueFirstAddedToBoard;
IssueCreated --> IssueFirstAssociatedWithMilestone;
IssueCreated --> IssueFirstMentionedInCommit;
IssueCreated --> IssueLastEdited;
IssueCreated --> IssueLabelAdded;
IssueCreated --> IssueLabelRemoved;
IssueCreated --> IssueFirstAssignedAt;
MergeRequestCreated --> MergeRequestMerged;
MergeRequestCreated --> MergeRequestClosed;
MergeRequestCreated --> MergeRequestFirstDeployedToProduction;
MergeRequestCreated --> MergeRequestLastBuildStarted;
MergeRequestCreated --> MergeRequestLastBuildFinished;
MergeRequestCreated --> MergeRequestLastEdited;
MergeRequestCreated --> MergeRequestLabelAdded;
MergeRequestCreated --> MergeRequestLabelRemoved;
MergeRequestCreated --> MergeRequestFirstAssignedAt;
MergeRequestFirstAssignedAt --> MergeRequestClosed;
MergeRequestFirstAssignedAt --> MergeRequestLastBuildStarted;
MergeRequestFirstAssignedAt --> MergeRequestLastEdited;
MergeRequestFirstAssignedAt --> MergeRequestMerged;
MergeRequestFirstAssignedAt --> MergeRequestLabelAdded;
MergeRequestFirstAssignedAt --> MergeRequestLabelRemoved;
MergeRequestLastBuildStarted --> MergeRequestLastBuildFinished;
MergeRequestLastBuildStarted --> MergeRequestClosed;
MergeRequestLastBuildStarted --> MergeRequestFirstDeployedToProduction;
MergeRequestLastBuildStarted --> MergeRequestLastEdited;
MergeRequestLastBuildStarted --> MergeRequestMerged;
MergeRequestLastBuildStarted --> MergeRequestLabelAdded;
MergeRequestLastBuildStarted --> MergeRequestLabelRemoved;
MergeRequestMerged --> MergeRequestFirstDeployedToProduction;
MergeRequestMerged --> MergeRequestClosed;
MergeRequestMerged --> MergeRequestFirstDeployedToProduction;
MergeRequestMerged --> MergeRequestLastEdited;
MergeRequestMerged --> MergeRequestLabelAdded;
MergeRequestMerged --> MergeRequestLabelRemoved;
IssueLabelAdded --> IssueLabelAdded;
IssueLabelAdded --> IssueLabelRemoved;
IssueLabelAdded --> IssueClosed;
IssueLabelAdded --> IssueFirstAssignedAt;
IssueLabelRemoved --> IssueClosed;
IssueLabelRemoved --> IssueFirstAssignedAt;
IssueFirstAddedToBoard --> IssueClosed;
IssueFirstAddedToBoard --> IssueFirstAssociatedWithMilestone;
IssueFirstAddedToBoard --> IssueFirstMentionedInCommit;
IssueFirstAddedToBoard --> IssueLastEdited;
IssueFirstAddedToBoard --> IssueLabelAdded;
IssueFirstAddedToBoard --> IssueLabelRemoved;
IssueFirstAddedToBoard --> IssueFirstAssignedAt;
IssueFirstAssignedAt --> IssueClosed;
IssueFirstAssignedAt --> IssueFirstAddedToBoard;
IssueFirstAssignedAt --> IssueFirstAssociatedWithMilestone;
IssueFirstAssignedAt --> IssueFirstMentionedInCommit;
IssueFirstAssignedAt --> IssueLastEdited;
IssueFirstAssignedAt --> IssueLabelAdded;
IssueFirstAssignedAt --> IssueLabelRemoved;
IssueFirstAssociatedWithMilestone --> IssueClosed;
IssueFirstAssociatedWithMilestone --> IssueFirstAddedToBoard;
IssueFirstAssociatedWithMilestone --> IssueFirstMentionedInCommit;
IssueFirstAssociatedWithMilestone --> IssueLastEdited;
IssueFirstAssociatedWithMilestone --> IssueLabelAdded;
IssueFirstAssociatedWithMilestone --> IssueLabelRemoved;
IssueFirstAssociatedWithMilestone --> IssueFirstAssignedAt;
IssueFirstMentionedInCommit --> IssueClosed;
IssueFirstMentionedInCommit --> IssueFirstAssociatedWithMilestone;
IssueFirstMentionedInCommit --> IssueFirstAddedToBoard;
IssueFirstMentionedInCommit --> IssueLastEdited;
IssueFirstMentionedInCommit --> IssueLabelAdded;
IssueFirstMentionedInCommit --> IssueLabelRemoved;
IssueClosed --> IssueLastEdited;
IssueClosed --> IssueLabelAdded;
IssueClosed --> IssueLabelRemoved;
MergeRequestClosed --> MergeRequestFirstDeployedToProduction;
MergeRequestClosed --> MergeRequestLastEdited;
MergeRequestClosed --> MergeRequestLabelAdded;
MergeRequestClosed --> MergeRequestLabelRemoved;
MergeRequestFirstDeployedToProduction --> MergeRequestLastEdited;
MergeRequestFirstDeployedToProduction --> MergeRequestLabelAdded;
MergeRequestFirstDeployedToProduction --> MergeRequestLabelRemoved;
MergeRequestLastBuildFinished --> MergeRequestClosed;
MergeRequestLastBuildFinished --> MergeRequestFirstDeployedToProduction;
MergeRequestLastBuildFinished --> MergeRequestLastEdited;
MergeRequestLastBuildFinished --> MergeRequestMerged;
MergeRequestLastBuildFinished --> MergeRequestLabelAdded;
MergeRequestLastBuildFinished --> MergeRequestLabelRemoved;
MergeRequestLabelAdded --> MergeRequestLabelAdded;
MergeRequestLabelAdded --> MergeRequestLabelRemoved;
MergeRequestLabelAdded --> MergeRequestMerged;
MergeRequestLabelAdded --> MergeRequestFirstAssignedAt;
MergeRequestLabelRemoved --> MergeRequestLabelAdded;
MergeRequestLabelRemoved --> MergeRequestLabelRemoved;
MergeRequestLabelRemoved --> MergeRequestFirstAssignedAt;
/doc/development/webhooks.md
Diagram 1
sequenceDiagram
Web or API node->>+Database: Fetch data for payload
Database-->>-Web or API node: Build payload
Note over Web or API node,Database: Webhook triggered
Web or API node->>Sidekiq: Queue webhook execution
Sidekiq->>+Remote webhook receiver: POST webhook payload
Remote webhook receiver-)-Database: Save response in WebHookLog
Note over Database,Remote webhook receiver: Webhook executed
/doc/development/wikis.md
Diagram 1
classDiagram
Wiki --> ProjectWiki
Wiki --> GroupWiki
class Wiki {
#container
#repository
}
class ProjectWiki {
#project → #container
}
class GroupWiki {
#group → #container
}
/doc/development/work_items.md
Diagram 1
graph TD
Event[Specific Interaction Counter] --> AC[Aggregate Counters]
AC --> Plan[Plan xMAU]
AC --> PM[Project Management xMAU]
AC --> PP[Product Planning xMAU]
AC --> Cer[Certify xMAU]
AC --> WI[Work Items Users]
/doc/development/workhorse/handlers.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
participant Client
participant Workhorse
participant Rails
Client->>+Workhorse: Request
Workhorse->>+Rails: Propagate the request as-is
Rails-->>-Workhorse: Respond with a special header that contains instructions for proceeding with the request
Workhorse-->>Client: Response
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
participant Client
participant Workhorse
participant Rails
participant Gitaly
Client->>+Workhorse: HTTP Request for a blob
Workhorse->>+Rails: Propagate the request as-is
Rails-->>-Workhorse: Respond with a git-blob:{encoded_data} header
Workhorse->>+Gitaly: BlobService.GetBlob gRPC request
Gitaly-->>-Workhorse: BlobService.GetBlob gRPC request
Workhorse-->>Client: Stream the data
Diagram 3
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
participant Client
participant Workhorse
participant Rails
participant Object Storage
Client->>+Workhorse: HTTP Request for a file
Workhorse->>+Rails: Propagate the request as-is
Rails-->>-Workhorse: Respond with a send-url:{encoded_data} header
Workhorse->>+Object Storage: Request for a file
Object Storage-->>-Workhorse: Stream the data
Workhorse-->>Client: Stream the data
Diagram 4
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
participant Client
participant Workhorse
participant Rails
participant Object Storage
Client->>+Workhorse: PUT /artifacts/uploads
Note right of Rails: Append `/authorize` to the original URL and call Rails for an Auth check
Workhorse->>+Rails: GET /artifacts/uploads/authorize
Rails-->>-Workhorse: Authorized successfully
Client->>+Workhorse: Stream the file content
Workhorse->>+Object Storage: Upload the file
Object Storage-->>-Workhorse: Success
Workhorse->>+Rails: Finalize the request
Note right of Rails: Workhorse calls the original URL to create a database record
Rails-->>-Workhorse: Finalized successfully
Workhorse-->>Client: Uploaded successfully
Diagram 5
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
participant Git on client
participant Workhorse
participant Rails
participant Gitaly
Note left of Git on client: git clone/fetch
Git on client->>+Workhorse: GET /foo/bar.git/info/refs?service=git-upload-pack
Workhorse->>+Rails: GET Repositories::GitHttpController#info_refs
Note right of Rails: Access check/Log activity
Rails-->>Workhorse: 200 OK, Gitlab::Workhorse.git_http_ok
Workhorse->>+Gitaly: SmartHTTPService.InfoRefsUploadPack gRPC request
Gitaly -->>-Workhorse: SmartHTTPService.InfoRefsUploadPack gRPC response
Workhorse-->>-Git on client: send info-refs response
Git on client->>+Workhorse: GET /foo/bar.git/info/refs?service=git-upload-pack
Workhorse->>+Rails: GET Repositories::GitHttpController#git_receive_pack
Note right of Rails: Access check/Update statistics
Rails-->>Workhorse: 200 OK, Gitlab::Workhorse.git_http_ok
Workhorse->>+Gitaly: SmartHTTPService.PostUploadPackWithSidechannel gRPC request
Gitaly -->>-Workhorse: SmartHTTPService.PostUploadPackWithSidechannel gRPC response
Workhorse-->>-Git on client: send response
Diagram 6
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
participant Git on client
participant Workhorse
participant Rails
participant Gitaly
Note left of Git on client: git push
Git on client->>+Workhorse: GET /foo/bar.git/info/refs?service=git-receive-pack
Workhorse->>+Rails: GET Repositories::GitHttpController#info_refs
Note right of Rails: Access check/Log activity
Rails-->>Workhorse: 200 OK, Gitlab::Workhorse.git_http_ok
Workhorse->>+Gitaly: SmartHTTPService.InfoRefsReceivePack gRPC request
Gitaly -->>-Workhorse: SmartHTTPService.InfoRefsReceivePack gRPC response
Workhorse-->>-Git on client: send info-refs response
Git on client->>+Workhorse: GET /foo/bar.git/info/refs?service=git-receive-pack
Workhorse->>+Rails: GET Repositories::GitHttpController#git_receive_pack
Note right of Rails: Access check/Update statistics
Rails-->>Workhorse: 200 OK, Gitlab::Workhorse.git_http_ok
Workhorse->>+Gitaly: SmartHTTPService.PostReceivePackWithSidechannel gRPC request
Gitaly -->>-Workhorse: SmartHTTPService.PostReceivePackWithSidechannel gRPC response
Workhorse-->>-Git on client: send response
/doc/editor_extensions/visual_studio_code/ssl.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
accTitle: Self-signed certificate chain
accDescr: Shows a self-signed CA that signs the GitLab instance certificate.
A[Self-signed CA] -- signed --> B[Your GitLab instance certificate]
/doc/integration/arkose.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: Sequence of an Arkose Protect challenge
accDescr: How GitLab sends data to Arkose Labs to determine whether to present a challenge during the sign-in attempt.
participant U as User
participant G as GitLab
participant A as Arkose Labs
U->>G: User loads signup form
G->>A: Sends device fingerprint and telemetry
A->>U: Returns Session token and decision on if to challenge
opt Requires Challenge
U->>U: User interacts with Challenge iframe
end
U->>G: Submits form with Arkose Labs token
G ->> A: Sends token to be verified
A ->> G: Returns verification response
Note over G: records `UserCustomAttribute::risk_band`
alt session_details.solved == true
G ->> U: Proceed
else session_details.solved == false
G ->> U: Do not proceed
end
/doc/integration/mattermost/_index.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: GitLab as OAuth 2.0 provider
accDescr: Sequence of actions that happen when a user authenticates to GitLab through Mattermost.
User->>Mattermost: GET https://mm.domain.com
Note over Mattermost, GitLab: Obtain access code
Mattermost->>GitLab: GET https://gitlab.domain.com/oauth/authorize
Note over User, GitLab: GitLab user signs in (if necessary)
Note over GitLab: GitLab verifies client_id matches an OAuth application
GitLab->>User: GitLab asks user to authorize Mattermost OAuth app
User->>GitLab: User selects 'Allow'
Note over GitLab: GitLab verifies redirect_uri matches list of valid URLs
GitLab->>User: 302 redirect: https://mm.domain.com/signup/gitlab/complete
User->>Mattermost: GET https://mm.domain.com/signup/gitlab/complete
Note over Mattermost, GitLab: Exchange access code for access token
Mattermost->>GitLab: POST http://gitlab.domain.com/oauth/token
GitLab->>GitLab: Doorkeeper::TokensController#35;create
GitLab->>Mattermost: Access token
Note over Mattermost, GitLab: Mattermost looks up GitLab user
Mattermost->>GitLab: GET https://gitlab.domain.com/api/v4/user
GitLab->>Mattermost: User details
Mattermost->>User: Mattermost/GitLab user ready
/doc/operations/incident_management/status_page.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TB
accTitle: Understand your status page
accDescr: How GitLab fetches, formats, and displays incident data
subgraph GitLab Instance
issues(issue updates) -- trigger --> middleware(Background job: JSON generation)
end
subgraph Cloud Provider
middleware --saves data --> c1(Cloud Bucket stores JSON file)
end
subgraph Status Page
d(Static Site on CDN) -- fetches data --> c1
end
/doc/solutions/integrations/aws_googlecloud_ollama.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart LR
accTitle: GitLab Duo Self-Hosted architecture
accDescr: Shows the flow from GitLab Ultimate to the AI gateway, which connects to Ollama running Mistral.
A[GitLab<br/>Ultimate] --> C
C[GitLab<br/>AI Gateway] --> B[Ollama<br/>Mistral]
/doc/topics/autodevops/upgrading_auto_deploy_dependencies.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD;
accTitle: v0 and v1 chart resource architecture
accDescr: Shows the relationships between the components of the v0 and v1 charts.
subgraph gl-managed-app
Z[Nginx Ingress]
end
Z[Nginx Ingress] --> A(Ingress);
Z[Nginx Ingress] --> B(Ingress);
subgraph stg namespace
B[Ingress] --> H(...);
end
subgraph prd namespace
A[Ingress] --> D(Service);
D[Service] --> E(Deployment:Pods:app:stable);
D[Service] --> F(Deployment:Pods:app:canary);
D[Service] --> I(Deployment:Pods:app:rollout);
E(Deployment:Pods:app:stable)---id1[(Pods:Postgres)]
F(Deployment:Pods:app:canary)---id1[(Pods:Postgres)]
I(Deployment:Pods:app:rollout)---id1[(Pods:Postgres)]
end
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD;
accTitle: v2 chart resource architecture
accDescr: Shows the relationships between the components of the v2 chart.
subgraph gl-managed-app
Z[Nginx Ingress]
end
Z[Nginx Ingress] --> A(Ingress);
Z[Nginx Ingress] --> B(Ingress);
Z[Nginx Ingress] --> |If canary is present or incremental rollout/|J(Canary Ingress);
subgraph stg namespace
B[Ingress] --> H(...);
end
subgraph prd namespace
subgraph stable track
A[Ingress] --> D[Service];
D[Service] --> E(Deployment:Pods:app:stable);
end
subgraph canary track
J(Canary Ingress) --> K[Service]
K[Service] --> F(Deployment:Pods:app:canary);
end
E(Deployment:Pods:app:stable)---id1[(Pods:Postgres)]
F(Deployment:Pods:app:canary)---id1[(Pods:Postgres)]
end
/doc/topics/git/undo.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart LR
accTitle: Git revert operation workflow diagram
accDescr: Shows commits A, B, C in sequence, then commit -B that reverses B's changes, followed by D. Commit B remains in history.
REMOTE["REMOTE"] --> A(A)
A --> B(B)
B --> C(C)
C --> negB("-B")
negB --> D(D)
B:::crossed
classDef crossed stroke:#000,stroke-width:3px,color:#000,stroke-dasharray: 5 5
negB -.->|reverts| B
/doc/topics/runner_fleet_design_guides/gitlab_runner_manager_performance.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart LR
accTitle: GitLab Runner manager pod architecture
accDescr: The manager pod polls GitLab for jobs, creates job pods through the Kubernetes API, manages the S3 cache, and forwards logs from job pods to GitLab.
subgraph "External Services"
GL[GitLab Instance]
S3[S3 Cache Storage]
end
subgraph "Manager Pod"
MP[Manager Process]
LB[Log Buffer]
CM[Cache Manager]
end
subgraph "Kubernetes API"
K8S[API Server]
end
subgraph "Job Pods"
JP1[Job Pod 1]
JP2[Job Pod 2]
JP3[Job Pod N]
end
GL <-->|Poll Jobs<br/>Update Status| MP
MP <-->|Create/Delete<br/>Monitor Pods| K8S
MP <-->|Cache Operations| S3
JP1 -->|Stream Logs| LB
JP2 -->|Stream Logs| LB
JP3 -->|Stream Logs| LB
LB -->|Forward Logs| GL
CM <-->|Manage Cache| S3
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart TD
accTitle: Metrics collection and monitoring flow
accDescr: The manager pod exposes metrics, Prometheus scrapes the metrics using PodMonitor configuration, Grafana visualizes the data, and Alertmanager notifies operators.
subgraph "Metrics Collection Flow"
MP[Manager Pod<br/>:9252/metrics]
PM[PodMonitor]
P[Prometheus]
G[Grafana]
A[Alertmanager]
MP -->|Expose Metrics| PM
PM -->|Scrape| P
P -->|Query| G
P -->|Alerts| A
A -->|Notify| O[Operators]
end
Diagram 3
%%{init: { "fontFamily": "GitLab Sans" }}%%
xychart-beta
accTitle: Manager pod resource usage compared to concurrent jobs
accDescr: Chart showing CPU usage (10-610 millicores) and memory usage (50-300 MB) that scale with concurrent jobs (0-100).
x-axis [0, 25, 50, 75, 100]
y-axis "Resource Usage" 0 --> 700
line "CPU (millicores)" [10, 160, 310, 460, 610]
line "Memory (MB)" [50, 112, 175, 237, 300]
Diagram 4
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TB
accTitle: Kubernetes node segregation architecture
accDescr: Node segregation with manager pods on dedicated manager nodes and job pods on worker nodes, separated by taints.
subgraph "Kubernetes Cluster"
subgraph "Manager Nodes"
MN1[Manager Node 1<br/>Taint: runner.gitlab.com/manager]
MN2[Manager Node 2<br/>Taint: runner.gitlab.com/manager]
MP1[Manager Pod 1]
MP2[Manager Pod 2]
MN1 --> MP1
MN2 --> MP2
end
subgraph "Worker Nodes"
WN1[Worker Node 1<br/>Taint: runner.gitlab.com/job]
WN2[Worker Node 2<br/>Taint: runner.gitlab.com/job]
WN3[Worker Node 3<br/>Taint: runner.gitlab.com/job]
JP1[Job Pod 1]
JP2[Job Pod 2]
JP3[Job Pod 3]
JP4[Job Pod 4]
WN1 --> JP1
WN1 --> JP2
WN2 --> JP3
WN3 --> JP4
end
end
MP1 -.->|Creates & Manages| JP1
MP1 -.->|Creates & Manages| JP2
MP2 -.->|Creates & Manages| JP3
MP2 -.->|Creates & Manages| JP4
/doc/tutorials/agile_sprint/_index.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD
accTitle: Iteration cadence
accDescr: Identify the group you should create an iteration cadence in
Group --> SubgroupA --> Project1
Group --> SubgroupB --> Project2
Group --> IterationCadence
/doc/tutorials/make_first_git_commit/_index.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
accTitle: Repository commit history
accDescr: Flowchart showing linear changes to a repository history
subgraph Repository commit history
direction LR
A(Author: Alex<br>Date: 3 Jan at 1PM<br>Commit message: Added sales figures<br> Commit ID: 123abc12) ---> B
B(Author: Sam<br>Date: 4 Jan at 10AM<br>Commit message: Removed old info<br> Commit ID: aabb1122) ---> C
C(Author: Zhang<br>Date: 5 Jan at 3PM<br>Commit message: Added invoices<br> Commit ID: ddee4455)
end
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart LR
accTitle: Use branches in Git
accDescr: The flow of creating, then using, a branch in Git
subgraph Default branch
A[Commit] --> B[Commit] --> C[Commit] --> D[Commit]
end
subgraph My branch
B --1. Create my branch--> E(Commit)
E --2. Add my commit--> F(Commit)
F --3. Merge my branch to default--> D
end
/doc/tutorials/merge_requests/homepage.md
Diagram 1
flowchart LR
A[Create a<br>merge request] --> B{Reviewers<br>added?}
B-->|Yes| D[<strong>Review<br>requested</strong>]
B -.->|No| C[<strong>Assigned<br>to you</strong>]
D -->|Approved| E[<strong>Approved<br>by others</strong>]
D -..->|Changes<br>requested| F[<strong>Returned<br>to you</strong>]
F -->|Author<br>makes changes| D
E -->G{All<br>approvals?}
G -->|Yes| K[Ready to merge!]
G -.->|No| J[Remains in<br><strong>Waiting for approvals</strong>]
linkStyle default stroke:red
linkStyle 0 stroke:green
linkStyle 1 stroke:green
linkStyle 3 stroke:green
linkStyle 5 stroke:green
linkStyle 6 stroke:green
linkStyle 7 stroke:green
style K stroke:black,fill:#28a745,color:#fff
/doc/tutorials/scrum_events/_index.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart TD
accTitle: GitLab inheritance model diagram
accDescr: Shows how groups, projects, issues, labels, milestones, iterations, tasks, and epics relate to one another in GitLab
Group -->|Contains| Project
Group -->|Contains| Epics
Group -->|Contains| Labels
Group -->|Contains| Boards
Group -->|Contains| Iterations
Group -->|Contains| Milestones
Group -->|Contains| Roadmaps
Project -->|Contains| Issues
Project -->|Contains| Templates
Project -->|Contains| Tasks
Project -->|Contains| Milestones
Project -->|Contains| Labels
Labels .->|Cascades To| Project
Issues .->|Rolls up to| Group
Iterations .->|Cascades to| Project
Milestones .->|Cascades to| Project
Templates .->|Cascades to| Project
Templates .->|Configured in| Group
Issues .->|Child of| Epics
Issues .->|Visible in| Boards
Issues .->|Visible in| Lists
Issues .->|Assigned to| Iterations
Issues .->|Assigned to| Milestones
Tasks .->|Child of| Issues
Tasks .->|Assigned to| Iterations
Tasks .->|Assigned to| Milestones
Epics .->|Visible in| Boards
Epics .->|Visible in| Roadmaps
Epics .->|Visible in| Lists
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart TD
accTitle: Deliverables structure
accDescr: Flowchart of features (epics) to job stories (issues) to implementation steps (tasks)
Epic["Feature (Epic)"] --> Issue["Job Story (Issue)"]
Issue --> Task["Implementation Step (Task)"]
Diagram 3
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart TD
accTitle: Slicing a feature
accDescr: Use the end user's journey to identify slices of work to be completed in iterations
Epic["Epic: When using the application,<br>I need to create an account,<br> so I can use the application features"] --> Issue1["Issue: When creating my account,<br> I need to specify my email address,<br> so I can receive future updates from the application"]
Epic --> Issue2["Issue: When creating my account,<br> I need to specify a password,<br> so my account remains secure"]
Epic --> Issue3["Issue: When creating my account<br> and entering the required info,<br> I need to finalize creating my account,<br> so I can sign in"]
Diagram 4
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart TD
accTitle: Break the story down further
accDescr: Split apart a story into smaller steps
Issue1["Issue: When creating my account,<br> I need to specify my email address,<br> so I can receive future updates from the application"]
Issue1 --> Task2["Task: Backend<br> Validate email formatting"]
Issue1 --> Task3["Task: Backend<br> API endpoint to accept<br> POST request from client"]
Issue1 --> Task4["Task: Frontend<br> Display email input"]
Issue1 --> Task5["Task: Frontend<br> Display error message when validation fails"]
/doc/user/application_security/dast/browser/configuration/authentication.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: Authentication variables
accDescr: A sequence diagram showing authentication variables at different stages of authentication.
participant DAST
participant Browser
participant Target
Note over DAST,Target: Initialization
DAST->>Browser: Initialize browser with proxy
DAST->>Browser: Navigate to DAST_AUTH_URL
Browser->>Target: Load initial page
Target-->>Browser: Return page content (may not contain login form)
Note over DAST,Target: Process before-login actions
DAST->>Browser: Click elements specified in DAST_AUTH_BEFORE_LOGIN_ACTIONS
Browser->>Target: Send click actions
Target-->>Browser: Render login form (modal/page)
Note over DAST,Target: Authentication
DAST->>Browser: Fill DAST_AUTH_USERNAME & DAST_AUTH_PASSWORD
DAST->>Browser: Click "submit"
Browser->>Target: Submit form
Target-->>Browser: Process authentication
Target-->>Browser: Set auth tokens
Note over DAST,Target: Process after-login actions (if specified)
DAST->>Browser: Execute DAST_AUTH_AFTER_LOGIN_ACTIONS
Browser->>Target: Actions after login but before login verification
Note over DAST,Target: Verification
DAST->>Browser: Check URL matches DAST_AUTH_SUCCESS_IF_AT_URL (if configured)
DAST->>Browser: Check element exists DAST_AUTH_SUCCESS_IF_ELEMENT_FOUND (if configured)
DAST->>Browser: Check login form absent DAST_AUTH_SUCCESS_IF_NO_LOGIN_FORM (default is true)
/doc/user/application_security/dast/browser/configuration/customize_settings.md
Diagram 1
%%{init: {
"gantt": {
"leftPadding": 250,
"sectionFontSize": 15,
"topPadding": 40,
"fontFamily": "GitLab Sans"
}
}}%%
gantt
dateFormat YYYY-MM-DD
axisFormat
section Document load
DAST_PAGE_READY_AFTER_NAVIGATION_TIMEOUT :done, nav1, 2024-01-01, 6d
Fetch HTML :active, nav1, 2024-01-01, 3d
Fetch CSS&JS :active, nav1, 2024-01-04, 3d
DocumentReady :milestone, nav1, 2024-01-07, 0d
section Load Data / Client-side render
DAST_PAGE_DOM_STABLE_WAIT :done, dom1, 2024-01-07, 3d
Initial JS Execution :active, dom1, 2024-01-07, 3d
DAST_PAGE_DOM_READY_TIMEOUT :done, ready1, 2024-01-10, 4d
Fetch Data :active, dom1, 2024-01-10, 2d
Render DOM :active, dom1, 2024-01-10, 2d
DAST_PAGE_IS_LOADING_ELEMENT :milestone, load1, 2024-01-14, 0d
/doc/user/application_security/gitlab_advisory_database/_index.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart TB
accTitle: Advisory ingestion process
accDescr: Sequence of actions that make up the advisory ingestion process.
subgraph Dependency scanning
A[GitLab advisory database]
end
subgraph Container Scanning
C[GitLab Advisory Database \n Open Source Edition \n integrated into Trivy]
end
A --> B{Ingest}
C --> B
B --> |store| D{{"Cloud Storage \n (NDJSON format)"}}
F[\GitLab Instance/] --> |pulls data| D
F --> |stores| G[(Relational database)]
/doc/user/application_security/policies/pipeline_execution_policies.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TB
classDef yaml text-align:left
ActualPolicyYAML["<pre>
variables:
MY_VAR: 'policy'
policy-job:
stage: test
</pre>"]
class ActualPolicyYAML yaml
ActualProjectYAML["<pre>
variables:
MY_VAR: 'project'
project-job:
stage: test
</pre>"]
class ActualProjectYAML yaml
PolicyVariablesYAML["<pre>
variables:
MY_VAR: 'policy'
</pre>"]
class PolicyVariablesYAML yaml
ProjectVariablesYAML["<pre>
variables:
MY_VAR: 'project'
</pre>"]
class ProjectVariablesYAML yaml
ResultingPolicyVariablesYAML["<pre>
variables:
MY_VAR: 'policy'
</pre>"]
class ResultingPolicyVariablesYAML yaml
ResultingProjectVariablesYAML["<pre>
variables:
MY_VAR: 'project'
</pre>"]
class ResultingProjectVariablesYAML yaml
PolicyCiYAML(Policy CI YAML) --> ActualPolicyYAML
ProjectCiYAML(<code>.gitlab-ci.yml</code>) --> ActualProjectYAML
subgraph "Policy Pipeline"
subgraph "Test stage"
subgraph "<code>policy-job</code>"
PolicyVariablesYAML
end
end
end
subgraph "Project Pipeline"
subgraph "Test stage"
subgraph "<code>project-job</code>"
ProjectVariablesYAML
end
end
end
ActualPolicyYAML -- "Used as source" --> PolicyVariablesYAML
ActualProjectYAML -- "Used as source" --> ProjectVariablesYAML
subgraph "Resulting Pipeline"
subgraph "Test stage"
subgraph "<code>policy-job</code> "
ResultingPolicyVariablesYAML
end
subgraph "<code>project-job</code> "
ResultingProjectVariablesYAML
end
end
end
PolicyVariablesYAML -- "Inject <code>policy-job</code> if Test Stage exists" --> ResultingPolicyVariablesYAML
ProjectVariablesYAML -- "Basis of the resulting pipeline" --> ResultingProjectVariablesYAML
/doc/user/application_security/secret_detection/automatic_response.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: Architecture diagram
accDescr: How a post-processing hook revokes a secret in the GitLab application.
autonumber
GitLab Rails-->+GitLab Rails: gl-secret-detection-report.json
GitLab Rails->>+GitLab Sidekiq: StoreScansService
GitLab Sidekiq-->+GitLab Sidekiq: ScanSecurityReportSecretsWorker
GitLab Sidekiq-->+GitLab Token Revocation API: GET revocable keys types
GitLab Token Revocation API-->>-GitLab Sidekiq: OK
GitLab Sidekiq->>+GitLab Token Revocation API: POST revoke revocable keys
GitLab Token Revocation API-->>-GitLab Sidekiq: ACCEPTED
GitLab Token Revocation API-->>+Partner API: revoke revocable keys
Partner API-->>+GitLab Token Revocation API: ACCEPTED
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: Partner API data flow
accDescr: How a Partner API should receive and respond to leaked token revocation requests.
autonumber
GitLab Token Revocation API-->>+Partner API: Send new leaked credentials
Partner API-->>+GitLab Public Keys endpoint: Get active public keys
GitLab Public Keys endpoint-->>+Partner API: One or more public keys
Partner API-->>+Partner API: Verify request is signed by GitLab
Partner API-->>+Partner API: Respond to leaks
Partner API-->>+GitLab Token Revocation API: HTTP status
/doc/user/application_security/vulnerabilities/_index.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
stateDiagram
accTitle: Vulnerability lifecycle
accDescr: Typical lifecycle of a vulnerability
direction LR
Needs_triage: Needs triage
[*] --> Needs_triage
Needs_triage --> Confirmed
Needs_triage --> Dismissed
Dismissed --> [*]
Confirmed --> Resolved
Resolved --> Needs_triage: If reintroduced and detected again
Resolved --> [*]
/doc/user/clusters/agent/gitops.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: Deployment sequence
accDescr: Shows the repositories and main actors in a GitOps deployment.
participant D as Developer
participant A as Application code repository
participant M as Deployment repository
participant R as OCI registry
participant C as Agent configuration repository
participant K as GitLab agent
participant F as Flux
loop Regularly
K-->>C: Grab the configuration
end
D->>+A: Pushing code changes
A->>M: Updating manifest
M->>R: Build an OCI artifact
M->>K: Notify
K->>F: Notify and watch sync
R-->>F: Pulling and applying changes
K->>M: Notify after sync
/doc/user/compliance/compliance_frameworks/_index.md
Diagram 1
sequenceDiagram
GitLab->>+External service: Requirement payload
External service-->>-GitLab: Control response
Note over External service,GitLab: Response includes SHA at HEAD
/doc/user/gitlab_duo/security.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart TD
A[API Request] --> B{Human user has access?}
B -->|No| D[Access denied]
B -->|Yes| C{Service account has access?}
C -->|No| D
C -->|Yes| E[API request succeeds]
style D fill:#ffcccc
style E fill:#ccffcc
/doc/user/group/_index.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans", 'theme':'neutral' }}%%
flowchart TD
accTitle: Group hierarchy
accDescr: Example of a group hierarchy in an organization
subgraph Organization
T[Group T] --> G[Group G]
G --> A[Group A]
G --> B[Group B]
end
/doc/user/group/epics/_index.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD
accTitle: Epics and issues
accDescr: How issues and child epics relate to parent epics and lateral relationships to work items
%% Main structure %%
Parent_epic -->|contains| Issue1
Parent_epic -->|contains| Child_epic
Child_epic -->|contains| Issue2
%% Additional work items and lateral relationships %%
Issue1 -- contains --> Task1["Task"]
Issue2 -- "blocked by" --> Objective1["Objective"]
Task1 -- blocking --> KeyResult1["Key Result"]
%% Work items linked to epics and issues %%
Parent_epic -. related .- Objective1
Child_epic -. "blocked by" .- KeyResult1
/doc/user/group/saml_sso/group_sync.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TB
accTitle: Automatic member removal
accDescr: How group membership of users is determined before sign in if group sync is set up.
subgraph SAML users
SAMLUserA[Sidney Jones]
SAMLUserB[Zhang Wei]
SAMLUserC[Alex Garcia]
SAMLUserD[Charlie Smith]
end
subgraph SAML groups
SAMLGroupA["Group A"] --> SAMLGroupB["Group B"]
SAMLGroupA --> SAMLGroupC["Group C"]
SAMLGroupA --> SAMLGroupD["Group D"]
end
SAMLGroupB --> |Member|SAMLUserA
SAMLGroupB --> |Member|SAMLUserB
SAMLGroupC --> |Member|SAMLUserA
SAMLGroupC --> |Member|SAMLUserB
SAMLGroupD --> |Member|SAMLUserD
SAMLGroupD --> |Member|SAMLUserC
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TB
accTitle: Automatic member removal
accDescr: User membership for Sidney when she has not signed into group C, and group B has not configured group links.
subgraph GitLab users
GitLabUserA[Sidney Jones]
GitLabUserB[Zhang Wei]
GitLabUserC[Alex Garcia]
GitLabUserD[Charlie Smith]
end
subgraph GitLab groups
GitLabGroupA["Group A<br> (SAML configured)"] --> GitLabGroupB["Group B<br> (SAML Group Link not configured)"]
GitLabGroupA --> GitLabGroupC["Group C<br> (SAML Group Link configured)"]
GitLabGroupA --> GitLabGroupD["Group D<br> (SAML Group Link configured)"]
end
GitLabGroupB --> |Member|GitLabUserA
GitLabGroupC --> |Member|GitLabUserB
GitLabGroupC --> |Member|GitLabUserC
GitLabGroupD --> |Member|GitLabUserC
GitLabGroupD --> |Member|GitLabUserD
Diagram 3
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TB
accTitle: Automatic member removal
accDescr: How membership of Alex Garcia works once she has signed into a group that has group links enabled.
subgraph GitLab users
GitLabUserA[Sidney Jones]
GitLabUserB[Zhang Wei]
GitLabUserC[Alex Garcia]
GitLabUserD[Charlie Smith]
end
subgraph GitLab groups after Alex Garcia signs in
GitLabGroupA[Group A]
GitLabGroupA["Group A<br> (SAML configured)"] --> GitLabGroupB["Group B<br> (SAML Group Link not configured)"]
GitLabGroupA --> GitLabGroupC["Group C<br> (SAML Group Link configured)"]
GitLabGroupA --> GitLabGroupD["Group D<br> (SAML Group Link configured)"]
end
GitLabGroupB --> |Member|GitLabUserA
GitLabGroupC --> |Member|GitLabUserB
GitLabGroupD --> |Member|GitLabUserC
GitLabGroupD --> |Member|GitLabUserD
/doc/user/group/saml_sso/scim_setup.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD
accTitle: Adding users to your SCIM application
accDescr: How GitLab determines whether or not to associate a SCIM identity with a user.
A[Add User to SCIM app] -->|IdP sends user info to GitLab| B(GitLab: Does the email exist?)
B -->|No| C[GitLab creates user with SCIM identity]
B -->|Yes| D(GitLab: Is the user part of the group?)
D -->|No| E(GitLab: Is SSO enforcement enabled?)
E -->|No| G
E -->|Yes| F[GitLab sends message back:\nThe member's email address is not linked to a SAML account]
D -->|Yes| G[Associate SCIM identity to user]
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD
accTitle: Deprovisioning users
accDescr: How removing users from your SCIM app removes them from GitLab groups.
A[Remove User from SCIM app] -->|IdP sends request to GitLab| B(GitLab: Is the user part of the group?)
B -->|No| C[Nothing to do]
B -->|Yes| D[GitLab removes user from GitLab group]
/doc/user/group/ssh_certificates.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
sequenceDiagram
accTitle: SSH certificate authentication flow
accDescr: Sequential diagram showing how a user obtains an SSH certificate from a Group Certificate Authority and uses it to access a Git repository through GitLab.
participant User
participant GroupCA as Group Certificate Authority
participant GitLab
participant GitRepo as Git Repository
User->>GroupCA: Request SSH certificate
GroupCA->>User: Issue signed SSH certificate
User->>GitLab: Attempt to access repository via SSH
GitLab->>GitLab: Verify certificate is valid and issued by Group CA
GitLab->>GitRepo: Grant access
GitRepo->>User: Allow repository operations
/doc/user/group/subgroups/_index.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD
accTitle: Parent and subgroup nesting
accDescr: How parent groups, subgroups, and projects nest.
subgraph "Parent group"
subgraph "Subgroup A"
subgraph "Subgroup A1"
G["Project E"]
end
C["Project A"]
D["Project B"]
E["Project C"]
end
subgraph "Subgroup B"
F["Project D"]
end
end
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart RL
accTitle: Subgroup membership
accDescr: How users become members of a subgroup - through direct, indirect, or inherited membership.
subgraph Group A
A(Direct member)
B{{Shared member}}
subgraph Subgroup A
H(1. Direct member)
C{{2. Inherited member}}
D{{Inherited member}}
E{{3. Shared member}}
end
A-->|Direct membership of Group A\nInherited membership of Subgroup A|C
end
subgraph Group C
G(Direct member)
end
subgraph Group B
F(Direct member)
end
F-->|Group B\nshared with\nGroup A|B
B-->|Inherited membership of Subgroup A|D
G-->|Group C shared with Subgroup A|E
/doc/user/markdown.md
Diagram 1
graph TD;
A-->B;
A-->C;
B-->D;
C-->D;
Diagram 2
graph TD;
A-->B;
A-->C;
B-->D;
C-->D;
Diagram 3
graph TB
SubGraph1 --> SubGraph1Flow
subgraph "SubGraph 1 Flow"
SubGraph1Flow(SubNode 1)
SubGraph1Flow -- Choice1 --> DoChoice1
SubGraph1Flow -- Choice2 --> DoChoice2
end
subgraph "Main Graph"
Node1[Node 1] --> Node2[Node 2]
Node2 --> SubGraph1[Jump to SubGraph1]
SubGraph1 --> FinalThing[Final Thing]
end
Diagram 4
graph TB
SubGraph1 --> SubGraph1Flow
subgraph "SubGraph 1 Flow"
SubGraph1Flow(SubNode 1)
SubGraph1Flow -- Choice1 --> DoChoice1
SubGraph1Flow -- Choice2 --> DoChoice2
end
subgraph "Main Graph"
Node1[Node 1] --> Node2[Node 2]
Node2 --> SubGraph1[Jump to SubGraph1]
SubGraph1 --> FinalThing[Final Thing]
end
/doc/user/packages/container_registry/immutable_container_tags.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD
accTitle: Evaluation of protected and immutable tag rules
accDescr: Flow chart showing the evaluation process for protected and immutable tag rules during an image push.
A[User attempts to push a tag] --> B{Protected tag check:<br/>Does user have required role<br/>to push this tag pattern?}
B -- Yes --> C{Does the tag already exist?}
B -- No --> D[Push denied:<br/>Protected tag - insufficient permissions]
C -- Yes --> E{Immutable tag check:<br/>Does tag match an<br/>immutable rule pattern?}
C -- No --> F[Tag is created successfully]
E -- Yes --> G[Push denied:<br/>Tag is immutable]
E -- No --> H[Tag is overwritten successfully]
/doc/user/profile/notifications.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans", 'theme':'neutral' }}%%
flowchart TD
accTitle: Notification hierarchy
accDescr: Example of a group, subgroup, and project
N[Default/global notification level set to Watch]
N --> A
A[Group A: Notification level set to Global]
A-. Inherits Watch level .-> N
A --> B[Subgroup B: Notification level set to Participate]
B --> C[Project C: Notification level set to Global]
C-. Inherits Participate level .-> B
/doc/user/project/changelogs.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
accTitle: Flowchart of 3 commits
accDescr: Shows the flow of 3 commits, where commit C reverts commit B, but it contains no trailer
A[Commit A<br>Changelog: changed] --> B[Commit B<br>Changelog: changed]
B --> C[Commit C<br>Reverts commit B]
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
accTitle: Flowchart of 3 commits
accDescr: Shows the flow of 3 commits, where commit C reverts commit B, but both commits A and C contain trailers
A[Commit A<br><br>Changelog: changed] --> B[Commit B<br><br>Changelog: changed]
B --> C[Commit C<br>Reverts commit B<br>Changelog: changed]
/doc/user/project/codeowners/advanced.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD
accTitle: Diagram of group inheritance
accDescr: If a subgroup owns a project, the parent group inherits ownership.
A[Parent group X] -->|owns| B[Project A]
A -->|contains| C[Subgroup Y]
C -->|owns| D[Project B]
A-. inherits ownership .-> D
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
accTitle: Diagram of subgroup inheritance
accDescr: Inviting a subgroup directly to a project affects whether their approvals can be made required.
A[Parent group X] -->|owns| B[Project A]
A -->|also contains| C[Subgroup Y]
C -.->D{Invite Subgroup Y<br/>to Project A?} -.->|yes| E[Members of Subgroup Y<br/>can submit Approvals]
D{Invite Subgroup Y<br/>to Project A?} -.->|no| F[Members of Subgroup Y<br />cannot submit Approvals]
E -.->|Add Subgroup Y<br/> as Code Owner to Project A| I[Approvals can be<br/>required] -.-> B
F -.-> |Add Subgroup Y<br/> as Code Owners to Project A| J[Approvals can only<br/>be optional] -.-> B
/doc/user/project/members/_index.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart RL
accTitle: Membership types
accDescr: Describes membership types and their inheritance
subgraph Group A
A(Direct member)
B{{Shared member}}
subgraph Project X
H(Direct member)
C{{Inherited member}}
D{{Inherited shared member}}
E{{Shared member}}
end
A-->|Inherited membership in Project X\nDirect membership in Group A|C
end
subgraph Group C
G(Direct member)
end
subgraph Group B
F(Direct member)
end
F-->|Group B\ninvited to\nGroup A|B
B-->|Inherited membership in Project X\nIndirect membership in Group A|D
G-->|Group C invited to Project X|E
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD
accTitle: Diagram of group inheritance
accDescr: User inheritance, both direct and indirect through subgroups
classDef user stroke:green,color:green;
root --> subgroup --> subsubgroup
root-2 --> subgroup-2 --> subsubgroup-2
root-3 --> subgroup-3 --> subsubgroup-3
subgroup -. shared .-> subgroup-2 -. shared .-> subgroup-3
User-. member .- subgroup
class User user
/doc/user/project/merge_requests/cherry_pick_changes.md
Diagram 1
gitGraph
commit id: "A"
branch develop
commit id:"B"
checkout main
commit id:"C"
checkout develop
commit id:"D"
checkout main
commit id:"E"
cherry-pick id:"B"
commit id:"G"
checkout develop
commit id:"H"
/doc/user/project/merge_requests/dependencies.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TB
accTitle: Merge request dependencies
accDescr: Shows how a merge request dependency prevents work from merging too soon.
A['me/myexample' project]
B['myfriend/library' project]
C[Merge request #1:<br>Create new version 2.5]
D[Merge request #2:<br>Add version 2.5<br>to build]
A-->|contains| D
B---->|contains| C
D-.->|depends on| C
C-.->|blocks| D
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR;
accTitle: Merge request dependency chain
accDescr: Flowchart that shows how merge request A depends on merge request B, while merge request B depends on merge request C
A[myfriend/library!10]-->|depends on| B[herfriend/another-lib!1]
B-->|depends on| C[mycorp/example!100]
/doc/user/project/merge_requests/homepage.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
flowchart LR
accTitle: Merge request review workflow
accDescr: Flow from merge request creation through review, approval, and merge stages with decision points for reviewers and approvals.
A[Your<br>merge request] --> B{Reviewers<br>added?}
B-->|Yes| D[<strong>Review<br>requested</strong>]
B -.->|No| C[<strong>Your merge<br>requests</strong>]
D -->|Approved| E[<strong>Approved<br>by others</strong>]
D -..->|Changes<br>requested| F[<strong>Returned<br>to you</strong>]
F -->|You make<br>changes| D
E -->G{All<br>approvals?}
G -->|Yes| K[Ready to merge]
G -.->|No| J[Remains in<br><strong>Waiting for approvals</strong>]
linkStyle default stroke:red
linkStyle 0 stroke:green
linkStyle 1 stroke:green
linkStyle 3 stroke:green
linkStyle 5 stroke:green
linkStyle 6 stroke:green
linkStyle 7 stroke:green
style K stroke:black,fill:#28a745,color:#fff
/doc/user/project/merge_requests/methods/_index.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
gitGraph
accTitle: Diagram of a merge
accDescr: A Git graph of five commits on two branches, which will be expanded on in other graphs in this page.
commit id: "A"
branch feature
commit id: "B"
commit id: "D"
checkout main
commit id: "C"
commit id: "E"
Diagram 2
%%{init: { 'gitGraph': {'logLevel': 'debug', 'showBranches': true, 'showCommitLabel':true,'mainBranchName': 'main', 'fontFamily': 'GitLab Sans'}} }%%
gitGraph
accTitle: Diagram of a merge commit
accDescr: A Git graph showing how merge commits are created in GitLab when a feature branch is merged.
commit id: "A"
branch feature
commit id: "B"
commit id: "D"
checkout main
commit id: "C"
commit id: "E"
merge feature
Diagram 3
%%{init: { 'gitGraph': {'showBranches': true, 'showCommitLabel':true,'mainBranchName': 'main', 'fontFamily': 'GitLab Sans'}} }%%
gitGraph
accTitle: Diagram of of a squash merge
accDescr: A Git graph showing repository and branch structure after a squash commit is added to the main branch.
commit id:"A"
branch feature
checkout main
commit id:"C"
checkout feature
commit id:"B"
commit id:"D"
checkout main
commit id:"E"
branch "B+D"
commit id: "B+D"
checkout main
merge "B+D"
Diagram 4
%%{init: { "fontFamily": "GitLab Sans" }}%%
gitGraph
accTitle: Diagram of a merge commit
accDescr: Shows the flow of commits when a branch merges with a merge commit.
commit id: "Init"
branch mr-branch-1
commit
commit
checkout main
merge mr-branch-1
branch mr-branch-2
commit
commit
checkout main
merge mr-branch-2
commit
branch squash-mr
commit id: "Squashed commits"
checkout main
merge squash-mr
Diagram 5
%%{init: { "fontFamily": "GitLab Sans" }}%%
gitGraph
accTitle: Diagram of a fast-forward merge
accDescr: Shows how a fast-forwarded merge request maintains a linear Git history, but does not add a merge commit.
commit id: "Init"
commit id: "Merge mr-branch-1"
commit id: "Merge mr-branch-2"
commit id: "Commit on main"
commit id: "Merge squash-mr"
/doc/user/project/merge_requests/status_checks.md
Diagram 1
sequenceDiagram
Merge request->>+External service: Merge request payload
External service-->>-Merge request: Status check response
Note over External service,Merge request: Response includes SHA at HEAD
/doc/user/project/protected_tags.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD
accTitle: Diagram of group inheritance for protected tags
accDescr: If a project is shared with a group, the group members inherit permissions for protected tags.
A[Parent group X] -->|owns| B[Project A]
A -->|contains| C[Subgroup Y]
B -->|shared with| C
C -->|members inherit permissions| B
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
accTitle: Diagram of project sharing for protected tag permissions
accDescr: Sharing a project with a group affects whether their members can have protected tag permissions.
A[Parent group X] -->|owns| B[Project A]
A -->|also contains| C[Subgroup Y]
C -.->D{Share Project A<br/>with Subgroup Y?} -.->|yes| E[Members of Subgroup Y<br/>can have protected<br/>tag permissions]
D{Share Project A<br/>with Subgroup Y?} -.->|no| F[Members of Subgroup Y<br />cannot have protected<br/>tag permissions]
E -.->|Add Subgroup Y<br/> to protected tag settings| I[Subgroup Y members<br/>can create tags] -.-> B
F -.-> |Add Subgroup Y<br/> to protected tag settings| J[Settings will not<br/>take effect] -.-> B
/doc/user/project/repository/branches/_index.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
gitGraph
accTitle: Diagram of multiple branches with the same commit
accDescr: Branches A and B contain the same commit, but branch B also contains other commits. Merging branch B makes branch A appear as merged, because all its commits are merged.
commit id:"a"
branch "branch A"
commit id:"b"
commit id:"c" type: HIGHLIGHT
branch "branch B"
commit id:"d"
checkout "branch A"
branch "branch C"
commit id:"e"
checkout main
merge "branch B" id:"merges commits b, c, d"
/doc/user/project/repository/branches/protected.md
Diagram 1
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph TD
accTitle: Diagram of group inheritance for protected branches
accDescr: If a project is shared with a group, the group members inherit permissions for protected branches.
A[Parent group X] -->|owns| B[Project A]
A -->|contains| C[Subgroup Y]
B -->|shared with| C
C -->|members inherit permissions| B
Diagram 2
%%{init: { "fontFamily": "GitLab Sans" }}%%
graph LR
accTitle: Diagram of project sharing for protected branch permissions
accDescr: Sharing a project with a group affects whether their members can have protected branch permissions.
A[Parent group X] -->|owns| B[Project A]
A -->|also contains| C[Subgroup Y]
C -.->D{Share Project A<br/>with Subgroup Y?} -.->|yes| E[Members of Subgroup Y<br/>can have protected<br/>branch permissions]
D{Share Project A<br/>with Subgroup Y?} -.->|no| F[Members of Subgroup Y<br />cannot have protected<br/>branch permissions]
E -.->|Add Subgroup Y<br/> to protected branch settings| I[Subgroup Y members<br/>can merge/push] -.-> B
F -.-> |Add Subgroup Y<br/> to protected branch settings| J[Settings will not<br/>take effect] -.-> B
/doc/user/project/repository/branches/strategies/_index.md
Diagram 1
%%{init: { 'gitGraph': {'mainBranchOrder':1}} }%%
gitGraph
commit tag: "1.0" id: "release v1.0"
branch "feature-1"
commit id: "start feature-1"
checkout main
commit id: "start feature-2"
branch "feature-2" order: 3
checkout feature-1
commit id: "refine feature-1"
checkout main
merge feature-1 type: HIGHLIGHT id: "merge feature-1 into main"
checkout feature-2
commit id: "build feature 2"
merge main type: HIGHLIGHT id: "merge main into feature-2"
commit
checkout main
merge feature-2 tag: "1.1" type: HIGHLIGHT id: "release v1.1"
Diagram 2
%%{init: { 'gitGraph': {'mainBranchOrder':2}} }%%
gitGraph
commit tag: "1.0"
branch hotfix order: 1
checkout main
branch "2.0" order: 3
commit
checkout hotfix
commit id: "security bug"
commit id: "performance bug"
checkout "2.0"
branch feature-1 order: 4
commit id: "create feature 1"
checkout main
commit id: " "
checkout 2.0
merge feature-1 id:"merge feature-1" tag: "2.0 RC 1"
checkout main
merge hotfix tag: "1.1" type: HIGHLIGHT
checkout 2.0
merge main tag: "2.0 RC 2" type: HIGHLIGHT
branch feature-2 order: 5
commit id: "create feature 2"
commit id: "refine feature 2"
checkout 2.0
merge feature-2 id: "merge feature-2" tag: "2.0 RC 3"
checkout main
merge 2.0 tag: "2.0" type: HIGHLIGHT
Diagram 3
gitGraph
commit id: "start feature"
branch feature-1
checkout main
commit tag: "v1.1 RC1" id: "start testing"
branch test
checkout feature-1
commit id: "develop feature"
commit id: "refine feature"
checkout test
commit id: " " tag: "v1.1 RC1"
branch UAT
checkout UAT
commit tag: "v1.1"
checkout main
merge feature-1 id: "merge feature-1"
commit
/doc/user/workspace/gitlab_agent_configuration.md
Diagram 1
%%{init: {'theme':'neutral'}}%%
graph TD;
classDef active fill:lightgreen, stroke:#green, color:green, stroke-width:1px;
topGroup[Top-Level Group, allowed Agent 1]
subgroup1[Subgroup 1, allowed Agent 2]
subgroup2[Subgroup 2, allowed Agent 3]
wp(Workspace Project, Agent 1, 2 & 3 all available)
topGroup --> subgroup1
subgroup1 --> subgroup2
subgroup2 --> wp
class wp active;
/doc/user/workspace/set_up_gitlab_agent_and_proxies.md
Diagram 1
%%{init: {'theme':'neutral'}}%%
graph TD;
classDef active fill:lightgreen, stroke:#green, color:green, stroke-width:1px;
topGroup[Top-level group]
subGroup[Subgroup]
workspaceProject[Workspace project]
agentProject[Agent project]
workspaceAgent[Workspace agent]
topGroup --> subGroup
subGroup --> workspaceProject
subGroup --> agentProject
agentProject -.- workspaceAgent
class workspaceProject active;
Type code to view diagram:
info