feat: add recover option to mr create command
Description
This MR introduces a -recover
flag as discussed in #472 (closed). The intent is to save the glab mr create [OPTIONS]
into a file if the creation fails.
If the file exists, we try to load the contents into the issue options and attempt to create the MR again.
Related Issues
Related to Friendlier recovery when issue/mr create fails (#472 - closed)
How has this been tested?
The easiest way to test locally is to force a failure before creating the issue with the API:
-
Return an error early in commands/mr/create/mr_create.go#L480:
return errors.New("fail on purpose")
-
Build the binary with the deliberate error running
make
-
Use a test project, I'm using https://gitlab.com/jaime/glab-cli-tests for my tests. Check it out locally and
cd
into the location -
Once in the test location, use the
glab
binary that you built, e.g./Users/jaime/dev/gitlab/cli/bin/glab
-
Attempt to create an issue using the
-recover
flag and verify it failsglab mr create --recover --draft -f -t "add test files" Failed to create MR. Created recovery file: /Users/jaime/.config/glab-cli/recover/jaime/glab-cli-tests/mr.json Run the command again with the '--recover' option to retry fail on purpose
-
Verify the file exists and contains the correct details
Click to expand
cat /Users/jaime/.config/glab-cli/recover/jaime/glab-cli-tests/mr.json | jq
{
"title": "Draft: add test files",
"description": "- added test file \n- another file \n",
"source_branch": "test-mr-recovery",
"target_branch": "main",
"target_tracking_branch": "origin/main",
"autofill": true,
"is_draft": true,
"should_push": true,
"source_project": {
"id": 40768206,
"description": "",
"default_branch": "main",
"public": false,
"visibility": "public",
"ssh_url_to_repo": "git@gitlab.com:jaime/glab-cli-tests.git",
"http_url_to_repo": "https://gitlab.com/jaime/glab-cli-tests.git",
"web_url": "https://gitlab.com/jaime/glab-cli-tests",
"readme_url": "https://gitlab.com/jaime/glab-cli-tests/-/blob/main/README.md",
"tag_list": [],
"topics": [],
"owner": {
"id": 4082686,
"username": "jaime",
"email": "",
"name": "Jaime Martinez",
"state": "active",
"web_url": "https://gitlab.com/jaime",
"created_at": null,
"bio": "",
"bot": false,
"location": "",
"public_email": "",
"skype": "",
"linkedin": "",
"twitter": "",
"website_url": "",
"organization": "",
"job_title": "",
"extern_uid": "",
"provider": "",
"theme_id": 0,
"last_activity_on": null,
"color_scheme_id": 0,
"is_admin": false,
"avatar_url": "https://gitlab.com/uploads/-/system/user/avatar/4082686/avatar.png",
"can_create_group": false,
"can_create_project": false,
"projects_limit": 0,
"current_sign_in_at": null,
"current_sign_in_ip": null,
"last_sign_in_at": null,
"last_sign_in_ip": null,
"confirmed_at": null,
"two_factor_enabled": false,
"note": "",
"identities": null,
"external": false,
"private_profile": false,
"shared_runners_minutes_limit": 0,
"extra_shared_runners_minutes_limit": 0,
"using_license_seat": false,
"custom_attributes": null,
"namespace_id": 0
},
"name": "glab-cli-tests",
"name_with_namespace": "Jaime Martinez / glab-cli-tests",
"path": "glab-cli-tests",
"path_with_namespace": "jaime/glab-cli-tests",
"issues_enabled": true,
"open_issues_count": 9,
"merge_requests_enabled": true,
"approvals_before_merge": 0,
"jobs_enabled": true,
"wiki_enabled": true,
"snippets_enabled": true,
"resolve_outdated_diff_discussions": false,
"container_expiration_policy": {
"cadence": "1d",
"keep_n": 10,
"older_than": "90d",
"name_regex_delete": "",
"name_regex_keep": "",
"enabled": false,
"next_run_at": "2022-11-05T03:52:31.746Z"
},
"container_registry_enabled": true,
"container_registry_access_level": "enabled",
"container_registry_image_prefix": "registry.gitlab.com/jaime/glab-cli-tests",
"created_at": "2022-11-04T03:52:31.722Z",
"last_activity_at": "2022-12-04T00:10:22.585Z",
"creator_id": 4082686,
"namespace": {
"id": 5336147,
"name": "Jaime Martinez",
"path": "jaime",
"kind": "user",
"full_path": "jaime",
"parent_id": 0,
"avatar_url": "/uploads/-/system/user/avatar/4082686/avatar.png",
"web_url": "https://gitlab.com/jaime"
},
"import_status": "none",
"import_error": "",
"permissions": {
"project_access": {
"access_level": 50,
"notification_level": "global"
},
"group_access": null
},
"marked_for_deletion_at": null,
"empty_repo": false,
"archived": false,
"avatar_url": "",
"license_url": "",
"license": null,
"shared_runners_enabled": true,
"forks_count": 0,
"star_count": 0,
"runners_token": "GR1348941Kw1dgWxWtsBC5ffbmUvV",
"public_builds": false,
"allow_merge_on_skipped_pipeline": false,
"only_allow_merge_if_pipeline_succeeds": false,
"only_allow_merge_if_all_discussions_are_resolved": false,
"remove_source_branch_after_merge": true,
"printing_merge_request_link_enabled": true,
"lfs_enabled": true,
"repository_storage": "",
"request_access_enabled": true,
"merge_method": "merge",
"forked_from_project": null,
"mirror": false,
"mirror_user_id": 0,
"mirror_trigger_builds": false,
"only_mirror_protected_branches": false,
"mirror_overwrites_diverged_branches": false,
"packages_enabled": true,
"service_desk_enabled": true,
"service_desk_address": "contact-project+jaime-glab-cli-tests-40768206-issue-@incoming.gitlab.com",
"issues_access_level": "enabled",
"repository_access_level": "enabled",
"merge_requests_access_level": "enabled",
"forking_access_level": "enabled",
"wiki_access_level": "enabled",
"builds_access_level": "enabled",
"snippets_access_level": "enabled",
"pages_access_level": "enabled",
"operations_access_level": "enabled",
"analytics_access_level": "enabled",
"autoclose_referenced_issues": true,
"suggestion_commit_message": "",
"auto_cancel_pending_pipelines": "enabled",
"ci_forward_deployment_enabled": true,
"squash_option": "default_off",
"shared_with_groups": [],
"statistics": {
"commit_count": 1,
"storage_size": 73400,
"repository_size": 73400,
"wiki_size": 0,
"lfs_objects_size": 0,
"job_artifacts_size": 0,
"pipeline_artifacts_size": 0,
"packages_size": 0,
"snippets_size": 0,
"uploads_size": 0
},
"_links": {
"self": "https://gitlab.com/api/v4/projects/40768206",
"issues": "https://gitlab.com/api/v4/projects/40768206/issues",
"merge_requests": "https://gitlab.com/api/v4/projects/40768206/merge_requests",
"repo_branches": "https://gitlab.com/api/v4/projects/40768206/repository/branches",
"labels": "https://gitlab.com/api/v4/projects/40768206/labels",
"events": "https://gitlab.com/api/v4/projects/40768206/events",
"members": "https://gitlab.com/api/v4/projects/40768206/members"
},
"ci_config_path": "",
"ci_default_git_depth": 20,
"custom_attributes": null,
"compliance_frameworks": [],
"build_coverage_regex": "",
"build_timeout": 3600,
"issues_template": "",
"merge_requests_template": "",
"keep_latest_artifact": true,
"merge_pipelines_enabled": false,
"merge_trains_enabled": false,
"restrict_user_defined_variables": false,
"merge_commit_template": "",
"squash_commit_template": "",
"auto_devops_deploy_strategy": "continuous",
"auto_devops_enabled": false,
"build_git_strategy": "fetch",
"emails_disabled": false,
"external_authorization_classification_label": "",
"requirements_access_level": "enabled",
"security_and_compliance_access_level": "private"
},
"target_project": {
"id": 40768206,
"description": "",
"default_branch": "main",
"public": false,
"visibility": "public",
"ssh_url_to_repo": "git@gitlab.com:jaime/glab-cli-tests.git",
"http_url_to_repo": "https://gitlab.com/jaime/glab-cli-tests.git",
"web_url": "https://gitlab.com/jaime/glab-cli-tests",
"readme_url": "https://gitlab.com/jaime/glab-cli-tests/-/blob/main/README.md",
"tag_list": [],
"topics": [],
"owner": {
"id": 4082686,
"username": "jaime",
"email": "",
"name": "Jaime Martinez",
"state": "active",
"web_url": "https://gitlab.com/jaime",
"created_at": null,
"bio": "",
"bot": false,
"location": "",
"public_email": "",
"skype": "",
"linkedin": "",
"twitter": "",
"website_url": "",
"organization": "",
"job_title": "",
"extern_uid": "",
"provider": "",
"theme_id": 0,
"last_activity_on": null,
"color_scheme_id": 0,
"is_admin": false,
"avatar_url": "https://gitlab.com/uploads/-/system/user/avatar/4082686/avatar.png",
"can_create_group": false,
"can_create_project": false,
"projects_limit": 0,
"current_sign_in_at": null,
"current_sign_in_ip": null,
"last_sign_in_at": null,
"last_sign_in_ip": null,
"confirmed_at": null,
"two_factor_enabled": false,
"note": "",
"identities": null,
"external": false,
"private_profile": false,
"shared_runners_minutes_limit": 0,
"extra_shared_runners_minutes_limit": 0,
"using_license_seat": false,
"custom_attributes": null,
"namespace_id": 0
},
"name": "glab-cli-tests",
"name_with_namespace": "Jaime Martinez / glab-cli-tests",
"path": "glab-cli-tests",
"path_with_namespace": "jaime/glab-cli-tests",
"issues_enabled": true,
"open_issues_count": 9,
"merge_requests_enabled": true,
"approvals_before_merge": 0,
"jobs_enabled": true,
"wiki_enabled": true,
"snippets_enabled": true,
"resolve_outdated_diff_discussions": false,
"container_expiration_policy": {
"cadence": "1d",
"keep_n": 10,
"older_than": "90d",
"name_regex_delete": "",
"name_regex_keep": "",
"enabled": false,
"next_run_at": "2022-11-05T03:52:31.746Z"
},
"container_registry_enabled": true,
"container_registry_access_level": "enabled",
"container_registry_image_prefix": "registry.gitlab.com/jaime/glab-cli-tests",
"created_at": "2022-11-04T03:52:31.722Z",
"last_activity_at": "2022-12-04T00:10:22.585Z",
"creator_id": 4082686,
"namespace": {
"id": 5336147,
"name": "Jaime Martinez",
"path": "jaime",
"kind": "user",
"full_path": "jaime",
"parent_id": 0,
"avatar_url": "/uploads/-/system/user/avatar/4082686/avatar.png",
"web_url": "https://gitlab.com/jaime"
},
"import_status": "none",
"import_error": "",
"permissions": {
"project_access": {
"access_level": 50,
"notification_level": "global"
},
"group_access": null
},
"marked_for_deletion_at": null,
"empty_repo": false,
"archived": false,
"avatar_url": "",
"license_url": "",
"license": null,
"shared_runners_enabled": true,
"forks_count": 0,
"star_count": 0,
"runners_token": "GR1348941Kw1dgWxWtsBC5ffbmUvV",
"public_builds": false,
"allow_merge_on_skipped_pipeline": false,
"only_allow_merge_if_pipeline_succeeds": false,
"only_allow_merge_if_all_discussions_are_resolved": false,
"remove_source_branch_after_merge": true,
"printing_merge_request_link_enabled": true,
"lfs_enabled": true,
"repository_storage": "",
"request_access_enabled": true,
"merge_method": "merge",
"forked_from_project": null,
"mirror": false,
"mirror_user_id": 0,
"mirror_trigger_builds": false,
"only_mirror_protected_branches": false,
"mirror_overwrites_diverged_branches": false,
"packages_enabled": true,
"service_desk_enabled": true,
"service_desk_address": "contact-project+jaime-glab-cli-tests-40768206-issue-@incoming.gitlab.com",
"issues_access_level": "enabled",
"repository_access_level": "enabled",
"merge_requests_access_level": "enabled",
"forking_access_level": "enabled",
"wiki_access_level": "enabled",
"builds_access_level": "enabled",
"snippets_access_level": "enabled",
"pages_access_level": "enabled",
"operations_access_level": "enabled",
"analytics_access_level": "enabled",
"autoclose_referenced_issues": true,
"suggestion_commit_message": "",
"auto_cancel_pending_pipelines": "enabled",
"ci_forward_deployment_enabled": true,
"squash_option": "default_off",
"shared_with_groups": [],
"statistics": {
"commit_count": 1,
"storage_size": 73400,
"repository_size": 73400,
"wiki_size": 0,
"lfs_objects_size": 0,
"job_artifacts_size": 0,
"pipeline_artifacts_size": 0,
"packages_size": 0,
"snippets_size": 0,
"uploads_size": 0
},
"_links": {
"self": "https://gitlab.com/api/v4/projects/40768206",
"issues": "https://gitlab.com/api/v4/projects/40768206/issues",
"merge_requests": "https://gitlab.com/api/v4/projects/40768206/merge_requests",
"repo_branches": "https://gitlab.com/api/v4/projects/40768206/repository/branches",
"labels": "https://gitlab.com/api/v4/projects/40768206/labels",
"events": "https://gitlab.com/api/v4/projects/40768206/events",
"members": "https://gitlab.com/api/v4/projects/40768206/members"
},
"ci_config_path": "",
"ci_default_git_depth": 20,
"custom_attributes": null,
"compliance_frameworks": [],
"build_coverage_regex": "",
"build_timeout": 3600,
"issues_template": "",
"merge_requests_template": "",
"keep_latest_artifact": true,
"merge_pipelines_enabled": false,
"merge_trains_enabled": false,
"restrict_user_defined_variables": false,
"merge_commit_template": "",
"squash_commit_template": "",
"auto_devops_deploy_strategy": "continuous",
"auto_devops_enabled": false,
"build_git_strategy": "fetch",
"emails_disabled": false,
"external_authorization_classification_label": "",
"requirements_access_level": "enabled",
"security_and_compliance_access_level": "private"
}
}
-
Undo the first step by removing the error in commands/mr/create/mr_create.go#L480
-
Compile the binary again using
make
-
Try to create the issue again with the
-recover
flagglab mr create --recover Recovered create options from file ? What's next? Submit Total 0 (delta 0), reused 0 (delta 0), pack-reused 0 remote: remote: To create a merge request for test-2, visit: remote: https://gitlab.com/jaime/glab-cli-tests/-/merge_requests/new?merge_request%5Bsource_branch%5D=test-2 remote: To gitlab.com:jaime/glab-cli-tests.git * [new branch] HEAD -> test-2 branch 'test-2' set up to track 'origin/test-2'. Creating draft merge request for test-2 into main in jaime/glab-cli-tests !2 Draft: Draft: Draft: add test files (test-2) https://gitlab.com/jaime/glab-cli-tests/-/merge_requests/2
-
Voila! MR created and the recover file should have been removed
cat /Users/jaime/.config/glab-cli/recover/jaime/glab-cli-tests/mr.json | jq cat: /Users/jaime/.config/glab-cli/recover/jaime/glab-cli-tests/mr.json: No such file or directory
Screenshots (if appropriate):
Types of changes
-
Bug fix (non-breaking change which fixes an issue) -
New feature (non-breaking change which adds functionality) -
Breaking change (fix or feature that would cause existing functionality to change) -
Documentation -
Chore (Related to CI or Packaging to platforms)
Next steps
There is an existing issue to create integration tests for the --recover
option #1163
Closes #472 (closed)