Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
		
							parent
							
								
									7b8ec6e718
								
							
						
					
					
						commit
						0ff031c7f4
					
				|  | @ -19,69 +19,18 @@ export default { | ||||||
|   }, |   }, | ||||||
|   computed: { |   computed: { | ||||||
|     environment() { |     environment() { | ||||||
|       let environmentText; |  | ||||||
|       switch (this.deploymentStatus.status) { |       switch (this.deploymentStatus.status) { | ||||||
|         case 'last': |         case 'last': | ||||||
|           environmentText = sprintf( |           return this.lastEnvironmentMessage(); | ||||||
|             __('This job is the most recent deployment to %{link}.'), |  | ||||||
|             { link: this.environmentLink }, |  | ||||||
|             false, |  | ||||||
|           ); |  | ||||||
|           break; |  | ||||||
|         case 'out_of_date': |         case 'out_of_date': | ||||||
|           if (this.hasLastDeployment) { |           return this.outOfDateEnvironmentMessage(); | ||||||
|             environmentText = sprintf( |  | ||||||
|               __( |  | ||||||
|                 'This job is an out-of-date deployment to %{environmentLink}. View the most recent deployment %{deploymentLink}.', |  | ||||||
|               ), |  | ||||||
|               { |  | ||||||
|                 environmentLink: this.environmentLink, |  | ||||||
|                 deploymentLink: this.deploymentLink(`#${this.lastDeployment.iid}`), |  | ||||||
|               }, |  | ||||||
|               false, |  | ||||||
|             ); |  | ||||||
|           } else { |  | ||||||
|             environmentText = sprintf( |  | ||||||
|               __('This job is an out-of-date deployment to %{environmentLink}.'), |  | ||||||
|               { environmentLink: this.environmentLink }, |  | ||||||
|               false, |  | ||||||
|             ); |  | ||||||
|           } |  | ||||||
| 
 |  | ||||||
|           break; |  | ||||||
|         case 'failed': |         case 'failed': | ||||||
|           environmentText = sprintf( |           return this.failedEnvironmentMessage(); | ||||||
|             __('The deployment of this job to %{environmentLink} did not succeed.'), |  | ||||||
|             { environmentLink: this.environmentLink }, |  | ||||||
|             false, |  | ||||||
|           ); |  | ||||||
|           break; |  | ||||||
|         case 'creating': |         case 'creating': | ||||||
|           if (this.hasLastDeployment) { |           return this.creatingEnvironmentMessage(); | ||||||
|             environmentText = sprintf( |  | ||||||
|               __( |  | ||||||
|                 'This job is creating a deployment to %{environmentLink} and will overwrite the %{deploymentLink}.', |  | ||||||
|               ), |  | ||||||
|               { |  | ||||||
|                 environmentLink: this.environmentLink, |  | ||||||
|                 deploymentLink: this.deploymentLink(__('latest deployment')), |  | ||||||
|               }, |  | ||||||
|               false, |  | ||||||
|             ); |  | ||||||
|           } else { |  | ||||||
|             environmentText = sprintf( |  | ||||||
|               __('This job is creating a deployment to %{environmentLink}.'), |  | ||||||
|               { environmentLink: this.environmentLink }, |  | ||||||
|               false, |  | ||||||
|             ); |  | ||||||
|           } |  | ||||||
|           break; |  | ||||||
|         default: |         default: | ||||||
|           break; |           return ''; | ||||||
|       } |       } | ||||||
|       return environmentText && this.hasCluster |  | ||||||
|         ? `${environmentText} ${this.clusterText}` |  | ||||||
|         : environmentText; |  | ||||||
|     }, |     }, | ||||||
|     environmentLink() { |     environmentLink() { | ||||||
|       if (this.hasEnvironment) { |       if (this.hasEnvironment) { | ||||||
|  | @ -137,11 +86,6 @@ export default { | ||||||
|         false, |         false, | ||||||
|       ); |       ); | ||||||
|     }, |     }, | ||||||
|     clusterText() { |  | ||||||
|       return this.hasCluster |  | ||||||
|         ? sprintf(__('Cluster %{cluster} was used.'), { cluster: this.clusterNameOrLink }, false) |  | ||||||
|         : ''; |  | ||||||
|     }, |  | ||||||
|   }, |   }, | ||||||
|   methods: { |   methods: { | ||||||
|     deploymentLink(name) { |     deploymentLink(name) { | ||||||
|  | @ -155,6 +99,91 @@ export default { | ||||||
|         false, |         false, | ||||||
|       ); |       ); | ||||||
|     }, |     }, | ||||||
|  |     failedEnvironmentMessage() { | ||||||
|  |       const { environmentLink } = this; | ||||||
|  | 
 | ||||||
|  |       return sprintf( | ||||||
|  |         __('The deployment of this job to %{environmentLink} did not succeed.'), | ||||||
|  |         { environmentLink }, | ||||||
|  |         false, | ||||||
|  |       ); | ||||||
|  |     }, | ||||||
|  |     lastEnvironmentMessage() { | ||||||
|  |       const { environmentLink, clusterNameOrLink, hasCluster } = this; | ||||||
|  | 
 | ||||||
|  |       const message = hasCluster | ||||||
|  |         ? __('This job is deployed to %{environmentLink} using cluster %{clusterNameOrLink}.') | ||||||
|  |         : __('This job is deployed to %{environmentLink}.'); | ||||||
|  | 
 | ||||||
|  |       return sprintf(message, { environmentLink, clusterNameOrLink }, false); | ||||||
|  |     }, | ||||||
|  |     outOfDateEnvironmentMessage() { | ||||||
|  |       const { hasLastDeployment, hasCluster, environmentLink, clusterNameOrLink } = this; | ||||||
|  | 
 | ||||||
|  |       if (hasLastDeployment) { | ||||||
|  |         const message = hasCluster | ||||||
|  |           ? __( | ||||||
|  |               'This job is an out-of-date deployment to %{environmentLink} using cluster %{clusterNameOrLink}. View the %{deploymentLink}.', | ||||||
|  |             ) | ||||||
|  |           : __( | ||||||
|  |               'This job is an out-of-date deployment to %{environmentLink}. View the %{deploymentLink}.', | ||||||
|  |             ); | ||||||
|  | 
 | ||||||
|  |         return sprintf( | ||||||
|  |           message, | ||||||
|  |           { | ||||||
|  |             environmentLink, | ||||||
|  |             clusterNameOrLink, | ||||||
|  |             deploymentLink: this.deploymentLink(__('most recent deployment')), | ||||||
|  |           }, | ||||||
|  |           false, | ||||||
|  |         ); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       const message = hasCluster | ||||||
|  |         ? __( | ||||||
|  |             'This job is an out-of-date deployment to %{environmentLink} using cluster %{clusterNameOrLink}.', | ||||||
|  |           ) | ||||||
|  |         : __('This job is an out-of-date deployment to %{environmentLink}.'); | ||||||
|  | 
 | ||||||
|  |       return sprintf( | ||||||
|  |         message, | ||||||
|  |         { | ||||||
|  |           environmentLink, | ||||||
|  |           clusterNameOrLink, | ||||||
|  |         }, | ||||||
|  |         false, | ||||||
|  |       ); | ||||||
|  |     }, | ||||||
|  |     creatingEnvironmentMessage() { | ||||||
|  |       const { hasLastDeployment, hasCluster, environmentLink, clusterNameOrLink } = this; | ||||||
|  | 
 | ||||||
|  |       if (hasLastDeployment) { | ||||||
|  |         const message = hasCluster | ||||||
|  |           ? __( | ||||||
|  |               'This job is creating a deployment to %{environmentLink} using cluster %{clusterNameOrLink}. This will overwrite the %{deploymentLink}.', | ||||||
|  |             ) | ||||||
|  |           : __( | ||||||
|  |               'This job is creating a deployment to %{environmentLink}. This will overwrite the %{deploymentLink}.', | ||||||
|  |             ); | ||||||
|  | 
 | ||||||
|  |         return sprintf( | ||||||
|  |           message, | ||||||
|  |           { | ||||||
|  |             environmentLink, | ||||||
|  |             clusterNameOrLink, | ||||||
|  |             deploymentLink: this.deploymentLink(__('latest deployment')), | ||||||
|  |           }, | ||||||
|  |           false, | ||||||
|  |         ); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       return sprintf( | ||||||
|  |         __('This job is creating a deployment to %{environmentLink}.'), | ||||||
|  |         { environmentLink }, | ||||||
|  |         false, | ||||||
|  |       ); | ||||||
|  |     }, | ||||||
|   }, |   }, | ||||||
| }; | }; | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
|  | @ -57,8 +57,7 @@ module AtomicInternalId | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       define_method("track_#{scope}_#{column}!") do |       define_method("track_#{scope}_#{column}!") do | ||||||
|         iid_always_track = Feature.enabled?(:iid_always_track, default_enabled: true) |         return unless @internal_id_needs_tracking | ||||||
|         return unless @internal_id_needs_tracking || iid_always_track |  | ||||||
| 
 | 
 | ||||||
