Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-11-11 03:08:57 +00:00
parent 5427433c6d
commit 534eb932e0
20 changed files with 140 additions and 70 deletions

View File

@ -44,7 +44,6 @@ module SendsBlob
Blob::CACHE_TIME
end
response.etag = blob.id
!stale
end

View File

@ -176,7 +176,6 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic
end
def update_diff_discussion_positions!
return unless Feature.enabled?(:merge_red_head_comments_position_on_demand, @merge_request.target_project, default_enabled: true)
return if @merge_request.has_any_diff_note_positions?
Discussions::CaptureDiffNotePositionsService.new(@merge_request).execute

View File

@ -12,7 +12,6 @@ class Projects::RawController < Projects::ApplicationController
before_action :authorize_download_code!
before_action :show_rate_limit, only: [:show], unless: :external_storage_request?
before_action :assign_ref_vars
before_action :no_cache_headers, only: [:show]
before_action :redirect_to_external_storage, only: :show, if: :static_objects_external_storage_enabled?
feature_category :source_code_management

View File

@ -10,6 +10,7 @@ class IssueLink < ApplicationRecord
validates :target, presence: true
validates :source, uniqueness: { scope: :target_id, message: 'is already related' }
validate :check_self_relation
validate :check_opposite_relation
scope :for_source_issue, ->(issue) { where(source_id: issue.id) }
scope :for_target_issue, ->(issue) { where(target_id: issue.id) }
@ -33,6 +34,14 @@ class IssueLink < ApplicationRecord
errors.add(:source, 'cannot be related to itself')
end
end
def check_opposite_relation
return unless source && target
if IssueLink.find_by(source: target, target: source)
errors.add(:source, 'is already related to this issue')
end
end
end
IssueLink.prepend_if_ee('EE::IssueLink')

View File

@ -0,0 +1,5 @@
---
title: Cache repository raw endpoint
merge_request: 47225
author:
type: changed

View File

@ -0,0 +1,6 @@
---
title: Reschedule again background migration which convers 'blocked_by' issue links
to 'block'
merge_request: 46770
author:
type: changed

View File

@ -1,8 +0,0 @@
---
name: merge_red_head_comments_position_on_demand
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34148
rollout_issue_url:
milestone: '13.1'
type: development
group: group::source code
default_enabled: true

View File

@ -19,10 +19,8 @@ class ScheduleBlockedByLinksReplacement < ActiveRecord::Migration[6.0]
end
def up
relation = IssueLink.where(link_type: 2)
queue_background_migration_jobs_by_range_at_intervals(
relation, MIGRATION, INTERVAL, batch_size: BATCH_SIZE)
# no-op
# superseded by db/post_migrate/20201102073808_schedule_blocked_by_links_replacement_second_try.rb
end
def down

View File

@ -0,0 +1,30 @@
# frozen_string_literal: true
class ScheduleBlockedByLinksReplacementSecondTry < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
INTERVAL = 2.minutes
# at the time of writing there were 12931 blocked_by issues:
# estimated time is 13 batches * 2 minutes -> 26 minutes
BATCH_SIZE = 1000
MIGRATION = 'ReplaceBlockedByLinks'
disable_ddl_transaction!
class IssueLink < ActiveRecord::Base
include EachBatch
self.table_name = 'issue_links'
end
def up
relation = IssueLink.where(link_type: 2)
queue_background_migration_jobs_by_range_at_intervals(
relation, MIGRATION, INTERVAL, batch_size: BATCH_SIZE)
end
def down
end
end

View File

@ -0,0 +1 @@
153b437ac481f4d79cd5bdee45dd3932f3cb58bf5dce793573c4b651a3b9314f

View File

