Commit 2b6dd165 authored by GitLab Bot's avatar GitLab Bot

Merge remote-tracking branch 'upstream/master' into ce-to-ee-2018-07-06

# Conflicts:
#	spec/services/ci/retry_build_service_spec.rb

[ci skip]
parents 3effb9ac 969b7c56
......@@ -150,6 +150,10 @@ All documentation can be found on [doc.gitlab.com/ee/](http://doc.gitlab.com/ee/
Please see [Getting help for GitLab](https://about.gitlab.com/getting-help/) on our website for the many options to get help.
## Why?
[Read here](https://about.gitlab.com/why/)
## Is it any good?
[Yes](https://news.ycombinator.com/item?id=3067434)
......
......@@ -85,9 +85,9 @@ export const allDiscussions = (state, getters) => {
export const resolvedDiscussionsById = state => {
const map = {};
state.discussions.forEach(n => {
state.discussions.filter(d => d.resolvable).forEach(n => {
if (n.notes) {
const resolved = n.notes.every(note => note.resolved && !note.system);
const resolved = n.notes.filter(note => note.resolvable).every(note => note.resolved);
if (resolved) {
map[n.id] = n;
......
......@@ -242,7 +242,7 @@ class KubernetesService < DeploymentService
end
def deprecation_validation
return if active_changed?(from: true, to: false)
return if active_changed?(from: true, to: false) || (new_record? && !active?)
if deprecated?
errors[:base] << deprecation_message
......
......@@ -286,9 +286,9 @@ class Service < ActiveRecord::Base
def self.build_from_template(project_id, template)
service = template.dup
service.active = false unless service.valid?
service.template = false
service.project_id = project_id
service.active = false if service.active? && !service.valid?
service
end
......
......@@ -18,8 +18,8 @@
#{time_ago_with_tooltip(@build.artifacts_expire_at)}
- elsif @build.has_expiring_artifacts?
%p.build-detail-row
The artifacts will be removed in
%span= time_ago_with_tooltip @build.artifacts_expire_at
The artifacts will be removed
#{time_ago_with_tooltip(@build.artifacts_expire_at)}
- if @build.artifacts?
.btn-group.d-flex{ role: :group }
......
......@@ -117,6 +117,9 @@
%li
JaCoCo (Java/Kotlin)
%code Total.*?([0-9]{1,3})%
%li
go test -cover (Go)
%code coverage: \d+.\d+% of statements
= f.submit _('Save changes'), class: "btn btn-save"
......
---
title: Fix double "in" in time to artifact deletion message
merge_request: 20357
author: "@bbodenmiller"
type: fixed
---
title: Deactivate new KubernetesService created from active template to prevent project creation from failing
merge_request:
author:
type: fixed
......@@ -530,6 +530,39 @@ GET /projects/:id
}
```
If the project is a fork, and you provide a valid token to authenticate, the
`forked_from_project` field will appear in the response.
```json
{
"id":3,
...
"forked_from_project":{
"id":13083,
"description":"GitLab Community Edition",
"name":"GitLab Community Edition",
"name_with_namespace":"GitLab.org / GitLab Community Edition",
"path":"gitlab-ce",
"path_with_namespace":"gitlab-org/gitlab-ce",
"created_at":"2013-09-26T06:02:36.000Z",
"default_branch":"master",
"tag_list":[],
"ssh_url_to_repo":"git@gitlab.com:gitlab-org/gitlab-ce.git",
"http_url_to_repo":"https://gitlab.com/gitlab-org/gitlab-ce.git",
"web_url":"https://gitlab.com/gitlab-org/gitlab-ce",
"avatar_url":"https://assets.gitlab-static.net/uploads/-/system/project/avatar/13083/logo-extra-whitespace.png",
"star_count":3812,
"forks_count":3561,
"last_activity_at":"2018-01-02T11:40:26.570Z"
}
...
}
```
## Get project users
Get the users list of a project.
......
......@@ -32,6 +32,12 @@ module QA
end
def self.configure!
RSpec.configure do |config|
config.define_derived_metadata(file_path: %r{/qa/specs/features/}) do |metadata|
metadata[:type] = :feature
end
end
return if Capybara.drivers.include?(:chrome)
Capybara.register_driver :chrome do |app|
......
......@@ -80,6 +80,13 @@ describe Projects::MergeRequestsController, '(JavaScript fixtures)', type: :cont
render_discussions_json(merge_request, example.description)
end
it 'merge_requests/resolved_diff_discussion.json' do |example|
note = create(:discussion_note_on_merge_request, :resolved, project: project, author: admin, position: position, noteable: merge_request)
create(:system_note, project: project, author: admin, noteable: merge_request, discussion_id: note.discussion.id)
render_discussions_json(merge_request, example.description)
end
context 'with image diff' do
let(:merge_request2) { create(:merge_request_with_diffs, :with_image_diffs, source_project: project, title: "Added images") }
let(:image_path) { "files/images/ee_repo_logo.png" }
......
......@@ -32,12 +32,12 @@ describe('DiscussionCounter component', () => {
{
...discussionMock,
id: discussionMock.id,
notes: [{ ...discussionMock.notes[0], resolved: true }],
notes: [{ ...discussionMock.notes[0], resolvable: true, resolved: true }],
},
{
...discussionMock,
id: discussionMock.id + 1,
notes: [{ ...discussionMock.notes[0], resolved: false }],
notes: [{ ...discussionMock.notes[0], resolvable: true, resolved: false }],
},
];
const firstDiscussionId = discussionMock.id + 1;
......
......@@ -4,22 +4,23 @@ import noteableDiscussion from '~/notes/components/noteable_discussion.vue';
import '~/behaviors/markdown/render_gfm';
import { noteableDataMock, discussionMock, notesDataMock } from '../mock_data';
const discussionWithTwoUnresolvedNotes = 'merge_requests/resolved_diff_discussion.json';
describe('noteable_discussion component', () => {
const Component = Vue.extend(noteableDiscussion);
let store;
let vm;
beforeEach(() => {
const Component = Vue.extend(noteableDiscussion);
preloadFixtures(discussionWithTwoUnresolvedNotes);
beforeEach(() => {
store = createStore();
store.dispatch('setNoteableData', noteableDataMock);
store.dispatch('setNotesData', notesDataMock);
vm = new Component({
store,
propsData: {
discussion: discussionMock,
},
propsData: { discussion: discussionMock },
}).$mount();
});
......@@ -84,7 +85,9 @@ describe('noteable_discussion component', () => {
});
it('is true if there are two unresolved discussions', done => {
spyOnProperty(vm, 'unresolvedDiscussions').and.returnValue([{}, {}]);
const discussion = getJSONFixture(discussionWithTwoUnresolvedNotes)[0];
discussion.notes[0].resolved = false;
vm.$store.dispatch('setInitialNotes', [discussion, discussion]);
Vue.nextTick()
.then(() => {
......@@ -105,12 +108,12 @@ describe('noteable_discussion component', () => {
{
...discussionMock,
id: discussionMock.id + 1,
notes: [{ ...discussionMock.notes[0], resolved: true }],
notes: [{ ...discussionMock.notes[0], resolvable: true, resolved: true }],
},
{
...discussionMock,
id: discussionMock.id + 2,
notes: [{ ...discussionMock.notes[0], resolved: false }],
notes: [{ ...discussionMock.notes[0], resolvable: true, resolved: false }],
},
];
const nextDiscussionId = discussionMock.id + 2;
......
......@@ -303,6 +303,7 @@ export const discussionMock = {
},
],
individual_note: false,
resolvable: true,
};
export const loggedOutnoteableData = {
......
......@@ -7,9 +7,13 @@ import {
collapseNotesMock,
} from '../mock_data';
const discussionWithTwoUnresolvedNotes = 'merge_requests/resolved_diff_discussion.json';
describe('Getters Notes Store', () => {
let state;
preloadFixtures(discussionWithTwoUnresolvedNotes);
beforeEach(() => {
state = {
discussions: [individualNote],
......@@ -22,12 +26,26 @@ describe('Getters Notes Store', () => {
noteableData: noteableDataMock,
};
});
describe('discussions', () => {
it('should return all discussions in the store', () => {
expect(getters.discussions(state)).toEqual([individualNote]);
});
});
describe('resolvedDiscussionsById', () => {
it('ignores unresolved system notes', () => {
const [discussion] = getJSONFixture(discussionWithTwoUnresolvedNotes);
discussion.notes[0].resolved = true;
discussion.notes[1].resolved = false;
state.discussions.push(discussion);
expect(getters.resolvedDiscussionsById(state)).toEqual({
[discussion.id]: discussion,
});
});
});
describe('Collapsed notes', () => {
const stateCollapsedNotes = {
discussions: collapseNotesMock,
......
......@@ -78,7 +78,7 @@ describe Service do
context 'when template is invalid' do
it 'sets service template to inactive when template is invalid' do
project = create(:project)
template = JiraService.new(template: true, active: true)
template = KubernetesService.new(template: true, active: true)
template.save(validate: false)
service = described_class.build_from_template(project.id, template)
......
......@@ -31,8 +31,13 @@ describe Ci::RetryBuildService do
commit_id deployments erased_by_id last_deployment project_id
runner_id tag_taggings taggings tags trigger_request_id
user_id auto_canceled_by_id retried failure_reason
<<<<<<< HEAD
sourced_pipelines artifacts_file_store artifacts_metadata_store
metadata runner_session trace_chunks].freeze # EE
=======
artifacts_file_store artifacts_metadata_store
metadata runner_session trace_chunks].freeze
>>>>>>> upstream/master
shared_examples 'build duplication' do
let(:another_pipeline) { create(:ci_empty_pipeline, project: project) }
......
......@@ -24,7 +24,9 @@ module WaitForRequests
# Wait for client-side AJAX requests
def wait_for_requests
wait_for('JS requests complete') { finished_all_js_requests? }
wait_for('JS requests complete', max_wait_time: 2 * Capybara.default_max_wait_time) do
finished_all_js_requests?
end
end
# Wait for active Rack requests and client-side AJAX requests
......
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