Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-07-19 00:09:42 +00:00
parent 540020f815
commit 91d37b9714
28 changed files with 494 additions and 69 deletions

View file

@ -49,3 +49,5 @@ export const SEARCH_RESULTS_DESCRIPTION = 'search-results-description';
export const SCOPE_TOKEN_MAX_LENGTH = 36;
export const INPUT_FIELD_PADDING = 52;
export const HEADER_INIT_EVENTS = ['input', 'focus'];

View file

@ -1,4 +1,5 @@
import * as Sentry from '@sentry/browser';
import { HEADER_INIT_EVENTS } from './constants';
async function eventHandler(callback = () => {}) {
if (this.newHeaderSearchFeatureFlag) {
@ -28,21 +29,25 @@ async function eventHandler(callback = () => {}) {
}
function cleanEventListeners() {
document.querySelector('#search').removeEventListener('focus', eventHandler);
HEADER_INIT_EVENTS.forEach((eventType) => {
document.querySelector('#search').removeEventListener(eventType, eventHandler);
});
}
function initHeaderSearch() {
const searchInputBox = document.querySelector('#search');
HEADER_INIT_EVENTS.forEach((eventType) => {
searchInputBox?.addEventListener(
'focus',
eventType,
eventHandler.bind(
{ searchInputBox, newHeaderSearchFeatureFlag: gon?.features?.newHeaderSearch },
cleanEventListeners,
),
{ once: true },
);
});
}
export default initHeaderSearch;
export { eventHandler };
export { eventHandler, cleanEventListeners };

View file

@ -6,9 +6,14 @@ module Types
graphql_name 'CiRunnerUpgradeStatusType'
::Ci::RunnerVersion::STATUS_DESCRIPTIONS.each do |status, description|
status = :invalid if status == :invalid_version
status_name_src =
if status == :invalid_version
:invalid
else
status
end
value status.to_s.upcase, description: description, value: status
value status_name_src.to_s.upcase, description: description, value: status
end
end
end

View file

@ -7,7 +7,7 @@ module Ci
enum_with_nil status: {
not_processed: nil,
invalid_version: -1, # Named invalid_version to avoid clash with auto-generated `invalid?` ActiveRecord method
invalid_version: -1,
unknown: 0,
not_available: 1,
available: 2,

View file

@ -1049,8 +1049,8 @@ class Repository
blob_data_at(sha, '.lfsconfig')
end
def changelog_config(ref = 'HEAD')
blob_data_at(ref, Gitlab::Changelog::Config::FILE_PATH)
def changelog_config(ref, path)
blob_data_at(ref, path)
end
def fetch_ref(source_repository, source_ref:, target_ref:)

View file

@ -41,6 +41,9 @@ module Repositories
# The `trailer` argument is the Git trailer to use for determining what
# commits to include in the changelog.
#
# The `config_file` arguments specifies the path to the configuration file as
# stored in the project's Git repository.
#
# The `file` arguments specifies the name/path of the file to commit the
# changes to. If the file doesn't exist, it's created automatically.
#
@ -57,6 +60,7 @@ module Repositories
to: branch,
date: DateTime.now,
trailer: DEFAULT_TRAILER,
config_file: Gitlab::Changelog::Config::DEFAULT_FILE_PATH,
file: DEFAULT_FILE,
message: "Add changelog for version #{version}"
)
@ -68,13 +72,14 @@ module Repositories
@date = date
@branch = branch
@trailer = trailer
@config_file = config_file
@file = file
@message = message
end
# rubocop: enable Metrics/ParameterLists
def execute(commit_to_changelog: true)
config = Gitlab::Changelog::Config.from_git(@project, @user)
config = Gitlab::Changelog::Config.from_git(@project, @user, @config_file)
from = start_of_commit_range(config)
# For every entry we want to only include the merge request that

View file

@ -7,7 +7,7 @@ module WaitableWorker
# Schedules multiple jobs and waits for them to be completed.
def bulk_perform_and_wait(args_list)
# Short-circuit: it's more efficient to do small numbers of jobs inline
if args_list.size == 1 || (args_list.size <= 3 && !inline_refresh_only_for_single_element?)
if args_list.size == 1
return bulk_perform_inline(args_list)
end
@ -29,10 +29,6 @@ module WaitableWorker
bulk_perform_async(failed) if failed.present?
end
def inline_refresh_only_for_single_element?
Feature.enabled?(:inline_project_authorizations_refresh_only_for_single_element)
end
end
def perform(*args)

View file

@ -1,8 +0,0 @@
---
name: inline_project_authorizations_refresh_only_for_single_element
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91572
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/366815
milestone: '15.2'
type: development
group: group::workspace
default_enabled: false

View file

@ -319,6 +319,7 @@ Supported attributes:
| `date` | datetime | no | The date and time of the release, defaults to the current time. |
| `branch` | string | no | The branch to commit the changelog changes to, defaults to the project's default branch. |
| `trailer` | string | no | The Git trailer to use for including commits, defaults to `Changelog`. |
| `config_file` | string | no | The path of changelog configuration file in the project's Git repository, defaults to `.gitlab/changelog_config.yml`. |
| `file` | string | no | The file to commit the changes to, defaults to `CHANGELOG.md`. |
| `message` | string | no | The commit message to produce when committing the changes, defaults to `Add changelog for version X` where X is the value of the `version` argument. |
@ -453,7 +454,7 @@ If a revert commit includes the trailer used for generating changelogs
### Customize the changelog output
The output is customized using a YAML configuration file stored in your
project's Git repository. This file must reside in
project's Git repository. This default configuration file path is
`.gitlab/changelog_config.yml`.
You can set the following variables in this file:
@ -736,6 +737,7 @@ Supported attributes:
| `to` | string | no | The end of the range of commits (as a SHA) to use for the changelog. This commit _is_ included in the list. Defaults to the branch specified in the `branch` attribute. |
| `date` | datetime | no | The date and time of the release, ISO 8601 formatted. Example: `2016-03-11T03:45:40Z`. Defaults to the current time. |
| `trailer` | string | no | The Git trailer to use for including commits, defaults to `Changelog`. |
| `config_file` | string | no | The path of changelog configuration file in the project's Git repository, defaults to `.gitlab/changelog_config.yml`. |
```shell
curl --header "PRIVATE-TOKEN: token" "https://gitlab.com/api/v4/projects/42/repository/changelog?version=1.0.0"

View file

@ -238,6 +238,10 @@ module API
end
params do
use :release_params
optional :config_file,
type: String,
desc: "The file path to the configuration file as stored in the project's Git repository. Defaults to '.gitlab/changelog_config.yml'"
end
get ':id/repository/changelog' do
service = ::Repositories::ChangelogService.new(
@ -262,6 +266,10 @@ module API
type: String,
desc: 'The branch to commit the changelog changes to'
optional :config_file,
type: String,
desc: "The file path to the configuration file as stored in the project's Git repository. Defaults to '.gitlab/changelog_config.yml'"
optional :file,
type: String,
desc: 'The file to commit the changelog changes to',

View file

@ -7,9 +7,9 @@ module Gitlab
# When rendering changelog entries, authors are not included.
AUTHORS_NONE = 'none'
# The path to the configuration file as stored in the project's Git
# The default path to the configuration file as stored in the project's Git
# repository.
FILE_PATH = '.gitlab/changelog_config.yml'
DEFAULT_FILE_PATH = '.gitlab/changelog_config.yml'
# The default date format to use for formatting release dates.
DEFAULT_DATE_FORMAT = '%Y-%m-%d'
@ -36,8 +36,9 @@ module Gitlab
attr_accessor :date_format, :categories, :template, :tag_regex, :always_credit_user_ids
def self.from_git(project, user = nil)
if (yaml = project.repository.changelog_config.presence)
def self.from_git(project, user = nil, path = nil)
yaml = project.repository.changelog_config('HEAD', path.presence || DEFAULT_FILE_PATH)
if yaml.present?
from_hash(project, YAML.safe_load(yaml), user)
else
new(project)

View file

@ -0,0 +1,86 @@
# frozen_string_literal: true
module Gitlab
module GithubImport
module Importer
module Events
class CrossReferenced
attr_reader :project, :user_id
def initialize(project, user_id)
@project = project
@user_id = user_id
end
# issue_event - An instance of `Gitlab::GithubImport::Representation::IssueEvent`.
def execute(issue_event)
mentioned_in_record_class = mentioned_in_type(issue_event)
mentioned_in_number = issue_event.source.dig(:issue, :number)
mentioned_in_record = init_mentioned_in(
mentioned_in_record_class, mentioned_in_number
)
return if mentioned_in_record.nil?
note_body = cross_reference_note_content(mentioned_in_record.gfm_reference(project))
track_activity(mentioned_in_record_class)
create_note(issue_event, note_body)
end
private
def track_activity(mentioned_in_class)
return if mentioned_in_class != Issue
Gitlab::UsageDataCounters::HLLRedisCounter.track_event(
Gitlab::UsageDataCounters::IssueActivityUniqueCounter::ISSUE_CROSS_REFERENCED,
values: user_id
)
end
def create_note(issue_event, note_body)
Note.create!(
system: true,
noteable_type: Issue.name,
noteable_id: issue_event.issue_db_id,
project: project,
author_id: user_id,
note: note_body,
system_note_metadata: SystemNoteMetadata.new(action: 'cross_reference'),
created_at: issue_event.created_at
)
end
def mentioned_in_type(issue_event)
is_pull_request = issue_event.source.dig(:issue, :pull_request).present?
is_pull_request ? MergeRequest : Issue
end
# record_class - Issue/MergeRequest
def init_mentioned_in(record_class, iid)
db_id = fetch_mentioned_in_db_id(record_class, iid)
return if db_id.nil?
record = record_class.new(id: db_id, iid: iid)
record.project = project
record.readonly!
record
end
# record_class - Issue/MergeRequest
def fetch_mentioned_in_db_id(record_class, number)
sawyer_mentioned_in_adapter = Struct.new(:iid, :issuable_type, keyword_init: true)
mentioned_in_adapter = sawyer_mentioned_in_adapter.new(
iid: number, issuable_type: record_class.name
)
Gitlab::GithubImport::IssuableFinder.new(project, mentioned_in_adapter).database_id
end
def cross_reference_note_content(gfm_reference)
"#{::SystemNotes::IssuablesService.cross_reference_note_prefix}#{gfm_reference}"
end
end
end
end
end
end

View file

@ -30,6 +30,9 @@ module Gitlab
when 'renamed'
Gitlab::GithubImport::Importer::Events::Renamed.new(project, author_id)
.execute(issue_event)
when 'cross-referenced'
Gitlab::GithubImport::Importer::Events::CrossReferenced.new(project, author_id)
.execute(issue_event)
else
Gitlab::GithubImport::Logger.debug(
message: 'UNSUPPORTED_EVENT_TYPE',

View file

@ -21,14 +21,12 @@ module Gitlab
author_id, author_found = user_finder.author_id_for(note)
note_body = MarkdownText.format(note.note, note.author, author_found)
attributes = {
noteable_type: note.noteable_type,
noteable_id: noteable_id,
project_id: project.id,
author_id: author_id,
note: note_body,
note: note_body(author_found),
discussion_id: note.discussion_id,
system: false,
created_at: note.created_at,
@ -48,6 +46,13 @@ module Gitlab
def find_noteable_id
GithubImport::IssuableFinder.new(project, note).database_id
end
private
def note_body(author_found)
text = MarkdownText.convert_ref_links(note.note, project)
MarkdownText.format(text, note.author, author_found)
end
end
end
end

View file

@ -19,6 +19,7 @@ module Gitlab
end
def each_associated(parent_record, associated)
compose_associated_id!(parent_record, associated)
return if already_imported?(associated)
Gitlab::GithubImport::ObjectCounter.increment(project, object_type, :fetched)
@ -68,6 +69,13 @@ module Gitlab
def collection_options
{ state: 'all', sort: 'created', direction: 'asc' }
end
# Cross-referenced events on Github doesn't have id.
def compose_associated_id!(issue, event)
return if event.event != 'cross-referenced'
event.id = "cross-reference##{issue.id}-in-#{event.source.issue.id}"
end
end
end
end

View file

@ -5,10 +5,36 @@ module Gitlab
class MarkdownText
include Gitlab::EncodingHelper
def self.format(*args)
ISSUE_REF_MATCHER = '%{github_url}/%{import_source}/issues'
PULL_REF_MATCHER = '%{github_url}/%{import_source}/pull'
class << self
def format(*args)
new(*args).to_s
end
# Links like `https://domain.github.com/<namespace>/<project>/pull/<iid>` needs to be converted
def convert_ref_links(text, project)
matcher_options = { github_url: github_url, import_source: project.import_source }
issue_ref_matcher = ISSUE_REF_MATCHER % matcher_options
pull_ref_matcher = PULL_REF_MATCHER % matcher_options
url_helpers = Rails.application.routes.url_helpers
text.gsub(issue_ref_matcher, url_helpers.project_issues_url(project))
.gsub(pull_ref_matcher, url_helpers.project_merge_requests_url(project))
end
private
# Returns github domain without slash in the end
def github_url
oauth_config = Gitlab::Auth::OAuth::Provider.config_for('github') || {}
url = oauth_config['url'].presence || 'https://github.com'
url = url.chop if url.end_with?('/')
url
end
end
# text - The Markdown text as a String.
# author - An instance of `Gitlab::GithubImport::Representation::User`
# exists - Boolean that indicates the user exists in the GitLab database.

View file

@ -9,7 +9,8 @@ module Gitlab
attr_reader :attributes
expose_attribute :id, :actor, :event, :commit_id, :label_title, :old_title, :new_title, :created_at
expose_attribute :id, :actor, :event, :commit_id, :label_title, :old_title, :new_title,
:source, :created_at
expose_attribute :issue_db_id # set in SingleEndpointIssueEventsImporter#each_associated
# Builds a event from a GitHub API response.
@ -24,6 +25,7 @@ module Gitlab
label_title: event.label && event.label[:name],
old_title: event.rename && event.rename[:from],
new_title: event.rename && event.rename[:to],
source: event.source,
issue_db_id: event.issue_db_id,
created_at: event.created_at
)

View file

@ -1,6 +1,6 @@
import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
import initHeaderSearch, { eventHandler } from '~/header_search/init';
import initHeaderSearch, { eventHandler, cleanEventListeners } from '~/header_search/init';
describe('Header Search EventListener', () => {
beforeEach(() => {
@ -21,24 +21,25 @@ describe('Header Search EventListener', () => {
it('attached event listener', () => {
const searchInputBox = document?.querySelector('#search');
const addEventListener = jest.spyOn(searchInputBox, 'addEventListener');
const addEventListenerSpy = jest.spyOn(searchInputBox, 'addEventListener');
initHeaderSearch();
expect(addEventListener).toBeCalled();
expect(addEventListenerSpy).toBeCalledTimes(2);
});
it('removes event listener ', async () => {
const removeEventListener = jest.fn();
const searchInputBox = document?.querySelector('#search');
const removeEventListenerSpy = jest.spyOn(searchInputBox, 'removeEventListener');
jest.mock('~/header_search', () => ({ initHeaderSearchApp: jest.fn() }));
await eventHandler.apply(
{
newHeaderSearchFeatureFlag: true,
searchInputBox: document.querySelector('#search'),
},
[removeEventListener],
[cleanEventListeners],
);
expect(removeEventListener).toBeCalled();
expect(removeEventListenerSpy).toBeCalledTimes(2);
});
it('attaches new vue dropdown when feature flag is enabled', async () => {

View file

@ -3,14 +3,22 @@
require 'spec_helper'
RSpec.describe Types::Ci::RunnerUpgradeStatusTypeEnum do
let(:model_only_enum_values) { %w[not_processed] }
let(:expected_graphql_source_values) do
Ci::RunnerVersion.statuses.keys - model_only_enum_values
end
specify { expect(described_class.graphql_name).to eq('CiRunnerUpgradeStatusType') }
it 'exposes all upgrade status values except not_processed' do
expect(described_class.values.keys).to match_array(
Ci::RunnerVersion.statuses.keys
.reject { |k| k == 'not_processed' }
.map { |k| k.upcase }
expected_graphql_source_values
.map(&:upcase)
.map { |v| v == 'INVALID_VERSION' ? 'INVALID' : v }
)
end
it 'exposes all upgrade status values except enum-only values' do
expect(described_class.values.values.map(&:value).map(&:to_s)).to match_array(expected_graphql_source_values)
end
end

View file

@ -20,6 +20,18 @@ RSpec.describe Gitlab::Changelog::Config do
described_class.from_git(project)
end
it "retrieves the specified configuration from git" do
allow(project.repository)
.to receive(:changelog_config).with('HEAD', 'specified_changelog_config.yml')
.and_return("---\ndate_format: '%Y'")
expect(described_class)
.to receive(:from_hash)
.with(project, { 'date_format' => '%Y' }, nil)
described_class.from_git(project, nil, 'specified_changelog_config.yml')
end
it 'returns the default configuration when no YAML file exists in Git' do
allow(project.repository)
.to receive(:changelog_config)

View file

@ -0,0 +1,96 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::GithubImport::Importer::Events::CrossReferenced, :clean_gitlab_redis_cache do
subject(:importer) { described_class.new(project, user.id) }
let_it_be(:project) { create(:project, :repository) }
let_it_be(:user) { create(:user) }
let(:sawyer_stub) { Struct.new(:iid, :issuable_type, keyword_init: true) }
let(:issue) { create(:issue, project: project) }
let(:referenced_in) { build_stubbed(:issue, project: project) }
let(:commit_id) { nil }
let(:issue_event) do
Gitlab::GithubImport::Representation::IssueEvent.from_json_hash(
'id' => 6501124486,
'node_id' => 'CE_lADOHK9fA85If7x0zwAAAAGDf0mG',
'url' => 'https://api.github.com/repos/elhowm/test-import/issues/events/6501124486',
'actor' => { 'id' => 4, 'login' => 'alice' },
'event' => 'cross-referenced',
'source' => {
'type' => 'issue',
'issue' => {
'number' => referenced_in.iid,
'pull_request' => pull_request_resource
}
},
'created_at' => '2022-04-26 18:30:53 UTC',
'issue_db_id' => issue.id
)
end
let(:pull_request_resource) { nil }
let(:expected_note_attrs) do
{
system: true,
noteable_type: Issue.name,
noteable_id: issue_event.issue_db_id,
project_id: project.id,
author_id: user.id,
note: expected_note_body,
created_at: issue_event.created_at
}.stringify_keys
end
context 'when referenced in other issue' do
let(:expected_note_body) { "mentioned in issue ##{issue.iid}" }
before do
other_issue_resource = sawyer_stub.new(iid: referenced_in.iid, issuable_type: 'Issue')
Gitlab::GithubImport::IssuableFinder.new(project, other_issue_resource)
.cache_database_id(referenced_in.iid)
end
it 'creates expected note' do
importer.execute(issue_event)
expect(issue.notes.count).to eq 1
expect(issue.notes[0]).to have_attributes expected_note_attrs
expect(issue.notes[0].system_note_metadata.action).to eq 'cross_reference'
end
end
context 'when referenced in pull request' do
let(:referenced_in) { build_stubbed(:merge_request, project: project) }
let(:pull_request_resource) { { 'id' => referenced_in.iid } }
let(:expected_note_body) { "mentioned in merge request !#{referenced_in.iid}" }
before do
other_issue_resource =
sawyer_stub.new(iid: referenced_in.iid, issuable_type: 'MergeRequest')
Gitlab::GithubImport::IssuableFinder.new(project, other_issue_resource)
.cache_database_id(referenced_in.iid)
end
it 'creates expected note' do
importer.execute(issue_event)
expect(issue.notes.count).to eq 1
expect(issue.notes[0]).to have_attributes expected_note_attrs
expect(issue.notes[0].system_note_metadata.action).to eq 'cross_reference'
end
end
context 'when referenced in out of project issue/pull_request' do
it 'creates expected note' do
importer.execute(issue_event)
expect(issue.notes.count).to eq 0
end
end
end

View file

@ -87,6 +87,13 @@ RSpec.describe Gitlab::GithubImport::Importer::IssueEventImporter, :clean_gitlab
Gitlab::GithubImport::Importer::Events::Renamed
end
context "when it's cross-referenced issue event" do
let(:event_name) { 'cross-referenced' }
it_behaves_like 'triggers specific event importer',
Gitlab::GithubImport::Importer::Events::CrossReferenced
end
context "when it's unknown issue event" do
let(:event_name) { 'fake' }

View file

@ -12,6 +12,54 @@ RSpec.describe Gitlab::GithubImport::MarkdownText do
end
end
describe '.convert_ref_links' do
let_it_be(:project) { create(:project) }
let(:paragraph) { FFaker::Lorem.paragraph }
let(:sentence) { FFaker::Lorem.sentence }
let(:issue_id) { rand(100) }
let(:pull_id) { rand(100) }
let(:text_in) do
<<-TEXT
#{paragraph}
https://github.com/#{project.import_source}/issues/#{issue_id}
#{sentence}
https://github.com/#{project.import_source}/pull/#{pull_id}
TEXT
end
let(:text_out) do
<<-TEXT
#{paragraph}
http://localhost/#{project.full_path}/-/issues/#{issue_id}
#{sentence}
http://localhost/#{project.full_path}/-/merge_requests/#{pull_id}
TEXT
end
it { expect(described_class.convert_ref_links(text_in, project)).to eq text_out }
context 'when Github EE with custom domain name' do
let(:github_domain) { 'https://custom.github.com/' }
let(:text_in) do
<<-TEXT
#{paragraph}
#{github_domain}#{project.import_source}/issues/#{issue_id}
#{sentence}
#{github_domain}#{project.import_source}/pull/#{pull_id}
TEXT
end
before do
allow(Gitlab::Auth::OAuth::Provider)
.to receive(:config_for).with('github').and_return({ 'url' => github_domain })
end
it { expect(described_class.convert_ref_links(text_in, project)).to eq text_out }
end
end
describe '#to_s' do
it 'returns the text when the author was found' do
author = double(:author, login: 'Alice')

View file

@ -21,6 +21,10 @@ RSpec.describe Gitlab::GithubImport::Representation::IssueEvent do
expect(issue_event.commit_id).to eq('570e7b2abdd848b95f2f578043fc23bd6f6fd24d')
end
it 'includes the issue event source' do
expect(issue_event.source).to eq({ type: 'issue', id: 123456 })
end
it 'includes the issue_db_id' do
expect(issue_event.issue_db_id).to eq(100500)
end
@ -89,7 +93,7 @@ RSpec.describe Gitlab::GithubImport::Representation::IssueEvent do
let(:response) do
event_resource = Struct.new(
:id, :node_id, :url, :actor, :event, :commit_id, :commit_url, :label,
:rename, :issue_db_id, :created_at, :performed_via_github_app,
:rename, :issue_db_id, :created_at, :performed_via_github_app, :source,
keyword_init: true
)
user_resource = Struct.new(:id, :login, keyword_init: true)
@ -103,6 +107,7 @@ RSpec.describe Gitlab::GithubImport::Representation::IssueEvent do
commit_url: 'https://api.github.com/repos/octocat/Hello-World/commits'\
'/570e7b2abdd848b95f2f578043fc23bd6f6fd24d',
rename: with_rename ? { from: 'old title', to: 'new title' } : nil,
source: { type: 'issue', id: 123456 },
issue_db_id: 100500,
label: with_label ? { name: 'label title' } : nil,
created_at: '2022-04-26 18:30:53 UTC',
@ -134,6 +139,7 @@ RSpec.describe Gitlab::GithubImport::Representation::IssueEvent do
'label_title' => (with_label ? 'label title' : nil),
'old_title' => with_rename ? 'old title' : nil,
'new_title' => with_rename ? 'new title' : nil,
'source' => { 'type' => 'issue', 'id' => 123456 },
"issue_db_id" => 100500,
'created_at' => '2022-04-26 18:30:53 UTC',
'performed_via_github_app' => nil

View file

@ -2735,6 +2735,33 @@ RSpec.describe Repository do
end
end
describe '#changelog_config' do
let(:user) { create(:user) }
let(:changelog_config_path) { Gitlab::Changelog::Config::DEFAULT_FILE_PATH }
before do
repository.create_file(
user,
changelog_config_path,
'CONTENT',
message: '...',
branch_name: 'master'
)
end
context 'when there is a changelog_config_path at the commit' do
it 'returns the content' do
expect(repository.changelog_config(repository.commit.sha, changelog_config_path)).to eq('CONTENT')
end
end
context 'when there is no changelog_config_path at the commit' do
it 'returns nil' do
expect(repository.changelog_config(repository.commit.parent.sha, changelog_config_path)).to be_nil
end
end
end
describe '#route_map_for' do
before do
repository.create_file(User.last, '.gitlab/route-map.yml', 'CONTENT', message: 'Add .gitlab/route-map.yml', branch_name: 'master')

View file

@ -784,6 +784,40 @@ RSpec.describe API::Repositories do
expect(json_response['notes']).to be_present
end
it 'supports specified config file path' do
spy = instance_spy(Repositories::ChangelogService)
expect(Repositories::ChangelogService)
.to receive(:new)
.with(
project,
user,
version: '1.0.0',
from: 'foo',
to: 'bar',
date: DateTime.new(2020, 1, 1),
trailer: 'Foo',
config_file: 'specified_changelog_config.yml'
)
.and_return(spy)
expect(spy).to receive(:execute).with(commit_to_changelog: false)
get(
api("/projects/#{project.id}/repository/changelog", user),
params: {
version: '1.0.0',
from: 'foo',
to: 'bar',
date: '2020-01-01',
trailer: 'Foo',
config_file: 'specified_changelog_config.yml'
}
)
expect(response).to have_gitlab_http_status(:ok)
end
context 'when previous tag version does not exist' do
it_behaves_like '422 response' do
let(:request) { get api("/projects/#{project.id}/repository/changelog", user), params: { version: 'v0.0.0' } }
@ -905,5 +939,45 @@ RSpec.describe API::Repositories do
expect(response).to have_gitlab_http_status(:unprocessable_entity)
expect(json_response['message']).to eq('Failed to generate the changelog: oops')
end
it "support specified config file path" do
spy = instance_spy(Repositories::ChangelogService)
expect(Repositories::ChangelogService)
.to receive(:new)
.with(
project,
user,
version: '1.0.0',
from: 'foo',
to: 'bar',
date: DateTime.new(2020, 1, 1),
branch: 'kittens',
trailer: 'Foo',
config_file: 'specified_changelog_config.yml',
file: 'FOO.md',
message: 'Commit message'
)
.and_return(spy)
allow(spy).to receive(:execute).with(commit_to_changelog: true)
post(
api("/projects/#{project.id}/repository/changelog", user),
params: {
version: '1.0.0',
from: 'foo',
to: 'bar',
date: '2020-01-01',
branch: 'kittens',
trailer: 'Foo',
config_file: 'specified_changelog_config.yml',
file: 'FOO.md',
message: 'Commit message'
}
)
expect(response).to have_gitlab_http_status(:ok)
end
end
end

View file

@ -194,6 +194,25 @@ RSpec.describe Repositories::ChangelogService do
end
end
end
context 'with specified changelog config file path' do
it 'return specified changelog content' do
config = Gitlab::Changelog::Config.from_hash(project, { 'template' => 'specified_changelog_content' }, creator)
allow(Gitlab::Changelog::Config)
.to receive(:from_git)
.with(project, creator, 'specified_changelog_config.yml')
.and_return(config)
described_class
.new(project, creator, version: '1.0.0', from: sha1, config_file: 'specified_changelog_config.yml')
.execute(commit_to_changelog: commit_to_changelog)
changelog = project.repository.blob_at('master', 'CHANGELOG.md')&.data
expect(changelog).to include('specified_changelog_content')
end
end
end
describe '#start_of_commit_range' do

View file

@ -54,25 +54,6 @@ RSpec.describe WaitableWorker do
worker.bulk_perform_and_wait(arguments)
end
context 'when the feature flag `inline_project_authorizations_refresh_only_for_single_element` is turned off' do
before do
stub_feature_flags(inline_project_authorizations_refresh_only_for_single_element: false)
end
it 'inlines the jobs' do
args_list = [[1], [2], [3]]
expect(worker).to receive(:bulk_perform_inline).with(args_list).and_call_original
expect(Gitlab::AppJsonLogger).to(
receive(:info).with(a_hash_including('message' => 'running inline',
'class' => 'Gitlab::Foo::Bar::DummyWorker',
'job_status' => 'running',
'queue' => 'foo_bar_dummy'))
.exactly(3).times)
worker.bulk_perform_and_wait(args_list)
end
end
end
context '>= 4 jobs' do