diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-10-21 00:09:04 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-10-21 00:09:04 +0300 |
commit | 40e8ba2fc8ac6c3695d7f297ff4143518615a3f9 (patch) | |
tree | ed39c719819b3f2a5e6216f2221cb31bbac3f62c /app | |
parent | a3764262c04bafcd6a54aff635541d73a8a630fd (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
10 files changed, 122 insertions, 56 deletions
diff --git a/app/assets/javascripts/pipelines/components/pipeline_mini_graph/pipeline_stage.vue b/app/assets/javascripts/pipelines/components/pipeline_mini_graph/pipeline_stage.vue index f1c6c6633eb..10a48c83716 100644 --- a/app/assets/javascripts/pipelines/components/pipeline_mini_graph/pipeline_stage.vue +++ b/app/assets/javascripts/pipelines/components/pipeline_mini_graph/pipeline_stage.vue @@ -27,6 +27,7 @@ export default { }, dropdownPopperOpts: { placement: 'bottom', + positionFixed: true, }, components: { CiIcon, diff --git a/app/assets/javascripts/runner/components/runner_jobs_table.vue b/app/assets/javascripts/runner/components/runner_jobs_table.vue index 7817577bab0..3941781408a 100644 --- a/app/assets/javascripts/runner/components/runner_jobs_table.vue +++ b/app/assets/javascripts/runner/components/runner_jobs_table.vue @@ -2,6 +2,7 @@ import { GlTableLite } from '@gitlab/ui'; import { __, s__ } from '~/locale'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; +import { durationTimeFormatted } from '~/lib/utils/datetime_utility'; import CiBadge from '~/vue_shared/components/ci_badge_link.vue'; import RunnerTags from '~/runner/components/runner_tags.vue'; import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue'; @@ -47,6 +48,14 @@ export default { commitPath(job) { return job.commitPath; }, + duration(job) { + const { duration } = job; + return duration ? durationTimeFormatted(duration) : ''; + }, + queued(job) { + const { queuedDuration } = job; + return queuedDuration ? durationTimeFormatted(queuedDuration) : ''; + }, }, fields: [ tableField({ key: 'status', label: s__('Job|Status') }), @@ -54,6 +63,8 @@ export default { tableField({ key: 'project', label: __('Project') }), tableField({ key: 'commit', label: __('Commit') }), tableField({ key: 'finished_at', label: s__('Job|Finished at') }), + tableField({ key: 'duration', label: s__('Job|Duration') }), + tableField({ key: 'queued', label: s__('Job|Queued') }), tableField({ key: 'tags', label: s__('Runners|Tags') }), ], }; @@ -84,12 +95,20 @@ export default { <link-cell :href="commitPath(item)"> {{ commitShortSha(item) }}</link-cell> </template> - <template #cell(tags)="{ item = {} }"> - <runner-tags :tag-list="item.tags" /> - </template> - <template #cell(finished_at)="{ item = {} }"> <time-ago v-if="item.finishedAt" :time="item.finishedAt" /> </template> + + <template #cell(duration)="{ item = {} }"> + {{ duration(item) }} + </template> + + <template #cell(queued)="{ item = {} }"> + {{ queued(item) }} + </template> + + <template #cell(tags)="{ item = {} }"> + <runner-tags :tag-list="item.tags" /> + </template> </gl-table-lite> </template> diff --git a/app/assets/javascripts/runner/graphql/show/runner_jobs.query.graphql b/app/assets/javascripts/runner/graphql/show/runner_jobs.query.graphql index 14585e62bf2..edfc22f644b 100644 --- a/app/assets/javascripts/runner/graphql/show/runner_jobs.query.graphql +++ b/app/assets/javascripts/runner/graphql/show/runner_jobs.query.graphql @@ -25,8 +25,10 @@ query getRunnerJobs($id: CiRunnerID!, $first: Int, $last: Int, $before: String, } shortSha commitPath - tags finishedAt + duration + queuedDuration + tags } pageInfo { ...PageInfo diff --git a/app/controllers/concerns/web_hooks/hook_actions.rb b/app/controllers/concerns/web_hooks/hook_actions.rb index ea11f13c7ef..69c0f2f30d5 100644 --- a/app/controllers/concerns/web_hooks/hook_actions.rb +++ b/app/controllers/concerns/web_hooks/hook_actions.rb @@ -20,7 +20,7 @@ module WebHooks unless hook.valid? self.hooks = relation.select(&:persisted?) - flash[:alert] = hook.errors.full_messages.join.html_safe + flash[:alert] = hook.errors.full_messages.to_sentence.html_safe end redirect_to action: :index @@ -64,7 +64,9 @@ module WebHooks end def hook_param_names - %i[enable_ssl_verification token url push_events_branch_filter] + param_names = %i[enable_ssl_verification token url push_events_branch_filter] + param_names.push(:branch_filter_strategy) if Feature.enabled?(:enhanced_webhook_support_regex) + param_names end def destroy_hook(hook) diff --git a/app/models/hooks/active_hook_filter.rb b/app/models/hooks/active_hook_filter.rb index 283e2d680f4..cdcfd3f3ff5 100644 --- a/app/models/hooks/active_hook_filter.rb +++ b/app/models/hooks/active_hook_filter.rb @@ -3,14 +3,36 @@ class ActiveHookFilter def initialize(hook) @hook = hook - @push_events_filter_matcher = RefMatcher.new(@hook.push_events_branch_filter) end def matches?(hooks_scope, data) - return true if hooks_scope != :push_hooks + return true unless hooks_scope == :push_hooks + + matches_branch?(data) + end + + private + + def matches_branch?(data) return true if @hook.push_events_branch_filter.blank? branch_name = Gitlab::Git.branch_name(data[:ref]) - @push_events_filter_matcher.matches?(branch_name) + + if Feature.disabled?(:enhanced_webhook_support_regex) + return RefMatcher.new(@hook.push_events_branch_filter).matches?(branch_name) + end + + case @hook.branch_filter_strategy + when 'all_branches' + true + when 'wildcard' + RefMatcher.new(@hook.push_events_branch_filter).matches?(branch_name) + when 'regex' + begin + Gitlab::UntrustedRegexp.new(@hook.push_events_branch_filter) === branch_name + rescue RegexpError + false + end + end end end diff --git a/app/models/hooks/web_hook.rb b/app/models/hooks/web_hook.rb index 71794964c99..2822e3131f8 100644 --- a/app/models/hooks/web_hook.rb +++ b/app/models/hooks/web_hook.rb @@ -36,11 +36,22 @@ class WebHook < ApplicationRecord validates :url, public_url: true, unless: ->(hook) { hook.is_a?(SystemHook) } validates :token, format: { without: /\n/ } - validates :push_events_branch_filter, branch_filter: true + after_initialize :initialize_url_variables + before_validation :set_branch_filter_nil, \ + if: -> { branch_filter_strategy_all_branches? && enhanced_webhook_support_regex? } + validates :push_events_branch_filter, \ + untrusted_regexp: true, if: -> { branch_filter_strategy_regex? && enhanced_webhook_support_regex? } + validates :push_events_branch_filter, \ + "web_hooks/wildcard_branch_filter": true, if: -> { branch_filter_strategy_wildcard? } + validates :url_variables, json_schema: { filename: 'web_hooks_url_variables' } validate :no_missing_url_variables - after_initialize :initialize_url_variables + enum branch_filter_strategy: { + wildcard: 0, + regex: 1, + all_branches: 2 + }, _prefix: true scope :executable, -> do next all unless Feature.enabled?(:web_hooks_disable_failed) @@ -224,4 +235,12 @@ class WebHook < ApplicationRecord errors.add(:url, "Invalid URL template. Missing keys: #{missing}") end + + def enhanced_webhook_support_regex? + Feature.enabled?(:enhanced_webhook_support_regex) + end + + def set_branch_filter_nil + self.push_events_branch_filter = nil + end end diff --git a/app/validators/branch_filter_validator.rb b/app/validators/branch_filter_validator.rb deleted file mode 100644 index 89d6343a9a4..00000000000 --- a/app/validators/branch_filter_validator.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -# BranchFilterValidator -# -# Custom validator for branch names. Squishes whitespace and ignores empty -# string. This only checks that a string is a valid git branch name. It does -# not check whether a branch already exists. -# -# Example: -# -# class Webhook < ActiveRecord::Base -# validates :push_events_branch_filter, branch_name: true -# end -# -class BranchFilterValidator < ActiveModel::EachValidator - def validate_each(record, attribute, value) - value.squish! unless value.nil? - - if value.present? - value_without_wildcards = value.tr('*', 'x') - - unless Gitlab::GitRefValidator.validate(value_without_wildcards) - record.errors.add(attribute, "is not a valid branch name") - end - - unless value.length <= 4000 - record.errors.add(attribute, "is longer than the allowed length of 4000 characters.") - end - end - end - - private - - def contains_wildcard?(value) - value.include?('*') - end -end diff --git a/app/validators/web_hooks/wildcard_branch_filter_validator.rb b/app/validators/web_hooks/wildcard_branch_filter_validator.rb new file mode 100644 index 00000000000..12ec78f05de --- /dev/null +++ b/app/validators/web_hooks/wildcard_branch_filter_validator.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +# WildcardBranchFilterValidator +# +# Custom validator for wildcard branch filter. Squishes whitespace and ignores +# empty string. This only checks that a string is a valid wildcard git branch +# like "feature/login" and "feature/*". It doesn't check whether a branch already +# exists. +# +# Example: +# +# class Webhook < ActiveRecord::Base +# validates :push_events_branch_filter, "web_hooks/wildcard_branch_filter": true +# end +# +module WebHooks + class WildcardBranchFilterValidator < ActiveModel::EachValidator + def validate_each(record, attribute, value) + value.squish! unless value.nil? + + return unless value.present? + + value_without_wildcards = value.tr('*', 'x') + + unless Gitlab::GitRefValidator.validate(value_without_wildcards) + record.errors.add(attribute, "is not a valid branch name") + end + + return if value.length <= 4000 + + record.errors.add(attribute, "is longer than the allowed length of 4000 characters.") + end + end +end diff --git a/app/views/projects/hooks/index.html.haml b/app/views/projects/hooks/index.html.haml index 0476193c2cb..e42c5f4c890 100644 --- a/app/views/projects/hooks/index.html.haml +++ b/app/views/projects/hooks/index.html.haml @@ -9,6 +9,6 @@ .col-lg-8.gl-mb-3 = gitlab_ui_form_for @hook, as: :hook, url: polymorphic_path([@project, :hooks]) do |f| = render partial: 'shared/web_hooks/form', locals: { form: f, hook: @hook } - = f.submit 'Add webhook', pajamas_button: true + = f.submit _('Add webhook'), pajamas_button: true, data: { qa_selector: "create_webhook_button" } = render 'shared/web_hooks/index', hooks: @hooks, hook_class: @hook.class diff --git a/app/views/shared/web_hooks/_form.html.haml b/app/views/shared/web_hooks/_form.html.haml index c95e63bdc83..d5b03647f85 100644 --- a/app/views/shared/web_hooks/_form.html.haml +++ b/app/views/shared/web_hooks/_form.html.haml @@ -19,12 +19,16 @@ = form.label :url, s_('Webhooks|Trigger'), class: 'label-bold' %ul.list-unstyled %li.gl-pb-5 - = form.gitlab_ui_checkbox_component :push_events, s_('Webhooks|Push events') - .gl-pl-6 - = form.text_field :push_events_branch_filter, class: 'form-control gl-form-input', - placeholder: 'Branch name or wildcard pattern to trigger on (leave blank for all)' - %p.form-text.text-muted.custom-control - = s_('Webhooks|Push to the repository.') + - if Feature.enabled?(:enhanced_webhook_support_regex) + - is_new_hook = hook.id.nil? + .js-vue-push-events{ data: { push_events: hook.push_events.to_s, strategy: hook.branch_filter_strategy, is_new_hook: is_new_hook.to_s, push_events_branch_filter: hook.push_events_branch_filter } } + - else + = form.gitlab_ui_checkbox_component :push_events, s_('Webhooks|Push events') + .gl-pl-6 + = form.text_field :push_events_branch_filter, class: 'form-control gl-form-input', + placeholder: 'Branch name or wildcard pattern to trigger on (leave blank for all)' + %p.form-text.text-muted.custom-control + = s_('Webhooks|Push to the repository.') %li.gl-pb-5 = form.gitlab_ui_checkbox_component :tag_push_events, s_('Webhooks|Tag push events'), |