Commit 727b1a89 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent aa0f0e99
......@@ -457,7 +457,7 @@ group :ed25519 do
end
# Gitaly GRPC protocol definitions
gem 'gitaly', '~> 1.73.0'
gem 'gitaly', '~> 1.81.0'
gem 'grpc', '~> 1.24.0'
......
......@@ -362,7 +362,7 @@ GEM
po_to_json (>= 1.0.0)
rails (>= 3.2.0)
git (1.5.0)
gitaly (1.73.0)
gitaly (1.81.0)
grpc (~> 1.0)
github-markup (1.7.0)
gitlab-chronic (0.10.5)
......@@ -1211,7 +1211,7 @@ DEPENDENCIES
gettext (~> 3.2.2)
gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.3)
gitaly (~> 1.73.0)
gitaly (~> 1.81.0)
github-markup (~> 1.7.0)
gitlab-chronic (~> 0.10.5)
gitlab-labkit (= 0.8.0)
......
......@@ -149,7 +149,7 @@ export default {
roleDropdownHelpText() {
return sprintf(
s__(
'ClusterIntegration|Select the IAM Role to allow Amazon EKS and the Kubernetes control plane to manage AWS resources on your behalf. To use a new role name, first create one on %{startLink}Amazon Web Services %{externalLinkIcon} %{endLink}.',
'ClusterIntegration|Your service role is distinct from the provision role used when authenticating. It will allow Amazon EKS and the Kubernetes control plane to manage AWS resources on your behalf. To use a new role, first create one on %{startLink}Amazon Web Services %{externalLinkIcon} %{endLink}.',
),
{
startLink:
......@@ -344,7 +344,7 @@ export default {
/>
</div>
<div class="form-group">
<label class="label-bold" for="eks-role">{{ s__('ClusterIntegration|Role name') }}</label>
<label class="label-bold" for="eks-role">{{ s__('ClusterIntegration|Service role') }}</label>
<cluster-form-dropdown
field-id="eks-role"
field-name="eks-role"
......@@ -352,7 +352,7 @@ export default {
:items="roles"
:loading="isLoadingRoles"
:loading-text="s__('ClusterIntegration|Loading IAM Roles')"
:placeholder="s__('ClusterIntergation|Select role name')"
:placeholder="s__('ClusterIntergation|Select service role')"
:search-field-placeholder="s__('ClusterIntegration|Search IAM Roles')"
:empty-text="s__('ClusterIntegration|No IAM Roles found')"
:has-errors="Boolean(loadingRolesError)"
......
......@@ -49,6 +49,10 @@ export default {
triggerEvent() {
this.$emit(this.selectedItem.eventName);
},
changeSelectedItem(item) {
this.selectedItem = item;
this.$emit('change', item);
},
},
};
</script>
......@@ -67,7 +71,7 @@ export default {
:key="item.eventName"
:active="selectedItem === item"
active-class="is-active"
@click="selectedItem = item"
@click="changeSelectedItem(item)"
>
<strong>{{ item.title }}</strong>
<div>{{ item.description }}</div>
......
......@@ -7,7 +7,7 @@ class Projects::ReleasesController < Projects::ApplicationController
before_action :authorize_read_release!
before_action do
push_frontend_feature_flag(:release_issue_summary, project)
push_frontend_feature_flag(:release_evidence_collection, project)
push_frontend_feature_flag(:release_evidence_collection, project, default_enabled: true)
end
before_action :authorize_update_release!, only: %i[edit update]
before_action :authorize_read_release_evidence!, only: [:evidence]
......
# frozen_string_literal: true
class SentryIssueFinder
attr_accessor :project, :current_user
def initialize(project, current_user: nil)
@project = project
@current_user = current_user
end
def execute(identifier)
return unless authorized?
SentryIssue
.for_project_and_identifier(project, identifier)
end
private
def authorized?
Ability.allowed?(current_user, :read_sentry_issue, project)
end
end
......@@ -449,7 +449,7 @@ class MergeRequest < ApplicationRecord
# Set off a rebase asynchronously, atomically updating the `rebase_jid` of
# the MR so that the status of the operation can be tracked.
def rebase_async(user_id)
def rebase_async(user_id, skip_ci: false)
with_rebase_lock do
raise ActiveRecord::StaleObjectError if !open? || rebase_in_progress?
......@@ -458,7 +458,7 @@ class MergeRequest < ApplicationRecord
# attribute is set *and* that the sidekiq job is still running. So a JID
# for a completed RebaseWorker is equivalent to a nil JID.
jid = Sidekiq::Worker.skipping_transaction_check do
RebaseWorker.perform_async(id, user_id)
RebaseWorker.perform_async(id, user_id, skip_ci)
end
update_column(:rebase_jid, jid)
......
......@@ -186,7 +186,11 @@ class Namespace < ApplicationRecord
# any ancestor can disable emails for all descendants
def emails_disabled?
strong_memoize(:emails_disabled) do
self_and_ancestors.where(emails_disabled: true).exists?
if parent_id
self_and_ancestors.where(emails_disabled: true).exists?
else
!!emails_disabled
end
end
end
......
......@@ -1062,18 +1062,22 @@ class Repository
rebase_sha
end
def rebase(user, merge_request)
def rebase(user, merge_request, skip_ci: false)
if Feature.disabled?(:two_step_rebase, default_enabled: true)
return rebase_deprecated(user, merge_request)
end
push_options = []
push_options << Gitlab::PushOptions::CI_SKIP if skip_ci
raw.rebase(
user,
merge_request.id,
branch: merge_request.source_branch,
branch_sha: merge_request.source_branch_sha,
remote_repository: merge_request.target_project.repository.raw,
remote_branch: merge_request.target_branch
remote_branch: merge_request.target_branch,
push_options: push_options
) do |commit_id|
merge_request.update!(rebase_commit_sha: commit_id, merge_error: nil)
end
......
......@@ -4,7 +4,11 @@ class SentryIssue < ApplicationRecord
belongs_to :issue
validates :issue, uniqueness: true, presence: true
validates :sentry_issue_identifier,
uniqueness: true,
presence: true
validates :sentry_issue_identifier, presence: true
def self.for_project_and_identifier(project, identifier)
joins(:issue)
.where(issues: { project_id: project.id })
.find_by_sentry_issue_identifier(identifier)
end
end
......@@ -8,8 +8,9 @@ module MergeRequests
attr_reader :merge_request
def execute(merge_request)
def execute(merge_request, skip_ci: false)
@merge_request = merge_request
@skip_ci = skip_ci
if rebase
success
......@@ -25,7 +26,7 @@ module MergeRequests
return false
end
repository.rebase(current_user, merge_request)
repository.rebase(current_user, merge_request, skip_ci: @skip_ci)
true
rescue => e
......
......@@ -7,12 +7,12 @@ class RebaseWorker
feature_category :source_code_management
def perform(merge_request_id, current_user_id)
def perform(merge_request_id, current_user_id, skip_ci = false)
current_user = User.find(current_user_id)
merge_request = MergeRequest.find(merge_request_id)
MergeRequests::RebaseService
.new(merge_request.source_project, current_user)
.execute(merge_request)
.execute(merge_request, skip_ci: skip_ci)
end
end
---
title: 'Geo: Fix Docker repository synchronization for local storage'
merge_request: 22981
author:
type: fixed
---
title: Bump cluster-applications image to v0.5.0 (Adds GitLab Runner support)
merge_request: 23110
author:
type: added
---
title: Detect go when doing dependency scanning
merge_request: 22712
author:
type: added
---
title: Allow "skip_ci" flag to be passed to rebase operation
merge_request: 22800
author:
type: added
---
title: Updates AWS EKS service role name help text to clarify it is distinct from provision role
merge_request:
author:
type: changed
---
title: Upgrade to Gitaly v1.81.0
merge_request: 23198
author:
type: changed
# frozen_string_literal: true
class AddIndexToSentryIssuesSentryIssueIdentifier < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_concurrent_index :sentry_issues, :sentry_issue_identifier
end
def down
remove_concurrent_index :sentry_issues, :sentry_issue_identifier
end
end
......@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2020_01_14_113341) do
ActiveRecord::Schema.define(version: 2020_01_14_204949) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm"
......@@ -3732,6 +3732,7 @@ ActiveRecord::Schema.define(version: 2020_01_14_113341) do
t.bigint "issue_id", null: false
t.bigint "sentry_issue_identifier", null: false
t.index ["issue_id"], name: "index_sentry_issues_on_issue_id", unique: true
t.index ["sentry_issue_identifier"], name: "index_sentry_issues_on_sentry_issue_identifier"
end
create_table "serverless_domain_cluster", primary_key: "uuid", id: :string, limit: 14, force: :cascade do |t|
......
......@@ -1613,6 +1613,7 @@ PUT /projects/:id/merge_requests/:merge_request_iid/rebase
| --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `merge_request_iid` | integer | yes | The internal ID of the merge request |
| `skip_ci` | boolean | no | Set to `true` to skip creating a CI pipeline |
```bash
curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/76/merge_requests/1/rebase
......
......@@ -476,6 +476,7 @@ Supported applications:
- [Ingress](#install-ingress-using-gitlab-ci)
- [cert-manager](#install-cert-manager-using-gitlab-ci)
- [Sentry](#install-sentry-using-gitlab-ci)
- [GitLab Runner](#install-gitlab-runner-using-gitlab-ci)
### Usage
......@@ -562,7 +563,7 @@ certManager:
installed: false
```
You can customize the installation of Ingress by defining
You can customize the installation of cert-manager by defining
`.gitlab/managed-apps/cert-manager/values.yaml` file in your cluster
management project. Refer to the
[chart](https://hub.helm.sh/charts/jetstack/cert-manager) for the
......@@ -629,6 +630,37 @@ postgresql:
postgresqlPassword: example-postgresql-password
```
### Install GitLab Runner using GitLab CI
GitLab Runner is installed using GitLab CI by defining configuration in
`.gitlab/managed-apps/config.yaml`.
The following configuration is required to install GitLab Runner using GitLab CI:
```yaml
gitlabRunner:
installed: true
```
GitLab Runner is installed into the `gitlab-managed-apps` namespace of your cluster.
In order for GitLab Runner to function, you **must** specify the following:
- `gitlabUrl` - the GitLab server full URL (e.g., `https://example.gitlab.com`) to register the Runner against.
- `runnerRegistrationToken` - The registration token for adding new Runners to GitLab. This must be
[retrieved from your GitLab instance](../../ci/runners/README.md).
These values can be specifed using [CI variables](../../ci/variables/README.md):
- `GITLAB_RUNNER_GITLAB_URL` will be used for `gitlabUrl`.
- `GITLAB_RUNNER_REGISTRATION_TOKEN` will be used for `runnerRegistrationToken`
You can customize the installation of GitLab Runner by defining
`.gitlab/managed-apps/gitlab-runner/values.yaml` file in your cluster
management project. Refer to the
[chart](https://gitlab.com/gitlab-org/charts/gitlab-runner) for the
available configuration options.
## Upgrading applications
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/24789) in GitLab 11.8.
......
......@@ -439,12 +439,15 @@ module API
desc 'Rebase the merge request against its target branch' do
detail 'This feature was added in GitLab 11.6'
end
params do
optional :skip_ci, type: Boolean, desc: 'Do not create CI pipeline'
end
put ':id/merge_requests/:merge_request_iid/rebase' do
merge_request = find_project_merge_request(params[:merge_request_iid])
authorize_push_to_merge_request!(merge_request)
merge_request.rebase_async(current_user.id)
merge_request.rebase_async(current_user.id, skip_ci: params[:skip_ci])
status :accepted
present rebase_in_progress: merge_request.rebase_in_progress?
......
apply:
stage: deploy
image: "registry.gitlab.com/gitlab-org/cluster-integration/cluster-applications:v0.4.0"
image: "registry.gitlab.com/gitlab-org/cluster-integration/cluster-applications:v0.5.0"
environment:
name: production
variables:
......@@ -9,6 +9,7 @@ apply:
INGRESS_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/ingress/values.yaml
CERT_MANAGER_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/cert-manager/values.yaml
SENTRY_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/sentry/values.yaml
GITLAB_RUNNER_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/gitlab-runner/values.yaml
script:
- gitlab-managed-apps /usr/local/share/gitlab-managed-apps/helmfile.yaml
only:
......
......@@ -93,7 +93,7 @@ gemnasium-dependency_scanning:
variables:
- $GITLAB_FEATURES =~ /\bdependency_scanning\b/ &&
$DS_DEFAULT_ANALYZERS =~ /gemnasium([^-]|$)/ &&
$CI_PROJECT_REPOSITORY_LANGUAGES =~ /ruby|javascript|php/
$CI_PROJECT_REPOSITORY_LANGUAGES =~ /ruby|javascript|php|\bgo\b/
gemnasium-maven-dependency_scanning:
extends: .ds-analyzer
......
......@@ -853,7 +853,7 @@ module Gitlab
end
end
def rebase(user, rebase_id, branch:, branch_sha:, remote_repository:, remote_branch:, &block)
def rebase(user, rebase_id, branch:, branch_sha:, remote_repository:, remote_branch:, push_options: [], &block)
wrapped_gitaly_errors do
gitaly_operation_client.rebase(
user,
......@@ -862,6 +862,7 @@ module Gitlab
branch_sha: branch_sha,
remote_repository: remote_repository,
remote_branch: remote_branch,
push_options: push_options,
&block
)
end
......
......@@ -233,7 +233,7 @@ module Gitlab
end
end
def rebase(user, rebase_id, branch:, branch_sha:, remote_repository:, remote_branch:)
def rebase(user, rebase_id, branch:, branch_sha:, remote_repository:, remote_branch:, push_options: [])
request_enum = QueueEnumerator.new
rebase_sha = nil
......@@ -256,7 +256,8 @@ module Gitlab
branch: encode_binary(branch),
branch_sha: branch_sha,
remote_repository: remote_repository.gitaly_repository,
remote_branch: encode_binary(remote_branch)
remote_branch: encode_binary(remote_branch),
git_push_options: push_options
)
)
)
......
......@@ -32,6 +32,8 @@ module Gitlab
OPTION_MATCHER = /(?<namespace>[^\.]+)\.(?<key>[^=]+)=?(?<value>.*)/.freeze
CI_SKIP = 'ci.skip'
attr_reader :options
def initialize(options = [])
......
......@@ -4271,9 +4271,6 @@ msgstr ""
msgid "ClusterIntegration|Request to begin uninstalling failed"
msgstr ""
msgid "ClusterIntegration|Role name"
msgstr ""
msgid "ClusterIntegration|Save changes"
msgstr ""
......@@ -4355,9 +4352,6 @@ msgstr ""
msgid "ClusterIntegration|Select project to choose zone"
msgstr ""
msgid "ClusterIntegration|Select the IAM Role to allow Amazon EKS and the Kubernetes control plane to manage AWS resources on your behalf. To use a new role name, first create one on %{startLink}Amazon Web Services %{externalLinkIcon} %{endLink}."
msgstr ""
msgid "ClusterIntegration|Select the key pair name that will be used to create EC2 nodes. To use a new key pair name, first create one on %{startLink}Amazon Web Services %{externalLinkIcon} %{endLink}."
msgstr ""
......@@ -4370,6 +4364,9 @@ msgstr ""
msgid "ClusterIntegration|Service Token"
msgstr ""
msgid "ClusterIntegration|Service role"
msgstr ""
msgid "ClusterIntegration|Service token is required."
msgstr ""
......@@ -4496,6 +4493,9 @@ msgstr ""
msgid "ClusterIntegration|Your cluster API is unreachable. Please ensure your API URL is correct."
msgstr ""
msgid "ClusterIntegration|Your service role is distinct from the provision role used when authenticating. It will allow Amazon EKS and the Kubernetes control plane to manage AWS resources on your behalf. To use a new role, first create one on %{startLink}Amazon Web Services %{externalLinkIcon} %{endLink}."
msgstr ""
msgid "ClusterIntegration|Zone"
msgstr ""
......@@ -4541,7 +4541,7 @@ msgstr ""
msgid "ClusterIntergation|Select key pair"
msgstr ""
msgid "ClusterIntergation|Select role name"
msgid "ClusterIntergation|Select service role"
msgstr ""
msgid "Code"
......
......@@ -94,6 +94,18 @@ module QA
select_element(:project_creation_level_dropdown, value)
click_element :save_permissions_changes_button
end
def toggle_request_access
expand_section :permission_lfs_2fa_section
if find_element(:request_access_checkbox).checked?
uncheck_element :request_access_checkbox
else
check_element :request_access_checkbox
end
click_element :save_permissions_changes_button
end
end
end
end
......
# frozen_string_literal: true
module QA
context 'Manage', :orchestrated, :oauth do
context 'Manage', :orchestrated, :oauth, quarantine: 'https://gitlab.com/gitlab-org/gitlab/issues/196517' do
describe 'OAuth login' do
it 'User logs in to GitLab with GitHub OAuth' do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
......
......@@ -1376,7 +1376,7 @@ describe Projects::MergeRequestsController do
end
def expect_rebase_worker_for(user)
expect(RebaseWorker).to receive(:perform_async).with(merge_request.id, user.id)
expect(RebaseWorker).to receive(:perform_async).with(merge_request.id, user.id, false)
end
context 'successfully' do
......
......@@ -3,6 +3,6 @@
FactoryBot.define do
factory :sentry_issue, class: 'SentryIssue' do
issue
sentry_issue_identifier { 1234567891 }
sequence(:sentry_issue_identifier) { |n| 10000000 + n }
end
end
......@@ -318,7 +318,9 @@ describe 'Issue Boards', :js do
wait_for_requests
click_link bug.title
within('.dropdown-menu-labels') { expect(page).to have_selector('.is-active', count: 3) }
wait_for_requests
click_link regression.title
wait_for_requests
......
# frozen_string_literal: true
require 'spec_helper'
describe SentryIssueFinder do
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
let(:issue) { create(:issue, project: project) }
let(:sentry_issue) { create(:sentry_issue, issue: issue) }
let(:finder) { described_class.new(project, current_user: user) }
describe '#execute' do
let(:identifier) { sentry_issue.sentry_issue_identifier }
subject { finder.execute(identifier) }
context 'when the user is not part of the project' do
it { is_expected.to be_nil }
end
context 'when the user is a project developer' do
before do
project.add_developer(user)
end
it { is_expected.to eq(sentry_issue) }
context 'when identifier is incorrect' do
let(:identifier) { 1234 }
it { is_expected.to be_nil }
end
context 'when accessing another projects identifier' do
let(:second_project) { create(:project) }
let(:second_issue) { create(:issue, project: second_project) }
let(:second_sentry_issue) { create(:sentry_issue, issue: second_issue) }
let(:identifier) { second_sentry_issue.sentry_issue_identifier }
it { is_expected.to be_nil }
end
end
end
end
......@@ -74,6 +74,7 @@ describe('SplitButton', () => {
describe('emitted event', () => {
let eventHandler;
let changeEventHandler;
beforeEach(() => {
createComponent({ actionItems: mockActionItems });
......@@ -84,6 +85,11 @@ describe('SplitButton', () => {
wrapper.vm.$once(eventName, () => eventHandler());
};
const addChangeEventHandler = () => {
changeEventHandler = jest.fn();
wrapper.vm.$once('change', item => changeEventHandler(item));
};
it('defaults to first actionItems event', () => {
addEventHandler(mockActionItems[0]);
......@@ -99,5 +105,13 @@ describe('SplitButton', () => {
.then(() => {
expect(eventHandler).toHaveBeenCalled();
}));
it('change to selected actionItem emits change event', () => {
addChangeEventHandler();
return selectItem(1).then(() => {
expect(changeEventHandler).toHaveBeenCalledWith(mockActionItems[1]);
});
});
});
});
......@@ -2022,7 +2022,7 @@ describe MergeRequest do
it 'atomically enqueues a RebaseWorker job and updates rebase_jid' do
expect(RebaseWorker)
.to receive(:perform_async)
.with(merge_request.id, user_id)
.with(merge_request.id, user_id, false)
.and_return(rebase_jid)
expect(merge_request).to receive(:expire_etag_cache)
......
......@@ -923,6 +923,12 @@ describe Namespace do
expect(group.emails_disabled?).to be_truthy
end
it 'does not query the db when there is no parent group' do
group = create(:group, emails_disabled: true)
expect { group.emails_disabled? }.not_to exceed_query_limit(0)
end
end
context 'when a subgroup' do
......
......@@ -13,6 +13,16 @@ describe SentryIssue do
it { is_expected.to validate_presence_of(:issue) }
it { is_expected.to validate_uniqueness_of(:issue) }
it { is_expected.to validate_presence_of(:sentry_issue_identifier) }
it { is_expected.to validate_uniqueness_of(:sentry_issue_identifier).with_message("has already been taken") }
end
describe '.for_project_and_identifier' do
let!(:sentry_issue) { create(:sentry_issue) }
let(:project) { sentry_issue.issue.project }
let(:identifier) { sentry_issue.sentry_issue_identifier }
let!(:second_sentry_issue) { create(:sentry_issue) }
subject { described_class.for_project_and_identifier(project, identifier) }
it { is_expected.to eq(sentry_issue) }
end
end
......@@ -2222,16 +2222,34 @@ describe API::MergeRequests do
end
describe 'PUT :id/merge_requests/:merge_request_iid/rebase' do
it 'enqueues a rebase of the merge request against the target branch' do
Sidekiq::Testing.fake! do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/rebase", user)
context 'when rebase can be performed' do
it 'enqueues a rebase of the merge request against the target branch' do
Sidekiq::Testing.fake! do
expect do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/rebase", user)
end.to change { RebaseWorker.jobs.size }.by(1)
end
expect(response).to have_gitlab_http_status(202)
expect(merge_request.reload).to be_rebase_in_progress
expect(json_response['rebase_in_progress']).to be(true)
end
expect(response).to have_gitlab_http_status(202)
expect(RebaseWorker.jobs.size).to eq(1)
context 'when skip_ci parameter is set' do
it 'enqueues a rebase of the merge request with skip_ci flag set' do
expect(RebaseWorker).to receive(:perform_async).with(merge_request.id, user.id, true).and_call_original
expect(merge_request.reload).to be_rebase_in_progress
expect(json_response['rebase_in_progress']).to be(true)
Sidekiq::Testing.fake! do
expect do
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/rebase", user), params: { skip_ci: true }
end.to change { RebaseWorker.jobs.size }.by(1)
end
expect(response).to have_gitlab_http_status(202)
expect(merge_request.reload).to be_rebase_in_progress
expect(json_response['rebase_in_progress']).to be(true)
end
end
end
it 'returns 403 if the user cannot push to the branch' do
......
......@@ -15,6 +15,7 @@ describe MergeRequests::RebaseService do
end
let(:project) { merge_request.project }
let(:repository) { project.repository.raw }
let(:skip_ci) { false }
subject(:service) { described_class.new(project, user, {}) }
......@@ -115,7 +116,7 @@ describe MergeRequests::RebaseService do
context 'valid params' do
shared_examples_for 'a service that can execute a successful rebase' do
before do
service.execute(merge_request)
service.execute(merge_request, skip_ci: skip_ci)
end
it 'rebases source branch' do
......@@ -155,6 +156,12 @@ describe MergeRequests::RebaseService do
it_behaves_like 'a service that can execute a successful rebase'
end
context 'when skip_ci flag is set' do
let(:skip_ci) { true }
it_behaves_like 'a service that can execute a successful rebase'
end
context 'fork' do
describe 'successful fork rebase' do
let(:forked_project) do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment