Douglas Barbosa Alexandre activity https://gitlab.com/dbalexandre 2026-03-16T22:32:21Z tag:gitlab.com,2026-03-16:5210284840 Douglas Barbosa Alexandre opened merge request !227564: Draft: Geo: Replicate DesignManagement::Action uploads at GitLab.org / GitLab 2026-03-16T22:32:21Z dbalexandre Douglas Barbosa Alexandre [email protected]

What does this MR do and why?

This code change adds support for replicating and verifying design management action uploads in GitLab's Geo feature (which keeps multiple GitLab instances synchronized).

The changes create a new database table to track the synchronization status of design files uploaded through GitLab's design management system. This includes adding verification states to ensure files are properly copied between different GitLab servers, along with checksums to verify file integrity.

The update also adds new monitoring metrics so administrators can track how many design uploads have been successfully synchronized, failed, or are pending verification across their GitLab instances. Additionally, it updates the API documentation to include these new design upload statistics in the Geo status reports.

This enhancement ensures that design files uploaded to GitLab projects are properly backed up and synchronized across multiple GitLab installations for disaster recovery and performance purposes.

References

Related to #589909

How to set up and validate locally

Prerequisites

1. Run database migrations

rails db:migrate # on the primary
rails db:migrate:geo # on the secondary

2. Enable the feature flags on the primary

# In Rails console on the primary
Feature.enable(:geo_design_management_action_upload_replication)
Feature.enable(:geo_design_management_action_upload_force_primary_checksumming)

3. Create test data on the primary

Upload a design to a project issue (e.g., attach an image via the Design Management tab on an issue). Alternatively, use the Rails console:

# In Rails console on the primary
project = Project.first
issue = project.issues.first || Issues::CreateService.new(container: project, current_user: User.first, params: { title: 'Test issue for designs' }).execute[:issue]

file = CarrierWaveStringFile.new_file(
  file_content: "Seeded design upload file in project #{project.full_path}",
  filename: 'seeded_design_upload.txt',
  content_type: 'text/plain'
)

UploadService.new(issue.design_collection, file, DesignManagement::DesignUploader).execute

Verify the upload exists in the design_management_action_uploads partition:

Geo::DesignManagementActionUpload.count
# Should be > 0

4. Verify checksumming on the primary

Wait for the verification worker to process, or trigger it manually:

# In Rails console on the primary
Geo::DesignManagementActionUpload.first.replicator.verify
Geo::DesignManagementActionUpload.first.design_management_action_upload_state.reload
Geo::DesignManagementActionUpload.first.design_management_action_upload_state.verification_state
# Should be 2 (verification_succeeded)

5. Verify replication on the secondary

Once the upload is created on the primary, Geo will automatically replicate it to the secondary. Check the sync status in the secondary Rails console:

# In Rails console on the secondary
Geo::DesignManagementActionUploadRegistry.count
# Should be > 0

registry = Geo::DesignManagementActionUploadRegistry.last
registry.state
# Should be 2 (synced)

If the registry is empty or not yet synced, you can manually trigger sync:

# In Rails console on the secondary
Geo::DesignManagementActionUploadReplicator.new(model_record_id: Geo::DesignManagementActionUpload.first.id).sync

6. Verify verification on the secondary

# In Rails console on the secondary
registry = Geo::DesignManagementActionUploadRegistry.last
registry.reload
registry.verification_state
# Should be 2 (verification_succeeded)

7. Test GraphQL API on the secondary

Note: You must be logged in as an admin user. Non-admin users will get null for Geo-related queries.

Note: When querying from the secondary's GraphQL explorer, add a custom header REQUEST_PATH with the value `/api/v4/geo/node_proxy/{node_id}/graphql

Open the GraphQL explorer on the secondary instance (http://<secondary-url>/-/graphql-explorer) and run:

query {
  geoNode {
    name
    primary
    designManagementActionUploadRegistries {
      nodes {
        id
        state
        verificationState
        designManagementActionUploadId
        lastSyncedAt
        verifiedAt
      }
    }
  }
}

Expected result: you should see registry entries with state: "SYNCED" and verificationState: "VERIFIED".

8. Verify Geo Sites API

Check the Geo Sites API includes the new design management action upload statistics:

curl --header "PRIVATE-TOKEN: <your-token>" "http://<primary-url>/api/v4/geo_sites/status"

Look for the new fields in the response:

  • design_management_action_uploads_count
  • design_management_action_uploads_checksummed_count
  • design_management_action_uploads_checksum_failed_count
  • design_management_action_uploads_synced_count
  • design_management_action_uploads_failed_count
  • design_management_action_uploads_registry_count
  • design_management_action_uploads_synced_in_percentage
  • design_management_action_uploads_verified_in_percentage

9. Verify Geo admin page

Visit /admin/geo/sites on the secondary and confirm that "Design Management Action Uploads" appears as a new data type with replication and verification progress.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

tag:gitlab.com,2026-03-16:5210275065 Douglas Barbosa Alexandre pushed new project branch 589909-geo-replicate-designmanagement-action-uploads-design_management_action_uploads at GitLab.org / GitLab 2026-03-16T22:27:51Z dbalexandre Douglas Barbosa Alexandre [email protected]

Douglas Barbosa Alexandre (96d30369) at 16 Mar 22:27

Geo: Replicate DesignManagement::Action uploads

... and 2 more commits

tag:gitlab.com,2026-03-16:5210139832 Douglas Barbosa Alexandre opened merge request !227556: Draft: Geo: Replicate User Uploads at GitLab.org / GitLab 2026-03-16T21:25:50Z dbalexandre Douglas Barbosa Alexandre [email protected]

What does this MR do and why?

This code change adds support for tracking and replicating user uploads in GitLab's Geo feature, which helps organizations maintain synchronized copies of their GitLab data across multiple locations.

The main additions include:

  1. New database table: Creates a "user_upload_states" table to track the verification status of user uploads, including when they were verified, any retry attempts, and checksums to ensure data integrity.

  2. Database structure: Adds proper indexing and foreign key relationships to efficiently query and maintain the verification states, with support for organization-based data sharding.

  3. GraphQL API updates: Extends the API to expose user upload registry information, allowing administrators to monitor replication status through GitLab's interface.

  4. Monitoring metrics: Adds Prometheus metrics to track user upload synchronization statistics like total uploads, successful verifications, and failed attempts across Geo sites.

  5. Documentation updates: Updates API documentation to include the new user upload tracking fields in Geo site status responses.

This enhancement ensures that user-uploaded files (like avatars, attachments, etc.) are properly replicated and verified across Geo sites, improving data consistency and reliability for organizations using GitLab's geographic replication feature.

References

Related to #589918

How to set up and validate locally

Prerequisites

1. Run database migrations

rails db:migrate # on the primary
rails db:migrate:geo # on the secondary

2. Enable the feature flags on the primary

# In Rails console on the primary
Feature.enable(:geo_user_upload_replication)
Feature.enable(:geo_user_upload_force_primary_checksumming)

3. Create test data on the primary

Upload a file to a user (e.g., update a user avatar). Alternatively, use the Rails console:

# In Rails console on the primary
user = User.first
file = CarrierWaveStringFile.new_file(
  file_content: "Seeded upload file for user #{user.username}",
  filename: 'seeded_upload.txt',
  content_type: 'text/plain'
)

UploadService.new(user, file, PersonalFileUploader).execute

Verify the upload exists in the user_uploads partition:

Geo::UserUpload.count
# Should be > 0

4. Verify checksumming on the primary

Wait for the verification worker to process, or trigger it manually:

# In Rails console on the primary
Geo::UserUpload.first.replicator.verify
Geo::UserUpload.first.user_upload_state.reload
Geo::UserUpload.first.user_upload_state.verification_state
# Should be 2 (verification_succeeded)

5. Verify replication on the secondary

Once the upload is created on the primary, Geo will automatically replicate it to the secondary. Check the sync status in the secondary Rails console:

# In Rails console on the secondary
Geo::UserUploadRegistry.count
# Should be > 0

registry = Geo::UserUploadRegistry.last
registry.state
# Should be 2 (synced)

If the registry is empty or not yet synced, you can manually trigger sync:

# In Rails console on the secondary
Geo::UserUploadReplicator.new(model_record_id: Geo::UserUpload.first.id).sync

6. Verify verification on the secondary

# In Rails console on the secondary
registry = Geo::UserUploadRegistry.last
registry.reload
registry.verification_state
# Should be 2 (verification_succeeded)

7. Test GraphQL API on the secondary

Note: You must be logged in as an admin user. Non-admin users will get null for Geo-related queries.

Note: When querying from the secondary's GraphQL explorer, add a custom header REQUEST_PATH with the value `/api/v4/geo/node_proxy/{node_id}/graphql

Open the GraphQL explorer on the secondary instance (http://<secondary-url>/-/graphql-explorer) and run:

query {
  geoNode {
    name
    primary
    userUploadRegistries {
      nodes {
        id
        state
        verificationState
        userUploadId
        lastSyncedAt
        verifiedAt
      }
    }
  }
}

Expected result: you should see registry entries with state: "SYNCED" and verificationState: "VERIFIED".

8. Verify Geo Sites API

Check the Geo Sites API includes the new user upload statistics:

curl --header "PRIVATE-TOKEN: <your-token>" "http://<primary-url>/api/v4/geo_sites/status"

Look for the new fields in the response:

  • user_uploads_count
  • user_uploads_checksummed_count
  • user_uploads_checksum_failed_count
  • user_uploads_synced_count
  • user_uploads_failed_count
  • user_uploads_registry_count
  • user_uploads_synced_in_percentage
  • user_uploads_verified_in_percentage

9. Verify Geo admin page

Visit /admin/geo/sites on the secondary and confirm that "User Uploads" appears as a new data type with replication and verification progress.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

tag:gitlab.com,2026-03-16:5210134705 Douglas Barbosa Alexandre pushed to project branch 589910-geo-replicate-group-uploads-namespace_uploads at GitLab.org / GitLab 2026-03-16T21:24:02Z dbalexandre Douglas Barbosa Alexandre [email protected]

Douglas Barbosa Alexandre (3d802589) at 16 Mar 21:24

Geo: Replicate Group Uploads

... and 2 more commits

tag:gitlab.com,2026-03-16:5210127390 Douglas Barbosa Alexandre pushed new project branch 589918-geo-replicate-user-uploads-user_uploads at GitLab.org / GitLab 2026-03-16T21:21:49Z dbalexandre Douglas Barbosa Alexandre [email protected]

Douglas Barbosa Alexandre (b56134f9) at 16 Mar 21:21

Geo: Replicate User Uploads

... and 1 more commit

tag:gitlab.com,2026-03-16:5210016582 Douglas Barbosa Alexandre commented on merge request !227188 at GitLab.org / GitLab 2026-03-16T20:40:02Z dbalexandre Douglas Barbosa Alexandre [email protected]

@nbelokolodov Could you do the analytics instrumentation review, please?

tag:gitlab.com,2026-03-16:5210016339 Douglas Barbosa Alexandre commented on merge request !227188 at GitLab.org / GitLab 2026-03-16T20:39:56Z dbalexandre Douglas Barbosa Alexandre [email protected]

@axil Could you do the technical writer review, please?

tag:gitlab.com,2026-03-16:5210015912 Douglas Barbosa Alexandre commented on merge request !227188 at GitLab.org / GitLab 2026-03-16T20:39:47Z dbalexandre Douglas Barbosa Alexandre [email protected]

@ahegyi Could you do the database maintainer review, please?

tag:gitlab.com,2026-03-16:5210015676 Douglas Barbosa Alexandre commented on merge request !227188 at GitLab.org / GitLab 2026-03-16T20:39:42Z dbalexandre Douglas Barbosa Alexandre [email protected]

@s_murray @mkozono will be on PTO from March 17 to 27. Do you mind taking over these MRS and doing the backend and groupgeo maintainer review, please?

Please note that there will be 20 more MRs like these. Ok to send them all to you?

tag:gitlab.com,2026-03-16:5210003829 Douglas Barbosa Alexandre commented on merge request !227186 at GitLab.org / GitLab 2026-03-16T20:35:32Z dbalexandre Douglas Barbosa Alexandre [email protected]

To make Rubocop happy. See https://docs.rubocop.org/rubocop-rails/latest/cops_rails.html#railsredundantforeignkey.

tag:gitlab.com,2026-03-16:5210001765 Douglas Barbosa Alexandre commented on merge request !227186 at GitLab.org / GitLab 2026-03-16T20:34:43Z dbalexandre Douglas Barbosa Alexandre [email protected]

I don't see anything wrong, but could you remind me what prompted this change?

To avoid an unnecessary join with the groups.

Does this def scope_method also need to change to namespace_id_in instead of group_id_in?

Good catch! I fixed it in !227188.

tag:gitlab.com,2026-03-16:5209859111 Douglas Barbosa Alexandre pushed to project branch 589910-geo-replicate-group-uploads-namespace_uploads at GitLab.org / GitLab 2026-03-16T19:42:43Z dbalexandre Douglas Barbosa Alexandre [email protected]

Douglas Barbosa Alexandre (64f58eb1) at 16 Mar 19:42

Geo: Replicate Group Uploads

... and 34 more commits

tag:gitlab.com,2026-03-16:5209232351 Douglas Barbosa Alexandre pushed to project branch 589910-geo-replicate-group-uploads-namespace_uploads at GitLab.org / GitLab 2026-03-16T16:35:22Z dbalexandre Douglas Barbosa Alexandre [email protected]

Douglas Barbosa Alexandre (ffe6a663) at 16 Mar 16:35

Geo: Replicate Group Uploads

... and 407 more commits

tag:gitlab.com,2026-03-13:5203212468 Douglas Barbosa Alexandre pushed to project branch 589910-geo-replicate-group-uploads-namespace_uploads at GitLab.org / GitLab 2026-03-13T23:56:18Z dbalexandre Douglas Barbosa Alexandre [email protected]

Douglas Barbosa Alexandre (1f6104d8) at 13 Mar 23:56

Geo: Replicate Group Uploads

... and 1 more commit

tag:gitlab.com,2026-03-13:5203206988 Douglas Barbosa Alexandre pushed to project branch 591313-generator-script at GitLab.org / GitLab 2026-03-13T23:51:33Z dbalexandre Douglas Barbosa Alexandre [email protected]

Douglas Barbosa Alexandre (ee041655) at 13 Mar 23:51

Make Rubocop happy

tag:gitlab.com,2026-03-13:5203056658 Douglas Barbosa Alexandre pushed to project branch 589910-geo-replicate-group-uploads-namespace_uploads at GitLab.org / GitLab 2026-03-13T22:01:35Z dbalexandre Douglas Barbosa Alexandre [email protected]

Douglas Barbosa Alexandre (4b666aab) at 13 Mar 22:01

Geo: Replicate Group Uploads

... and 2 more commits

tag:gitlab.com,2026-03-13:5203049742 Douglas Barbosa Alexandre pushed to project branch 591313-generator-script at GitLab.org / GitLab 2026-03-13T21:58:13Z dbalexandre Douglas Barbosa Alexandre [email protected]

Douglas Barbosa Alexandre (04e34334) at 13 Mar 21:58

Improve manual steps output

... and 1 more commit