Commit 6e361ed5 authored by Lin Jen-Shin's avatar Lin Jen-Shin

Merge remote-tracking branch 'upstream/master' into ce-to-ee-2017-08-25

* upstream/master: (39 commits)
  Fix searching for files by path
  Fix invite by email address duplication
  Revert "Merge branch 'mk-reenable-mysql-tests-on-all-branches' into 'master'"
  Revert "Merge branch 'sh-sidekiq-backtrace' into 'master'"
  Add missing third argument to `Git::Repository#initialize` in spec
  New doc: how to install GitLab on Azure
  Enable 5 lines of Sidekiq backtrace lines to aid in debugging
  Reenable MySQL tests on all branches
  Add `:nested_groups` metadata to `Groups::NestedCreateService` specs
  Re-allow appearances.description_html to be NULL
  Remove leftover API helper for removed CI API
  Define ldap methods at runtime
  Changed all font-weight values to 400 and 600
  Use gitaly-proto 0.31.0
  Avoid committer = lines
  Reword job to pipeline on the chart view
  Remove underscore-rails gem
  Hide group title on sidebar collapse; use more generic class for titles
  Add tests for Committer#==
  Added repo_service_spec for commitFlash and corrected repo_commit-Secion api spec
  ...
parents bab59bce 4a2cc381
......@@ -217,9 +217,6 @@ gem 'kubeclient', '~> 2.2.0'
# d3
gem 'd3_rails', '~> 3.5.0'
# underscore-rails
gem 'underscore-rails', '~> 1.8.0'
# Sanitize user input
gem 'sanitize', '~> 2.0'
gem 'babosa', '~> 1.0.2'
......@@ -417,7 +414,7 @@ group :ed25519 do
end
# Gitaly GRPC client
gem 'gitaly', '~> 0.30.0'
gem 'gitaly-proto', '~> 0.31.0', require: 'gitaly'
gem 'toml-rb', '~> 0.3.15', require: false
......
......@@ -299,7 +299,7 @@ GEM
po_to_json (>= 1.0.0)
rails (>= 3.2.0)
gherkin-ruby (0.3.2)
gitaly (0.30.0)
gitaly-proto (0.31.0)
google-protobuf (~> 3.1)
grpc (~> 1.0)
github-linguist (4.7.6)
......@@ -929,7 +929,6 @@ GEM
uglifier (2.7.2)
execjs (>= 0.3.0)
json (>= 1.8.0)
underscore-rails (1.8.3)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.2)
......@@ -1054,7 +1053,7 @@ DEPENDENCIES
gettext (~> 3.2.2)
gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.2.0)
gitaly (~> 0.30.0)
gitaly-proto (~> 0.31.0)
github-linguist (~> 4.7.0)
gitlab-flowdock-git-hook (~> 1.0.1)
gitlab-license (~> 1.0)
......@@ -1202,7 +1201,6 @@ DEPENDENCIES
truncato (~> 0.7.8)
u2f (~> 0.2.1)
uglifier (~> 2.7.2)
underscore-rails (~> 1.8.0)
unf (~> 0.1.4)
unicorn (~> 5.1.0)
unicorn-worker-killer (~> 0.4.4)
......
......@@ -97,18 +97,17 @@ const Api = {
.done(projects => callback(projects));
},
commitMultiple(id, data, callback) {
commitMultiple(id, data) {
// see https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions
const url = Api.buildUrl(Api.commitPath)
.replace(':id', id);
return $.ajax({
return this.wrapAjaxCall({
url,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(data),
dataType: 'json',
})
.done(commitData => callback(commitData))
.fail(message => callback(message.responseJSON));
});
},
// Return text for a specific license
......
......@@ -42,7 +42,9 @@ export default {
actions,
};
Store.submitCommitsLoading = true;
Service.commitFiles(payload, this.resetCommitState);
Service.commitFiles(payload)
.then(this.resetCommitState)
.catch(() => Flash('An error occured while committing your changes'));
},
resetCommitState() {
......
......@@ -65,15 +65,17 @@ const RepoService = {
return urlArray.join('/');
},
commitFiles(payload, cb) {
Api.commitMultiple(Store.projectId, payload, (data) => {
if (data.short_id && data.stats) {
Flash(`Your changes have been committed. Commit ${data.short_id} with ${data.stats.additions} additions, ${data.stats.deletions} deletions.`, 'notice');
} else {
Flash(data.message);
}
cb();
});
commitFiles(payload) {
return Api.commitMultiple(Store.projectId, payload)
.then(this.commitFlash);
},
commitFlash(data) {
if (data.short_id && data.stats) {
window.Flash(`Your changes have been committed. Commit ${data.short_id} with ${data.stats.additions} additions, ${data.stats.deletions} deletions.`, 'notice');
} else {
window.Flash(data.message);
}
},
};
......
......@@ -588,9 +588,10 @@ function UsersSelect(currentUser, els) {
if (showEmailUser && data.results.length === 0 && query.term.match(/^[^@]+@[^@]+$/)) {
var trimmed = query.term.trim();
emailUser = {
name: "Invite \"" + query.term + "\"",
name: "Invite \"" + query.term + "\" by email",
username: trimmed,
id: trimmed
id: trimmed,
invite: true
};
data.results.unshift(emailUser);
}
......@@ -642,7 +643,7 @@ UsersSelect.prototype.formatResult = function(user) {
} else {
avatar = gon.default_avatar_url;
}
return "<div class='user-result " + (!user.username ? 'no-username' : void 0) + "'> <div class='user-image'><img class='avatar avatar-inline s32' src='" + avatar + "'></div> <div class='user-name dropdown-menu-user-full-name'>" + user.name + "</div> <div class='user-username dropdown-menu-user-username'>" + ("@" + user.username || "") + "</div> </div>";
return "<div class='user-result " + (!user.username ? 'no-username' : void 0) + "'> <div class='user-image'><img class='avatar avatar-inline s32' src='" + avatar + "'></div> <div class='user-name dropdown-menu-user-full-name'>" + user.name + "</div> <div class='user-username dropdown-menu-user-username'>" + (!user.invite ? "@" + _.escape(user.username) : "") + "</div> </div>";
};
UsersSelect.prototype.formatSelection = function(user) {
......
......@@ -70,8 +70,7 @@ $new-sidebar-collapsed-width: 50px;
background-color: $white-light;
}
.project-title,
.group-title {
.sidebar-context-title {
overflow: hidden;
text-overflow: ellipsis;
}
......@@ -109,7 +108,7 @@ $new-sidebar-collapsed-width: 50px;
}
.badge,
.project-title {
.sidebar-context-title {
display: none;
}
......
......@@ -840,6 +840,7 @@ a.allowed-to-push {
label {
margin-top: 6px;
font-weight: $gl-font-weight-normal;
<<<<<<< HEAD
}
}
......@@ -847,6 +848,8 @@ a.allowed-to-push {
.protected-branch-merge-access-list {
a {
color: $white-light;
=======
>>>>>>> upstream/master
}
}
......
......@@ -11,6 +11,14 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController
end
end
if Gitlab::LDAP::Config.enabled?
Gitlab::LDAP::Config.available_servers.each do |server|
define_method server['provider_name'] do
ldap
end
end
end
# Extend the standard message generation to accept our custom exception
def failure_message
exception = env["omniauth.error"]
......
......@@ -6,14 +6,6 @@ class SessionsController < Devise::SessionsController
skip_before_action :check_two_factor_requirement, only: [:destroy]
# Explicitly call protect from forgery before anything else. Otherwise the
# CSFR-token might be cleared before authentication is done. This was the case
# when LDAP was enabled and the `OmniauthCallbacksController` is loaded
#
# *Note:* `prepend: true` is the default for rails4, but this will be changed
# to `prepend: false` in rails5.
protect_from_forgery prepend: true, with: :exception
prepend_before_action :check_initial_setup, only: [:new]
prepend_before_action :authenticate_with_two_factor,
if: :two_factor_enabled?, only: [:create]
......
......@@ -50,7 +50,10 @@ module Ci
before_save :ensure_token
before_destroy { unscoped_project }
after_create :execute_hooks
after_create do |build|
run_after_commit { BuildHooksWorker.perform_async(build.id) }
end
after_commit :update_project_statistics_after_save, on: [:create, :update]
after_commit :update_project_statistics, on: :destroy
......
......@@ -17,6 +17,10 @@ module Ci
validates :pipeline, presence: true, unless: :importing?
validates :name, presence: true, unless: :importing?
after_initialize do |stage|
self.status = DEFAULT_STATUS if self.status.nil?
end
state_machine :status, initial: :created do
event :enqueue do
transition created: :pending
......
......@@ -1272,7 +1272,7 @@ class Repository
end
def initialize_raw_repository
Gitlab::Git::Repository.new(project.repository_storage, disk_path + '.git')
Gitlab::Git::Repository.new(project.repository_storage, disk_path + '.git', Gitlab::GlRepository.gl_repository(project, false))
end
def circuit_breaker
......
......@@ -17,7 +17,7 @@ module Commits
new_commit = create_commit!
success(result: new_commit)
rescue ValidationError, ChangeError, Gitlab::Git::Index::IndexError, Repository::CommitError, GitHooksService::PreReceiveError => ex
rescue ValidationError, ChangeError, Gitlab::Git::Index::IndexError, Repository::CommitError, Gitlab::Git::HooksService::PreReceiveError => ex
error(ex.message)
end
......
......@@ -14,7 +14,7 @@ class CreateBranchService < BaseService
else
error('Invalid reference name')
end
rescue GitHooksService::PreReceiveError => ex
rescue Gitlab::Git::HooksService::PreReceiveError => ex
error(ex.message)
end
......
......@@ -16,7 +16,7 @@ class DeleteBranchService < BaseService
else
error('Failed to remove branch')
end
rescue GitHooksService::PreReceiveError => ex
rescue Gitlab::Git::HooksService::PreReceiveError => ex
error(ex.message)
end
......
class GitHooksService
PreReceiveError = Class.new(StandardError)
attr_accessor :oldrev, :newrev, :ref
def execute(user, project, oldrev, newrev, ref)
@project = project
@user = Gitlab::GlId.gl_id(user)
@oldrev = oldrev
@newrev = newrev
@ref = ref
%w(pre-receive update).each do |hook_name|
status, message = run_hook(hook_name)
unless status
raise PreReceiveError, message
end
end
yield(self).tap do
run_hook('post-receive')
end
end
private
def run_hook(name)
hook = Gitlab::Git::Hook.new(name, @project)
hook.trigger(@user, oldrev, newrev, ref)
end
end
class GitOperationService
attr_reader :user, :repository
attr_reader :committer, :repository
def initialize(committer, new_repository)
committer = Gitlab::Git::Committer.from_user(committer) if committer.is_a?(User)
@committer = committer
def initialize(new_user, new_repository)
@user = new_user
@repository = new_repository
end
......@@ -118,9 +120,9 @@ class GitOperationService
end
def with_hooks(ref, newrev, oldrev)
GitHooksService.new.execute(
user,
repository.project,
Gitlab::Git::HooksService.new.execute(
committer,
repository,
oldrev,
newrev,
ref) do |service|
......
......@@ -78,7 +78,7 @@ module MergeRequests
raise MergeError, 'Conflicts detected during merge' unless commit_id
merge_request.update(merge_commit_sha: commit_id)
rescue GitHooksService::PreReceiveError => e
rescue Gitlab::Git::HooksService::PreReceiveError => e
raise MergeError, e.message
rescue StandardError => e
raise MergeError, "Something went wrong during merge: #{e.message}"
......
......@@ -13,7 +13,7 @@ module Tags
new_tag = repository.add_tag(current_user, tag_name, target, message)
rescue Rugged::TagError
return error("Tag #{tag_name} already exists")
rescue GitHooksService::PreReceiveError => ex
rescue Gitlab::Git::HooksService::PreReceiveError => ex
return error(ex.message)
end
......
......@@ -21,7 +21,7 @@ module Tags
else
error('Failed to remove tag')
end
rescue GitHooksService::PreReceiveError => ex
rescue Gitlab::Git::HooksService::PreReceiveError => ex
error(ex.message)
end
......
......@@ -13,7 +13,7 @@ class ValidateNewBranchService < BaseService
end
success
rescue GitHooksService::PreReceiveError => ex
rescue Gitlab::Git::HooksService::PreReceiveError => ex
error(ex.message)
end
end
.nav-sidebar{ class: ("sidebar-icons-only" if collapsed_sidebar?) }
<<<<<<< HEAD
.context-header
= link_to admin_root_path, title: 'Admin Overview' do
.avatar-container.s40.settings-avatar
......@@ -114,6 +115,17 @@
- if akismet_enabled?
= nav_link(controller: :spam_logs) do
= link_to admin_spam_logs_path, title: "Spam Logs" do
=======
.nav-sidebar-inner-scroll
.context-header
= link_to admin_root_path, title: 'Admin Overview' do
.avatar-container.s40.settings-avatar
= icon('wrench')
.sidebar-context-title Admin Area
%ul.sidebar-top-level-items
= nav_link(controller: %w(dashboard admin projects users groups jobs runners cohorts), html_options: {class: 'home'}) do
= link_to admin_root_path, title: 'Overview', class: 'shortcuts-tree' do
>>>>>>> upstream/master
.nav-icon-container
= custom_icon('overview')
%span.nav-item-name
......
......@@ -4,7 +4,7 @@
= link_to group_path(@group), title: @group.name do
.avatar-container.s40.group-avatar
= image_tag group_icon(@group), class: "avatar s40 avatar-tile"
.group-title
.sidebar-context-title
= @group.name
%ul.sidebar-top-level-items
= nav_link(path: ['groups#show', 'groups#activity', 'groups#subgroups', 'analytics#show'], html_options: { class: 'home' }) do
......
......@@ -4,7 +4,7 @@
= link_to profile_path, title: 'Profile Settings' do
.avatar-container.s40.settings-avatar
= icon('user')
.project-title User Settings
.sidebar-context-title User Settings
%ul.sidebar-top-level-items
= nav_link(path: 'profiles#show', html_options: {class: 'home'}) do
= link_to profile_path, title: 'Profile Settings' do
......
......@@ -5,7 +5,7 @@
= link_to project_path(@project), title: @project.name do
.avatar-container.s40.project-avatar
= project_icon(@project, alt: @project.name, class: 'avatar s40 avatar-tile')
.project-title
.sidebar-context-title
= @project.name
%ul.sidebar-top-level-items
= nav_link(path: ['projects#show', 'projects#activity', 'cycle_analytics#show'], html_options: { class: 'home' }) do
......
......@@ -14,19 +14,19 @@
.prepend-top-default
%p.light
= _("Jobs for last week")
= _("Pipelines for last week")
(#{date_from_to(Date.today - 7.days, Date.today)})
%canvas#weekChart{ height: 200 }
.prepend-top-default
%p.light
= _("Jobs for last month")
= _("Pipelines for last month")
(#{date_from_to(Date.today - 30.days, Date.today)})
%canvas#monthChart{ height: 200 }
.prepend-top-default
%p.light
= _("Jobs for last year")
= _("Pipelines for last year")
%canvas#yearChart.padded{ height: 250 }
%script#pipelinesChartsData{ type: "application/json" }
......
......@@ -8,7 +8,7 @@
- if runner.locked?
= icon('lock', class: 'has-tooltip', title: 'Locked to current projects')
%small
%small.edit-runner
= link_to edit_project_runner_path(@project, runner) do
%i.fa.fa-edit.btn
- else
......
---
title: Fix invite by email address duplication
merge_request:
author:
type: fixed
---
title: Fix searching for files by path
merge_request: 13798
author:
type: fixed
---
title: Fire hooks asynchronously when creating a new job to improve performance
merge_request: 13734
author:
type: changed
---
title: Re-allow appearances.description_html to be NULL
merge_request:
author:
type: fixed
---
title: Reword job to pipeline to reflect what the graphs are really about
merge_request:
author:
type: fixed
......@@ -6,12 +6,6 @@ if Gitlab::LDAP::Config.enabled?
const_set(server['provider_class'], Class.new(LDAP))
end
end
OmniauthCallbacksController.class_eval do
Gitlab::LDAP::Config.available_servers.each do |server|
alias_method server['provider_name'], :ldap
end
end
end
OmniAuth.config.full_host = Settings.gitlab['base_url']
......
......@@ -15,7 +15,7 @@ class Gitlab::Seeder::CycleAnalytics
# to disable the `pre_receive` hook in order to remove this
# dependency on the GitLab API.
def stub_git_pre_receive!
GitHooksService.class_eval do
Gitlab::Git::HooksService.class_eval do
def run_hook(name)
[true, '']
end
......
......@@ -11,7 +11,7 @@ class MigrateRepoSize < ActiveRecord::Migration
path = File.join(namespace_path, project['project_path'] + '.git')
begin
repo = Gitlab::Git::Repository.new('default', path)
repo = Gitlab::Git::Repository.new('default', path, '')
if repo.empty?
print '-'
else
......
......@@ -7,7 +7,7 @@ class CleanupAppearancesSchema < ActiveRecord::Migration
# Set this constant to true if this migration requires downtime.
DOWNTIME = false
NOT_NULL_COLUMNS = %i[title description description_html created_at updated_at]
NOT_NULL_COLUMNS = %i[title description created_at updated_at]
TIME_COLUMNS = %i[created_at updated_at]
......
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AllowAppearancesDescriptionHtmlNull < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
# Set this constant to true if this migration requires downtime.
DOWNTIME = false
def up
change_column_null :appearances, :description_html, true
end
def down
# This column should not have a `NOT NULL` class, so we don't want to revert
# back to re-adding it.
end
end
......@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20170820100558) do
ActiveRecord::Schema.define(version: 20170824162758) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......@@ -35,7 +35,7 @@ ActiveRecord::Schema.define(version: 20170820100558) do
t.integer "updated_by"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.text "description_html", null: false
t.text "description_html"
t.integer "cached_markdown_version"
end
......
......@@ -76,7 +76,8 @@ Learn how to deploy a static website with [GitLab Pages](../user/project/pages/i
## Install and maintain GitLab
Install, upgrade, integrate, migrate to GitLab:
[Admin](../README.md#administrator-documentation), [install](../install/README.md),
upgrade, integrate, migrate to GitLab:
| Article title | Category | Publishing date |
| :------------ | :------: | --------------: |
......
......@@ -18,9 +18,17 @@ the hardware requirements.
Useful for unsupported systems like *BSD. For an overview of the directory
structure, read the [structure documentation](structure.md).
- [Docker](https://docs.gitlab.com/omnibus/docker/) - Install GitLab using Docker.
## Install GitLab on cloud providers
- [Installing in Kubernetes](kubernetes/index.md) - Install GitLab into a Kubernetes
Cluster using our official Helm Chart Repository.
- Testing only! [DigitalOcean and Docker Machine](digitaloceandocker.md) -
- [Install GitLab on OpenShift](../articles/openshift_and_gitlab/index.md)
- [Install GitLab on DC/OS](https://mesosphere.com/blog/gitlab-dcos/) via [GitLab-Mesosphere integration](https://about.gitlab.com/2016/09/16/announcing-gitlab-and-mesosphere/)
- [Install GitLab on Azure](azure/index.md)
- [Install GitLab on Google Cloud Platform](google_cloud_platform/index.md)
- [Install on AWS](https://about.gitlab.com/aws/)
- _Testing only!_ [DigitalOcean and Docker Machine](digitaloceandocker.md) -
Quickly test any version of GitLab on DigitalOcean using Docker Machine.
- [GitLab Pivotal Tile](pivotal/index.md) - Install and configure GitLab
Enterprise Edition Premium on Pivotal Cloud Foundry.
......
# Install GitLab on Microsoft Azure
> _This article was originally written by Dave Wentzel and [published on the GitLab Blog][Original-Blog-Post]._
>
> _Ported to the GitLab documentation and updated on 2017-08-24 by [Ian Scorer](https://gitlab.com/iscorer)._
Azure is Microsoft's business cloud and GitLab is a pre-configured offering on the Azure Marketplace.
Hopefully, you aren't surprised to hear that Microsoft and Azure have embraced open source software
like Ubuntu, Red Hat Enterprise Linux, and of course - GitLab! This means that you can spin up a
pre-configured GitLab VM and have your very own private GitLab up and running in around 30 minutes.
Let's get started.
### Getting started
First, you'll need an account on Azure. There are three ways to do this:
- If your company (or you) already has an account, then you are ready to go!
- You can also open your own Azure account for free. _At time of writing_, you get $200
of credit to spend on Azure services for 30 days. You can use this credit to try out paid Azure
services, exploring Microsoft's cloud for free. Even after the first 30 days, you never have to pay
anything unless you decide to transition to paid services with a Pay-As-You-Go Azure subscription.
This is a great way to try out Azure and cloud computing, and you can
[read more in their comprehensive FAQ][Azure-Free-Account-FAQ].
- If you have an MSDN subscription, you can activate your Azure subscriber benefits. Your MSDN
subscription gives you recurring Azure credits every month, so why not put those credits to use and
try out GitLab right now?
### Working with Azure
Once you have an Azure account, you can get started. Login to Azure using
[portal.azure.com](https://portal.azure.com) and the first thing you will see is the Dashboard:
![Azure Dashboard](img/azure-dashboard.png)
The Dashboard gives you a quick overview of Azure resources, and from here you you can build VMs,
create SQL Databases, author websites, and perform lots of other cloud tasks.
### Create New VM
The [Azure Marketplace][Azure-Marketplace] is an online store for pre-configured applications and
services which have been optimized for the cloud by software vendors like GitLab, and both
the [Community Edition ("CE")][CE] and the [Enterprise Edition ("EE")][EE] versions of GitLab are
available on the Azure Marketplace as pre-configured solutions.
To begin creating a new GitLab VM, click on the **+ New** icon, type "GitLab" into the search
box, and then click the **"GitLab Community Edition"** search result:
![Azure - New - Search for 'GitLab'](img/azure-new-search-gitlab.png)
A new "blade" window will pop-out, where you can read more about the **"GitLab Community Edition"**
offering which is freely available under the MIT Expat License:
![Azure - New - Select 'GitLab Community Edition'](img/azure-new-gitlab-ce.png)
Click **"Create"** and you will be presented with the "Create virtual machine" blade:
![Azure - Create Virtual Machine - Basics](img/azure-create-virtual-machine-basics.png)
### Basics
The first items we need to configure are the basic settings of the underlying virtual machine:
1. Enter a `Name` for the VM - e.g. **"GitLab-CE"**
1. Select a `VM disk type` - either **HDD** _(slower, lower cost)_ or **SSD** _(faster, higher cost)_
1. Enter a `User name` - e.g. **"gitlab-admin"**
1. Select an `Authentication type`, either **SSH public key** or **Password**:
>**Note:** if you're unsure which authentication type to use, select **Password**
1. If you chose **SSH public key** - enter your `SSH public key` into the field provided
_(read the [SSH documentation][GitLab-Docs-SSH] to learn more about how to setup SSH
public keys)_
1. If you chose **Password** - enter the password you wish to use _(this is the password that you
will use later in this tutorial to [SSH] into the VM, so make sure it's a strong password/passphrase)_
1. Choose the appropriate `Subscription` tier for your Azure account
1. Choose an existing `Resource Group` or create a new one - e.g. **"GitLab-CE-Azure"**
>**Note:** a "Resource group" is a way to group related resources together for easier administration.
We chose "GitLab-CE-Azure", but your resource group can have the same name as your VM.
1. Choose a `Location` - if you're unsure, select the default location
Here are the settings we've used:
![Azure - Create Virtual Machine - Basics Completed](img/azure-create-virtual-machine-basics-password.png)
Check the settings you have entered, and then click **"OK"** when you're ready to proceed.
### Size
Next, you need to choose the size of your VM - selecting features such as the number of CPU cores,
the amount of RAM, the size of storage (and its speed), etc.
>**Note:** in common with other cloud vendors, Azure operates a resource/usage pricing model, i.e.
the more resources your VM consumes the more it will cost you to run, so make your selection
carefully. You'll see that Azure provides an _estimated_ monthly cost beneath each VM Size to help
guide your selection.
The default size - the lowest cost **"DS1_V2 Standard"** VM - meets the minimum system requirements
to run a small GitLab environment for testing and evaluation purposes, and so we're going to go
ahead and select this one, but please choose the size which best meets your own requirements:
![Azure - Create Virtual Machine - Size](img/azure-create-virtual-machine-size.png)
>**Note:** be aware that whilst your VM is active (known as "allocated"), it will incur
"compute charges" which, ultimately, you will be billed for. So, even if you're using the
free trial credits, you'll likely want to learn
[how to properly shutdown an Azure VM to save money][Azure-Properly-Shutdown-VM].
Go ahead and click your chosen size, then click **"Select"** when you're ready to proceed to the
next step.
### Settings
On the next blade, you're asked to configure the Storage, Network and Extension settings.
We've gone with the default settings as they're sufficient for test-driving GitLab, but please
choose the settings which best meet your own requirements:
![Azure - Create Virtual Machine - Settings](img/azure-create-virtual-machine-settings.png)
Review the settings and then click **"OK"** when you're ready to proceed to the last step.
### Purchase
The Purchase page is the last step and here you will be presented with the price per hour for your
new VM. You'll be billed only for the VM itself (e.g. "Standard DS1 v2") because the
**"GitLab Community Edition"** marketplace solution is free to use at 0 USD/hr:
![Azure - Create Virtual Machine - Purchase](img/azure-create-virtual-machine-purchase.png)
>**Note:** at this stage, you can review and modify the any of the settings you have made during all
previous steps, just click on any of the four steps to re-open them.
When you have read and agreed to the terms of use and are ready to proceed, click **"Purchase"**.
### Deployment
At this point, Azure will begin deploying your new VM. The deployment process will take a few
minutes to complete, with progress displayed on the **"Deployment"** blade:
![Azure - Create Virtual Machine - Deployment](img/azure-create-virtual-machine-deployment.png)
Once the deployment process is complete, the new VM and its associated resources will be displayed
on the Azure Dashboard (you may need to refresh the page):
![Azure - Dashboard - All resources](img/azure-dashboard-running-resources.png)
The new VM can also be accessed by clicking the `All resources` or `Virtual machines` icons in the
Azure Portal sidebar navigation menu.
### Setup a domain name
The VM will have a public IP address (static by default), but Azure allows us to assign a friendly
DNS name to the VM, so let's go ahead and do that.
From the Dashboard, click on the **"GitLab-CE"** tile to open the management blade for the new VM.
The public IP address that the VM uses is shown in the 'Essentials' section:
![Azure - VM - Management - Public IP Address](img/azure-vm-management-public-ip.png)
Click on the public IP address - which should open the **"Public IP address - Configuration"** blade,
then click on **"Configuration"** (under "Settings"). Now enter a friendly DNS name for your instance
in the `DNS name label` field:
![Azure - VM - Domain Name](img/azure-vm-domain-name.png)
In the screenshot above, you'll see that we've set the `DNS name label` to **"gitlab-ce-test"**.
This will make our VM accessible at `gitlab-ce-test.centralus.cloudapp.azure.com`
_(the full domain name of your own VM will be different, of course)_.
Click **"Save"** for the changes to take effect.
>**Note:** if you want to use your own domain name, you will need to add a DNS `A` record at your
domain registrar which points to the public IP address of your Azure VM. If you do this, you'll need
to make sure your VM is configured to use a _static_ public IP address (i.e. not a _dynamic_ one)
or you will have to reconfigure the DNS `A` record each time Azure reassigns your VM a new public IP
address. Read [IP address types and allocation methods in Azure][Azure-IP-Address-Types] to learn more.
### Let's open some ports!
At this stage you should have a running and fully operational VM. However, none of the services on
your VM (e.g. GitLab) will be publicly accessible via the internet until you have opened up the
neccessary ports to enable access to those services.
Ports are opened by adding _security rules_ to the **"Network security group"** (NSG) which our VM
has been assigned to. If you followed the process above, then Azure will have automatically created
an NSG named `GitLab-CE-nsg` and assigned the `GitLab-CE` VM to it.
>**Note:** if you gave your VM a different name then the NSG automatically created by Azure will
also have a different name - the name you have your VM, with `-nsg` appended to it.
You can navigate to the NSG settings via many different routes in the Azure Portal, but one of the
simplest ways is to go to the Azure Dashboard, and then click on the Network Security Group listed
in the **"All resources"** tile:
![Azure - Dashboard - All resources - Network security group](img/azure-dashboard-highlight-nsg.png)
With the **"Network security group"** blade open, click on **"Inbound security rules"** under
**"Settings"**:
![Azure - Network security group - Inbound security rules](img/azure-nsg-inbound-sec-rules-highlight.png)
Next, click **"Add"**:
![Azure - Network security group - Inbound security rules - Add](img/azure-nsg-inbound-sec-rules-add-highlight.png)
#### Which ports to open?
Like all servers, our VM will be running many services. However, we want to open up the correct
ports to enable public internet access to two services in particular:
1. **HTTP** (port 80) - opening port 80 will enable our VM to respond to HTTP requests, allowing
public access to the instance of GitLab running on our VM.
1. **SSH** (port 22) - opening port 22 will enable our VM to respond to SSH connection requests,
allowing public access (with authentication) to remote terminal sessions
_(you'll see why we need [SSH] access to our VM [later on in this tutorial](#maintaining-your-gitlab-instance))_
#### Open HTTP on Port 80
In the **"Add inbound security rule"** blade, let's open port 80 so that our VM will accept HTTP
connections:
![Azure - Add inbound security rules - HTTP](img/azure-add-inbound-sec-rule-http.png)
1. Enter **"HTTP"** in the `Name` field
1. Select **HTTP** from the options in the `Service` drop-down
1. Make sure the `Action` is set to **Allow**
1. Click **"OK"**
#### Open SSH on Port 22
Repeat the above process, adding a second Inbound security rule to open port 22, enabling our VM to
accept [SSH] connections:
![Azure - Add inbound security rules - SSH](img/azure-add-inbound-sec-rule-ssh.png)
1. Enter **"SSH"** in the `Name` field
1. Select **SSH** from the options in the `Service` drop-down
1. Make sure the `Action` is set to **Allow**
1. Click **"OK"**
It will take a moment for Azure to add each new Inbound Security Rule (and you may need to click on
**"Inbound security rules"** to refresh the list), but once completed, you should see the two new
rules in the list:
![Azure - Inbound security rules - List](img/azure-inbound-sec-rules-list.png)
## Connecting to GitLab
Use the domain name you set up earlier (or the public IP address) to visit your new GitLab instance
in your browser. If everything has gone according to plan you should be presented with the
following page, asking you to set a _new_ password for the administrator account automatically
created by GitLab:
![GitLab - Change Password](img/gitlab-change-password.png)
Enter your _new_ password into both form fields, and then click **"Change your password"**.
Once you have changed the password you will be redirected to the GitLab login page. Use `root` as
the username, enter the new password you set in the previous step, and then click **"Sign in"**:
![GitLab - Login](img/gitlab-login.png)
### Success?
After signing in successfully, you should see the GitLab Projects page displaying a
**"Welcome to GitLab!"** message:
![GitLab - Projects Page](img/gitlab-home.png)
If so, you now have a working GitLab instance on your own private Azure VM. **Congratulations!**
## Creating your first GitLab project
You can skip this section if you are familiar with Git and GitLab. Otherwise, let's create our first
project. From the Welcome page, click **"New Project"**.
Let's give our project a name and a description, and then accept the default values for everything
else:
1. Enter **"demo"** into the `Project path` project name field
1. Enter a `description`, e.g. **"My awesome demo project!"**
1. Click **"Create project"**
![GitLab - New Project](img/gitlab-new-project.png)
Once the new project has been created (which should only take a moment), you'll be redirected to
homepage for the project:
![GitLab - Empty Project](img/gitlab-project-home-empty.png)
If you scroll further down the project's home page, you'll see some basic instructions on how to
setup a local clone of your new repository and push and pull from it:
![GitLab - Empty Project - Basic Instructions](img/gitlab-project-home-instructions.png)
**That's it! You now have your own private GitLab environment installed and running in the cloud!**
## Maintaining your GitLab instance
It's important to keep your GitLab environment up-to-date. The GitLab team is constantly making
enhancements and occasionally you may need to update for security reasons. So let's review how to
update GitLab.
### Checking our current version
To check which version of GitLab we're currently running, click on the "Admin Area" link - it's the
the wrench icon displayed in the top-right, next to the search box.
In the following screenshot you can see an **"update asap"** notification message in the top-right.
This particular message indicates that there is a newer version of GitLab available which contains
one or more security fixes:
![GitLab - update asap](img/gitlab-admin-area.png)
Under the **"Components"** section, we can see that our VM is currently running version `8.6.5` of
GitLab. This is the version of GitLab which was contained in the Azure Marketplace
**"GitLab Community Edition"** offering we used to build the VM when we wrote this tutorial.
>**Note:** The version of GitLab in your own VM instance may well be different, but the update
process will still be the same.
### Connect via SSH
To perform an update, we need to connect directly to our Azure VM instance and run some commands
from the terminal. Our Azure VM is actually a server running Linux (Ubuntu), so we'll need to
connect to it using SSH ([Secure Shell][SSH]).
If you're running Windows, you'll need to connect using [PuTTY] or an equivalent Windows SSH client.
If you're running Linux or macOS, then you already have an SSH client installed.
>**Note:**
- Remember that you will need to login with the username and password you specified
[when you created](#basics) your Azure VM
- If you need to reset your VM password, read
[how to reset SSH credentials for a user on an Azure VM][Azure-Troubleshoot-SSH-Connection].
#### SSH from the command-line
If you're running [SSH] from the command-line (terminal), then type in the following command to
connect to your VM, substituting `username` and `your-azure-domain-name.com` for the correct values.
Again, remember that your Azure VM domain name will be the one you
[setup previously in the tutorial](#set-up-a-domain-name). If you didn't setup a domain name for
your VM, you can use the IP address in its place in the following command:
```bash
ssh username@your-azure-domain-name.com
```
Provide your password at the prompt to authenticate.
#### SSH from Windows (PuTTY)
If you're using [PuTTY] in Windows as your [SSH] client, then you might want to take a quick
read on [using PuTTY in Windows][Using-SSH-In-Putty].
### Updating GitLab
Once you've logged in via SSH, enter the following command to update GitLab to the latest
version:
```bash
sudo apt-get update && sudo apt-get install gitlab-ce
```
This command will update GitLab and its associated components to the latest versions, so it will
take a little time to complete. You'll see various update tasks being completed in your SSH
terminal window:
![GitLab updating](img/gitlab-ssh-update-in-progress.png)
Once the update process has completed, you'll see a message like this:
```
Upgrade complete! If your GitLab server is misbehaving try running
sudo gitlab-ctl restart
before anything else.
```
#### Check out your updated GitLab
Refresh your GitLab instance in the browser and navigate to the Admin Area. You should now have an
up-to-date GitLab instance.
When we wrote this tutorial our Azure VM GitLab instance was updated to the latest version at time
of writing (`9.4.0`). You can see that the message which was previously displaying **"update asap"**
is now showing **"up-to-date"**:
![GitLab up to date](img/gitlab-admin-area-9.4.0.png)
## Conclusion
Naturally, we believe that GitLab is a great git repository tool. However, GitLab is a whole lot
more than that too. GitLab unifies issues, code review, CI and CD into a single UI, helping you to
move faster from idea to production, and in this tutorial we showed you how quick and easy it is to
setup and run your own instance of GitLab on Azure, Microsoft's cloud service.
Azure is a great way to experiment with GitLab, and if you decide (as we hope) that GitLab is for
you, you can continue to use Azure as your secure, scalable cloud provider or of course run GitLab
on any cloud service you choose.
## Where to next?
Check out our other [Technical Articles][GitLab-Technical-Articles] or browse the [GitLab Documentation][GitLab-Docs] to learn more about GitLab.
### Useful links
- [GitLab Community Edition][CE]
- [GitLab Enterprise Edition][EE]
- [Microsoft Azure][Azure]
- [Azure - Free Account FAQ][Azure-Free-Account-FAQ]
- [Azure - Marketplace][Azure-Marketplace]
- [Azure Portal][Azure-Portal]
- [Azure - Pricing Calculator][Azure-Pricing-Calculator]
- [Azure - Troubleshoot SSH Connections to an Azure Linux VM][Azure-Troubleshoot-SSH-Connection]
- [Azure - Properly Shutdown an Azure VM][Azure-Properly-Shutdown-VM]
- [SSH], [PuTTY] and [Using SSH in PuTTY][Using-SSH-In-Putty]
[Original-Blog-Post]: https://about.gitlab.com/2016/07/13/how-to-setup-a-gitlab-instance-on-microsoft-azure/ "How to Setup a GitLab Instance on Microsoft Azure"
[GitLab-Docs]: https://docs.gitlab.com/ce/README.html "GitLab Documentation"
[GitLab-Technical-Articles]: https://docs.gitlab.com/ce/articles/index.html "GitLab Technical Articles"
[GitLab-Docs-SSH]: https://docs.gitlab.com/ce/ssh/README.html "GitLab Documentation: SSH"
[CE]: https://about.gitlab.com/features/
[EE]: https://about.gitlab.com/features/#ee-starter
[Azure-Troubleshoot-Linux-VM]: https://docs.microsoft.com/en-us/azure/virtual-machines/linux/troubleshoot-app-connection "Troubleshoot application connectivity issues on a Linux virtual machine in Azure"
[Azure-IP-Address-Types]: https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-ip-addresses-overview-arm "IP address types and allocation methods in Azure"
[Azure-How-To-Open-Ports]: https://docs.microsoft.com/en-us/azure/virtual-machines/windows/nsg-quickstart-portal "How to open ports to a virtual machine with the Azure portal"
[Azure-Troubleshoot-SSH-Connection]: https://docs.microsoft.com/en-us/azure/virtual-machines/linux/troubleshoot-ssh-connection "Troubleshoot SSH connections to an Azure Linux VM"
[Azure]: https://azure.microsoft.com/en-us/
[Azure-Free-Account-FAQ]: https://azure.microsoft.com/en-us/free/free-account-faq/
[Azure-Marketplace]: https://azure.microsoft.com/en-us/marketplace/
[Azure-Portal]: https://portal.azure.com
[Azure-Pricing-Calculator]: https://azure.microsoft.com/en-us/pricing/calculator/
[Azure-Properly-Shutdown-VM]: https://buildazure.com/2017/03/16/properly-shutdown-azure-vm-to-save-money/ "Properly Shutdown an Azure VM to Save Money"
[SSH]: https://en.wikipedia.org/wiki/Secure_Shell
[PuTTY]: http://www.putty.org/
[Using-SSH-In-Putty]: https://mediatemple.net/community/products/dv/204404604/using-ssh-in-putty-
\ No newline at end of file
......@@ -38,9 +38,9 @@ class Spinach::Features::ProjectGraph < Spinach::FeatureSteps
step 'page should have CI graphs' do
expect(page).to have_content 'Overall'
expect(page).to have_content 'Jobs for last week'
expect(page).to have_content 'Jobs for last month'
expect(page).to have_content 'Jobs for last year'
expect(page).to have_content 'Pipelines for last week'
expect(page).to have_content 'Pipelines for last month'
expect(page).to have_content 'Pipelines for last year'
expect(page).to have_content 'Commit duration in minutes for last 30 commits'
end
......
......@@ -35,7 +35,10 @@ class Spinach::Features::ProjectPages < Spinach::FeatureSteps
end
step 'pages are deployed' do
pipeline = @project.pipelines.create(ref: 'HEAD', sha: @project.commit('HEAD').sha)
pipeline = @project.pipelines.create(ref: 'HEAD',
sha: @project.commit('HEAD').sha,
source: :push)
build = build(:ci_build,
project: @project,
pipeline: pipeline,
......@@ -43,6 +46,7 @@ class Spinach::Features::ProjectPages < Spinach::FeatureSteps
artifacts_file: fixture_file_upload(Rails.root + 'spec/fixtures/pages.zip'),
artifacts_metadata: fixture_file_upload(Rails.root + 'spec/fixtures/pages.zip.meta')
)
result = ::Projects::UpdatePagesService.new(@project, build).execute
expect(result[:status]).to eq(:success)
end
......
......@@ -6,27 +6,48 @@ module Gitlab
attr_reader :project, :ref
delegate :repository, to: :project
def initialize(project, ref)
@project = project
@ref = ref
end
def find(query)
blobs = project.repository.search_files_by_content(query, ref).first(BATCH_SIZE)
found_file_names = Set.new
by_content = find_by_content(query)
results = blobs.map do |blob|
blob = Gitlab::ProjectSearchResults.parse_search_result(blob)
found_file_names << blob.filename
already_found = Set.new(by_content.map(&:filename))
by_filename = find_by_filename(query, except: already_found)
[blob.filename, blob]
end
(by_content + by_filename)
.sort_by(&:filename)
.map { |blob| [blob.filename, blob] }
end
project.repository.search_files_by_name(query, ref).first(BATCH_SIZE).each do |filename|
results << [filename, OpenStruct.new(ref: ref)] unless found_file_names.include?(filename)
end
private
results.sort_by(&:first)
def find_by_content(query)
results = repository.search_files_by_content(query, ref).first(BATCH_SIZE)
results.map { |result| Gitlab::ProjectSearchResults.parse_search_result(result) }
end
def find_by_filename(query, except: [])
filenames = repository.search_files_by_name(query, ref).first(BATCH_SIZE)
filenames.delete_if { |filename| except.include?(filename) } unless except.empty?
blob_refs = filenames.map { |filename| [ref, filename] }
blobs = Gitlab::Git::Blob.batch(repository, blob_refs, blob_size_limit: 1024)
blobs.map do |blob|
Gitlab::SearchResults::FoundBlob.new(
id: blob.id,
filename: blob.path,
basename: File.basename(blob.path),
ref: ref,
startline: 1,
data: blob.data
)
end
end
end
end
module Gitlab
module Git
class Committer
attr_reader :name, :email, :gl_id
def self.from_user(user)
new(user.name, user.email, Gitlab::GlId.gl_id(user))
end
def initialize(name, email, gl_id)
@name = name
@email = email
@gl_id = gl_id
end
def ==(other)
[name, email, gl_id] == [other.name, other.email, other.gl_id]
end
end
end
end
# Gitaly note: JV: looks like this is only used by GitHooksService in
# Gitaly note: JV: looks like this is only used by Gitlab::Git::HooksService in
# app/services. We shouldn't bother migrating this until we know how
# GitHooksService will be migrated.
# Gitlab::Git::HooksService will be migrated.
module Gitlab
module Git
class Hook
GL_PROTOCOL = 'web'.freeze
attr_reader :name, :repo_path, :path
attr_reader :name, :path, :repository
def initialize(name, project)
def initialize(name, repository)
@name = name
@project = project
@repo_path = project.repository.path
@repository = repository
@path = File.join(repo_path.strip, 'hooks', name)
end
def repo_path
repository.path
end
def exists?
File.exist?(path)
end
......@@ -44,7 +47,7 @@ module Gitlab
'GL_ID' => gl_id,
'PWD' => repo_path,
'GL_PROTOCOL' => GL_PROTOCOL,
'GL_REPOSITORY' => Gitlab::GlRepository.gl_repository(@project, false)
'GL_REPOSITORY' => repository.gl_repository
}
options = {
......
module Gitlab
module Git
class HooksService
PreReceiveError = Class.new(StandardError)
attr_accessor :oldrev, :newrev, :ref
def execute(committer, repository, oldrev, newrev, ref)
@repository = repository
@gl_id = committer.gl_id
@oldrev = oldrev
@newrev = newrev
@ref = ref
%w(pre-receive update).each do |hook_name|
status, message = run_hook(hook_name)
unless status
raise PreReceiveError, message
end
end
yield(self).tap do
run_hook('post-receive')
end
end
private
def run_hook(name)
hook = Gitlab::Git::Hook.new(name, @repository)
hook.trigger(@gl_id, oldrev, newrev, ref)
end
end
end
end
......@@ -49,13 +49,14 @@ module Gitlab
# Rugged repo object
attr_reader :rugged
attr_reader :storage
attr_reader :storage, :gl_repository, :relative_path
# 'path' must be the path to a _bare_ git repository, e.g.
# /path/to/my-repo.git
def initialize(storage, relative_path)
def initialize(storage, relative_path, gl_repository)
@storage = storage
@relative_path = relative_path
@gl_repository = gl_repository
storage_path = Gitlab.config.repositories.storages[@storage]['path']
@path = File.join(storage_path, @relative_path)
......
......@@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gitlab 1.0.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-08-18 14:15+0530\n"
"PO-Revision-Date: 2017-08-18 14:15+0530\n"
"POT-Creation-Date: 2017-08-24 09:29+0200\n"
"PO-Revision-Date: 2017-08-24 09:29+0200\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
......@@ -517,15 +517,6 @@ msgstr ""
msgid "Issue events"
msgstr ""
msgid "Jobs for last month"
msgstr ""
msgid "Jobs for last week"
msgstr ""
msgid "Jobs for last year"
msgstr ""
msgid "LFSStatus|Disabled"
msgstr ""
......@@ -766,6 +757,15 @@ msgstr ""
msgid "Pipelines charts"
msgstr ""
msgid "Pipelines for last month"
msgstr ""
msgid "Pipelines for last week"
msgstr ""
msgid "Pipelines for last year"
msgstr ""
msgid "Pipeline|all"
msgstr ""
......
......@@ -99,6 +99,6 @@ feature 'Import/Export - project import integration test', js: true do
end
def project_hook_exists?(project)
Gitlab::Git::Hook.new('post-receive', project).exists?
Gitlab::Git::Hook.new('post-receive', project.repository.raw_repository).exists?
end
end
require 'spec_helper'
describe "Runners" do
let(:user) { create(:user) }
feature 'Runners' do
given(:user) { create(:user) }
before do
background do
sign_in(user)
end
describe "specific runners" do
before do
@project = FactoryGirl.create :project, shared_runners_enabled: false
@project.team << [user, :master]
context 'when a project has enabled shared_runners' do
given(:project) { create(:project) }
@project2 = FactoryGirl.create :project
@project2.team << [user, :master]
background do
project.add_master(user)
end
@project3 = FactoryGirl.create :project
@project3.team << [user, :developer]
context 'when a specific runner is activated on the project' do
given(:specific_runner) { create(:ci_runner, :specific) }
@shared_runner = FactoryGirl.create :ci_runner, :shared
@specific_runner = FactoryGirl.create :ci_runner
@specific_runner2 = FactoryGirl.create :ci_runner
@specific_runner3 = FactoryGirl.create :ci_runner
@project.runners << @specific_runner
@project2.runners << @specific_runner2
@project3.runners << @specific_runner3
background do
project.runners << specific_runner
end
visit runners_path(@project)
end
scenario 'user sees the specific runner' do
visit runners_path(project)
before do
expect(page).not_to have_content(@specific_runner3.display_name)
expect(page).not_to have_content(@specific_runner3.display_name)
end
within '.activated-specific-runners' do
expect(page).to have_content(specific_runner.display_name)
end
it "places runners in right places" do
expect(page.find(".available-specific-runners")).to have_content(@specific_runner2.display_name)
expect(page.find(".activated-specific-runners")).to have_content(@specific_runner.display_name)
expect(page.find(".available-shared-runners")).to have_content(@shared_runner.display_name)
end
click_on specific_runner.short_sha
it "enables specific runner for project" do
within ".available-specific-runners" do
click_on "Enable for this project"
expect(page).to have_content(specific_runner.platform)
end
expect(page.find(".activated-specific-runners")).to have_content(@specific_runner2.display_name)
end
scenario 'user removes an activated specific runner if this is last project for that runners' do
visit runners_path(project)
it "disables specific runner for project" do
@project2.runners << @specific_runner
visit runners_path(@project)
within '.activated-specific-runners' do
click_on 'Remove Runner'
end
within ".activated-specific-runners" do
click_on "Disable for this project"
expect(page).not_to have_content(specific_runner.display_name)
end
expect(page.find(".available-specific-runners")).to have_content(@specific_runner.display_name)
end
context 'when a runner has a tag' do
background do
specific_runner.update(tag_list: ['tag'])
end
it "removes specific runner for project if this is last project for that runners" do
within ".activated-specific-runners" do
click_on "Remove Runner"
end
scenario 'user edits runner not to run untagged jobs' do
visit runners_path(project)
expect(Ci::Runner.exists?(id: @specific_runner)).to be_falsey
end
end
within '.activated-specific-runners' do
first('.edit-runner > a').click
end
describe "shared runners" do
before do
@project = FactoryGirl.create :project, shared_runners_enabled: false
@project.team << [user, :master]
visit runners_path(@project)
end
expect(page.find_field('runner[run_untagged]')).to be_checked
it "enables shared runners" do
click_on "Enable shared Runners"
expect(@project.reload.shared_runners_enabled).to be_truthy
end
end
uncheck 'runner_run_untagged'
click_button 'Save changes'
describe "shared runners description" do
let(:shared_runners_text) { 'custom **shared** runners description' }
let(:shared_runners_html) { 'custom shared runners description' }
expect(page).to have_content 'Can run untagged jobs No'
end
end
before do
stub_application_setting(shared_runners_text: shared_runners_text)
project = FactoryGirl.create :project, shared_runners_enabled: false
project.team << [user, :master]
visit runners_path(project)
end
context 'when a shared runner is activated on the project' do
given!(:shared_runner) { create(:ci_runner, :shared) }
it "sees shared runners description" do
expect(page.find(".shared-runners-description")).to have_content(shared_runners_html)
end
end
scenario 'user sees CI/CD setting page' do
visit runners_path(project)
describe "show page" do
before do
@project = FactoryGirl.create :project
@project.team << [user, :master]
@specific_runner = FactoryGirl.create :ci_runner
@project.runners << @specific_runner
expect(page.find('.available-shared-runners')).to have_content(shared_runner.display_name)
end
end
end
it "shows runner information" do
visit runners_path(@project)
click_on @specific_runner.short_sha
expect(page).to have_content(@specific_runner.platform)
end
end
context 'when a specific runner exists in another project' do
given(:another_project) { create(:project) }
given(:specific_runner) { create(:ci_runner, :specific) }
feature 'configuring runners ability to picking untagged jobs' do
given(:project) { create(:project) }
given(:runner) { create(:ci_runner) }
background do
another_project.add_master(user)
another_project.runners << specific_runner
end
background do
project.team << [user, :master]
project.runners << runner
end
scenario 'user enables and disables a specific runner' do
visit runners_path(project)
within '.available-specific-runners' do
click_on 'Enable for this project'
end
scenario 'user checks default configuration' do
visit project_runner_path(project, runner)
expect(page.find('.activated-specific-runners')).to have_content(specific_runner.display_name)
expect(page).to have_content 'Can run untagged jobs Yes'
within '.activated-specific-runners' do
click_on 'Disable for this project'
end
expect(page.find('.available-specific-runners')).to have_content(specific_runner.display_name)
end
end
context 'when runner has tags' do
before do
runner.update_attribute(:tag_list, ['tag'])
context 'when application settings have shared_runners_text' do
given(:shared_runners_text) { 'custom **shared** runners description' }
given(:shared_runners_html) { 'custom shared runners description' }
background do
stub_application_setting(shared_runners_text: shared_runners_text)
end
scenario 'user wants to prevent runner from running untagged job' do
scenario 'user sees shared runners description' do
visit runners_path(project)
page.within('.activated-specific-runners') do
first('small > a').click
end
uncheck 'runner_run_untagged'
click_button 'Save changes'
expect(page).to have_content 'Can run untagged jobs No'
expect(runner.reload.run_untagged?).to eq false
expect(page.find('.shared-runners-description')).to have_content(shared_runners_html)
end
end
end
context 'when a project has disabled shared_runners' do
given(:project) { create(:project, shared_runners_enabled: false) }
background do
project.add_master(user)
end
scenario 'user enables shared runners' do
visit runners_path(project)
click_on 'Enable shared Runners'
expect(page.find('.shared-runners-description')).to have_content('Disable shared Runners')
end
end
end
......@@ -36,8 +36,8 @@ feature 'Master deletes tag' do
context 'when pre-receive hook fails', js: true do
before do
allow_any_instance_of(GitHooksService).to receive(:execute)
.and_raise(GitHooksService::PreReceiveError, 'Do not delete tags')
allow_any_instance_of(Gitlab::Git::HooksService).to receive(:execute)
.and_raise(Gitlab::Git::HooksService::PreReceiveError, 'Do not delete tags')
end
scenario 'shows the error message' do
......
import Vue from 'vue';
import repoCommitSection from '~/repo/components/repo_commit_section.vue';
import RepoStore from '~/repo/stores/repo_store';
import Api from '~/api';
import RepoService from '~/repo/services/repo_service';
describe('RepoCommitSection', () => {
const branch = 'master';
......@@ -111,7 +111,7 @@ describe('RepoCommitSection', () => {
expect(submitCommit.disabled).toBeFalsy();
spyOn(vm, 'makeCommit').and.callThrough();
spyOn(Api, 'commitMultiple');
spyOn(RepoService, 'commitFiles').and.callFake(() => Promise.resolve());
submitCommit.click();
......@@ -119,10 +119,9 @@ describe('RepoCommitSection', () => {
expect(vm.makeCommit).toHaveBeenCalled();
expect(submitCommit.querySelector('.fa-spinner.fa-spin')).toBeTruthy();
const args = Api.commitMultiple.calls.allArgs()[0];
const { commit_message, actions, branch: payloadBranch } = args[1];
const args = RepoService.commitFiles.calls.allArgs()[0];
const { commit_message, actions, branch: payloadBranch } = args[0];
expect(args[0]).toBe(projectId);
expect(commit_message).toBe(commitMessage);
expect(actions.length).toEqual(2);
expect(payloadBranch).toEqual(branch);
......
import axios from 'axios';
import RepoService from '~/repo/services/repo_service';
import RepoStore from '~/repo/stores/repo_store';
import Api from '~/api';
describe('RepoService', () => {
it('has default json format param', () => {
......@@ -118,4 +120,52 @@ describe('RepoService', () => {
}).catch(done.fail);
});
});
describe('commitFiles', () => {
it('calls commitMultiple and .then commitFlash', (done) => {
const projectId = 'projectId';
const payload = {};
RepoStore.projectId = projectId;
spyOn(Api, 'commitMultiple').and.returnValue(Promise.resolve());
spyOn(RepoService, 'commitFlash');
const apiPromise = RepoService.commitFiles(payload);
expect(Api.commitMultiple).toHaveBeenCalledWith(projectId, payload);
apiPromise.then(() => {
expect(RepoService.commitFlash).toHaveBeenCalled();
done();
}).catch(done.fail);
});
});
describe('commitFlash', () => {
it('calls Flash with data.message', () => {
const data = {
message: 'message',
};
spyOn(window, 'Flash');
RepoService.commitFlash(data);
expect(window.Flash).toHaveBeenCalledWith(data.message);
});
it('calls Flash with success string if short_id and stats', () => {
const data = {
short_id: 'short_id',
stats: {
additions: '4',
deletions: '5',
},
};
spyOn(window, 'Flash');
RepoService.commitFlash(data);
expect(window.Flash).toHaveBeenCalledWith(`Your changes have been committed. Commit ${data.short_id} with ${data.stats.additions} additions, ${data.stats.deletions} deletions.`, 'notice');
});
});
});
......@@ -7,15 +7,23 @@ describe Gitlab::FileFinder do
it 'finds by name' do
results = finder.find('files')
expect(results.map(&:first)).to include('files/images/wm.svg')
filename, blob = results.find { |_, blob| blob.filename == 'files/images/wm.svg' }
expect(filename).to eq('files/images/wm.svg')
expect(blob).to be_a(Gitlab::SearchResults::FoundBlob)
expect(blob.ref).to eq(finder.ref)
expect(blob.data).not_to be_empty
end
it 'finds by content' do
results = finder.find('files')
blob = results.select { |result| result.first == "CHANGELOG" }.flatten.last
filename, blob = results.find { |_, blob| blob.filename == 'CHANGELOG' }
expect(blob.filename).to eq("CHANGELOG")
expect(filename).to eq('CHANGELOG')
expect(blob).to be_a(Gitlab::SearchResults::FoundBlob)
expect(blob.ref).to eq(finder.ref)
expect(blob.data).not_to be_empty
end
end
end
......@@ -2,7 +2,7 @@
require "spec_helper"
describe Gitlab::Git::Blame, seed_helper: true do
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') }
let(:blame) do
Gitlab::Git::Blame.new(repository, SeedRepo::Commit::ID, "CONTRIBUTING.md")
end
......
......@@ -3,7 +3,7 @@
require "spec_helper"
describe Gitlab::Git::Blob, seed_helper: true do
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') }
describe 'initialize' do
let(:blob) { Gitlab::Git::Blob.new(name: 'test') }
......
require "spec_helper"
describe Gitlab::Git::Branch, seed_helper: true do
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') }
subject { repository.branches }
......
require "spec_helper"
describe Gitlab::Git::Commit, seed_helper: true do
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') }
let(:commit) { described_class.find(repository, SeedRepo::Commit::ID) }
let(:rugged_commit) do
repository.rugged.lookup(SeedRepo::Commit::ID)
......@@ -9,7 +9,7 @@ describe Gitlab::Git::Commit, seed_helper: true do
describe "Commit info" do
before do
repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH).rugged
repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '').rugged
@committer = {
email: 'mike@smith.com',
......@@ -59,7 +59,7 @@ describe Gitlab::Git::Commit, seed_helper: true do
after do
# Erase the new commit so other tests get the original repo
repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH).rugged
repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '').rugged
repo.references.update("refs/heads/master", SeedRepo::LastCommit::ID)
end
end
......@@ -144,7 +144,7 @@ describe Gitlab::Git::Commit, seed_helper: true do
end
context 'with broken repo' do
let(:repository) { Gitlab::Git::Repository.new('default', TEST_BROKEN_REPO_PATH) }
let(:repository) { Gitlab::Git::Repository.new('default', TEST_BROKEN_REPO_PATH, '') }
it 'returns nil' do
expect(described_class.find(repository, SeedRepo::Commit::ID)).to be_nil
......
require 'spec_helper'
describe Gitlab::Git::Committer do
let(:name) { 'Jane Doe' }
let(:email) { 'janedoe@example.com' }
let(:gl_id) { 'user-123' }
subject { described_class.new(name, email, gl_id) }
describe '#==' do
def eq_other(name, email, gl_id)
eq(described_class.new(name, email, gl_id))
end
it { expect(subject).to eq_other(name, email, gl_id) }
it { expect(subject).not_to eq_other(nil, nil, nil) }
it { expect(subject).not_to eq_other(name + 'x', email, gl_id) }
it { expect(subject).not_to eq_other(name, email + 'x', gl_id) }
it { expect(subject).not_to eq_other(name, email, gl_id + 'x') }
end
end
require "spec_helper"
describe Gitlab::Git::Compare, seed_helper: true do
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') }
let(:compare) { Gitlab::Git::Compare.new(repository, SeedRepo::BigCommit::ID, SeedRepo::Commit::ID, straight: false) }
let(:compare_straight) { Gitlab::Git::Compare.new(repository, SeedRepo::BigCommit::ID, SeedRepo::Commit::ID, straight: true) }
......
require "spec_helper"
describe Gitlab::Git::Diff, seed_helper: true do
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') }
before do
@raw_diff_hash = {
......
......@@ -10,7 +10,8 @@ describe Gitlab::Git::Hook do
describe "#trigger" do
let(:project) { create(:project, :repository) }
let(:repo_path) { project.repository.path }
let(:repository) { project.repository.raw_repository }
let(:repo_path) { repository.path }
let(:user) { create(:user) }
let(:gl_id) { Gitlab::GlId.gl_id(user) }
......@@ -48,7 +49,7 @@ describe Gitlab::Git::Hook do
it "returns success with no errors" do
create_hook(hook_name)
hook = described_class.new(hook_name, project)
hook = described_class.new(hook_name, repository)
blank = Gitlab::Git::BLANK_SHA
ref = Gitlab::Git::BRANCH_REF_PREFIX + 'new_branch'
......@@ -66,7 +67,7 @@ describe Gitlab::Git::Hook do
context "when the hook is unsuccessful" do
it "returns failure with errors" do
create_failing_hook(hook_name)
hook = described_class.new(hook_name, project)
hook = described_class.new(hook_name, repository)
blank = Gitlab::Git::BLANK_SHA
ref = Gitlab::Git::BRANCH_REF_PREFIX + 'new_branch'
......@@ -80,7 +81,7 @@ describe Gitlab::Git::Hook do
context "when the hook doesn't exist" do
it "returns success with no errors" do
hook = described_class.new('unknown_hook', project)
hook = described_class.new('unknown_hook', repository)
blank = Gitlab::Git::BLANK_SHA
ref = Gitlab::Git::BRANCH_REF_PREFIX + 'new_branch'
......
require 'spec_helper'
describe GitHooksService do
include RepoHelpers
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
describe Gitlab::Git::HooksService, seed_helper: true do
let(:committer) { Gitlab::Git::Committer.new('Jane Doe', 'janedoe@example.com', 'user-456') }
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, 'project-123') }
let(:service) { described_class.new }
before do
@blankrev = Gitlab::Git::BLANK_SHA
@oldrev = sample_commit.parent_id
@newrev = sample_commit.id
@oldrev = SeedRepo::Commit::PARENT_ID
@newrev = SeedRepo::Commit::ID
@ref = 'refs/heads/feature'
end
......@@ -20,7 +18,7 @@ describe GitHooksService do
hook = double(trigger: [true, nil])
expect(Gitlab::Git::Hook).to receive(:new).exactly(3).times.and_return(hook)
service.execute(user, project, @blankrev, @newrev, @ref) { }
service.execute(committer, repository, @blankrev, @newrev, @ref) { }
end
end
......@@ -30,8 +28,8 @@ describe GitHooksService do
expect(service).not_to receive(:run_hook).with('post-receive')
expect do
service.execute(user, project, @blankrev, @newrev, @ref)
end.to raise_error(GitHooksService::PreReceiveError)
service.execute(committer, repository, @blankrev, @newrev, @ref)
end.to raise_error(Gitlab::Git::HooksService::PreReceiveError)
end
end
......@@ -42,8 +40,8 @@ describe GitHooksService do
expect(service).not_to receive(:run_hook).with('post-receive')
expect do
service.execute(user, project, @blankrev, @newrev, @ref)
end.to raise_error(GitHooksService::PreReceiveError)
service.execute(committer, repository, @blankrev, @newrev, @ref)
end.to raise_error(Gitlab::Git::HooksService::PreReceiveError)
end
end
end
......
require 'spec_helper'
describe Gitlab::Git::Index, seed_helper: true do
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') }
let(:index) { described_class.new(repository) }
before do
......
......@@ -17,7 +17,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
end
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') }
describe "Respond to" do
subject { repository }
......@@ -56,14 +56,14 @@ describe Gitlab::Git::Repository, seed_helper: true do
describe "#rugged" do
describe 'when storage is broken', broken_storage: true do
it 'raises a storage exception when storage is not available' do
broken_repo = described_class.new('broken', 'a/path.git')
broken_repo = described_class.new('broken', 'a/path.git', '')
expect { broken_repo.rugged }.to raise_error(Gitlab::Git::Storage::Inaccessible)
end
end
it 'raises a no repository exception when there is no repo' do
broken_repo = described_class.new('default', 'a/path.git')
broken_repo = described_class.new('default', 'a/path.git', '')
expect { broken_repo.rugged }.to raise_error(Gitlab::Git::Repository::NoRepository)
end
......@@ -257,7 +257,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
describe '#submodule_url_for' do
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') }
let(:ref) { 'master' }
def submodule_url(path)
......@@ -295,7 +295,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
context '#submodules' do
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') }
context 'where repo has submodules' do
let(:submodules) { repository.send(:submodules, 'master') }
......@@ -391,7 +391,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
describe "#delete_branch" do
before(:all) do
@repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH)
@repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '')
@repo.delete_branch("feature")
end
......@@ -407,7 +407,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
describe "#create_branch" do
before(:all) do
@repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH)
@repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '')
end
it "should create a new branch" do
......@@ -445,7 +445,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
describe "#remote_delete" do
before(:all) do
@repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH)
@repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '')
@repo.remote_delete("expendable")
end
......@@ -461,7 +461,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
describe "#remote_add" do
before(:all) do
@repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH)
@repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '')
@repo.remote_add("new_remote", SeedHelper::GITLAB_GIT_TEST_REPO_URL)
end
......@@ -477,7 +477,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
describe "#remote_update" do
before(:all) do
@repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH)
@repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '')
@repo.remote_update("expendable", url: TEST_NORMAL_REPO_PATH)
end
......@@ -506,7 +506,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
before(:context) do
# Add new commits so that there's a renamed file in the commit history
repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH).rugged
repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '').rugged
@commit_with_old_name_id = new_commit_edit_old_file(repo)
@rename_commit_id = new_commit_move_file(repo)
@commit_with_new_name_id = new_commit_edit_new_file(repo)
......@@ -514,7 +514,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
after(:context) do
# Erase our commits so other tests get the original repo
repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH).rugged
repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '').rugged
repo.references.update("refs/heads/master", SeedRepo::LastCommit::ID)
end
......@@ -849,7 +849,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
describe '#autocrlf' do
before(:all) do
@repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH)
@repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '')
@repo.rugged.config['core.autocrlf'] = true
end
......@@ -864,7 +864,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
describe '#autocrlf=' do
before(:all) do
@repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH)
@repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '')
@repo.rugged.config['core.autocrlf'] = false
end
......@@ -933,7 +933,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
context 'with local and remote branches' do
let(:repository) do
Gitlab::Git::Repository.new('default', File.join(TEST_MUTABLE_REPO_PATH, '.git'))
Gitlab::Git::Repository.new('default', File.join(TEST_MUTABLE_REPO_PATH, '.git'), '')
end
before do
......@@ -980,7 +980,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
context 'with local and remote branches' do
let(:repository) do
Gitlab::Git::Repository.new('default', File.join(TEST_MUTABLE_REPO_PATH, '.git'))
Gitlab::Git::Repository.new('default', File.join(TEST_MUTABLE_REPO_PATH, '.git'), '')
end
before do
......@@ -1186,7 +1186,7 @@ describe Gitlab::Git::Repository, seed_helper: true do
describe '#local_branches' do
before(:all) do
@repo = Gitlab::Git::Repository.new('default', File.join(TEST_MUTABLE_REPO_PATH, '.git'))
@repo = Gitlab::Git::Repository.new('default', File.join(TEST_MUTABLE_REPO_PATH, '.git'), '')
end
after(:all) do
......
require "spec_helper"
describe Gitlab::Git::Tag, seed_helper: true do
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') }
shared_examples 'Gitlab::Git::Repository#tags' do
describe 'first tag' do
......
require "spec_helper"
describe Gitlab::Git::Tree, seed_helper: true do
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH) }
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') }
context :repo do
let(:tree) { Gitlab::Git::Tree.where(repository, SeedRepo::Commit::ID) }
......
......@@ -396,7 +396,7 @@ describe Gitlab::GitAccess do
def stub_git_hooks
# Running the `pre-receive` hook is expensive, and not necessary for this test.
allow_any_instance_of(GitHooksService).to receive(:execute) do |service, &block|
allow_any_instance_of(Gitlab::Git::HooksService).to receive(:execute) do |service, &block|
block.call(service)
end
end
......
......@@ -34,7 +34,7 @@ describe Gitlab::ImportExport::RepoRestorer do
it 'has the webhooks' do
restorer.restore
expect(Gitlab::Git::Hook.new('post-receive', project)).to exist
expect(Gitlab::Git::Hook.new('post-receive', project.repository.raw_repository)).to exist
end
end
end
......@@ -22,6 +22,16 @@ describe Ci::Build do
it { is_expected.to respond_to(:has_trace?) }
it { is_expected.to respond_to(:trace) }
describe 'callbacks' do
context 'when running after_create callback' do
it 'triggers asynchronous build hooks worker' do
expect(BuildHooksWorker).to receive(:perform_async)
create(:ci_build)
end
end
end
describe '.manual_actions' do
let!(:manual_but_created) { create(:ci_build, :manual, status: :created, pipeline: pipeline) }
let!(:manual_but_succeeded) { create(:ci_build, :manual, status: :success, pipeline: pipeline) }
......
......@@ -38,6 +38,17 @@ describe Ci::Stage, :models do
expect(stage.status).to eq 'success'
end
end
context 'when stage status is not defined' do
before do
stage.update_column(:status, nil)
end
it 'sets the default value' do
expect(described_class.find(stage.id).status)
.to eq 'created'
end
end
end
describe 'update_status' do
......
......@@ -8,6 +8,7 @@ describe Repository, models: true do
let(:repository) { project.repository }
let(:broken_repository) { create(:project, :broken_storage).repository }
let(:user) { create(:user) }
let(:committer) { Gitlab::Git::Committer.from_user(user) }
let(:commit_options) do
author = repository.user_to_committer(user)
......@@ -852,7 +853,7 @@ describe Repository, models: true do
expect do
repository.add_branch(user, 'new_feature', 'master')
end.to raise_error(GitHooksService::PreReceiveError)
end.to raise_error(Gitlab::Git::HooksService::PreReceiveError)
end
it 'does not create the branch' do
......@@ -860,7 +861,7 @@ describe Repository, models: true do
expect do
repository.add_branch(user, 'new_feature', 'master')
end.to raise_error(GitHooksService::PreReceiveError)
end.to raise_error(Gitlab::Git::HooksService::PreReceiveError)
expect(repository.find_branch('new_feature')).to be_nil
end
end
......@@ -890,8 +891,8 @@ describe Repository, models: true do
context 'when pre hooks were successful' do
it 'runs without errors' do
expect_any_instance_of(GitHooksService).to receive(:execute)
.with(user, project, old_rev, blank_sha, 'refs/heads/feature')
expect_any_instance_of(Gitlab::Git::HooksService).to receive(:execute)
.with(committer, repository, old_rev, blank_sha, 'refs/heads/feature')
expect { repository.rm_branch(user, 'feature') }.not_to raise_error
end
......@@ -911,7 +912,7 @@ describe Repository, models: true do
expect do
repository.rm_branch(user, 'feature')
end.to raise_error(GitHooksService::PreReceiveError)
end.to raise_error(Gitlab::Git::HooksService::PreReceiveError)
end
it 'does not delete the branch' do
......@@ -919,7 +920,7 @@ describe Repository, models: true do
expect do
repository.rm_branch(user, 'feature')
end.to raise_error(GitHooksService::PreReceiveError)
end.to raise_error(Gitlab::Git::HooksService::PreReceiveError)
expect(repository.find_branch('feature')).not_to be_nil
end
end
......@@ -931,23 +932,23 @@ describe Repository, models: true do
context 'when pre hooks were successful' do
before do
service = GitHooksService.new
expect(GitHooksService).to receive(:new).and_return(service)
service = Gitlab::Git::HooksService.new
expect(Gitlab::Git::HooksService).to receive(:new).and_return(service)
expect(service).to receive(:execute)
.with(user, project, old_rev, new_rev, 'refs/heads/feature')
.with(committer, repository, old_rev, new_rev, 'refs/heads/feature')
.and_yield(service).and_return(true)
end
it 'runs without errors' do
expect do
GitOperationService.new(user, repository).with_branch('feature') do
GitOperationService.new(committer, repository).with_branch('feature') do
new_rev
end
end.not_to raise_error
end
it 'ensures the autocrlf Git option is set to :input' do
service = GitOperationService.new(user, repository)
service = GitOperationService.new(committer, repository)
expect(service).to receive(:update_autocrlf_option)
......@@ -958,7 +959,7 @@ describe Repository, models: true do
it 'updates the head' do
expect(repository.find_branch('feature').dereferenced_target.id).to eq(old_rev)
GitOperationService.new(user, repository).with_branch('feature') do
GitOperationService.new(committer, repository).with_branch('feature') do
new_rev
end
......@@ -980,7 +981,7 @@ describe Repository, models: true do
end
expect do
GitOperationService.new(user, target_project.repository)
GitOperationService.new(committer, target_project.repository)
.with_branch('feature',
start_project: project,
&:itself)
......@@ -1002,7 +1003,7 @@ describe Repository, models: true do
repository.add_branch(user, branch, old_rev)
expect do
GitOperationService.new(user, repository).with_branch(branch) do
GitOperationService.new(committer, repository).with_branch(branch) do
new_rev
end
end.not_to raise_error
......@@ -1020,7 +1021,7 @@ describe Repository, models: true do
# Updating 'master' to new_rev would lose the commits on 'master' that
# are not contained in new_rev. This should not be allowed.
expect do
GitOperationService.new(user, repository).with_branch(branch) do
GitOperationService.new(committer, repository).with_branch(branch) do
new_rev
end
end.to raise_error(Repository::CommitError)
......@@ -1032,10 +1033,10 @@ describe Repository, models: true do
allow_any_instance_of(Gitlab::Git::Hook).to receive(:trigger).and_return([false, ''])
expect do
GitOperationService.new(user, repository).with_branch('feature') do
GitOperationService.new(committer, repository).with_branch('feature') do
new_rev
end
end.to raise_error(GitHooksService::PreReceiveError)
end.to raise_error(Gitlab::Git::HooksService::PreReceiveError)
end
end
......@@ -1050,7 +1051,7 @@ describe Repository, models: true do
expect(repository).not_to receive(:expire_emptiness_caches)
expect(repository).to receive(:expire_branches_cache)
GitOperationService.new(user, repository)
GitOperationService.new(committer, repository)
.with_branch('new-feature') do
new_rev
end
......
......@@ -76,7 +76,7 @@ describe Files::UpdateService do
let(:branch_name) { "#{project.default_branch}-new" }
it 'fires hooks only once' do
expect(GitHooksService).to receive(:new).once.and_call_original
expect(Gitlab::Git::HooksService).to receive(:new).once.and_call_original
subject.execute
end
......
......@@ -14,14 +14,14 @@ describe Groups::NestedCreateService do
expect(service.execute).to eq(child)
end
it 'reuses a parent if it already existed' do
it 'reuses a parent if it already existed', :nested_groups do
parent = create(:group, path: 'a-group')
parent.add_owner(user)
expect(service.execute.parent).to eq(parent)
end
it 'creates group and subgroup in the database' do
it 'creates group and subgroup in the database', :nested_groups do
service.execute
parent = Group.find_by_full_path('a-group')
......
......@@ -233,7 +233,7 @@ describe MergeRequests::MergeService do
it 'logs and saves error if there is an PreReceiveError exception' do
error_message = 'error message'
allow(service).to receive(:repository).and_raise(GitHooksService::PreReceiveError, error_message)
allow(service).to receive(:repository).and_raise(Gitlab::Git::HooksService::PreReceiveError, error_message)
allow(service).to receive(:execute_hooks)
service.execute(merge_request)
......
......@@ -41,7 +41,7 @@ describe Tags::CreateService do
it 'returns an error' do
expect(repository).to receive(:add_tag)
.with(user, 'v1.1.0', 'master', 'Foo')
.and_raise(GitHooksService::PreReceiveError, 'something went wrong')
.and_raise(Gitlab::Git::HooksService::PreReceiveError, 'something went wrong')
response = service.execute('v1.1.0', 'master', 'Foo')
......
......@@ -45,18 +45,4 @@ module ApiHelpers
oauth_access_token: oauth_access_token
)
end
def ci_api(path, user = nil)
"/ci/api/v1/#{path}" +
# Normalize query string
(path.index('?') ? '' : '?') +
# Append private_token if given a User object
if user.respond_to?(:private_token)
"&private_token=#{user.private_token}"
else
''
end
end
end
......@@ -78,6 +78,8 @@ module CycleAnalyticsHelpers
@dummy_pipeline ||=
Ci::Pipeline.new(
sha: project.repository.commit('master').sha,
ref: 'master',
source: :push,
project: project)
end
......
......@@ -3,7 +3,7 @@ require 'spec_helper'
describe BuildFinishedWorker do
describe '#perform' do
context 'when build exists' do
let(:build) { create(:ci_build) }
let!(:build) { create(:ci_build) }
it 'calculates coverage and calls hooks' do
expect(BuildCoverageWorker)
......
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