|         scope_value = internal_id_read_scope(scope) |         scope_value = internal_id_read_scope(scope) | ||||||
|         return unless scope_value |         return unless scope_value | ||||||
|  |  | ||||||
|  | @ -54,7 +54,7 @@ class InternalId < ApplicationRecord | ||||||
|     last_value |     last_value | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   # Temporary instrumentation to track for-update locks |   # Instrumentation to track for-update locks | ||||||
|   def update_and_save_counter |   def update_and_save_counter | ||||||
|     strong_memoize(:update_and_save_counter) do |     strong_memoize(:update_and_save_counter) do | ||||||
|       Gitlab::Metrics.counter(:gitlab_internal_id_for_update_lock, 'Number of ROW SHARE (FOR UPDATE) locks on individual records from internal_ids') |       Gitlab::Metrics.counter(:gitlab_internal_id_for_update_lock, 'Number of ROW SHARE (FOR UPDATE) locks on individual records from internal_ids') | ||||||
|  |  | ||||||
|  | @ -16,9 +16,7 @@ | ||||||
|       %thead |       %thead | ||||||
|         %tr |         %tr | ||||||
|           %th |           %th | ||||||
|             = s_("ProtectedBranch|Protected branch (%{protected_branches_count})") % { protected_branches_count: @protected_branches_count } |             = s_("ProtectedBranch|Branch") | ||||||
|           %th |  | ||||||
|             = s_("ProtectedBranch|Last commit") |  | ||||||
|           %th |           %th | ||||||
|             = s_("ProtectedBranch|Allowed to merge") |             = s_("ProtectedBranch|Allowed to merge") | ||||||
|           %th |           %th | ||||||
|  |  | ||||||
|  | @ -5,17 +5,14 @@ | ||||||
|     %span.ref-name= protected_branch.name |     %span.ref-name= protected_branch.name | ||||||
| 
 | 
 | ||||||