@ -311,7 +311,7 @@ Parameters:
| --------- | ---- | -------- | ----------- |
| `webhook` | string | true | The Unify Circuit webhook. For example, `https://circuit.com/rest/v2/webhooks/incoming/...`. |
| `notify_only_broken_pipelines` | boolean | false | Send notifications for broken pipelines |
| `branches_to_be_notified` | string | all | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected" |
| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected". The default value is "default" |
| `push_events` | boolean | false | Enable notifications for push events |
| `issues_events` | boolean | false | Enable notifications for issue events |
| `confidential_issues_events` | boolean | false | Enable notifications for confidential issue events |
@ -356,7 +356,7 @@ Parameters:
| --------- | ---- | -------- | ----------- |
| `webhook` | string | true | The Webex Teams webhook. For example, `https://api.ciscospark.com/v1/webhooks/incoming/...`. |
| `notify_only_broken_pipelines` | boolean | false | Send notifications for broken pipelines |
| `branches_to_be_notified` | string | all | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected" |
| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected". The default value is "default" |
| `push_events` | boolean | false | Enable notifications for push events |
| `issues_events` | boolean | false | Enable notifications for issue events |
| `confidential_issues_events` | boolean | false | Enable notifications for confidential issue events |
@ -482,7 +482,7 @@ Parameters:
| `send_from_committer_email` | boolean | false | Send from committer |
| `push_events` | boolean | false | Enable notifications for push events |
| `tag_push_events` | boolean | false | Enable notifications for tag push events |
| `branches_to_be_notified` | string | all | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected". Notifications will be always fired for tag pushes. |
| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected". Notifications will be always fired for tag pushes. The default value is "all" |
### Delete Emails on push service
@ -665,7 +665,7 @@ Parameters:
| `webhook` | string | true | The Hangouts Chat webhook. For example, `https://chat.googleapis.com/v1/spaces...`. |
| `notify_only_broken_pipelines` | boolean | false | Send notifications for broken pipelines |
| `notify_only_default_branch` | boolean | false | DEPRECATED: This parameter has been replaced with `branches_to_be_notified` |
| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected" |
| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected". The default value is "default" |
| `push_events` | boolean | false | Enable notifications for push events |
| `issues_events` | boolean | false | Enable notifications for issue events |
| `confidential_issues_events` | boolean | false | Enable notifications for confidential issue events |
@ -978,7 +978,7 @@ Parameters:
| `recipients` | string | yes | Comma-separated list of recipient email addresses |
| `add_pusher` | boolean | no | Add pusher to recipients list |
| `notify_only_broken_pipelines` | boolean | no | Notify only broken pipelines |
| `branches_to_be_notified` | string | all | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected" |
| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected. The default value is "default" |
| `notify_only_default_branch` | boolean | no | Send notifications only for the default branch ([introduced in GitLab 12.0](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/28271)) |
| `pipeline_events` | boolean | false | Enable notifications for pipeline events |
@ -1171,7 +1171,7 @@ Parameters:
| `channel` | string | false | Default channel to use if others are not configured |
| `notify_only_broken_pipelines` | boolean | false | Send notifications for broken pipelines |
| `notify_only_default_branch` | boolean | false | DEPRECATED: This parameter has been replaced with `branches_to_be_notified` |
| `branches_to_be_notified` | string | all | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected" |
| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected". The default value is "default" |
| `commit_events` | boolean | false | Enable notifications for commit events |
| `confidential_issue_channel` | string | false | The name of the channel to receive confidential issues events notifications |
| `confidential_issues_events` | boolean | false | Enable notifications for confidential issue events |
@ -1230,7 +1230,7 @@ Parameters:
| `webhook` | string | true | The Microsoft Teams webhook. For example, `https://outlook.office.com/webhook/...` |
| `notify_only_broken_pipelines` | boolean | false | Send notifications for broken pipelines |
| `notify_only_default_branch` | boolean | false | DEPRECATED: This parameter has been replaced with `branches_to_be_notified` |
| `branches_to_be_notified` | string | all | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected" |
| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected". The default value is "default" |
| `push_events` | boolean | false | Enable notifications for push events |
| `issues_events` | boolean | false | Enable notifications for issue events |
| `confidential_issues_events` | boolean | false | Enable notifications for confidential issue events |
@ -1281,7 +1281,7 @@ Parameters:
| `channel` | string | false | Default channel to use if others are not configured |
| `notify_only_broken_pipelines` | boolean | false | Send notifications for broken pipelines |
| `notify_only_default_branch` | boolean | false | DEPRECATED: This parameter has been replaced with `branches_to_be_notified` |
| `branches_to_be_notified` | string | all | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected" |
| `branches_to_be_notified` | string | false | Branches to send notifications for. Valid options are "all", "default", "protected", and "default_and_protected". The default value is "default" |
| `push_events` | boolean | false | Enable notifications for push events |
| `issues_events` | boolean | false | Enable notifications for issue events |
| `confidential_issues_events` | boolean | false | Enable notifications for confidential issue events |

View File

@ -23,13 +23,24 @@ for static analysis offenses before pushing your changes.
To install `lefthook`, run the following in your GitLab source directory:
```shell
# Make sure to uninstall Overcommit first
# 1. Make sure to uninstall Overcommit first
overcommit --uninstall
# If using rbenv, at this point you may need to do: rbenv rehash
# Install lefthook
gem install lefthook && lefthook install -f
# 2. Install lefthook...
## With Homebrew (macOS)
brew install Arkweid/lefthook/lefthook
## Or with Go
go get github.com/Arkweid/lefthook
## Or with Rubygems
gem install lefthook
# 3. Install the Git hooks
lefthook install -f
```
Before you push your changes, Lefthook then automatically run Danger checks, and other checks

View File

@ -21,7 +21,7 @@ pre-push:
scss-lint:
tags: stylesheet css style
files: git diff --name-only $(git merge-base origin/master HEAD)..HEAD
glob: "*.scss.css"
glob: "*.scss{,.css}"
exclude: "app/assets/stylesheets/pages/emojis.scss"
run: bundle exec scss-lint --config .scss-lint.yml {files}
rubocop:

View File

@ -12,14 +12,19 @@ module Gitlab
blocked_by_links = IssueLink.where(id: start_id..stop_id).where(link_type: 2)
ActiveRecord::Base.transaction do
# if there is duplicit bi-directional relation (issue2 is blocked by issue1
# and issue1 already links issue2), then we can just delete 'blocked by'.
# This should be rare as we have a pre-create check which checks if issues are
# already linked
blocked_by_links
# There could be two edge cases:
# 1) issue1 is blocked by issue2 AND issue2 blocks issue1 (type 1)
# 2) issue1 is blocked by issue2 AND issue2 is related to issue1 (type 0)
# In both cases cases we couldn't convert blocked by relation to
# `issue2 blocks issue` because there is already a link with the same
# source/target id. To avoid these conflicts, we first delete any
# "opposite" links before we update `blocked by` relation. This
# should be rare as we have a pre-create check which checks if issues
# are already linked
opposite_ids = blocked_by_links
.select('opposite_links.id')
.joins('INNER JOIN issue_links as opposite_links ON issue_links.source_id = opposite_links.target_id AND issue_links.target_id = opposite_links.source_id')
.where('opposite_links.link_type': 1)
.delete_all
IssueLink.where(id: opposite_ids).delete_all
blocked_by_links.update_all('source_id=target_id,target_id=source_id,link_type=1')
end

View File

@ -33,11 +33,6 @@ RSpec.describe Projects::RawController do
it_behaves_like 'project cache control headers'
it_behaves_like 'content disposition headers'
it_behaves_like 'uncached response' do
before do
subject
end
end
end
context 'image header' do
@ -225,6 +220,23 @@ RSpec.describe Projects::RawController do
end
end
end
describe 'caching' do
def request_file
get(:show, params: { namespace_id: project.namespace, project_id: project, id: 'master/README.md' })
end
context 'when If-None-Match header is set' do
it 'returns a 304 status' do
request_file
request.headers['If-None-Match'] = response.headers['ETag']
request_file
expect(response).to have_gitlab_http_status(:not_modified)
end
end
end
end
def execute_raw_requests(requests:, project:, file_path:, **params)

View File

@ -9,28 +9,34 @@ RSpec.describe Gitlab::BackgroundMigration::ReplaceBlockedByLinks, schema: 20201
let(:issue2) { table(:issues).create!(project_id: project.id, title: 'b') }
let(:issue3) { table(:issues).create!(project_id: project.id, title: 'c') }
let(:issue_links) { table(:issue_links) }
let!(:blocks_link) { issue_links.create!(source_id: issue1.id, target_id: issue2.id, link_type: 1) }
let!(:bidirectional_link) { issue_links.create!(source_id: issue2.id, target_id: issue1.id, link_type: 2) }
let!(:blocked_link) { issue_links.create!(source_id: issue1.id, target_id: issue3.id, link_type: 2) }
let!(:blocked_link1) { issue_links.create!(source_id: issue2.id, target_id: issue1.id, link_type: 2) }
let!(:opposite_link1) { issue_links.create!(source_id: issue1.id, target_id: issue2.id, link_type: 1) }
let!(:blocked_link2) { issue_links.create!(source_id: issue1.id, target_id: issue3.id, link_type: 2) }
let!(:opposite_link2) { issue_links.create!(source_id: issue3.id, target_id: issue1.id, link_type: 0) }
let!(:nochange_link) { issue_links.create!(source_id: issue2.id, target_id: issue3.id, link_type: 1) }
subject { described_class.new.perform(issue_links.minimum(:id), issue_links.maximum(:id)) }
it 'deletes issue links where opposite relation already exists' do
expect { subject }.to change { issue_links.count }.by(-1)
it 'deletes any opposite relations' do
subject
expect(issue_links.ids).to match_array([nochange_link.id, blocked_link1.id, blocked_link2.id])
end
it 'ignores issue links other than blocked_by' do
subject
expect(blocks_link.reload.link_type).to eq(1)
expect(nochange_link.reload.link_type).to eq(1)
end
it 'updates blocked_by issue links' do
subject
link = blocked_link.reload
expect(link.link_type).to eq(1)
expect(link.source_id).to eq(issue3.id)
expect(link.target_id).to eq(issue1.id)
expect(blocked_link1.reload.link_type).to eq(1)
expect(blocked_link1.source_id).to eq(issue1.id)
expect(blocked_link1.target_id).to eq(issue2.id)
expect(blocked_link2.reload.link_type).to eq(1)
expect(blocked_link2.source_id).to eq(issue3.id)
expect(blocked_link2.target_id).to eq(issue1.id)
end
end

View File

@ -1,9 +1,9 @@
# frozen_string_literal: true
require 'spec_helper'
require Rails.root.join('db', 'post_migrate', '20201015073808_schedule_blocked_by_links_replacement')
require Rails.root.join('db', 'post_migrate', '20201102073808_schedule_blocked_by_links_replacement_second_try')
RSpec.describe ScheduleBlockedByLinksReplacement do
RSpec.describe ScheduleBlockedByLinksReplacementSecondTry do
let(:namespace) { table(:namespaces).create!(name: 'gitlab', path: 'gitlab-org') }
let(:project) { table(:projects).create!(namespace_id: namespace.id, name: 'gitlab') }
let(:issue1) { table(:issues).create!(project_id: project.id, title: 'a') }

View File

@ -27,7 +27,14 @@ RSpec.describe IssueLink do
.with_message(/already related/)
end
context 'self relation' do
it 'is not valid if an opposite link already exists' do
issue_link = build(:issue_link, source: subject.target, target: subject.source)
expect(issue_link).to be_invalid
expect(issue_link.errors[:source]).to include('is already related to this issue')
end
context 'when it relates to itself' do
let(:issue) { create :issue }
context 'cannot be validated' do

View File

@ -537,13 +537,16 @@ RSpec.describe API::Files do
expect(response).to have_gitlab_http_status(:ok)
end
it_behaves_like 'uncached response' do
before do
url = route('.gitignore') + "/raw"
expect(Gitlab::Workhorse).to receive(:send_git_blob)
it 'sets no-cache headers' do
url = route('.gitignore') + "/raw"
expect(Gitlab::Workhorse).to receive(:send_git_blob)
get api(url, current_user), params: params
end
get api(url, current_user), params: params
expect(response.headers["Cache-Control"]).to include("no-store")
expect(response.headers["Cache-Control"]).to include("no-cache")
expect(response.headers["Pragma"]).to eq("no-cache")
expect(response.headers["Expires"]).to eq("Fri, 01 Jan 1990 00:00:00 GMT")
end
context 'when mandatory params are not given' do

View File

@ -1,12 +0,0 @@
# frozen_string_literal: true
#
# Negates lib/gitlab/no_cache_headers.rb
#
RSpec.shared_examples 'cached response' do
it 'defines a cached header response' do
expect(response.headers["Cache-Control"]).not_to include("no-store", "no-cache")
expect(response.headers["Pragma"]).not_to eq("no-cache")
expect(response.headers["Expires"]).not_to eq("Fri, 01 Jan 1990 00:00:00 GMT")
end
end