Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
		
							parent
							
								
									e67a224437
								
							
						
					
					
						commit
						65edff9059
					
				|  | @ -89,6 +89,7 @@ export default { | |||
|     v-gl-tooltip.hover | ||||
|     category="secondary" | ||||
|     data-testid="subscribe-button" | ||||
|     :data-subscribed="subscribedToNotifications ? 'true' : 'false'" | ||||
|     :title="notificationTooltip" | ||||
|     class="btn-icon" | ||||
|     @click="toggleNotifications(!subscribedToNotifications)" | ||||
|  |  | |||
|  | @ -10,6 +10,7 @@ import { | |||
|   BASE_ALLOWED_CREATE_TYPES, | ||||
|   WORK_ITEM_TYPE_NAME_ISSUE, | ||||
|   WORK_ITEM_TYPE_NAME_INCIDENT, | ||||
|   WORK_ITEM_TYPE_NAME_TASK, | ||||
| } from '../constants'; | ||||
| import workItemRelatedItemQuery from '../graphql/work_item_related_item.query.graphql'; | ||||
| import { convertTypeEnumToName } from '../utils'; | ||||
|  | @ -69,14 +70,17 @@ export default { | |||
|     }, | ||||
|   }, | ||||
|   computed: { | ||||
|     isIssue() { | ||||
|       return this.workItemType === WORK_ITEM_TYPE_NAME_ISSUE; | ||||
|     }, | ||||
|     isIncident() { | ||||
|       return this.workItemType === WORK_ITEM_TYPE_NAME_INCIDENT; | ||||
|     }, | ||||
|     allowedWorkItemTypes() { | ||||
|       if (this.isIssue || this.isIncident) { | ||||
|       if ( | ||||
|         [ | ||||
|           WORK_ITEM_TYPE_NAME_ISSUE, | ||||
|           WORK_ITEM_TYPE_NAME_INCIDENT, | ||||
|           WORK_ITEM_TYPE_NAME_TASK, | ||||
|         ].includes(this.workItemType) | ||||
|       ) { | ||||
|         return BASE_ALLOWED_CREATE_TYPES; | ||||
|       } | ||||
| 
 | ||||
|  | @ -150,7 +154,7 @@ export default { | |||
|       :is-group="isGroup" | ||||
|       :related-item="relatedItem" | ||||
|       :should-discard-draft="shouldDiscardDraft" | ||||
|       :always-show-work-item-type-select="isIncident || isIssue" | ||||
|       :always-show-work-item-type-select="!isGroup" | ||||
|       :allowed-work-item-types="allowedWorkItemTypes" | ||||
|       @updateType="updateWorkItemType($event)" | ||||
|       @confirmCancel="handleConfirmCancellation" | ||||
|  |  | |||
|  | @ -9,6 +9,10 @@ class Groups::BoardsController < Groups::ApplicationController | |||
|     push_frontend_feature_flag(:board_multi_select, group) | ||||
|     push_frontend_feature_flag(:issues_list_drawer, group) | ||||
|     push_force_frontend_feature_flag(:work_items_beta, !!group&.work_items_beta_feature_flag_enabled?) | ||||
|     push_frontend_feature_flag(:notifications_todos_buttons) | ||||
|     push_force_frontend_feature_flag(:glql_integration, !!group&.glql_integration_feature_flag_enabled?) | ||||
|     push_force_frontend_feature_flag(:continue_indented_text, !!group&.continue_indented_text_feature_flag_enabled?) | ||||
|     push_frontend_feature_flag(:work_item_status_feature_flag, group&.root_ancestor) | ||||
|   end | ||||
| 
 | ||||
|   feature_category :team_planning | ||||
|  |  | |||
|  | @ -9,6 +9,10 @@ class Projects::BoardsController < Projects::ApplicationController | |||
|     push_frontend_feature_flag(:board_multi_select, project) | ||||
|     push_frontend_feature_flag(:issues_list_drawer, project) | ||||
|     push_force_frontend_feature_flag(:work_items_beta, !!project&.work_items_beta_feature_flag_enabled?) | ||||
|     push_frontend_feature_flag(:notifications_todos_buttons) | ||||
|     push_force_frontend_feature_flag(:glql_integration, !!project&.glql_integration_feature_flag_enabled?) | ||||
|     push_force_frontend_feature_flag(:continue_indented_text, !!project&.continue_indented_text_feature_flag_enabled?) | ||||
|     push_frontend_feature_flag(:work_item_status_feature_flag, project&.root_ancestor) | ||||
|   end | ||||
| 
 | ||||
|   feature_category :team_planning | ||||
|  |  | |||
|  | @ -74,18 +74,32 @@ validates :new_setting, | |||
| ## Migrate a database column to a JSONB column | ||||
| 
 | ||||
| To migrate a column to JSONB, add the new setting under the JSONB accessor. | ||||
| Follow the [process to add a new application setting](#add-a-new-application-setting). | ||||
| 
 | ||||
| You can use the same name as the existing column to maintain consistency. During the | ||||
| transition period, Rails writes the same information to both the existing database | ||||
| ### Adding the JSONB setting | ||||
| 
 | ||||
| - Follow the [process to add a new application setting](#add-a-new-application-setting). | ||||
| - Use the same name as the existing column to maintain consistency. | ||||
| - During transition, Rails writes the same information to both the existing database | ||||
| column and the field under the new JSONB column. This ensures data consistency and | ||||
| prevents downtime. | ||||
| 
 | ||||
| You must follow the [process for dropping columns](database/avoiding_downtime_in_migrations.md#dropping-columns) to remove the original column. | ||||
| This a required multi-milestone process that involves: | ||||
| ### Required cleanup steps | ||||
| 
 | ||||
| You must follow the [process for dropping columns](database/avoiding_downtime_in_migrations.md#dropping-columns) | ||||
| to remove the original column. This a required multi-milestone process that involves: | ||||
| 
 | ||||
| 1. Ignoring the column. | ||||
| 1. Dropping the column. | ||||
| 1. Removing the ignore rule. | ||||
| 
 | ||||
| {{< alert type="warning" >}} | ||||
| 
 | ||||
| Dropping the original column before ignoring it in the model can cause problems with zero-downtime migrations. | ||||
| 
 | ||||
| {{< /alert >}} | ||||
| 
 | ||||
| ### Default values | ||||
| 
 | ||||
| When migrating settings to JSONB columns with `jsonb_accessor` defaults, | ||||
| remove them from `ApplicationSettingImplementation.defaults` because | ||||
| JSONB accessors take precedence over the `defaults` method. | ||||
|  |  | |||
|  | @ -259,7 +259,6 @@ to the table's database dictionary file. This can be used for: | |||
| 
 | ||||
| - JiHu specific tables, since they do not have any data on the .com database. [!145905](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/145905) | ||||
| - tables that are marked to be dropped soon, like `operations_feature_flag_scopes`. [!147541](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/147541) | ||||
| - tables that mandatorily need to be present per cell to support a cell's operations, have unique data per cell, but cannot have a sharding key defined. For example, `zoekt_nodes`. | ||||
| 
 | ||||
| When tables are exempted from sharding key requirements, they also do not show up in our | ||||
| [progress dashboard](https://cells-progress-tracker-gitlab-org-tenant-scale-g-f4ad96bf01d25f.gitlab.io/sharding_keys). | ||||
|  |  | |||
|  | @ -322,6 +322,10 @@ The `GITLAB_TOKEN` for the [@gl-service-dev-secure-analyzers-automation](https:/ | |||
| 
 | ||||
|       The `ci-templates` project requires the `GITLAB_TOKEN` to allow certain scripts to execute API calls. This step can be removed after [allow JOB-TOKEN access to CI/lint endpoint](https://gitlab.com/gitlab-org/gitlab/-/issues/438781) has been completed. | ||||
| 
 | ||||
|    1. `GITLAB_TOKEN` CI/CD variable for the [`gitlab-org/secure/tools/security-triage-automation`](https://gitlab.com/gitlab-org/secure/tools/security-triage-automation) project. | ||||
| 
 | ||||
|       This must be explicitly configured because the `security-triage-automation` project is not nested under the `gitlab-org/security-products/analyzers` namespace, and therefore _does not inherit_ the `GITLAB_TOKEN` value. | ||||
| 
 | ||||
|    1. `SEC_REGISTRY_PASSWORD` CI/CD variable for [`gitlab-advanced-sast`](https://gitlab.com/gitlab-org/security-products/analyzers/gitlab-advanced-sast/-/settings/ci_cd#js-cicd-variables-settings). | ||||
| 
 | ||||
|       This allows our [tagging script](https://gitlab.com/gitlab-org/security-products/ci-templates/blob/cfe285a/scripts/tag_image.sh) to pull from the private container registry in the development project `registry.gitlab.com/gitlab-org/security-products/analyzers/<analyzer-name>/tmp`, and push to the publicly accessible container registry `registry.gitlab.com/security-products/<analyzer-name>`. | ||||
|  |  | |||
|  | @ -21,6 +21,7 @@ RSpec.describe 'Project issue boards sidebar', :js, feature_category: :portfolio | |||
|   context 'when issues drawer is disabled' do | ||||
|     before do | ||||
|       stub_feature_flags(issues_list_drawer: false) | ||||
|       stub_feature_flags(notifications_todos_buttons: false) | ||||
|       sign_in(user) | ||||
| 
 | ||||
|       visit project_board_path(project, board) | ||||
|  |  | |||
|  | @ -131,6 +131,18 @@ describe('WorkItemActions component', () => { | |||
|       expect(findNotificationsButton().findComponent(GlIcon).props('name')).toBe(icon); | ||||
|     }); | ||||
| 
 | ||||
|     it.each` | ||||
|       scenario                   | subscribedToNotifications | dataSubscribed | ||||
|       ${'notifications are off'} | ${false}                  | ${'false'} | ||||
|       ${'notifications are on'}  | ${true}                   | ${'true'} | ||||
|     `(
 | ||||
|       'has the correct data-subscribed attribute when $scenario', | ||||
|       ({ subscribedToNotifications, dataSubscribed }) => { | ||||
|         createComponent({ subscribedToNotifications }); | ||||
|         expect(findNotificationsButton().attributes('data-subscribed')).toBe(dataSubscribed); | ||||
|       }, | ||||
|     ); | ||||
| 
 | ||||
|     it('emits error when the update notification mutation fails', async () => { | ||||
|       createComponent({ | ||||
|         notificationsMutationHandler: toggleNotificationsFailureHandler, | ||||
|  |  | |||
|  | @ -81,6 +81,16 @@ describe('Create work item page component', () => { | |||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|   it('passes alwaysShowWorkItemTypeSelect prop as `true` to the CreateWorkItem component when isGroup is false', () => { | ||||
|     const pushMock = jest.fn(); | ||||
|     createComponent({ push: pushMock }, false); | ||||
| 
 | ||||
|     expect(findCreateWorkItem().props()).toMatchObject({ | ||||
|       alwaysShowWorkItemTypeSelect: true, | ||||
|       allowedWorkItemTypes: ['Incident', 'Issue', 'Task'], | ||||
|     }); | ||||
|   }); | ||||
| 
 | ||||
|   it('visits work item detail page after create if router is not present', () => { | ||||
|     createComponent(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -111,6 +111,7 @@ module InvokeRopSteps | |||
|     context_passed_along_steps: | ||||
|   ) | ||||
|     expected_rop_steps = [] | ||||
|     skip_unless_inspect = false | ||||
| 
 | ||||
|     rop_steps.each do |rop_step| | ||||
|       step_class = rop_step[0] | ||||
|  | @ -121,13 +122,11 @@ module InvokeRopSteps | |||
|         step_action: step_action | ||||
|       } | ||||
| 
 | ||||
|       next if skip_unless_inspect && [:inspect_ok, :inspect_err].freeze.exclude?(step_action) | ||||
| 
 | ||||
|       if err_results_for_steps.key?(step_class) | ||||
|         expected_rop_step[:returned_object] = err_results_for_steps[step_class] | ||||
| 
 | ||||
|         # Currently, only a single error step is supported, so we assign expected_rop_step as the last entry | ||||
|         # in expected_rop_steps, break out of the loop early, and do not add any more steps | ||||
|         expected_rop_steps << expected_rop_step | ||||
|         break | ||||
|         skip_unless_inspect = true | ||||
|       elsif ok_results_for_steps.key?(step_class) | ||||
|         expected_rop_step[:returned_object] = ok_results_for_steps[step_class] | ||||
|       elsif step_action == :and_then | ||||
|  | @ -169,7 +168,9 @@ module InvokeRopSteps | |||
|     context_passed_along_steps:, | ||||
|     returned_object: | ||||
|   ) | ||||
|     expect(step_class).to receive(step_class_method).with(context_passed_along_steps).ordered do | ||||
|     expectation = expect(step_class).to receive(step_class_method) | ||||
|     expectation = expectation.with(context_passed_along_steps) if step_class_method != :observe | ||||
|     expectation.ordered do | ||||
|       returned_object | ||||
|     end | ||||
|   end | ||||
|  |  | |||
|  | @ -64,38 +64,21 @@ RSpec.shared_examples 'work item drawer' do | |||
|   end | ||||
| 
 | ||||
|   context 'when in notifications subscription' do | ||||
|     before do | ||||
|       within_testid('work-item-drawer') do | ||||
|         find_by_testid('work-item-actions-dropdown').click | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     it 'displays notifications toggle', :aggregate_failures do | ||||
|       within_testid('work-item-drawer') do | ||||
|         expect(page).to have_selector('[data-testid="notifications-toggle-form"]') | ||||
|         expect(page).to have_content('Notifications') | ||||
|         expect(page).not_to have_content('Disabled by project owner') | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     it 'shows toggle as on then as off as user toggles to subscribe and unsubscribe', :aggregate_failures do | ||||
|       within_testid('notifications-toggle-form') do | ||||
|         subscription_button = find('[data-testid="notifications-toggle"] button') | ||||
|       subscribe_button = find_by_testid('subscribe-button') | ||||
|       expect(page).to have_selector("button[data-testid='subscribe-button'][data-subscribed='false']") | ||||
| 
 | ||||
|         expect(page).not_to have_css("button.is-checked") | ||||
|       subscribe_button.click | ||||
|       wait_for_requests | ||||
| 
 | ||||
|         subscription_button.click | ||||
|       expect(page).to have_content("Notifications turned on.") | ||||
|       expect(page).to have_selector("button[data-testid='subscribe-button'][data-subscribed='true']") | ||||
| 
 | ||||
|         wait_for_requests | ||||
|       subscribe_button.click | ||||
|       wait_for_requests | ||||
| 
 | ||||
|         expect(page).to have_css("button.is-checked") | ||||
| 
 | ||||
|         subscription_button.click | ||||
| 
 | ||||
|         wait_for_requests | ||||
| 
 | ||||
|         expect(page).not_to have_css("button.is-checked") | ||||
|       end | ||||
|       expect(page).to have_content("Notifications turned off.") | ||||
|       expect(page).to have_selector("button[data-testid='subscribe-button'][data-subscribed='false']") | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue