Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
a6db6a23d1
commit
5bc16a3b1a
|
@ -157,6 +157,7 @@ export const SCANNER_NAMES_MAP = {
|
|||
COVERAGE_FUZZING: COVERAGE_FUZZING_NAME,
|
||||
SECRET_DETECTION: SECRET_DETECTION_NAME,
|
||||
DEPENDENCY_SCANNING: DEPENDENCY_SCANNING_NAME,
|
||||
GENERIC: s__('ciReport|Manually Added'),
|
||||
};
|
||||
|
||||
export const securityFeatures = [
|
||||
|
|
|
@ -20,7 +20,7 @@ module Projects
|
|||
|
||||
override :hook
|
||||
def hook
|
||||
@hook ||= integration.service_hook || not_found
|
||||
@hook ||= integration.try(:service_hook) || not_found
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -122,7 +122,7 @@ module Projects
|
|||
end
|
||||
|
||||
def web_hook_logs
|
||||
return unless integration.service_hook.present?
|
||||
return unless integration.try(:service_hook).present?
|
||||
|
||||
@web_hook_logs ||= integration.service_hook.web_hook_logs.recent.page(params[:page])
|
||||
end
|
||||
|
|
|
@ -6,6 +6,7 @@ module Integrations
|
|||
|
||||
included do
|
||||
after_save :update_web_hook!, if: :activated?
|
||||
has_one :service_hook, inverse_of: :integration, foreign_key: :service_id
|
||||
end
|
||||
|
||||
# Return the URL to be used for the webhook.
|
||||
|
|
|
@ -89,7 +89,6 @@ class Integration < ApplicationRecord
|
|||
|
||||
belongs_to :project, inverse_of: :integrations
|
||||
belongs_to :group, inverse_of: :integrations
|
||||
has_one :service_hook, inverse_of: :integration, foreign_key: :service_id
|
||||
|
||||
validates :project_id, presence: true, unless: -> { instance_level? || group_level? }
|
||||
validates :group_id, presence: true, unless: -> { instance_level? || project_level? }
|
||||
|
|
|
@ -27,15 +27,9 @@ module Namespaces
|
|||
def self_and_ancestors(include_self: true, upto: nil, hierarchy_order: nil)
|
||||
return super unless use_traversal_ids_for_ancestor_scopes?
|
||||
|
||||
if Feature.enabled?(:use_traversal_ids_for_ancestor_scopes_with_inner_join)
|
||||
self_and_ancestors_from_inner_join(include_self: include_self,
|
||||
upto: upto, hierarchy_order:
|
||||
hierarchy_order)
|
||||
else
|
||||
self_and_ancestors_from_ancestors_cte(include_self: include_self,
|
||||
upto: upto,
|
||||
hierarchy_order: hierarchy_order)
|
||||
end
|
||||
self_and_ancestors_from_inner_join(include_self: include_self,
|
||||
upto: upto, hierarchy_order:
|
||||
hierarchy_order)
|
||||
end
|
||||
|
||||
def self_and_ancestor_ids(include_self: true)
|
||||
|
@ -117,37 +111,6 @@ module Namespaces
|
|||
use_traversal_ids?
|
||||
end
|
||||
|
||||
def self_and_ancestors_from_ancestors_cte(include_self: true, upto: nil, hierarchy_order: nil)
|
||||
base_cte = all.select('namespaces.id', 'namespaces.traversal_ids').as_cte(:base_ancestors_cte)
|
||||
|
||||
# We have to alias id with 'AS' to avoid ambiguous column references by calling methods.
|
||||
ancestors_cte = unscoped
|
||||
.unscope(where: [:type])
|
||||
.select('id as base_id',
|
||||
"#{unnest_func(base_cte.table['traversal_ids']).to_sql} as ancestor_id")
|
||||
.from(base_cte.table)
|
||||
.as_cte(:ancestors_cte)
|
||||
|
||||
namespaces = Arel::Table.new(:namespaces)
|
||||
|
||||
records = unscoped
|
||||
.with(base_cte.to_arel, ancestors_cte.to_arel)
|
||||
.distinct
|
||||
.from([ancestors_cte.table, namespaces])
|
||||
.where(namespaces[:id].eq(ancestors_cte.table[:ancestor_id]))
|
||||
.order_by_depth(hierarchy_order)
|
||||
|
||||
unless include_self
|
||||
records = records.where(ancestors_cte.table[:base_id].not_eq(ancestors_cte.table[:ancestor_id]))
|
||||
end
|
||||
|
||||
if upto
|
||||
records = records.where.not(id: unscoped.where(id: upto).select('unnest(traversal_ids)'))
|
||||
end
|
||||
|
||||
records
|
||||
end
|
||||
|
||||
def self_and_ancestors_from_inner_join(include_self: true, upto: nil, hierarchy_order: nil)
|
||||
base_cte = all.reselect('namespaces.traversal_ids').as_cte(:base_ancestors_cte)
|
||||
|
||||
|
|
|
@ -1,38 +1,39 @@
|
|||
- verification_enabled = Gitlab::CurrentSettings.pages_domain_verification_enabled?
|
||||
|
||||
- if can?(current_user, :update_pages, @project) && @domains.any?
|
||||
.card
|
||||
.card-header
|
||||
= render Pajamas::CardComponent.new(card_options: { class: 'gl-mb-5'}) do |c|
|
||||
- c.header do
|
||||
Domains (#{@domains.size})
|
||||
%ul.list-group.list-group-flush
|
||||
- @domains.each do |domain|
|
||||
%li.list-group-item.gl-display-flex.gl-justify-content-space-between.gl-align-items-center
|
||||
.gl-display-flex.gl-align-items-center
|
||||
- if verification_enabled
|
||||
- tooltip, status = domain.unverified? ? [s_('GitLabPages|Unverified'), 'failed'] : [s_('GitLabPages|Verified'), 'success']
|
||||
.domain-status.ci-status-icon.has-tooltip{ class: "gl-mr-5 ci-status-icon-#{status}", title: tooltip }
|
||||
= sprite_icon("status_#{status}" )
|
||||
.domain-name
|
||||
= external_link(domain.url, domain.url)
|
||||
- if domain.certificate
|
||||
%div
|
||||
= gl_badge_tag(s_('GitLabPages|Certificate: %{subject}') % { subject: domain.pages_domain.subject })
|
||||
- if domain.expired?
|
||||
= gl_badge_tag s_('GitLabPages|Expired'), variant: :danger
|
||||
%div
|
||||
= link_to s_('GitLabPages|Edit'), project_pages_domain_path(@project, domain), class: "btn gl-button btn-sm btn-grouped btn-confirm btn-inverted"
|
||||
= link_to s_('GitLabPages|Remove'), project_pages_domain_path(@project, domain), data: { confirm: s_('GitLabPages|Are you sure?'), 'confirm-btn-variant': 'danger'}, "aria-label": s_("GitLabPages|Remove domain"), method: :delete, class: "btn gl-button btn-danger btn-sm btn-grouped"
|
||||
- if domain.needs_verification?
|
||||
%li.list-group-item.bs-callout-warning
|
||||
- details_link_start = "<a href='#{project_pages_domain_path(@project, domain)}'>".html_safe
|
||||
- details_link_end = '</a>'.html_safe
|
||||
= s_('GitLabPages|%{domain} is not verified. To learn how to verify ownership, visit your %{link_start}domain details%{link_end}.').html_safe % { domain: domain.domain,
|
||||
link_start: details_link_start,
|
||||
link_end: details_link_end }
|
||||
- if domain.show_auto_ssl_failed_warning?
|
||||
%li.list-group-item.bs-callout-warning
|
||||
- details_link_start = "<a href='#{project_pages_domain_path(@project, domain)}'>".html_safe
|
||||
- details_link_end = '</a>'.html_safe
|
||||
= s_("GitLabPages|Something went wrong while obtaining the Let's Encrypt certificate for %{domain}. To retry visit your %{link_start}domain details%{link_end}.").html_safe % { domain: domain.domain,
|
||||
link_start: details_link_start,
|
||||
link_end: details_link_end }
|
||||
- c.body do
|
||||
%ul.list-group.list-group-flush
|
||||
- @domains.each do |domain|
|
||||
%li.list-group-item.gl-display-flex.gl-justify-content-space-between.gl-align-items-center.gl-p-0
|
||||
.gl-display-flex.gl-align-items-center
|
||||
- if verification_enabled
|
||||
- tooltip, status = domain.unverified? ? [s_('GitLabPages|Unverified'), 'failed'] : [s_('GitLabPages|Verified'), 'success']
|
||||
.domain-status.ci-status-icon.has-tooltip{ class: "gl-mr-5 ci-status-icon-#{status}", title: tooltip }
|
||||
= sprite_icon("status_#{status}" )
|
||||
.domain-name
|
||||
= external_link(domain.url, domain.url)
|
||||
- if domain.certificate
|
||||
%div
|
||||
= gl_badge_tag(s_('GitLabPages|Certificate: %{subject}') % { subject: domain.pages_domain.subject })
|
||||
- if domain.expired?
|
||||
= gl_badge_tag s_('GitLabPages|Expired'), variant: :danger
|
||||
%div
|
||||
= link_to s_('GitLabPages|Edit'), project_pages_domain_path(@project, domain), class: "btn gl-button btn-sm btn-grouped btn-confirm btn-inverted"
|
||||
= link_to s_('GitLabPages|Remove'), project_pages_domain_path(@project, domain), data: { confirm: s_('GitLabPages|Are you sure?'), 'confirm-btn-variant': 'danger'}, "aria-label": s_("GitLabPages|Remove domain"), method: :delete, class: "btn gl-button btn-danger btn-sm btn-grouped"
|
||||
- if domain.needs_verification?
|
||||
%li.list-group-item.bs-callout-warning
|
||||
- details_link_start = "<a href='#{project_pages_domain_path(@project, domain)}'>".html_safe
|
||||
- details_link_end = '</a>'.html_safe
|
||||
= s_('GitLabPages|%{domain} is not verified. To learn how to verify ownership, visit your %{link_start}domain details%{link_end}.').html_safe % { domain: domain.domain,
|
||||
link_start: details_link_start,
|
||||
link_end: details_link_end }
|
||||
- if domain.show_auto_ssl_failed_warning?
|
||||
%li.list-group-item.bs-callout-warning
|
||||
- details_link_start = "<a href='#{project_pages_domain_path(@project, domain)}'>".html_safe
|
||||
- details_link_end = '</a>'.html_safe
|
||||
= s_("GitLabPages|Something went wrong while obtaining the Let's Encrypt certificate for %{domain}. To retry visit your %{link_start}domain details%{link_end}.").html_safe % { domain: domain.domain,
|
||||
link_start: details_link_start,
|
||||
link_end: details_link_end }
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: use_traversal_ids_for_ancestor_scopes_with_inner_join
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/83371
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/356628
|
||||
milestone: '15.1'
|
||||
type: development
|
||||
group: group::workspace
|
||||
default_enabled: false
|
|
@ -201,9 +201,9 @@ GEM
|
|||
nokogiri (1.13.8)
|
||||
mini_portile2 (~> 2.8.0)
|
||||
racc (~> 1.4)
|
||||
octokit (4.21.0)
|
||||
faraday (>= 0.9)
|
||||
sawyer (~> 0.8.0, >= 0.5.3)
|
||||
octokit (4.25.1)
|
||||
faraday (>= 1, < 3)
|
||||
sawyer (~> 0.9)
|
||||
oj (3.13.11)
|
||||
os (1.1.4)
|
||||
parallel (1.19.2)
|
||||
|
@ -270,9 +270,9 @@ GEM
|
|||
rake (>= 0.8.1)
|
||||
ruby2_keywords (0.0.4)
|
||||
rubyzip (2.3.2)
|
||||
sawyer (0.8.2)
|
||||
sawyer (0.9.2)
|
||||
addressable (>= 2.3.5)
|
||||
faraday (> 0.8, < 2.0)
|
||||
faraday (>= 0.17.3, < 3)
|
||||
selenium-webdriver (4.0.3)
|
||||
childprocess (>= 0.5, < 5.0)
|
||||
rexml (~> 3.2, >= 3.2.5)
|
||||
|
|
|
@ -75,7 +75,7 @@ describe('Edit Actions component', () => {
|
|||
it('renders all buttons as enabled', () => {
|
||||
const buttons = findEditButtons().wrappers;
|
||||
buttons.forEach((button) => {
|
||||
expect(button.attributes('disabled')).toBeFalsy();
|
||||
expect(button.attributes('disabled')).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe Gitlab::Git::Tag, :seed_helper do
|
||||
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '', 'group/project') }
|
||||
RSpec.describe Gitlab::Git::Tag do
|
||||
let_it_be(:project) { create(:project, :repository) }
|
||||
let_it_be(:repository) { project.repository.raw }
|
||||
|
||||
describe '#tags' do
|
||||
describe 'first tag' do
|
||||
let(:tag) { repository.tags.first }
|
||||
describe 'unsigned tag' do
|
||||
let(:tag) { repository.tags.detect { |t| t.name == 'v1.0.0' } }
|
||||
|
||||
it { expect(tag.name).to eq("v1.0.0") }
|
||||
it { expect(tag.target).to eq("f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8") }
|
||||
|
@ -22,29 +23,13 @@ RSpec.describe Gitlab::Git::Tag, :seed_helper do
|
|||
it { expect(tag.tagger.timezone).to eq("+0200") }
|
||||
end
|
||||
|
||||
describe 'last tag' do
|
||||
let(:tag) { repository.tags.last }
|
||||
|
||||
it { expect(tag.name).to eq("v1.2.1") }
|
||||
it { expect(tag.target).to eq("2ac1f24e253e08135507d0830508febaaccf02ee") }
|
||||
it { expect(tag.dereferenced_target.sha).to eq("fa1b1e6c004a68b7d8763b86455da9e6b23e36d6") }
|
||||
it { expect(tag.message).to eq("Version 1.2.1") }
|
||||
it { expect(tag.has_signature?).to be_falsey }
|
||||
it { expect(tag.signature_type).to eq(:NONE) }
|
||||
it { expect(tag.signature).to be_nil }
|
||||
it { expect(tag.tagger.name).to eq("Douwe Maan") }
|
||||
it { expect(tag.tagger.email).to eq("douwe@selenight.nl") }
|
||||
it { expect(tag.tagger.date).to eq(Google::Protobuf::Timestamp.new(seconds: 1427789449)) }
|
||||
it { expect(tag.tagger.timezone).to eq("+0200") }
|
||||
end
|
||||
|
||||
describe 'signed tag' do
|
||||
let(:project) { create(:project, :repository) }
|
||||
let(:tag) { project.repository.find_tag('v1.1.1') }
|
||||
let(:tag) { repository.tags.detect { |t| t.name == 'v1.1.1' } }
|
||||
|
||||
it { expect(tag.name).to eq("v1.1.1") }
|
||||
it { expect(tag.target).to eq("8f03acbcd11c53d9c9468078f32a2622005a4841") }
|
||||
it { expect(tag.dereferenced_target.sha).to eq("189a6c924013fc3fe40d6f1ec1dc20214183bc97") }
|
||||
it { expect(tag.message).to eq("x509 signed tag" + "\n" + X509Helpers::User1.signed_tag_signature.chomp) }
|
||||
it { expect(tag.message).to eq("x509 signed tag\n" + X509Helpers::User1.signed_tag_signature.chomp) }
|
||||
it { expect(tag.has_signature?).to be_truthy }
|
||||
it { expect(tag.signature_type).to eq(:X509) }
|
||||
it { expect(tag.signature).not_to be_nil }
|
||||
|
@ -54,11 +39,11 @@ RSpec.describe Gitlab::Git::Tag, :seed_helper do
|
|||
it { expect(tag.tagger.timezone).to eq("+0100") }
|
||||
end
|
||||
|
||||
it { expect(repository.tags.size).to eq(SeedRepo::Repo::TAGS.size) }
|
||||
it { expect(repository.tags.size).to be > 0 }
|
||||
end
|
||||
|
||||
describe '.get_message' do
|
||||
let(:tag_ids) { %w[f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8 8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b] }
|
||||
let(:tag_ids) { %w[f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8 8f03acbcd11c53d9c9468078f32a2622005a4841] }
|
||||
|
||||
subject do
|
||||
tag_ids.map { |id| described_class.get_message(repository, id) }
|
||||
|
@ -66,7 +51,7 @@ RSpec.describe Gitlab::Git::Tag, :seed_helper do
|
|||
|
||||
it 'gets tag messages' do
|
||||
expect(subject[0]).to eq("Release\n")
|
||||
expect(subject[1]).to eq("Version 1.1.0\n")
|
||||
expect(subject[1]).to eq("x509 signed tag\n" + X509Helpers::User1.signed_tag_signature)
|
||||
end
|
||||
|
||||
it 'gets messages in one batch', :request_store do
|
||||
|
|
|
@ -11,7 +11,6 @@ RSpec.describe Integration do
|
|||
describe "Associations" do
|
||||
it { is_expected.to belong_to(:project).inverse_of(:integrations) }
|
||||
it { is_expected.to belong_to(:group).inverse_of(:integrations) }
|
||||
it { is_expected.to have_one(:service_hook).inverse_of(:integration).with_foreign_key(:service_id) }
|
||||
it { is_expected.to have_one(:issue_tracker_data).autosave(true).inverse_of(:integration).with_foreign_key(:service_id).class_name('Integrations::IssueTrackerData') }
|
||||
it { is_expected.to have_one(:jira_tracker_data).autosave(true).inverse_of(:integration).with_foreign_key(:service_id).class_name('Integrations::JiraTrackerData') }
|
||||
end
|
||||
|
|
|
@ -374,14 +374,6 @@ RSpec.describe Namespace do
|
|||
|
||||
context 'linear' do
|
||||
it_behaves_like 'namespace traversal scopes'
|
||||
|
||||
context 'without inner join ancestors query' do
|
||||
before do
|
||||
stub_feature_flags(use_traversal_ids_for_ancestor_scopes_with_inner_join: false)
|
||||
end
|
||||
|
||||
it_behaves_like 'namespace traversal scopes'
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'makes recursive queries' do
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
RSpec.shared_examples "chat integration" do |integration_name|
|
||||
describe "Associations" do
|
||||
it { is_expected.to belong_to :project }
|
||||
it { is_expected.to have_one :service_hook }
|
||||
end
|
||||
|
||||
describe "Validations" do
|
||||
|
|
|
@ -13,7 +13,6 @@ RSpec.shared_examples Integrations::SlackMattermostNotifier do |integration_name
|
|||
|
||||
describe "Associations" do
|
||||
it { is_expected.to belong_to :project }
|
||||
it { is_expected.to have_one :service_hook }
|
||||
end
|
||||
|
||||
describe 'Validations' do
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
RSpec.shared_examples Integrations::HasWebHook do
|
||||
include AfterNextHelpers
|
||||
|
||||
describe 'associations' do
|
||||
it { is_expected.to have_one(:service_hook).inverse_of(:integration).with_foreign_key(:service_id) }
|
||||
end
|
||||
|
||||
describe 'callbacks' do
|
||||
it 'calls #update_web_hook! when enabled' do
|
||||
expect(integration).to receive(:update_web_hook!)
|
||||
|
|
Loading…
Reference in New Issue