|     - if @project.root_ref?(protected_branch.name) |     - if @project.root_ref?(protected_branch.name) | ||||||
|       %span.badge.badge-info.prepend-left-5 default |       %span.badge.badge-info.d-inline default | ||||||
|   %td | 
 | ||||||
|     - if protected_branch.wildcard? |     %div | ||||||
|       - matching_branches = protected_branch.matching(repository.branches) |       - if protected_branch.wildcard? | ||||||
|       = link_to pluralize(matching_branches.count, "matching branch"), namespace_project_protected_branch_path(@project.namespace, @project, protected_branch) |         - matching_branches = protected_branch.matching(repository.branches) | ||||||
|     - else |         = link_to pluralize(matching_branches.count, "matching branch"), namespace_project_protected_branch_path(@project.namespace, @project, protected_branch) | ||||||
|       - if commit = protected_branch.commit |       - elsif !protected_branch.commit | ||||||
|         = link_to(commit.short_id, namespace_project_commit_path(@project.namespace, @project, commit.id), class: 'commit-sha') |         %span.text-muted Branch was deleted. | ||||||
|         = time_ago_with_tooltip(commit.committed_date) |  | ||||||
|       - else |  | ||||||
|         (branch was deleted from repository) |  | ||||||
| 
 | 
 | ||||||
|   = yield |   = yield | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,5 @@ | ||||||
|  | --- | ||||||
|  | title: Update cluster link text | ||||||
|  | merge_request: 18322 | ||||||
|  | author: | ||||||
|  | type: changed | ||||||
|  | @ -0,0 +1,5 @@ | ||||||
|  | --- | ||||||
|  | title: Add matching branch info to branch column | ||||||
|  | merge_request: 18352 | ||||||
|  | author: | ||||||
|  | type: added | ||||||
|  | @ -0,0 +1,5 @@ | ||||||
|  | --- | ||||||
|  | title: Avoid unnecessary locks on internal_ids | ||||||
|  | merge_request: 18328 | ||||||
|  | author: | ||||||
|  | type: performance | ||||||
|  | @ -47,6 +47,8 @@ to be enabled: | ||||||
|   when an issue is deleted. |   when an issue is deleted. | ||||||
| - Design Management | - Design Management | ||||||
|   [isn't supported by Geo](https://gitlab.com/groups/gitlab-org/-/epics/1633) yet. |   [isn't supported by Geo](https://gitlab.com/groups/gitlab-org/-/epics/1633) yet. | ||||||
|  | - Only the latest version of the designs can be deleted. | ||||||
|  | - Deleted designs cannot be recovered but you can see them on previous designs versions. | ||||||
| 
 | 
 | ||||||
| ## The Design Management page | ## The Design Management page | ||||||
| 
 | 
 | ||||||
|  | @ -77,6 +79,34 @@ to help summarize changes between versions. | ||||||
| | Modified (in the selected version) |  | | | Modified (in the selected version) |  | | ||||||
| | Added (in the selected version) |  | | | Added (in the selected version) |  | | ||||||
| 
 | 
 | ||||||
|  | ## Deleting designs | ||||||
|  | 
 | ||||||
|  | > [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/11089) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.4. | ||||||
|  | 
 | ||||||
|  | There are two ways to delete designs: manually delete them | ||||||
|  | individually, or select a few of them to delete at once, | ||||||
|  | as shown below. | ||||||
|  | 
 | ||||||
|  | To delete a single design, click it to view it enlarged, | ||||||
|  | then click the trash icon on the top right corner and confirm | ||||||
|  | the deletion by clicking the **Delete** button on the modal window: | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | To delete multiple designs at once, on the design's list view, | ||||||
|  | first select the designs you want to delete: | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | Once selected, click the **Delete selected** button to confirm the deletion: | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | 
 | ||||||
|  | NOTE: **Note:** | ||||||
|  | Only the latest version of the designs can be deleted. | ||||||
|  | Deleted designs are not permanently lost; they can be | ||||||
|  | viewed by browsing previous versions. | ||||||
|  | 
 | ||||||
| ## Adding annotations to designs | ## Adding annotations to designs | ||||||
| 
 | 
 | ||||||
| When a design image is displayed, you can add annotations to it by clicking on | When a design image is displayed, you can add annotations to it by clicking on | ||||||
|  |  | ||||||
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 743 KiB | 
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 1.3 MiB | 
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 2.7 MiB | 
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 1.3 MiB | 
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 1.3 MiB | 
|  | @ -3348,9 +3348,6 @@ msgstr "" | ||||||
| msgid "Closes this %{quick_action_target}." | msgid "Closes this %{quick_action_target}." | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
| msgid "Cluster %{cluster} was used." |  | ||||||
| msgstr "" |  | ||||||
| 
 |  | ||||||
| msgid "Cluster Health" | msgid "Cluster Health" | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  | @ -5448,6 +5445,9 @@ msgstr "" | ||||||
| msgid "DesignManagement|An error occurred while loading designs. Please try again." | msgid "DesignManagement|An error occurred while loading designs. Please try again." | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  | msgid "DesignManagement|Are you sure you want to delete the selected designs?" | ||||||
|  | msgstr "" | ||||||
|  | 
 | ||||||
| msgid "DesignManagement|Could not add a new comment. Please try again" | msgid "DesignManagement|Could not add a new comment. Please try again" | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  | @ -5457,6 +5457,18 @@ msgstr "" | ||||||
| msgid "DesignManagement|Could not find design, please try again." | msgid "DesignManagement|Could not find design, please try again." | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  | msgid "DesignManagement|Delete" | ||||||
|  | msgstr "" | ||||||
|  | 
 | ||||||
|  | msgid "DesignManagement|Delete designs confirmation" | ||||||
|  | msgstr "" | ||||||
|  | 
 | ||||||
|  | msgid "DesignManagement|Delete selected" | ||||||
|  | msgstr "" | ||||||
|  | 
 | ||||||
|  | msgid "DesignManagement|Deselect all" | ||||||
|  | msgstr "" | ||||||
|  | 
 | ||||||
| msgid "DesignManagement|Error uploading a new design. Please try again" | msgid "DesignManagement|Error uploading a new design. Please try again" | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  | @ -5475,6 +5487,9 @@ msgstr "" | ||||||
| msgid "DesignManagement|Requested design version does not exist. Showing latest version instead" | msgid "DesignManagement|Requested design version does not exist. Showing latest version instead" | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  | msgid "DesignManagement|Select all" | ||||||
|  | msgstr "" | ||||||
|  | 
 | ||||||
| msgid "DesignManagement|The maximum number of designs allowed to be uploaded is %{upload_limit}. Please try again." | msgid "DesignManagement|The maximum number of designs allowed to be uploaded is %{upload_limit}. Please try again." | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  | @ -5484,6 +5499,9 @@ msgstr "" | ||||||
| msgid "DesignManagement|Upload and view the latest designs for this issue. Consistent and easy to find, so everyone is up to date." | msgid "DesignManagement|Upload and view the latest designs for this issue. Consistent and easy to find, so everyone is up to date." | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  | msgid "DesignManagement|We could not delete design(s). Please try again." | ||||||
|  | msgstr "" | ||||||
|  | 
 | ||||||
| msgid "Designs" | msgid "Designs" | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  | @ -13088,10 +13106,10 @@ msgstr "" | ||||||
| msgid "ProtectedBranch|Allowed to push:" | msgid "ProtectedBranch|Allowed to push:" | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
| msgid "ProtectedBranch|Code owner approval" | msgid "ProtectedBranch|Branch" | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
| msgid "ProtectedBranch|Last commit" | msgid "ProtectedBranch|Code owner approval" | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
| msgid "ProtectedBranch|Protect" | msgid "ProtectedBranch|Protect" | ||||||
|  | @ -14369,6 +14387,9 @@ msgstr "" | ||||||
| msgid "Security Reports|Dismissed '%{vulnerabilityName}'" | msgid "Security Reports|Dismissed '%{vulnerabilityName}'" | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  | msgid "Security Reports|Dismissed '%{vulnerabilityName}'. Turn off the hide dismissed toggle to view." | ||||||
|  | msgstr "" | ||||||
|  | 
 | ||||||
| msgid "Security Reports|Either you don't have permission to view this dashboard or the dashboard has not been setup. Please check your permission settings with your administrator or check your dashboard configurations to proceed." | msgid "Security Reports|Either you don't have permission to view this dashboard or the dashboard has not been setup. Please check your permission settings with your administrator or check your dashboard configurations to proceed." | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  | @ -16662,21 +16683,36 @@ msgstr "" | ||||||
| msgid "This job has not started yet" | msgid "This job has not started yet" | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  | msgid "This job is an out-of-date deployment to %{environmentLink} using cluster %{clusterNameOrLink}." | ||||||
|  | msgstr "" | ||||||
|  | 
 | ||||||
|  | msgid "This job is an out-of-date deployment to %{environmentLink} using cluster %{clusterNameOrLink}. View the %{deploymentLink}." | ||||||
|  | msgstr "" | ||||||
|  | 
 | ||||||
| msgid "This job is an out-of-date deployment to %{environmentLink}." | msgid "This job is an out-of-date deployment to %{environmentLink}." | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
| msgid "This job is an out-of-date deployment to %{environmentLink}. View the most recent deployment %{deploymentLink}." | msgid "This job is an out-of-date deployment to %{environmentLink}. View the %{deploymentLink}." | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
| msgid "This job is archived. Only the complete pipeline can be retried." | msgid "This job is archived. Only the complete pipeline can be retried." | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
| msgid "This job is creating a deployment to %{environmentLink} and will overwrite the %{deploymentLink}." | msgid "This job is creating a deployment to %{environmentLink} using cluster %{clusterNameOrLink}. This will overwrite the %{deploymentLink}." | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
| msgid "This job is creating a deployment to %{environmentLink}." | msgid "This job is creating a deployment to %{environmentLink}." | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  | msgid "This job is creating a deployment to %{environmentLink}. This will overwrite the %{deploymentLink}." | ||||||
|  | msgstr "" | ||||||
|  | 
 | ||||||
|  | msgid "This job is deployed to %{environmentLink} using cluster %{clusterNameOrLink}." | ||||||
|  | msgstr "" | ||||||
|  | 
 | ||||||
|  | msgid "This job is deployed to %{environmentLink}." | ||||||
|  | msgstr "" | ||||||
|  | 
 | ||||||
| msgid "This job is in pending state and is waiting to be picked by a runner" | msgid "This job is in pending state and is waiting to be picked by a runner" | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  | @ -16692,9 +16728,6 @@ msgstr "" | ||||||
| msgid "This job is stuck because you don't have any active runners that can run this job." | msgid "This job is stuck because you don't have any active runners that can run this job." | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
| msgid "This job is the most recent deployment to %{link}." |  | ||||||
| msgstr "" |  | ||||||
| 
 |  | ||||||
| msgid "This job requires a manual action" | msgid "This job requires a manual action" | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  | @ -19713,6 +19746,9 @@ msgstr "" | ||||||
| msgid "missing" | msgid "missing" | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  | msgid "most recent deployment" | ||||||
|  | msgstr "" | ||||||
|  | 
 | ||||||
| msgid "mrWidgetCommitsAdded|%{commitCount} and %{mergeCommitCount} will be added to %{targetBranch}." | msgid "mrWidgetCommitsAdded|%{commitCount} and %{mergeCommitCount} will be added to %{targetBranch}." | ||||||
| msgstr "" | msgstr "" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -534,7 +534,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
|         it 'shows deployment message' do |         it 'shows deployment message' do | ||||||
|           expect(page).to have_content 'This job is the most recent deployment to production' |           expect(page).to have_content 'This job is deployed to production' | ||||||
|           expect(find('.js-environment-link')['href']).to match("environments/#{environment.id}") |           expect(find('.js-environment-link')['href']).to match("environments/#{environment.id}") | ||||||
|         end |         end | ||||||
| 
 | 
 | ||||||
|  | @ -548,14 +548,14 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do | ||||||
|           end |           end | ||||||
| 
 | 
 | ||||||
|           it 'shows the name of the cluster' do |           it 'shows the name of the cluster' do | ||||||
|             expect(page).to have_content 'Cluster the-cluster was used' |             expect(page).to have_content 'using cluster the-cluster' | ||||||
|           end |           end | ||||||
| 
 | 
 | ||||||
|           context 'when the user is not able to view the cluster' do |           context 'when the user is not able to view the cluster' do | ||||||
|             let(:user_access_level) { :developer } |             let(:user_access_level) { :developer } | ||||||
| 
 | 
 | ||||||
|             it 'includes only the name of the cluster without a link' do |             it 'includes only the name of the cluster without a link' do | ||||||
|               expect(page).to have_content 'Cluster the-cluster was used' |               expect(page).to have_content 'using cluster the-cluster' | ||||||
|               expect(page).not_to have_link 'the-cluster' |               expect(page).not_to have_link 'the-cluster' | ||||||
|             end |             end | ||||||
|           end |           end | ||||||
|  | @ -623,8 +623,7 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do | ||||||
|         let!(:second_deployment) { create(:deployment, :success, environment: environment, deployable: second_build) } |         let!(:second_deployment) { create(:deployment, :success, environment: environment, deployable: second_build) } | ||||||
| 
 | 
 | ||||||
|         it 'shows deployment message' do |         it 'shows deployment message' do | ||||||
|           expected_text = 'This job is an out-of-date deployment ' \ |           expected_text = 'This job is an out-of-date deployment to staging. View the most recent deployment.' | ||||||
|             "to staging. View the most recent deployment ##{second_deployment.iid}." |  | ||||||
| 
 | 
 | ||||||
|           expect(page).to have_css('.environment-information', text: expected_text) |           expect(page).to have_css('.environment-information', text: expected_text) | ||||||
|         end |         end | ||||||
|  |  | ||||||
|  | @ -92,7 +92,10 @@ describe 'Protected Branches', :js do | ||||||
|         set_protected_branch_name('some-branch') |         set_protected_branch_name('some-branch') | ||||||
|         click_on "Protect" |         click_on "Protect" | ||||||
| 
 | 
 | ||||||
|         within(".protected-branches-list") { expect(page).to have_content(commit.id[0..7]) } |         within(".protected-branches-list") do | ||||||
|  |           expect(page).not_to have_content("matching") | ||||||
|  |           expect(page).not_to have_content("was deleted") | ||||||
|  |         end | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       it "displays an error message if the named branch does not exist" do |       it "displays an error message if the named branch does not exist" do | ||||||
|  | @ -101,7 +104,7 @@ describe 'Protected Branches', :js do | ||||||
|         set_protected_branch_name('some-branch') |         set_protected_branch_name('some-branch') | ||||||
|         click_on "Protect" |         click_on "Protect" | ||||||
| 
 | 
 | ||||||
|         within(".protected-branches-list") { expect(page).to have_content('branch was deleted') } |         within(".protected-branches-list") { expect(page).to have_content('Branch was deleted') } | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|  | @ -127,7 +130,6 @@ describe 'Protected Branches', :js do | ||||||
|         click_on "Protect" |         click_on "Protect" | ||||||
| 
 | 
 | ||||||
|         within(".protected-branches-list") do |         within(".protected-branches-list") do | ||||||
|           expect(page).to have_content("Protected branch (2)") |  | ||||||
|           expect(page).to have_content("2 matching branches") |           expect(page).to have_content("2 matching branches") | ||||||
|         end |         end | ||||||
|       end |       end | ||||||
|  |  | ||||||
|  | @ -2,6 +2,9 @@ import Vue from 'vue'; | ||||||
| import component from '~/jobs/components/environments_block.vue'; | import component from '~/jobs/components/environments_block.vue'; | ||||||
| import mountComponent from '../../helpers/vue_mount_component_helper'; | import mountComponent from '../../helpers/vue_mount_component_helper'; | ||||||
| 
 | 
 | ||||||
|  | const TEST_CLUSTER_NAME = 'test_cluster'; | ||||||
|  | const TEST_CLUSTER_PATH = 'path/to/test_cluster'; | ||||||
|  | 
 | ||||||
| describe('Environments block', () => { | describe('Environments block', () => { | ||||||
|   const Component = Vue.extend(component); |   const Component = Vue.extend(component); | ||||||
|   let vm; |   let vm; | ||||||
|  | @ -20,22 +23,53 @@ describe('Environments block', () => { | ||||||
| 
 | 
 | ||||||
|   const lastDeployment = { iid: 'deployment', deployable: { build_path: 'bar' } }; |   const lastDeployment = { iid: 'deployment', deployable: { build_path: 'bar' } }; | ||||||
| 
 | 
 | ||||||
|  |   const createEnvironmentWithLastDeployment = () => ({ | ||||||
|  |     ...environment, | ||||||
|  |     last_deployment: { ...lastDeployment }, | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   const createEnvironmentWithCluster = () => ({ | ||||||
|  |     ...environment, | ||||||
|  |     last_deployment: { | ||||||
|  |       ...lastDeployment, | ||||||
|  |       cluster: { name: TEST_CLUSTER_NAME, path: TEST_CLUSTER_PATH }, | ||||||
|  |     }, | ||||||
|  |   }); | ||||||
|  | 
 | ||||||
|  |   const createComponent = (deploymentStatus = {}) => { | ||||||
|  |     vm = mountComponent(Component, { | ||||||
|  |       deploymentStatus, | ||||||
|  |       iconStatus: status, | ||||||
|  |     }); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const findText = () => vm.$el.textContent.trim(); | ||||||
|  |   const findJobDeploymentLink = () => vm.$el.querySelector('.js-job-deployment-link'); | ||||||
|  |   const findEnvironmentLink = () => vm.$el.querySelector('.js-environment-link'); | ||||||
|  |   const findClusterLink = () => vm.$el.querySelector('.js-job-cluster-link'); | ||||||
|  | 
 | ||||||
|   afterEach(() => { |   afterEach(() => { | ||||||
|     vm.$destroy(); |     vm.$destroy(); | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   describe('with last deployment', () => { |   describe('with last deployment', () => { | ||||||
|     it('renders info for most recent deployment', () => { |     it('renders info for most recent deployment', () => { | ||||||
|       vm = mountComponent(Component, { |       createComponent({ | ||||||
|         deploymentStatus: { |         status: 'last', | ||||||
|           status: 'last', |         environment, | ||||||
|           environment, |  | ||||||
|         }, |  | ||||||
|         iconStatus: status, |  | ||||||
|       }); |       }); | ||||||
| 
 | 
 | ||||||
|       expect(vm.$el.textContent.trim()).toEqual( |       expect(findText()).toEqual('This job is deployed to environment.'); | ||||||
|         'This job is the most recent deployment to environment.', |     }); | ||||||
|  | 
 | ||||||
|  |     it('renders info with cluster', () => { | ||||||
|  |       createComponent({ | ||||||
|  |         status: 'last', | ||||||
|  |         environment: createEnvironmentWithCluster(), | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       expect(findText()).toEqual( | ||||||
|  |         `This job is deployed to environment using cluster ${TEST_CLUSTER_NAME}.`, | ||||||
|       ); |       ); | ||||||
|     }); |     }); | ||||||
|   }); |   }); | ||||||
|  | @ -43,133 +77,106 @@ describe('Environments block', () => { | ||||||
|   describe('with out of date deployment', () => { |   describe('with out of date deployment', () => { | ||||||
|     describe('with last deployment', () => { |     describe('with last deployment', () => { | ||||||
|       it('renders info for out date and most recent', () => { |       it('renders info for out date and most recent', () => { | ||||||
|         vm = mountComponent(Component, { |         createComponent({ | ||||||
|           deploymentStatus: { |           status: 'out_of_date', | ||||||
|             status: 'out_of_date', |           environment: createEnvironmentWithLastDeployment(), | ||||||
|             environment: Object.assign({}, environment, { |  | ||||||
|               last_deployment: lastDeployment, |  | ||||||
|             }), |  | ||||||
|           }, |  | ||||||
|           iconStatus: status, |  | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         expect(vm.$el.textContent.trim()).toEqual( |         expect(findText()).toEqual( | ||||||
|           'This job is an out-of-date deployment to environment. View the most recent deployment #deployment.', |           'This job is an out-of-date deployment to environment. View the most recent deployment.', | ||||||
|         ); |         ); | ||||||
| 
 | 
 | ||||||
|         expect(vm.$el.querySelector('.js-job-deployment-link').getAttribute('href')).toEqual('bar'); |         expect(findJobDeploymentLink().getAttribute('href')).toEqual('bar'); | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       it('renders info with cluster', () => { | ||||||
|  |         createComponent({ | ||||||
|  |           status: 'out_of_date', | ||||||
|  |           environment: createEnvironmentWithCluster(), | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |         expect(findText()).toEqual( | ||||||
|  |           `This job is an out-of-date deployment to environment using cluster ${TEST_CLUSTER_NAME}. View the most recent deployment.`, | ||||||
|  |         ); | ||||||
|       }); |       }); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     describe('without last deployment', () => { |     describe('without last deployment', () => { | ||||||
|       it('renders info about out of date deployment', () => { |       it('renders info about out of date deployment', () => { | ||||||
|         vm = mountComponent(Component, { |         createComponent({ | ||||||
|           deploymentStatus: { |           status: 'out_of_date', | ||||||
|             status: 'out_of_date', |           environment, | ||||||
|             environment, |  | ||||||
|           }, |  | ||||||
|           iconStatus: status, |  | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         expect(vm.$el.textContent.trim()).toEqual( |         expect(findText()).toEqual('This job is an out-of-date deployment to environment.'); | ||||||
|           'This job is an out-of-date deployment to environment.', |  | ||||||
|         ); |  | ||||||
|       }); |       }); | ||||||
|     }); |     }); | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   describe('with failed deployment', () => { |   describe('with failed deployment', () => { | ||||||
|     it('renders info about failed deployment', () => { |     it('renders info about failed deployment', () => { | ||||||
|       vm = mountComponent(Component, { |       createComponent({ | ||||||
|         deploymentStatus: { |         status: 'failed', | ||||||
|           status: 'failed', |         environment, | ||||||
|           environment, |  | ||||||
|         }, |  | ||||||
|         iconStatus: status, |  | ||||||
|       }); |       }); | ||||||
| 
 | 
 | ||||||
|       expect(vm.$el.textContent.trim()).toEqual( |       expect(findText()).toEqual('The deployment of this job to environment did not succeed.'); | ||||||
|         'The deployment of this job to environment did not succeed.', |  | ||||||
|       ); |  | ||||||
|     }); |     }); | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   describe('creating deployment', () => { |   describe('creating deployment', () => { | ||||||
|     describe('with last deployment', () => { |     describe('with last deployment', () => { | ||||||
|       it('renders info about creating deployment and overriding latest deployment', () => { |       it('renders info about creating deployment and overriding latest deployment', () => { | ||||||
|         vm = mountComponent(Component, { |         createComponent({ | ||||||
|           deploymentStatus: { |           status: 'creating', | ||||||
|             status: 'creating', |           environment: createEnvironmentWithLastDeployment(), | ||||||
|             environment: Object.assign({}, environment, { |  | ||||||
|               last_deployment: lastDeployment, |  | ||||||
|             }), |  | ||||||
|           }, |  | ||||||
|           iconStatus: status, |  | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         expect(vm.$el.textContent.trim()).toEqual( |         expect(findText()).toEqual( | ||||||
|           'This job is creating a deployment to environment and will overwrite the latest deployment.', |           'This job is creating a deployment to environment. This will overwrite the latest deployment.', | ||||||
|         ); |         ); | ||||||
| 
 | 
 | ||||||
|         expect(vm.$el.querySelector('.js-job-deployment-link').getAttribute('href')).toEqual('bar'); |         expect(findJobDeploymentLink().getAttribute('href')).toEqual('bar'); | ||||||
|  |         expect(findEnvironmentLink().getAttribute('href')).toEqual(environment.environment_path); | ||||||
|  |         expect(findClusterLink()).toBeNull(); | ||||||
|       }); |       }); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     describe('without last deployment', () => { |     describe('without last deployment', () => { | ||||||
|       it('renders info about failed deployment', () => { |       it('renders info about failed deployment', () => { | ||||||
|         vm = mountComponent(Component, { |         createComponent({ | ||||||
|           deploymentStatus: { |           status: 'creating', | ||||||
|             status: 'creating', |           environment, | ||||||
|             environment, |  | ||||||
|           }, |  | ||||||
|           iconStatus: status, |  | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         expect(vm.$el.textContent.trim()).toEqual( |         expect(findText()).toEqual('This job is creating a deployment to environment.'); | ||||||
|           'This job is creating a deployment to environment.', |  | ||||||
|         ); |  | ||||||
|       }); |       }); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     describe('without environment', () => { |     describe('without environment', () => { | ||||||
|       it('does not render environment link', () => { |       it('does not render environment link', () => { | ||||||
|         vm = mountComponent(Component, { |         createComponent({ | ||||||
|           deploymentStatus: { |           status: 'creating', | ||||||
|             status: 'creating', |           environment: null, | ||||||
|             environment: null, |  | ||||||
|           }, |  | ||||||
|           iconStatus: status, |  | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         expect(vm.$el.querySelector('.js-environment-link')).toBeNull(); |         expect(findEnvironmentLink()).toBeNull(); | ||||||
|       }); |       }); | ||||||
|     }); |     }); | ||||||
|   }); |   }); | ||||||
| 
 | 
 | ||||||
|   describe('with a cluster', () => { |   describe('with a cluster', () => { | ||||||
|     it('renders the cluster link', () => { |     it('renders the cluster link', () => { | ||||||
|       const cluster = { |       createComponent({ | ||||||
|         name: 'the-cluster', |         status: 'last', | ||||||
|         path: '/the-cluster-path', |         environment: createEnvironmentWithCluster(), | ||||||
|       }; |  | ||||||
|       vm = mountComponent(Component, { |  | ||||||
|         deploymentStatus: { |  | ||||||
|           status: 'last', |  | ||||||
|           environment: Object.assign({}, environment, { |  | ||||||
|             last_deployment: { |  | ||||||
|               ...lastDeployment, |  | ||||||
|               cluster, |  | ||||||
|             }, |  | ||||||
|           }), |  | ||||||
|         }, |  | ||||||
|         iconStatus: status, |  | ||||||
|       }); |       }); | ||||||
| 
 | 
 | ||||||
|       expect(vm.$el.textContent.trim()).toContain('Cluster the-cluster was used.'); |       expect(findText()).toEqual( | ||||||
| 
 |         `This job is deployed to environment using cluster ${TEST_CLUSTER_NAME}.`, | ||||||
|       expect(vm.$el.querySelector('.js-job-cluster-link').getAttribute('href')).toEqual( |  | ||||||
|         '/the-cluster-path', |  | ||||||
|       ); |       ); | ||||||
|  | 
 | ||||||
|  |       expect(findClusterLink().getAttribute('href')).toEqual(TEST_CLUSTER_PATH); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     describe('when the cluster is missing the path', () => { |     describe('when the cluster is missing the path', () => { | ||||||
|  | @ -177,39 +184,20 @@ describe('Environments block', () => { | ||||||
|         const cluster = { |         const cluster = { | ||||||
|           name: 'the-cluster', |           name: 'the-cluster', | ||||||
|         }; |         }; | ||||||
|         vm = mountComponent(Component, { |         createComponent({ | ||||||
|           deploymentStatus: { |  | ||||||
|             status: 'last', |  | ||||||
|             environment: Object.assign({}, environment, { |  | ||||||
|               last_deployment: { |  | ||||||
|                 ...lastDeployment, |  | ||||||
|                 cluster, |  | ||||||
|               }, |  | ||||||
|             }), |  | ||||||
|           }, |  | ||||||
|           iconStatus: status, |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|         expect(vm.$el.textContent.trim()).toContain('Cluster the-cluster was used.'); |  | ||||||
| 
 |  | ||||||
|         expect(vm.$el.querySelector('.js-job-cluster-link')).toBeNull(); |  | ||||||
|       }); |  | ||||||
|     }); |  | ||||||
|   }); |  | ||||||
| 
 |  | ||||||
|   describe('without a cluster', () => { |  | ||||||
|     it('does not render a cluster link', () => { |  | ||||||
|       vm = mountComponent(Component, { |  | ||||||
|         deploymentStatus: { |  | ||||||
|           status: 'last', |           status: 'last', | ||||||
|           environment: Object.assign({}, environment, { |           environment: Object.assign({}, environment, { | ||||||
|             last_deployment: lastDeployment, |             last_deployment: { | ||||||
|  |               ...lastDeployment, | ||||||
|  |               cluster, | ||||||
|  |             }, | ||||||
|           }), |           }), | ||||||
|         }, |         }); | ||||||
|         iconStatus: status, |  | ||||||
|       }); |  | ||||||
| 
 | 
 | ||||||
|       expect(vm.$el.querySelector('.js-job-cluster-link')).toBeNull(); |         expect(findText()).toContain('using cluster the-cluster.'); | ||||||
|  | 
 | ||||||
|  |         expect(findClusterLink()).toBeNull(); | ||||||
|  |       }); | ||||||
|     }); |     }); | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -22,41 +22,22 @@ describe AtomicInternalId do | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     context 'when value is set by ensure_project_iid!' do |     context 'when value is set by ensure_project_iid!' do | ||||||
|       context 'with iid_always_track false' do |       it 'does not track the value' do | ||||||
|         before do |         expect(InternalId).not_to receive(:track_greatest) | ||||||
|           stub_feature_flags(iid_always_track: false) |  | ||||||
|         end |  | ||||||
| 
 | 
 | ||||||
|         it 'does not track the value' do |         milestone.ensure_project_iid! | ||||||
|           expect(InternalId).not_to receive(:track_greatest) |         subject | ||||||
| 
 |  | ||||||
|           milestone.ensure_project_iid! |  | ||||||
|           subject |  | ||||||
|         end |  | ||||||
| 
 |  | ||||||
|         it 'tracks the iid for the scope that is actually present' do |  | ||||||
|           milestone.iid = external_iid |  | ||||||
| 
 |  | ||||||
|           expect(InternalId).to receive(:track_greatest).once.with(milestone, scope_attrs, usage, external_iid, anything) |  | ||||||
|           expect(InternalId).not_to receive(:generate_next) |  | ||||||
| 
 |  | ||||||
|           # group scope is not present here, the milestone does not have a group |  | ||||||
|           milestone.track_group_iid! |  | ||||||
|           subject |  | ||||||
|         end |  | ||||||
|       end |       end | ||||||
| 
 | 
 | ||||||
|       context 'with iid_always_track enabled' do |       it 'tracks the iid for the scope that is actually present' do | ||||||
|         before do |         milestone.iid = external_iid | ||||||
|           stub_feature_flags(iid_always_track: true) |  | ||||||
|         end |  | ||||||
| 
 | 
 | ||||||
|         it 'does not track the value' do |         expect(InternalId).to receive(:track_greatest).once.with(milestone, scope_attrs, usage, external_iid, anything) | ||||||
|           expect(InternalId).to receive(:track_greatest) |         expect(InternalId).not_to receive(:generate_next) | ||||||
| 
 | 
 | ||||||
|           milestone.ensure_project_iid! |         # group scope is not present here, the milestone does not have a group | ||||||
|           subject |         milestone.track_group_iid! | ||||||
|         end |         subject | ||||||
|       end |       end | ||||||
|     end |     end | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  | @ -47,10 +47,6 @@ shared_examples_for 'AtomicInternalId' do |validate_presence: true| | ||||||
|     end |     end | ||||||
| 
 | 
 | ||||||
|     describe 'internal id generation' do |     describe 'internal id generation' do | ||||||
|       before do |  | ||||||
|         stub_feature_flags(iid_always_track: false) |  | ||||||
|       end |  | ||||||
| 
 |  | ||||||
|       subject { instance.save! } |       subject { instance.save! } | ||||||
| 
 | 
 | ||||||
|       it 'calls InternalId.generate_next and sets internal id attribute' do |       it 'calls InternalId.generate_next and sets internal id attribute' do | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue