diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-01-10 00:08:39 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-01-10 00:08:39 +0300 |
commit | d4b2ad25a56a9baf41a27a2190458330645b3102 (patch) | |
tree | fdfa7d67e75eedb35bf689ade0b5d09f4bae3f4b /app | |
parent | 17deb2a503bb8163514fe37618bf36f75376b9ae (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
50 files changed, 283 insertions, 150 deletions
diff --git a/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules.vue b/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules.vue index fe16cb7a92e..db55fd96ad0 100644 --- a/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules.vue +++ b/app/assets/javascripts/ci/pipeline_schedules/components/pipeline_schedules.vue @@ -1,9 +1,19 @@ <script> -import { GlAlert, GlBadge, GlButton, GlLoadingIcon, GlTabs, GlTab } from '@gitlab/ui'; +import { + GlAlert, + GlBadge, + GlButton, + GlLoadingIcon, + GlTabs, + GlTab, + GlSprintf, + GlLink, +} from '@gitlab/ui'; import { s__, sprintf } from '~/locale'; import { limitedCounterWithDelimiter } from '~/lib/utils/text_utility'; import { queryToObject } from '~/lib/utils/url_utility'; import deletePipelineScheduleMutation from '../graphql/mutations/delete_pipeline_schedule.mutation.graphql'; +import playPipelineScheduleMutation from '../graphql/mutations/play_pipeline_schedule.mutation.graphql'; import takeOwnershipMutation from '../graphql/mutations/take_ownership.mutation.graphql'; import getPipelineSchedulesQuery from '../graphql/queries/get_pipeline_schedules.query.graphql'; import PipelineSchedulesTable from './table/pipeline_schedules_table.vue'; @@ -16,11 +26,15 @@ export default { scheduleDeleteError: s__( 'PipelineSchedules|There was a problem deleting the pipeline schedule.', ), + schedulePlayError: s__('PipelineSchedules|There was a problem playing the pipeline schedule.'), takeOwnershipError: s__( 'PipelineSchedules|There was a problem taking ownership of the pipeline schedule.', ), newSchedule: s__('PipelineSchedules|New schedule'), deleteSuccess: s__('PipelineSchedules|Pipeline schedule successfully deleted.'), + playSuccess: s__( + 'PipelineSchedules|Successfully scheduled a pipeline to run. Go to the %{linkStart}Pipelines page%{linkEnd} for details. ', + ), }, components: { DeletePipelineScheduleModal, @@ -30,6 +44,8 @@ export default { GlLoadingIcon, GlTabs, GlTab, + GlSprintf, + GlLink, PipelineSchedulesTable, TakeOwnershipModal, }, @@ -37,6 +53,9 @@ export default { fullPath: { default: '', }, + pipelinesPath: { + default: '', + }, }, apollo: { schedules: { @@ -68,6 +87,7 @@ export default { }, scope, hasError: false, + playSuccess: false, errorMessage: '', scheduleId: null, showDeleteModal: false, @@ -185,6 +205,27 @@ export default { this.reportError(this.$options.i18n.takeOwnershipError); } }, + async playPipelineSchedule(id) { + try { + const { + data: { + pipelineSchedulePlay: { errors }, + }, + } = await this.$apollo.mutate({ + mutation: playPipelineScheduleMutation, + variables: { id }, + }); + + if (errors.length > 0) { + throw new Error(); + } else { + this.playSuccess = true; + } + } catch { + this.playSuccess = false; + this.reportError(this.$options.i18n.schedulePlayError); + } + }, fetchPipelineSchedulesByStatus(scope) { this.scope = scope; this.$apollo.queries.schedules.refetch(); @@ -195,62 +236,69 @@ export default { <template> <div> - <gl-alert v-if="hasError" class="gl-mb-2" variant="danger" @dismiss="hasError = false"> + <gl-alert v-if="hasError" class="gl-my-3" variant="danger" @dismiss="hasError = false"> {{ errorMessage }} </gl-alert> - <template v-else> - <gl-tabs - sync-active-tab-with-query-params - query-param-name="scope" - nav-class="gl-flex-grow-1 gl-align-items-center" + <gl-alert v-if="playSuccess" class="gl-my-3" variant="info" @dismiss="playSuccess = false"> + <gl-sprintf :message="$options.i18n.playSuccess"> + <template #link="{ content }"> + <gl-link :href="pipelinesPath" class="gl-text-decoration-none!">{{ content }}</gl-link> + </template> + </gl-sprintf> + </gl-alert> + + <gl-tabs + sync-active-tab-with-query-params + query-param-name="scope" + nav-class="gl-flex-grow-1 gl-align-items-center" + > + <gl-tab + v-for="tab in tabs" + :key="tab.text" + :title-link-attributes="tab.attrs" + :query-param-value="tab.scope" + @click="fetchPipelineSchedulesByStatus(tab.scope)" > - <gl-tab - v-for="tab in tabs" - :key="tab.text" - :title-link-attributes="tab.attrs" - :query-param-value="tab.scope" - @click="fetchPipelineSchedulesByStatus(tab.scope)" - > - <template #title> - <span>{{ tab.text }}</span> + <template #title> + <span>{{ tab.text }}</span> - <template v-if="tab.showBadge"> - <gl-loading-icon v-if="tab.scope === scope && isLoading" class="gl-ml-2" /> + <template v-if="tab.showBadge"> + <gl-loading-icon v-if="tab.scope === scope && isLoading" class="gl-ml-2" /> - <gl-badge v-else-if="tab.count" size="sm" class="gl-tab-counter-badge"> - {{ tab.count }} - </gl-badge> - </template> + <gl-badge v-else-if="tab.count" size="sm" class="gl-tab-counter-badge"> + {{ tab.count }} + </gl-badge> </template> + </template> - <gl-loading-icon v-if="isLoading" size="lg" /> - <pipeline-schedules-table - v-else - :schedules="schedules.list" - @showTakeOwnershipModal="setTakeOwnershipModal" - @showDeleteModal="setDeleteModal" - /> - </gl-tab> + <gl-loading-icon v-if="isLoading" size="lg" /> + <pipeline-schedules-table + v-else + :schedules="schedules.list" + @showTakeOwnershipModal="setTakeOwnershipModal" + @showDeleteModal="setDeleteModal" + @playPipelineSchedule="playPipelineSchedule" + /> + </gl-tab> - <template #tabs-end> - <gl-button variant="confirm" class="gl-ml-auto" data-testid="new-schedule-button"> - {{ $options.i18n.newSchedule }} - </gl-button> - </template> - </gl-tabs> + <template #tabs-end> + <gl-button variant="confirm" class="gl-ml-auto" data-testid="new-schedule-button"> + {{ $options.i18n.newSchedule }} + </gl-button> + </template> + </gl-tabs> - <take-ownership-modal - :visible="showTakeOwnershipModal" - @takeOwnership="takeOwnership" - @hideModal="hideModal" - /> + <take-ownership-modal + :visible="showTakeOwnershipModal" + @takeOwnership="takeOwnership" + @hideModal="hideModal" + /> - <delete-pipeline-schedule-modal - :visible="showDeleteModal" - @deleteSchedule="deleteSchedule" - @hideModal="hideModal" - /> - </template> + <delete-pipeline-schedule-modal + :visible="showDeleteModal" + @deleteSchedule="deleteSchedule" + @hideModal="hideModal" + /> </div> </template> diff --git a/app/assets/javascripts/ci/pipeline_schedules/components/table/cells/pipeline_schedule_actions.vue b/app/assets/javascripts/ci/pipeline_schedules/components/table/cells/pipeline_schedule_actions.vue index 8656e5d3536..45b4f618e17 100644 --- a/app/assets/javascripts/ci/pipeline_schedules/components/table/cells/pipeline_schedule_actions.vue +++ b/app/assets/javascripts/ci/pipeline_schedules/components/table/cells/pipeline_schedule_actions.vue @@ -44,7 +44,14 @@ export default { <template> <div class="gl-display-flex gl-justify-content-end"> <gl-button-group> - <gl-button v-if="canPlay" v-gl-tooltip :title="$options.i18n.playTooltip" icon="play" /> + <gl-button + v-if="canPlay" + v-gl-tooltip + :title="$options.i18n.playTooltip" + icon="play" + data-testid="play-pipeline-schedule-btn" + @click="$emit('playPipelineSchedule', schedule.id)" + /> <gl-button v-if="canTakeOwnership" v-gl-tooltip diff --git a/app/assets/javascripts/ci/pipeline_schedules/components/table/pipeline_schedules_table.vue b/app/assets/javascripts/ci/pipeline_schedules/components/table/pipeline_schedules_table.vue index 1b97a35a51e..e8cfc5b29f3 100644 --- a/app/assets/javascripts/ci/pipeline_schedules/components/table/pipeline_schedules_table.vue +++ b/app/assets/javascripts/ci/pipeline_schedules/components/table/pipeline_schedules_table.vue @@ -96,6 +96,7 @@ export default { :schedule="item" @showTakeOwnershipModal="$emit('showTakeOwnershipModal', $event)" @showDeleteModal="$emit('showDeleteModal', $event)" + @playPipelineSchedule="$emit('playPipelineSchedule', $event)" /> </template> </gl-table-lite> diff --git a/app/assets/javascripts/ci/pipeline_schedules/graphql/mutations/play_pipeline_schedule.mutation.graphql b/app/assets/javascripts/ci/pipeline_schedules/graphql/mutations/play_pipeline_schedule.mutation.graphql new file mode 100644 index 00000000000..4892f41b93f --- /dev/null +++ b/app/assets/javascripts/ci/pipeline_schedules/graphql/mutations/play_pipeline_schedule.mutation.graphql @@ -0,0 +1,6 @@ +mutation playPipelineSchedule($id: CiPipelineScheduleID!) { + pipelineSchedulePlay(input: { id: $id }) { + clientMutationId + errors + } +} diff --git a/app/assets/javascripts/ci/pipeline_schedules/mount_pipeline_schedules_app.js b/app/assets/javascripts/ci/pipeline_schedules/mount_pipeline_schedules_app.js index 4c06fa321e5..8bca4f85e9f 100644 --- a/app/assets/javascripts/ci/pipeline_schedules/mount_pipeline_schedules_app.js +++ b/app/assets/javascripts/ci/pipeline_schedules/mount_pipeline_schedules_app.js @@ -18,7 +18,7 @@ export default () => { return false; } - const { fullPath } = containerEl.dataset; + const { fullPath, pipelinesPath } = containerEl.dataset; return new Vue({ el: containerEl, @@ -26,6 +26,7 @@ export default () => { apolloProvider, provide: { fullPath, + pipelinesPath, }, render(createElement) { return createElement(PipelineSchedules); diff --git a/app/assets/stylesheets/framework/selects.scss b/app/assets/stylesheets/framework/selects.scss index ea741af918c..98083fbc72a 100644 --- a/app/assets/stylesheets/framework/selects.scss +++ b/app/assets/stylesheets/framework/selects.scss @@ -37,3 +37,14 @@ } } } + +.approvers-select { + .dropdown-menu { + @include gl-w-full; + @include gl-max-w-none; + } + + .gl-dropdown-item-check-icon { + @include gl-display-none; + } +} diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb index 45585ab84b4..668b2ebaf9e 100644 --- a/app/controllers/autocomplete_controller.rb +++ b/app/controllers/autocomplete_controller.rb @@ -9,7 +9,7 @@ class AutocompleteController < ApplicationController feature_category :users, [:users, :user] feature_category :projects, [:projects] feature_category :team_planning, [:award_emojis] - feature_category :code_review, [:merge_request_target_branches] + feature_category :code_review_workflow, [:merge_request_target_branches] feature_category :continuous_delivery, [:deploy_keys_with_owners] urgency :low, [:merge_request_target_branches, :deploy_keys_with_owners, :users] diff --git a/app/controllers/dashboard_controller.rb b/app/controllers/dashboard_controller.rb index 82e5bb6cd7c..3d9184979d7 100644 --- a/app/controllers/dashboard_controller.rb +++ b/app/controllers/dashboard_controller.rb @@ -16,7 +16,7 @@ class DashboardController < Dashboard::ApplicationController feature_category :users, [:activity] feature_category :team_planning, [:issues, :issues_calendar] - feature_category :code_review, [:merge_requests] + feature_category :code_review_workflow, [:merge_requests] urgency :low, [:merge_requests, :activity] urgency :low, [:issues, :issues_calendar] diff --git a/app/controllers/groups/autocomplete_sources_controller.rb b/app/controllers/groups/autocomplete_sources_controller.rb index 171494e66bd..6936733c4f7 100644 --- a/app/controllers/groups/autocomplete_sources_controller.rb +++ b/app/controllers/groups/autocomplete_sources_controller.rb @@ -3,7 +3,7 @@ class Groups::AutocompleteSourcesController < Groups::ApplicationController feature_category :subgroups, [:members] feature_category :team_planning, [:issues, :labels, :milestones, :commands] - feature_category :code_review, [:merge_requests] + feature_category :code_review_workflow, [:merge_requests] urgency :low, [:issues, :labels, :milestones, :commands, :merge_requests, :members] diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index db0655edcc3..faef5c6a2d0 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -55,7 +55,7 @@ class GroupsController < Groups::ApplicationController ] feature_category :team_planning, [:issues, :issues_calendar, :preview_markdown] - feature_category :code_review, [:merge_requests, :unfoldered_environment_names] + feature_category :code_review_workflow, [:merge_requests, :unfoldered_environment_names] feature_category :projects, [:projects] feature_category :importers, [:export, :download_export] urgency :low, [:export, :download_export] diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index 8650b6cbc6f..ac1d7ecc01c 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -306,7 +306,6 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController end def persist_accepted_terms_if_required(user) - return unless Feature.enabled?(:update_oauth_registration_flow) return unless user.persisted? return unless Gitlab::CurrentSettings.current_application_settings.enforce_terms? diff --git a/app/controllers/projects/autocomplete_sources_controller.rb b/app/controllers/projects/autocomplete_sources_controller.rb index ef20c71cd77..52e3ca066d7 100644 --- a/app/controllers/projects/autocomplete_sources_controller.rb +++ b/app/controllers/projects/autocomplete_sources_controller.rb @@ -5,7 +5,7 @@ class Projects::AutocompleteSourcesController < Projects::ApplicationController before_action :authorize_read_crm_contact!, only: :contacts feature_category :team_planning, [:issues, :labels, :milestones, :commands, :contacts] - feature_category :code_review, [:merge_requests] + feature_category :code_review_workflow, [:merge_requests] feature_category :users, [:members] feature_category :source_code_management, [:snippets] diff --git a/app/controllers/projects/merge_requests/application_controller.rb b/app/controllers/projects/merge_requests/application_controller.rb index 76b06b2ce9d..be44c78ac9d 100644 --- a/app/controllers/projects/merge_requests/application_controller.rb +++ b/app/controllers/projects/merge_requests/application_controller.rb @@ -5,7 +5,7 @@ class Projects::MergeRequests::ApplicationController < Projects::ApplicationCont before_action :merge_request before_action :authorize_read_merge_request! - feature_category :code_review + feature_category :code_review_workflow private diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 4a5fa7bfbea..b0920b3fbdb 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -54,7 +54,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo after_action :log_merge_request_show, only: [:show, :diffs] - feature_category :code_review, [ + feature_category :code_review_workflow, [ :assign_related_issues, :bulk_update, :cancel_auto_merge, :commit_change_content, :commits, :context_commits, :destroy, :discussions, :edit, :index, :merge, :rebase, :remove_wip, diff --git a/app/controllers/projects/settings/ci_cd_controller.rb b/app/controllers/projects/settings/ci_cd_controller.rb index cf07de4dc29..3365f36c874 100644 --- a/app/controllers/projects/settings/ci_cd_controller.rb +++ b/app/controllers/projects/settings/ci_cd_controller.rb @@ -4,6 +4,7 @@ module Projects module Settings class CiCdController < Projects::ApplicationController include RunnerSetupScripts + include ZuoraCSP NUMBER_OF_RUNNERS_PER_PAGE = 20 diff --git a/app/controllers/projects/settings/merge_requests_controller.rb b/app/controllers/projects/settings/merge_requests_controller.rb index 93e10695767..f09e324f574 100644 --- a/app/controllers/projects/settings/merge_requests_controller.rb +++ b/app/controllers/projects/settings/merge_requests_controller.rb @@ -9,7 +9,7 @@ module Projects before_action :present_project, only: [:edit] before_action :authorize_admin_project! - feature_category :code_review + feature_category :code_review_workflow def update result = ::Projects::UpdateService.new(@project, current_user, project_params).execute diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index efd1a2821da..ee2c268ff33 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -58,7 +58,7 @@ class ProjectsController < Projects::ApplicationController feature_category :source_code_management, [:remove_fork, :housekeeping, :refs] feature_category :team_planning, [:preview_markdown, :new_issuable_address] feature_category :importers, [:export, :remove_export, :generate_new_export, :download_export] - feature_category :code_review, [:unfoldered_environment_names] + feature_category :code_review_workflow, [:unfoldered_environment_names] feature_category :portfolio_management, [:planning_hierarchy] urgency :low, [:export, :remove_export, :generate_new_export, :download_export] diff --git a/app/graphql/resolvers/projects/branch_rules_resolver.rb b/app/graphql/resolvers/projects/branch_rules_resolver.rb index e99d7ae4d5f..d1b39df602f 100644 --- a/app/graphql/resolvers/projects/branch_rules_resolver.rb +++ b/app/graphql/resolvers/projects/branch_rules_resolver.rb @@ -10,7 +10,15 @@ module Resolvers alias_method :project, :object def resolve_with_lookahead(**args) - apply_lookahead(project.protected_branches) + protected_branches.map do |protected_branch| + ::Projects::BranchRule.new(project, protected_branch) + end + end + + private + + def protected_branches + apply_lookahead(project.protected_branches.sorted_by_name) end end end diff --git a/app/graphql/types/projects/branch_rule_type.rb b/app/graphql/types/projects/branch_rule_type.rb index 1afd2cc3fef..08b1203d4a3 100644 --- a/app/graphql/types/projects/branch_rule_type.rb +++ b/app/graphql/types/projects/branch_rule_type.rb @@ -5,7 +5,6 @@ module Types class BranchRuleType < BaseObject graphql_name 'BranchRule' description 'List of branch rules for a project, grouped by branch name.' - accepts ::ProtectedBranch authorize :read_protected_branch alias_method :branch_rule, :object @@ -22,6 +21,12 @@ module Types calls_gitaly: true, description: "Check if this branch rule protects the project's default branch." + field :is_protected, + type: GraphQL::Types::Boolean, + null: false, + method: :protected?, + description: "Check if this branch rule protects access for the branch." + field :matching_branches_count, type: GraphQL::Types::Int, null: false, @@ -30,9 +35,8 @@ module Types field :branch_protection, type: Types::BranchRules::BranchProtectionType, - null: false, - description: 'Branch protections configured for this branch rule.', - method: :itself + null: true, + description: 'Branch protections configured for this branch rule.' field :created_at, Types::TimeType, @@ -43,10 +47,6 @@ module Types Types::TimeType, null: false, description: 'Timestamp of when the branch rule was last updated.' - - def matching_branches_count - branch_rule.matching(branch_rule.project.repository.branch_names).count - end end end end diff --git a/app/helpers/emails_helper.rb b/app/helpers/emails_helper.rb index cad39854c0e..f6de405cecb 100644 --- a/app/helpers/emails_helper.rb +++ b/app/helpers/emails_helper.rb @@ -284,23 +284,38 @@ module EmailsHelper end def change_reviewer_notification_text(new_reviewers, previous_reviewers, html_tag = nil) - new = new_reviewers.any? ? users_to_sentence(new_reviewers) : s_('ChangeReviewer|Unassigned') - old = previous_reviewers.any? ? users_to_sentence(previous_reviewers) : nil + if new_reviewers.empty? + s_('ChangeReviewer|All reviewers were removed.') + else + added_reviewers = new_reviewers - previous_reviewers + removed_reviewers = previous_reviewers - new_reviewers - if html_tag.present? - new = content_tag(html_tag, new) - old = content_tag(html_tag, old) if old.present? - end + added_reviewers_template_text = added_reviewers.size > 1 ? "were added as reviewers.<br>" : "was added as a reviewer.<br>" + removed_reviewers_template_text = removed_reviewers.size > 1 ? "were removed from reviewers." : "was removed from reviewers." - if old.present? - s_('ChangeReviewer|Reviewer changed from %{old} to %{new}').html_safe % { old: old, new: new } - else - s_('ChangeReviewer|Reviewer changed to %{new}').html_safe % { new: new } + added = format_reviewers_string(added_reviewers, html_tag) + removed = format_reviewers_string(removed_reviewers, html_tag) + + added_reviewers_text = added ? "#{added} #{added_reviewers_template_text}".html_safe : '' + removed_reviewers_text = removed ? "#{removed} #{removed_reviewers_template_text}".html_safe : '' + s_('ChangeReviewer|%{added_reviewers_text}%{removed_reviewers_text}').html_safe % { added_reviewers_text: added_reviewers_text, removed_reviewers_text: removed_reviewers_text } end end private + def format_reviewers_string(reviewers, html_tag = nil) + return unless reviewers.any? + + formatted_reviewers = users_to_sentence(reviewers) + + if html_tag.present? + content_tag(html_tag, formatted_reviewers) + else + formatted_reviewers + end + end + def users_to_sentence(users) sanitize_name(users.map(&:name).to_sentence) end diff --git a/app/models/projects/branch_rule.rb b/app/models/projects/branch_rule.rb new file mode 100644 index 00000000000..ae59d24e557 --- /dev/null +++ b/app/models/projects/branch_rule.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module Projects + class BranchRule + extend Forwardable + + attr_reader :project, :protected_branch + + def_delegators(:protected_branch, :name, :group, :default_branch?, :created_at, :updated_at) + + def initialize(project, protected_branch) + @protected_branch = protected_branch + @project = project + end + + def protected? + true + end + + def matching_branches_count + branch_names = project.repository.branch_names + matching_branches = protected_branch.matching(branch_names) + matching_branches.count + end + + def branch_protection + protected_branch + end + end +end + +Projects::BranchRule.prepend_mod diff --git a/app/models/protected_branch.rb b/app/models/protected_branch.rb index c59ef4cd80b..1753b2a0220 100644 --- a/app/models/protected_branch.rb +++ b/app/models/protected_branch.rb @@ -8,11 +8,9 @@ class ProtectedBranch < ApplicationRecord validate :validate_either_project_or_top_group - scope :requiring_code_owner_approval, - -> { where(code_owner_approval_required: true) } - - scope :allowing_force_push, - -> { where(allow_force_push: true) } + scope :requiring_code_owner_approval, -> { where(code_owner_approval_required: true) } + scope :allowing_force_push, -> { where(allow_force_push: true) } + scope :sorted_by_name, -> { order(name: :asc) } protected_ref_access_levels :merge, :push diff --git a/app/models/user.rb b/app/models/user.rb index dedf12c25ed..c3ca6af2650 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -69,7 +69,7 @@ class User < ApplicationRecord attribute :hide_no_password, default: false attribute :project_view, default: :files attribute :notified_of_own_activity, default: false - attribute :preferred_language, default: -> { I18n.default_locale } + attribute :preferred_language, default: -> { Gitlab::CurrentSettings.default_preferred_language } attribute :theme_id, default: -> { gitlab_config.default_theme } attr_encrypted :otp_secret, @@ -541,9 +541,7 @@ class User < ApplicationRecord strip_attributes! :name def preferred_language - read_attribute('preferred_language') || - I18n.default_locale.to_s.presence_in(Gitlab::I18n.available_locales) || - default_preferred_language + read_attribute('preferred_language').presence || Gitlab::CurrentSettings.default_preferred_language end def active_for_authentication? @@ -2227,11 +2225,6 @@ class User < ApplicationRecord otp_backup_codes.first.start_with?("$pbkdf2-sha512$") end - # To enable JiHu repository to modify the default language options - def default_preferred_language - 'en' - end - # rubocop: disable CodeReuse/ServiceClass def add_primary_email_to_emails! Emails::CreateService.new(self, user: self, email: self.email).execute(confirmed_at: self.confirmed_at) diff --git a/app/policies/projects/branch_rule_policy.rb b/app/policies/projects/branch_rule_policy.rb new file mode 100644 index 00000000000..9ea15ea26d4 --- /dev/null +++ b/app/policies/projects/branch_rule_policy.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +module Projects + class BranchRulePolicy < ::ProtectedBranchPolicy + end +end + +Projects::BranchRulePolicy.prepend_mod diff --git a/app/services/boards/base_items_list_service.rb b/app/services/boards/base_items_list_service.rb index 2a9cbb83cc4..bf68aee2c1f 100644 --- a/app/services/boards/base_items_list_service.rb +++ b/app/services/boards/base_items_list_service.rb @@ -18,7 +18,6 @@ module Boards # TODO: eliminate need for SQL literal fragment columns = Arel.sql(fields.values_at(*keys).join(', ')) results = item_model.where(id: collection_ids) - results = query_additions(results, required_fields) results = results.select(columns) Hash[keys.zip(results.pluck(columns).flatten)] @@ -27,11 +26,6 @@ module Boards private - # override if needed - def query_additions(items, required_fields) - items - end - def collection_ids @collection_ids ||= init_collection.select(item_model.arel_table[:id]) end diff --git a/app/services/concerns/integrations/project_test_data.rb b/app/services/concerns/integrations/project_test_data.rb index ae1e1d1e66c..b3427697052 100644 --- a/app/services/concerns/integrations/project_test_data.rb +++ b/app/services/concerns/integrations/project_test_data.rb @@ -2,8 +2,14 @@ module Integrations module ProjectTestData + NoDataError = Class.new(ArgumentError) + private + def no_data_error(msg) + raise NoDataError, msg + end + def push_events_data Gitlab::DataBuilder::Push.build_sample(project, current_user) end @@ -11,7 +17,7 @@ module Integrations def note_events_data note = NotesFinder.new(current_user, project: project, target: project, sort: 'id_desc').execute.first - return { error: s_('TestHooks|Ensure the project has notes.') } unless note.present? + no_data_error(s_('TestHooks|Ensure the project has notes.')) unless note.present? Gitlab::DataBuilder::Note.build(note, current_user) end @@ -19,7 +25,7 @@ module Integrations def issues_events_data issue = IssuesFinder.new(current_user, project_id: project.id, sort: 'created_desc').execute.first - return { error: s_('TestHooks|Ensure the project has issues.') } unless issue.present? + no_data_error(s_('TestHooks|Ensure the project has issues.')) unless issue.present? issue.to_hook_data(current_user) end @@ -27,7 +33,7 @@ module Integrations def merge_requests_events_data merge_request = MergeRequestsFinder.new(current_user, project_id: project.id, sort: 'created_desc').execute.first - return { error: s_('TestHooks|Ensure the project has merge requests.') } unless merge_request.present? + no_data_error(s_('TestHooks|Ensure the project has merge requests.')) unless merge_request.present? merge_request.to_hook_data(current_user) end @@ -35,7 +41,7 @@ module Integrations def job_events_data build = Ci::JobsFinder.new(current_user: current_user, project: project).execute.first - return { error: s_('TestHooks|Ensure the project has CI jobs.') } unless build.present? + no_data_error(s_('TestHooks|Ensure the project has CI jobs.')) unless build.present? Gitlab::DataBuilder::Build.build(build) end @@ -43,7 +49,7 @@ module Integrations def pipeline_events_data pipeline = Ci::PipelinesFinder.new(project, current_user, order_by: 'id', sort: 'desc').execute.first - return { error: s_('TestHooks|Ensure the project has CI pipelines.') } unless pipeline.present? + no_data_error(s_('TestHooks|Ensure the project has CI pipelines.')) unless pipeline.present? Gitlab::DataBuilder::Pipeline.build(pipeline) end @@ -51,9 +57,7 @@ module Integrations def wiki_page_events_data page = project.wiki.list_pages(limit: 1).first - if !project.wiki_enabled? || page.blank? - return { error: s_('TestHooks|Ensure the wiki is enabled and has pages.') } - end + no_data_error(s_('TestHooks|Ensure the wiki is enabled and has pages.')) if !project.wiki_enabled? || page.blank? Gitlab::DataBuilder::WikiPage.build(page, current_user, 'create') end @@ -61,7 +65,7 @@ module Integrations def deployment_events_data deployment = DeploymentsFinder.new(project: project, order_by: 'created_at', sort: 'desc').execute.first - return { error: s_('TestHooks|Ensure the project has deployments.') } unless deployment.present? + no_data_error(s_('TestHooks|Ensure the project has deployments.')) unless deployment.present? Gitlab::DataBuilder::Deployment.build(deployment, deployment.status, Time.current) end @@ -69,7 +73,7 @@ module Integrations def releases_events_data release = ReleasesFinder.new(project, current_user, order_by: :created_at, sort: :desc).execute.first - return { error: s_('TestHooks|Ensure the project has releases.') } unless release.present? + no_data_error(s_('TestHooks|Ensure the project has releases.')) unless release.present? release.to_hook_data('create') end diff --git a/app/services/integrations/test/base_service.rb b/app/services/integrations/test/base_service.rb index a8a027092d5..6291f2dfbaa 100644 --- a/app/services/integrations/test/base_service.rb +++ b/app/services/integrations/test/base_service.rb @@ -21,9 +21,9 @@ module Integrations return error('Testing not available for this event') end - return error(data[:error]) if data[:error].present? - integration.test(data) + rescue ArgumentError => e + error(e.message) end private diff --git a/app/services/test_hooks/base_service.rb b/app/services/test_hooks/base_service.rb index b41a9959c13..3f2949a53ba 100644 --- a/app/services/test_hooks/base_service.rb +++ b/app/services/test_hooks/base_service.rb @@ -16,9 +16,16 @@ module TestHooks trigger_key = hook.class.triggers.key(trigger.to_sym) return error('Testing not available for this hook') if trigger_key.nil? || data.blank? + return error(data[:error]) if data[:error].present? hook.execute(data, trigger_key, force: true) + rescue ArgumentError => e + error(e.message) + end + + def error(message) + ServiceResponse.error(message: message) end end end diff --git a/app/views/devise/shared/_signup_omniauth_provider_list.haml b/app/views/devise/shared/_signup_omniauth_provider_list.haml index 5c085555872..a96c8d6358b 100644 --- a/app/views/devise/shared/_signup_omniauth_provider_list.haml +++ b/app/views/devise/shared/_signup_omniauth_provider_list.haml @@ -1,4 +1,4 @@ -- register_omniauth_params = Feature.enabled?(:update_oauth_registration_flow) ? { intent: :register } : {} +- register_omniauth_params = { intent: :register } - if Feature.enabled?(:restyle_login_page, @project) .gl-text-center.gl-pt-5 %label.gl-font-weight-normal diff --git a/app/views/projects/pipeline_schedules/index.html.haml b/app/views/projects/pipeline_schedules/index.html.haml index cb7cd631859..ab86d505f0f 100644 --- a/app/views/projects/pipeline_schedules/index.html.haml +++ b/app/views/projects/pipeline_schedules/index.html.haml @@ -6,7 +6,7 @@ #pipeline-schedules-callout{ data: { docs_url: help_page_path('ci/pipelines/schedules'), illustration_url: image_path('illustrations/pipeline_schedule_callout.svg') } } - if Feature.enabled?(:pipeline_schedules_vue, @project) - #pipeline-schedules-app{ data: { full_path: @project.full_path } } + #pipeline-schedules-app{ data: { full_path: @project.full_path, pipelines_path: project_pipelines_path(@project) } } - else .top-area - schedule_path_proc = ->(scope) { pipeline_schedules_path(@project, scope: scope) } diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml index 5a2303400bd..81a6b95d04e 100644 --- a/app/workers/all_queues.yml +++ b/app/workers/all_queues.yml @@ -698,7 +698,7 @@ :tags: [] - :name: cronjob:remove_unreferenced_lfs_objects :worker_name: RemoveUnreferencedLfsObjectsWorker - :feature_category: :git_lfs + :feature_category: :source_code_management :has_external_dependencies: false :urgency: :low :resource_boundary: :unknown @@ -725,7 +725,7 @@ :tags: [] - :name: cronjob:schedule_merge_request_cleanup_refs :worker_name: ScheduleMergeRequestCleanupRefsWorker - :feature_category: :code_review + :feature_category: :code_review_workflow :has_external_dependencies: false :urgency: :low :resource_boundary: :unknown @@ -734,7 +734,7 @@ :tags: [] - :name: cronjob:schedule_migrate_external_diffs :worker_name: ScheduleMigrateExternalDiffsWorker - :feature_category: :code_review + :feature_category: :code_review_workflow :has_external_dependencies: false :urgency: :low :resource_boundary: :unknown @@ -779,7 +779,7 @@ :tags: [] - :name: cronjob:stuck_merge_jobs :worker_name: StuckMergeJobsWorker - :feature_category: :code_review + :feature_category: :code_review_workflow :has_external_dependencies: false :urgency: :low :resource_boundary: :unknown @@ -2345,7 +2345,7 @@ :tags: [] - :name: create_note_diff_file :worker_name: CreateNoteDiffFileWorker - :feature_category: :code_review + :feature_category: :code_review_workflow :has_external_dependencies: false :urgency: :low :resource_boundary: :unknown @@ -2363,7 +2363,7 @@ :tags: [] - :name: delete_diff_files :worker_name: DeleteDiffFilesWorker - :feature_category: :code_review + :feature_category: :code_review_workflow :has_external_dependencies: false :urgency: :low :resource_boundary: :unknown @@ -2750,7 +2750,7 @@ :tags: [] - :name: merge_request_cleanup_refs :worker_name: MergeRequestCleanupRefsWorker - :feature_category: :code_review + :feature_category: :code_review_workflow :has_external_dependencies: false :urgency: :low :resource_boundary: :unknown @@ -2759,7 +2759,7 @@ :tags: [] - :name: merge_request_mergeability_check :worker_name: MergeRequestMergeabilityCheckWorker - :feature_category: :code_review + :feature_category: :code_review_workflow :has_external_dependencies: false :urgency: :low :resource_boundary: :unknown @@ -2768,7 +2768,7 @@ :tags: [] - :name: merge_requests_close_issue :worker_name: MergeRequests::CloseIssueWorker - :feature_category: :code_review + :feature_category: :code_review_workflow :has_external_dependencies: true :urgency: :low :resource_boundary: :unknown @@ -2777,7 +2777,7 @@ :tags: [] - :name: merge_requests_create_approval_event :worker_name: MergeRequests::CreateApprovalEventWorker - :feature_category: :code_review + :feature_category: :code_review_workflow :has_external_dependencies: false :urgency: :low :resource_boundary: :unknown @@ -2786,7 +2786,7 @@ :tags: [] - :name: merge_requests_create_approval_note :worker_name: MergeRequests::CreateApprovalNoteWorker - :feature_category: :code_review + :feature_category: :code_review_workflow :has_external_dependencies: false :urgency: :low :resource_boundary: :unknown @@ -2804,7 +2804,7 @@ :tags: [] - :name: merge_requests_execute_approval_hooks :worker_name: MergeRequests::ExecuteApprovalHooksWorker - :feature_category: :code_review + :feature_category: :code_review_workflow :has_external_dependencies: true :urgency: :low :resource_boundary: :unknown @@ -2813,7 +2813,7 @@ :tags: [] - :name: merge_requests_handle_assignees_change :worker_name: MergeRequests::HandleAssigneesChangeWorker - :feature_category: :code_review + :feature_category: :code_review_workflow :has_external_dependencies: false :urgency: :high :resource_boundary: :unknown @@ -2822,7 +2822,7 @@ :tags: [] - :name: merge_requests_resolve_todos :worker_name: MergeRequests::ResolveTodosWorker - :feature_category: :code_review + :feature_category: :code_review_workflow :has_external_dependencies: false :urgency: :high :resource_boundary: :unknown @@ -2831,7 +2831,7 @@ :tags: [] - :name: merge_requests_resolve_todos_after_approval :worker_name: MergeRequests::ResolveTodosAfterApprovalWorker - :feature_category: :code_review + :feature_category: :code_review_workflow :has_external_dependencies: false :urgency: :low :resource_boundary: :unknown @@ -2840,7 +2840,7 @@ :tags: [] - :name: merge_requests_update_head_pipeline :worker_name: MergeRequests::UpdateHeadPipelineWorker - :feature_category: :code_review + :feature_category: :code_review_workflow :has_external_dependencies: false :urgency: :high :resource_boundary: :cpu @@ -2867,7 +2867,7 @@ :tags: [] - :name: migrate_external_diffs :worker_name: MigrateExternalDiffsWorker - :feature_category: :code_review + :feature_category: :code_review_workflow :has_external_dependencies: false :urgency: :low :resource_boundary: :unknown @@ -2903,7 +2903,7 @@ :tags: [] - :name: new_merge_request :worker_name: NewMergeRequestWorker - :feature_category: :code_review + :feature_category: :code_review_workflow :has_external_dependencies: false :urgency: :high :resource_boundary: :cpu @@ -3362,7 +3362,7 @@ :tags: [] - :name: update_merge_requests :worker_name: UpdateMergeRequestsWorker - :feature_category: :code_review + :feature_category: :code_review_workflow :has_external_dependencies: false :urgency: :high :resource_boundary: :cpu diff --git a/app/workers/create_note_diff_file_worker.rb b/app/workers/create_note_diff_file_worker.rb index 8481fd0a2ab..c5b5e1cef41 100644 --- a/app/workers/create_note_diff_file_worker.rb +++ b/app/workers/create_note_diff_file_worker.rb @@ -7,7 +7,7 @@ class CreateNoteDiffFileWorker # rubocop:disable Scalability/IdempotentWorker sidekiq_options retry: 3 - feature_category :code_review + feature_category :code_review_workflow def perform(diff_note_id) return unless diff_note_id.present? diff --git a/app/workers/delete_diff_files_worker.rb b/app/workers/delete_diff_files_worker.rb index 54d8fcb6dfd..f9f5e6ed35b 100644 --- a/app/workers/delete_diff_files_worker.rb +++ b/app/workers/delete_diff_files_worker.rb @@ -7,7 +7,7 @@ class DeleteDiffFilesWorker # rubocop:disable Scalability/IdempotentWorker sidekiq_options retry: 3 - feature_category :code_review + feature_category :code_review_workflow # rubocop: disable CodeReuse/ActiveRecord def perform(merge_request_diff_id) diff --git a/app/workers/merge_request_cleanup_refs_worker.rb b/app/workers/merge_request_cleanup_refs_worker.rb index db6f4649f47..92dfe8a8cb0 100644 --- a/app/workers/merge_request_cleanup_refs_worker.rb +++ b/app/workers/merge_request_cleanup_refs_worker.rb @@ -9,7 +9,7 @@ class MergeRequestCleanupRefsWorker sidekiq_options retry: 3 - feature_category :code_review + feature_category :code_review_workflow idempotent! # Hard-coded to 4 for now. Will be configurable later on via application settings. diff --git a/app/workers/merge_request_mergeability_check_worker.rb b/app/workers/merge_request_mergeability_check_worker.rb index 0e1ab505644..2ef4220131a 100644 --- a/app/workers/merge_request_mergeability_check_worker.rb +++ b/app/workers/merge_request_mergeability_check_worker.rb @@ -7,7 +7,7 @@ class MergeRequestMergeabilityCheckWorker sidekiq_options retry: 3 - feature_category :code_review + feature_category :code_review_workflow idempotent! def logger diff --git a/app/workers/merge_requests/close_issue_worker.rb b/app/workers/merge_requests/close_issue_worker.rb index 86d63e571ac..8c3ba1bc5ab 100644 --- a/app/workers/merge_requests/close_issue_worker.rb +++ b/app/workers/merge_requests/close_issue_worker.rb @@ -5,7 +5,7 @@ module MergeRequests include ApplicationWorker data_consistency :always - feature_category :code_review + feature_category :code_review_workflow urgency :low idempotent! diff --git a/app/workers/merge_requests/create_approval_event_worker.rb b/app/workers/merge_requests/create_approval_event_worker.rb index 9b1a3c262e4..09ae51e943c 100644 --- a/app/workers/merge_requests/create_approval_event_worker.rb +++ b/app/workers/merge_requests/create_approval_event_worker.rb @@ -5,7 +5,7 @@ module MergeRequests include Gitlab::EventStore::Subscriber data_consistency :always - feature_category :code_review + feature_category :code_review_workflow urgency :low idempotent! diff --git a/app/workers/merge_requests/create_approval_note_worker.rb b/app/workers/merge_requests/create_approval_note_worker.rb index 841431f6a9d..18b0533169a 100644 --- a/app/workers/merge_requests/create_approval_note_worker.rb +++ b/app/workers/merge_requests/create_approval_note_worker.rb @@ -5,7 +5,7 @@ module MergeRequests include Gitlab::EventStore::Subscriber data_consistency :always - feature_category :code_review + feature_category :code_review_workflow urgency :low idempotent! diff --git a/app/workers/merge_requests/execute_approval_hooks_worker.rb b/app/workers/merge_requests/execute_approval_hooks_worker.rb index 81eca425a38..0a127e16f26 100644 --- a/app/workers/merge_requests/execute_approval_hooks_worker.rb +++ b/app/workers/merge_requests/execute_approval_hooks_worker.rb @@ -5,7 +5,7 @@ module MergeRequests include Gitlab::EventStore::Subscriber data_consistency :always - feature_category :code_review + feature_category :code_review_workflow urgency :low idempotent! diff --git a/app/workers/merge_requests/handle_assignees_change_worker.rb b/app/workers/merge_requests/handle_assignees_change_worker.rb index 7cf1be51d23..05e02905008 100644 --- a/app/workers/merge_requests/handle_assignees_change_worker.rb +++ b/app/workers/merge_requests/handle_assignees_change_worker.rb @@ -7,7 +7,7 @@ class MergeRequests::HandleAssigneesChangeWorker sidekiq_options retry: 3 - feature_category :code_review + feature_category :code_review_workflow urgency :high deduplicate :until_executed idempotent! diff --git a/app/workers/merge_requests/resolve_todos_after_approval_worker.rb b/app/workers/merge_requests/resolve_todos_after_approval_worker.rb index 7d9c76ea872..ef02e501de1 100644 --- a/app/workers/merge_requests/resolve_todos_after_approval_worker.rb +++ b/app/workers/merge_requests/resolve_todos_after_approval_worker.rb @@ -5,7 +5,7 @@ module MergeRequests include Gitlab::EventStore::Subscriber data_consistency :always - feature_category :code_review + feature_category :code_review_workflow urgency :low idempotent! diff --git a/app/workers/merge_requests/resolve_todos_worker.rb b/app/workers/merge_requests/resolve_todos_worker.rb index 314cdac4414..15bf92c8ae1 100644 --- a/app/workers/merge_requests/resolve_todos_worker.rb +++ b/app/workers/merge_requests/resolve_todos_worker.rb @@ -7,7 +7,7 @@ class MergeRequests::ResolveTodosWorker sidekiq_options retry: 3 - feature_category :code_review + feature_category :code_review_workflow urgency :high deduplicate :until_executed idempotent! diff --git a/app/workers/merge_requests/update_head_pipeline_worker.rb b/app/workers/merge_requests/update_head_pipeline_worker.rb index bc3a289c1e1..2479bc51cc4 100644 --- a/app/workers/merge_requests/update_head_pipeline_worker.rb +++ b/app/workers/merge_requests/update_head_pipeline_worker.rb @@ -4,7 +4,7 @@ module MergeRequests class UpdateHeadPipelineWorker include Gitlab::EventStore::Subscriber - feature_category :code_review + feature_category :code_review_workflow urgency :high worker_resource_boundary :cpu data_consistency :always diff --git a/app/workers/migrate_external_diffs_worker.rb b/app/workers/migrate_external_diffs_worker.rb index 566797d8b8a..4f1393a631c 100644 --- a/app/workers/migrate_external_diffs_worker.rb +++ b/app/workers/migrate_external_diffs_worker.rb @@ -7,7 +7,7 @@ class MigrateExternalDiffsWorker # rubocop:disable Scalability/IdempotentWorker sidekiq_options retry: 3 - feature_category :code_review + feature_category :code_review_workflow def perform(merge_request_diff_id) diff = MergeRequestDiff.find_by_id(merge_request_diff_id) diff --git a/app/workers/new_merge_request_worker.rb b/app/workers/new_merge_request_worker.rb index 9694d44e8c1..d6e8d517b5a 100644 --- a/app/workers/new_merge_request_worker.rb +++ b/app/workers/new_merge_request_worker.rb @@ -8,7 +8,7 @@ class NewMergeRequestWorker # rubocop:disable Scalability/IdempotentWorker sidekiq_options retry: 3 include NewIssuable - feature_category :code_review + feature_category :code_review_workflow urgency :high worker_resource_boundary :cpu weight 2 diff --git a/app/workers/remove_unreferenced_lfs_objects_worker.rb b/app/workers/remove_unreferenced_lfs_objects_worker.rb index c67ab6e356a..52e17b250c8 100644 --- a/app/workers/remove_unreferenced_lfs_objects_worker.rb +++ b/app/workers/remove_unreferenced_lfs_objects_worker.rb @@ -10,7 +10,7 @@ class RemoveUnreferencedLfsObjectsWorker include CronjobQueue # rubocop:enable Scalability/CronWorkerContext - feature_category :git_lfs + feature_category :source_code_management deduplicate :until_executed idempotent! diff --git a/app/workers/schedule_merge_request_cleanup_refs_worker.rb b/app/workers/schedule_merge_request_cleanup_refs_worker.rb index 8099c3d56b6..ced1f443ea6 100644 --- a/app/workers/schedule_merge_request_cleanup_refs_worker.rb +++ b/app/workers/schedule_merge_request_cleanup_refs_worker.rb @@ -7,7 +7,7 @@ class ScheduleMergeRequestCleanupRefsWorker include CronjobQueue # rubocop:disable Scalability/CronWorkerContext - feature_category :code_review + feature_category :code_review_workflow idempotent! def perform diff --git a/app/workers/schedule_migrate_external_diffs_worker.rb b/app/workers/schedule_migrate_external_diffs_worker.rb index b2dea5083b4..8f643cf7819 100644 --- a/app/workers/schedule_migrate_external_diffs_worker.rb +++ b/app/workers/schedule_migrate_external_diffs_worker.rb @@ -13,7 +13,7 @@ class ScheduleMigrateExternalDiffsWorker # rubocop:disable Scalability/Idempoten include Gitlab::ExclusiveLeaseHelpers - feature_category :code_review + feature_category :code_review_workflow def perform in_lock(self.class.name.underscore, ttl: 2.hours, retries: 0) do diff --git a/app/workers/stuck_merge_jobs_worker.rb b/app/workers/stuck_merge_jobs_worker.rb index 3a650fcb7bf..44f2d5ade58 100644 --- a/app/workers/stuck_merge_jobs_worker.rb +++ b/app/workers/stuck_merge_jobs_worker.rb @@ -7,7 +7,7 @@ class StuckMergeJobsWorker # rubocop:disable Scalability/IdempotentWorker include CronjobQueue # rubocop:disable Scalability/CronWorkerContext - feature_category :code_review + feature_category :code_review_workflow def self.logger Gitlab::AppLogger diff --git a/app/workers/update_merge_requests_worker.rb b/app/workers/update_merge_requests_worker.rb index eb69c0eaba6..caf46c1ac4e 100644 --- a/app/workers/update_merge_requests_worker.rb +++ b/app/workers/update_merge_requests_worker.rb @@ -7,7 +7,7 @@ class UpdateMergeRequestsWorker # rubocop:disable Scalability/IdempotentWorker sidekiq_options retry: 3 - feature_category :code_review + feature_category :code_review_workflow urgency :high worker_resource_boundary :cpu weight 3 |