Call the rename base repository API when changing a project's path
Overview
From #420755 (closed), we are now in a good position to use the new rename repository API exposed by the Container Registry to facilitate renaming projects (changing the project path) from Gitlab Rails.
Currently, we raise an error when the user attempts to change the project path of a project with existing container registry tags. With this new rename repository API endpoint, we can now allow the renaming of such projects and we use the new endpoint to update the project's resources in the container registry.
From #420755 (closed), we can also see that the new API endpoint exposes a dry-run function and we will use this to validate that we can continue with the rename operation.
A new function will be added to GitlabApiClient
in #423995 (closed) and this function will be the one that we will use to call the new rename repository API endpoint
Current Behaviour
In the UI, an Edit Project Page exists at https://gitlab.com/namespace/proj-path/edit
. This goes to the ProjectsController#update
function which calls Projects::UpdateService
. In the service, we have a validation and we raise an error when we are trying to rename a project with container registry tags.
def validate!
...
if renaming_project_with_container_registry_tags?
raise ValidationError, s_('UpdateProject|Cannot rename project because it contains container registry tags!')
end
...
end
Implementation Plan
First of all, we will put the changes behind a feature flag so we can roll it out gradually and toggle whenever we need/want to.
In the validate!
function, when the feature flag is on, instead of raising an error, we will call
the rename API endpoint on dry-run mode (to check that a dry-run can be successful). If the dry-run succeeds, after the validate!
function is called, we will call the rename API endpoint to do the actual renaming, otherwise, if the dry-run failed, we will raise an error.
# Note: pseudocode, variables and function names can still change :) feel free to suggest!
def execute
...
validate!
ContainerRegistry::GitlabApiClient.rename_base_repository_path(path)
...
end
def validate!
...
if renaming_project_with_container_registry_tags?
if Feature.enabled?(:call_rename_api_when_changing_project_path)
raise CannotRenameError unless ContainerRegistry::GitlabApiClient.rename_base_repository_path(path, dry_run: true)
else
raise ValidationError, s_('UpdateProject|Cannot rename project because it contains container registry tags!')
end
end
...
end
where ContainerRegistry::GitlabApiClient.rename_base_repository_path
will be added in #423995 (closed) and calls the rename API endpoint directly. If the operation fails (even when dry-run was successful), we will also raise an error and abort the rename.