Commit fed371ec authored by GitLab Bot's avatar GitLab Bot

Merge remote-tracking branch 'upstream/master' into ce-to-ee-2018-05-11

parents bd79e130 f1a2ada1
...@@ -140,7 +140,7 @@ export default { ...@@ -140,7 +140,7 @@ export default {
this.file.staged && this.file.key.indexOf('unstaged-') === 0 ? head : null, this.file.staged && this.file.key.indexOf('unstaged-') === 0 ? head : null,
); );
if (this.viewer === viewerTypes.mr) { if (this.viewer === viewerTypes.mr && this.file.mrChange) {
this.editor.attachMergeRequestModel(this.model); this.editor.attachMergeRequestModel(this.model);
} else { } else {
this.editor.attachModel(this.model); this.editor.attachModel(this.model);
......
...@@ -44,6 +44,7 @@ export const dataStructure = () => ({ ...@@ -44,6 +44,7 @@ export const dataStructure = () => ({
size: 0, size: 0,
parentPath: null, parentPath: null,
lastOpenedAt: 0, lastOpenedAt: 0,
mrChange: null,
}); });
export const decorateData = entity => { export const decorateData = entity => {
......
...@@ -111,7 +111,13 @@ ...@@ -111,7 +111,13 @@
</td> </td>
<td> <td>
<span
v-tooltip
:title="tooltipTitle(item.createdAt)"
data-placement="bottom"
>
{{ timeFormated(item.createdAt) }} {{ timeFormated(item.createdAt) }}
</span>
</td> </td>
<td class="content"> <td class="content">
......
...@@ -109,12 +109,12 @@ export default { ...@@ -109,12 +109,12 @@ export default {
rel="noopener noreferrer nofollow" rel="noopener noreferrer nofollow"
class="deploy-link js-deploy-url" class="deploy-link js-deploy-url"
> >
{{ deployment.external_url_formatted }}
<i <i
class="fa fa-external-link" class="fa fa-external-link"
aria-hidden="true" aria-hidden="true"
> >
</i> </i>
{{ deployment.external_url_formatted }}
</a> </a>
</template> </template>
<span <span
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
line-height: $line-height-base;
.title { .title {
display: flex; display: flex;
...@@ -33,10 +34,14 @@ ...@@ -33,10 +34,14 @@
.navbar-collapse { .navbar-collapse {
padding-right: 0; padding-right: 0;
.navbar-nav {
margin: 0;
}
} }
.nav li a { .nav li {
color: $theme-gray-700; float: none;
} }
} }
......
...@@ -109,7 +109,13 @@ module Ci ...@@ -109,7 +109,13 @@ module Ci
end end
def assign_to(project, current_user = nil) def assign_to(project, current_user = nil)
if shared?
self.is_shared = false if shared? self.is_shared = false if shared?
self.runner_type = :project_type
elsif group_type?
raise ArgumentError, 'Transitioning a group runner to a project runner is not supported'
end
self.save self.save
project.runner_projects.create(runner_id: self.id) project.runner_projects.create(runner_id: self.id)
end end
......
...@@ -20,10 +20,10 @@ ...@@ -20,10 +20,10 @@
= brand_header_logo = brand_header_logo
- logo_text = brand_header_logo_type - logo_text = brand_header_logo_type
- if logo_text.present? - if logo_text.present?
%span.logo-text.hidden-xs.prepend-left-8 %span.logo-text.prepend-left-8
= logo_text = logo_text
- if header_link?(:user_dropdown) - if header_link?(:user_dropdown)
.navbar-collapse.collapse .navbar-collapse
%ul.nav.navbar-nav %ul.nav.navbar-nav
%li.header-user.dropdown %li.header-user.dropdown
= link_to current_user, class: user_dropdown_class, data: { toggle: "dropdown" } do = link_to current_user, class: user_dropdown_class, data: { toggle: "dropdown" } do
......
---
title: Moves MR widget external link icon to the right
merge_request: 18828
author: Jacopo Beschi @jacopo-beschi
type: changed
---
title: 46210 Display logo and user dropdown on mobile for terms page and fix styling
merge_request:
author:
type: fixed
---
title: Expand documentation for Runners API
merge_request: 16484
author:
type: other
---
title: 'Add missing tooltip to creation date on container registry overview'
merge_request: 18767
author: Lars Greiss
type: fixed
...@@ -26,17 +26,6 @@ def validate_storages_config ...@@ -26,17 +26,6 @@ def validate_storages_config
Gitlab.config.repositories.storages.each do |name, repository_storage| Gitlab.config.repositories.storages.each do |name, repository_storage|
storage_validation_error("\"#{name}\" is not a valid storage name") unless storage_name_valid?(name) storage_validation_error("\"#{name}\" is not a valid storage name") unless storage_name_valid?(name)
if repository_storage.is_a?(String)
raise "#{name} is not a valid storage, because it has no `path` key. " \
"It may be configured as:\n\n#{name}:\n path: #{repository_storage}\n\n" \
"For source installations, update your config/gitlab.yml Refer to gitlab.yml.example for an updated example.\n\n" \
"If you're using the Gitlab Development Kit, you can update your configuration running `gdk reconfigure`.\n"
end
if !repository_storage.is_a?(Gitlab::GitalyClient::StorageSettings) || repository_storage.legacy_disk_path.nil?
storage_validation_error("#{name} is not a valid storage, because it has no `path` key. Refer to gitlab.yml.example for an updated example")
end
%w(failure_count_threshold failure_reset_time storage_timeout).each do |setting| %w(failure_count_threshold failure_reset_time storage_timeout).each do |setting|
# Falling back to the defaults is fine! # Falling back to the defaults is fine!
next if repository_storage[setting].nil? next if repository_storage[setting].nil?
......
...@@ -411,3 +411,86 @@ DELETE /projects/:id/runners/:runner_id ...@@ -411,3 +411,86 @@ DELETE /projects/:id/runners/:runner_id
``` ```
curl --request DELETE --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/9/runners/9" curl --request DELETE --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/9/runners/9"
``` ```
## Register a new Runner
Register a new Runner for the instance.
```
POST /runners
```
| Attribute | Type | Required | Description |
|-------------|---------|----------|---------------------|
| `token` | string | yes | Registration token ([Read how to obtain a token](../ci/runners/README.md)) |
| `description`| string | no | Runner's description|
| `info` | hash | no | Runner's metadata |
| `active` | boolean| no | Whether the Runner is active |
| `locked` | boolean| no | Whether the Runner should be locked for current project |
| `run_untagged` | boolean | no | Whether the Runner should handle untagged jobs |
| `tag_list` | Array[String] | no | List of Runner's tags |
| `maximum_timeout` | integer | no | Maximum timeout set when this Runner will handle the job |
```
curl --request POST "https://gitlab.example.com/api/v4/runners" --form "token=ipzXrMhuyyJPifUt6ANz" --form "description=test-1-20150125-test" --form "tag_list=ruby,mysql,tag1,tag2"
```
Response:
| Status | Description |
|-----------|---------------------------------|
| 201 | Runner was created |
Example response:
```json
{
"id": "12345",
"token": "6337ff461c94fd3fa32ba3b1ff4125"
}
```
## Delete a registered Runner
Deletes a registed Runner.
```
DELETE /runners
```
| Attribute | Type | Required | Description |
|-------------|---------|----------|---------------------|
| `token` | string | yes | Runner's authentication token |
```
curl --request DELETE "https://gitlab.example.com/api/v4/runners" --form "token=ebb6fc00521627750c8bb750f2490e"
```
Response:
| Status | Description |
|-----------|---------------------------------|
| 204 | Runner was deleted |
## Verify authentication for a registered Runner
Validates authentication credentials for a registered Runner.
```
POST /runners/verify
```
| Attribute | Type | Required | Description |
|-------------|---------|----------|---------------------|
| `token` | string | yes | Runner's authentication token |
```
curl --request POST "https://gitlab.example.com/api/v4/runners/verify" --form "token=ebb6fc00521627750c8bb750f2490e"
```
Response:
| Status | Description |
|-----------|---------------------------------|
| 200 | Credentials are valid |
| 403 | Credentials are invalid |
...@@ -5,6 +5,14 @@ module Gitlab ...@@ -5,6 +5,14 @@ module Gitlab
# directly. # directly.
class StorageSettings class StorageSettings
DirectPathAccessError = Class.new(StandardError) DirectPathAccessError = Class.new(StandardError)
InvalidConfigurationError = Class.new(StandardError)
INVALID_STORAGE_MESSAGE = <<~MSG.freeze
Storage is invalid because it has no `path` key.
For source installations, update your config/gitlab.yml Refer to gitlab.yml.example for an updated example.
If you're using the Gitlab Development Kit, you can update your configuration running `gdk reconfigure`.
MSG
# This class will give easily recognizable NoMethodErrors # This class will give easily recognizable NoMethodErrors
Deprecated = Class.new Deprecated = Class.new
...@@ -12,7 +20,8 @@ module Gitlab ...@@ -12,7 +20,8 @@ module Gitlab
attr_reader :legacy_disk_path attr_reader :legacy_disk_path
def initialize(storage) def initialize(storage)
raise "expected a Hash, got a #{storage.class.name}" unless storage.is_a?(Hash) raise InvalidConfigurationError, "expected a Hash, got a #{storage.class.name}" unless storage.is_a?(Hash)
raise InvalidConfigurationError, INVALID_STORAGE_MESSAGE unless storage.has_key?('path')
# Support a nil 'path' field because some of the circuit breaker tests use it. # Support a nil 'path' field because some of the circuit breaker tests use it.
@legacy_disk_path = File.expand_path(storage['path'], Rails.root) if storage['path'] @legacy_disk_path = File.expand_path(storage['path'], Rails.root) if storage['path']
......
...@@ -42,26 +42,6 @@ describe '6_validations' do ...@@ -42,26 +42,6 @@ describe '6_validations' do
expect { validate_storages_config }.to raise_error('"name with spaces" is not a valid storage name. Please fix this in your gitlab.yml before starting GitLab.') expect { validate_storages_config }.to raise_error('"name with spaces" is not a valid storage name. Please fix this in your gitlab.yml before starting GitLab.')
end end
end end
context 'with incomplete settings' do
before do
mock_storages('foo' => {})
end
it 'throws an error suggesting the user to update its settings' do
expect { validate_storages_config }.to raise_error('foo is not a valid storage, because it has no `path` key. Refer to gitlab.yml.example for an updated example. Please fix this in your gitlab.yml before starting GitLab.')
end
end
context 'with deprecated settings structure' do
before do
mock_storages('foo' => 'tmp/tests/paths/a/b/c')
end
it 'throws an error suggesting the user to update its settings' do
expect { validate_storages_config }.to raise_error("foo is not a valid storage, because it has no `path` key. It may be configured as:\n\nfoo:\n path: tmp/tests/paths/a/b/c\n\nFor source installations, update your config/gitlab.yml Refer to gitlab.yml.example for an updated example.\n\nIf you're using the Gitlab Development Kit, you can update your configuration running `gdk reconfigure`.\n")
end
end
end end
describe 'validate_storages_paths' do describe 'validate_storages_paths' do
......
...@@ -24,7 +24,7 @@ describe('RepoEditor', () => { ...@@ -24,7 +24,7 @@ describe('RepoEditor', () => {
f.active = true; f.active = true;
f.tempFile = true; f.tempFile = true;
vm.$store.state.openFiles.push(f); vm.$store.state.openFiles.push(f);
vm.$store.state.entries[f.path] = f; Vue.set(vm.$store.state.entries, f.path, f);
vm.monaco = true; vm.monaco = true;
vm.$mount(); vm.$mount();
...@@ -215,6 +215,30 @@ describe('RepoEditor', () => { ...@@ -215,6 +215,30 @@ describe('RepoEditor', () => {
expect(vm.editor.attachModel).toHaveBeenCalledWith(vm.model); expect(vm.editor.attachModel).toHaveBeenCalledWith(vm.model);
}); });
it('attaches model to merge request editor', () => {
vm.$store.state.viewer = 'mrdiff';
vm.file.mrChange = true;
spyOn(vm.editor, 'attachMergeRequestModel');
Editor.editorInstance.modelManager.dispose();
vm.setupEditor();
expect(vm.editor.attachMergeRequestModel).toHaveBeenCalledWith(vm.model);
});
it('does not attach model to merge request editor when not a MR change', () => {
vm.$store.state.viewer = 'mrdiff';
vm.file.mrChange = false;
spyOn(vm.editor, 'attachMergeRequestModel');
Editor.editorInstance.modelManager.dispose();
vm.setupEditor();
expect(vm.editor.attachMergeRequestModel).not.toHaveBeenCalledWith(vm.model);
});
it('adds callback methods', () => { it('adds callback methods', () => {
spyOn(vm.editor, 'onPositionChange').and.callThrough(); spyOn(vm.editor, 'onPositionChange').and.callThrough();
......
require 'spec_helper'
describe Gitlab::GitalyClient::StorageSettings do
describe "#initialize" do
context 'when the storage contains no path' do
it 'raises an error' do
expect do
described_class.new("foo" => {})
end.to raise_error(described_class::InvalidConfigurationError)
end
end
context "when the argument isn't a hash" do
it 'raises an error' do
expect do
described_class.new("test")
end.to raise_error("expected a Hash, got a String")
end
end
context 'when the storage is valid' do
it 'raises no error' do
expect do
described_class.new("path" => Rails.root)
end.not_to raise_error
end
end
end
end
...@@ -200,15 +200,29 @@ describe Ci::Runner do ...@@ -200,15 +200,29 @@ describe Ci::Runner do
describe '#assign_to' do describe '#assign_to' do
let!(:project) { FactoryBot.create(:project) } let!(:project) { FactoryBot.create(:project) }
let!(:shared_runner) { FactoryBot.create(:ci_runner, :shared) }
before do subject { runner.assign_to(project) }
shared_runner.assign_to(project)
context 'with shared_runner' do
let!(:runner) { FactoryBot.create(:ci_runner, :shared) }
it 'transitions shared runner to project runner and assigns project' do
subject
expect(runner).to be_specific
expect(runner).to be_project_type
expect(runner.projects).to eq([project])
expect(runner.only_for?(project)).to be_truthy
end end
end
context 'with group runner' do
let!(:runner) { FactoryBot.create(:ci_runner, runner_type: :group_type) }
it { expect(shared_runner).to be_specific } it 'raises an error' do
it { expect(shared_runner.projects).to eq([project]) } expect { subject }
it { expect(shared_runner.only_for?(project)).to be_truthy } .to raise_error(ArgumentError, 'Transitioning a group runner to a project runner is not supported')
end
end
end end
describe '.online' do describe '.online' 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