/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