Commit 51769eb2 authored by Robert Speicher's avatar Robert Speicher

Merge branch 'ce-981829f3-to-master' into 'master'

Merge CE 981829f3 into EE master

This merges everything up to (and including) CE commit 981829f3 into EE. This was done mainly to have the update guides for CE also in EE along with any other changes since the last merge.

See merge request !442
parents ff0bfe78 e774b022
......@@ -96,6 +96,11 @@ scss-lint:
script:
- bundle exec rake scss_lint
license-finder:
stage: test
script:
- bundle exec license_finder
brakeman:
stage: test
script:
......
......@@ -6,6 +6,7 @@ v 8.8.1
v 8.9.0 (unreleased)
- Bulk assign/unassign labels to issues.
- Allow enabling wiki page events from Webhook management UI
- Bump rouge to 1.11.0
- Make EmailsOnPushWorker use Sidekiq mailers queue
- Fix wiki page events' webhook to point to the wiki repository
- Fix issue todo not remove when leave project !4150 (Long Nguyen)
......@@ -39,8 +40,10 @@ v 8.9.0 (unreleased)
- Cache project build count in sidebar nav
- Reduce number of queries needed to render issue labels in the sidebar
- Improve error handling importing projects
- Remove duplicated notification settings
- Put project Files and Commits tabs under Code tab
- Replace Colorize with Rainbow for coloring console output in Rake tasks.
- An indicator is now displayed at the top of the comment field for confidential issues.
v 8.8.4 (unreleased)
- Ensure branch cleanup regardless of whether the GitHub import process succeeds
......@@ -48,6 +51,10 @@ v 8.8.4 (unreleased)
- Fix todos page throwing errors when you have a project pending deletion
- Reduce number of SQL queries when rendering user references
- Upgrade to jQuery 2
- Remove prev/next buttons on issues and merge requests
- Import GitHub repositories respecting the API rate limit
- Fix importer for GitHub comments on diff
- Disable Webhooks before proceeding with the GitHub import
v 8.8.3
- Fix 404 page when viewing TODOs that contain milestones or labels in different projects. !4312
......@@ -168,6 +175,7 @@ v 8.7.6
- Fix import from GitLab.com to a private instance failure. !4181
- Fix external imports not finding the import data. !4106
- Fix notification delay when changing status of an issue
- Bump Workhorse to 0.7.5 so it can serve raw diffs
v 8.7.5
- Fix relative links in wiki pages. !4050
......
......@@ -121,7 +121,7 @@ gem 'org-ruby', '~> 0.9.12'
gem 'creole', '~> 0.5.0'
gem 'wikicloth', '0.8.1'
gem 'asciidoctor', '~> 1.5.2'
gem 'rouge', '~> 1.10.1'
gem 'rouge', '~> 1.11'
# See https://groups.google.com/forum/#!topic/ruby-security-ann/aSbgDiwb24s
# and https://groups.google.com/forum/#!topic/ruby-security-ann/Dy7YiKb_pMM
......@@ -317,6 +317,8 @@ group :development, :test do
gem 'bundler-audit', require: false
gem 'benchmark-ips', require: false
gem "license_finder", require: false
end
group :test do
......
......@@ -390,6 +390,12 @@ GEM
actionmailer (>= 3.2)
letter_opener (~> 1.0)
railties (>= 3.2)
license_finder (2.1.0)
bundler
httparty
rubyzip
thor
xml-simple
licensee (8.0.0)
rugged (>= 0.24b)
listen (3.0.5)
......@@ -593,7 +599,7 @@ GEM
railties (>= 4.2.0, < 5.1)
rinku (1.7.3)
rotp (2.1.2)
rouge (1.10.1)
rouge (1.11.0)
rqrcode (0.7.0)
chunky_png
rqrcode-rails3 (0.1.7)
......@@ -642,6 +648,7 @@ GEM
sexp_processor (~> 4.1)
rubyntlm (0.5.2)
rubypants (0.2.0)
rubyzip (1.2.0)
rufus-scheduler (3.1.10)
rugged (0.24.0)
safe_yaml (1.0.4)
......@@ -816,6 +823,7 @@ GEM
builder
expression_parser
rinku
xml-simple (1.1.5)
xpath (2.0.0)
nokogiri (~> 1.3)
......@@ -907,6 +915,7 @@ DEPENDENCIES
jwt
kaminari (~> 0.17.0)
letter_opener_web (~> 1.3.0)
license_finder
licensee (~> 8.0.0)
loofah (~> 2.0.3)
mail_room (~> 0.7)
......@@ -959,7 +968,7 @@ DEPENDENCIES
request_store (~> 1.3.0)
rerun (~> 0.11.0)
responders (~> 2.0)
rouge (~> 1.10.1)
rouge (~> 1.11)
rqrcode-rails3 (~> 0.1.7)
rspec-rails (~> 3.4.0)
rspec-retry
......
......@@ -10,14 +10,6 @@ class @ShortcutsIssuable extends ShortcutsNavigation
@replyWithSelectedText()
return false
)
Mousetrap.bind('j', =>
@prevIssue()
return false
)
Mousetrap.bind('k', =>
@nextIssue()
return false
)
Mousetrap.bind('e', =>
@editIssue()
return false
......@@ -29,16 +21,6 @@ class @ShortcutsIssuable extends ShortcutsNavigation
else
@enabledHelp.push('.hidden-shortcut.issues')
prevIssue: ->
$prevBtn = $('.prev-btn')
if not $prevBtn.hasClass('disabled')
Turbolinks.visit($prevBtn.attr('href'))
nextIssue: ->
$nextBtn = $('.next-btn')
if not $nextBtn.hasClass('disabled')
Turbolinks.visit($nextBtn.attr('href'))
replyWithSelectedText: ->
if window.getSelection
selected = window.getSelection().toString()
......
......@@ -66,10 +66,6 @@
display: none;
}
%ul.notes .note-role, .note-actions {
display: none;
}
.nav-links, .nav-links {
li a {
font-size: 14px;
......
......@@ -87,6 +87,39 @@
}
}
.md-header .nav-links {
display: flex;
display: -webkit-flex;
flex-flow: row wrap;
-webkit-flex-flow: row wrap;
width: 100%;
.pull-right {
// Flexbox quirk to make sure right-aligned items stay right-aligned.
margin-left: auto;
}
}
.confidential-issue-warning {
background-color: $gray-normal;
border-radius: 3px;
padding: 3px 12px;
margin: auto;
margin-top: 0;
text-align: center;
font-size: 13px;
@media (max-width: $screen-md-min) {
// On smaller devices the warning becomes the fourth item in the list,
// rather than centering, and grows to span the full width of the
// comment area.
order: 4;
-webkit-order: 4;
margin: 6px auto;
width: 100%;
}
}
.discussion-form {
padding: $gl-padding-top $gl-padding;
background-color: $white-light;
......
......@@ -134,6 +134,11 @@ ul.notes {
.note-header {
padding-bottom: 3px;
padding-right: 20px;
@media (min-width: $screen-sm-min) {
padding-right: 0;
}
}
.note-emoji-button {
......@@ -211,6 +216,8 @@ ul.notes {
.discussion-header,
.note-header {
position: relative;
a {
color: inherit;
......@@ -247,6 +254,16 @@ ul.notes {
color: $notes-action-color;
}
.note-actions {
position: absolute;
right: 0;
top: 0;
@media (min-width: $screen-sm-min) {
position: relative;
}
}
.discussion-actions {
@media (max-width: $screen-md-max) {
float: none;
......@@ -260,8 +277,13 @@ ul.notes {
.note-action-button {
display: inline-block;
margin-left: 0;
line-height: 20px;
@media (min-width: $screen-sm-min) {
margin-left: 10px;
line-height: 24px;
}
.fa {
color: $notes-action-color;
......
......@@ -26,9 +26,9 @@ class Projects::BuildsController < Projects::ApplicationController
end
def show
@builds = @project.ci_commits.find_by_sha(@build.sha).builds.order('id DESC')
@builds = @project.pipelines.find_by_sha(@build.sha).builds.order('id DESC')
@builds = @builds.where("id not in (?)", @build.id)
@commit = @build.commit
@pipeline = @build.pipeline
respond_to do |format|
format.html
......
......@@ -99,12 +99,12 @@ class Projects::CommitController < Projects::ApplicationController
@commit ||= @project.commit(params[:id])
end
def ci_commits
@ci_commits ||= project.ci_commits.where(sha: commit.sha)
def pipelines
@pipelines ||= project.pipelines.where(sha: commit.sha)
end
def ci_builds
@ci_builds ||= Ci::Build.where(commit: ci_commits)
@ci_builds ||= Ci::Build.where(pipeline: pipelines)
end
def define_show_vars
......@@ -117,8 +117,8 @@ class Projects::CommitController < Projects::ApplicationController
@diff_refs = [commit.parent || commit, commit]
@notes_count = commit.notes.count
@statuses = CommitStatus.where(commit: ci_commits)
@builds = Ci::Build.where(commit: ci_commits)
@statuses = CommitStatus.where(pipeline: pipelines)
@builds = Ci::Build.where(pipeline: pipelines)
end
def assign_change_commit_vars(mr_source_branch)
......
......@@ -60,8 +60,15 @@ class Projects::MergeRequestsController < Projects::ApplicationController
respond_to do |format|
format.html
format.json { render json: @merge_request, methods: :rebase_in_progress? }
format.diff { render text: @merge_request.to_diff }
format.patch { render text: @merge_request.to_patch }
format.diff do
headers.store(*Gitlab::Workhorse.send_git_diff(@project.repository,
@merge_request.diff_base_commit.id,
@merge_request.last_commit.id))
headers['Content-Disposition'] = 'inline'
head :ok
end
end
end
......@@ -121,8 +128,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
@diffs = @merge_request.compare.diffs(diff_options) if @merge_request.compare
@diff_notes_disabled = true
@ci_commit = @merge_request.ci_commit
@statuses = @ci_commit.statuses if @ci_commit
@pipeline = @merge_request.pipeline
@statuses = @pipeline.statuses if @pipeline
@note_counts = Note.where(commit_id: @commits.map(&:id)).
group(:commit_id).count
......@@ -130,8 +137,6 @@ class Projects::MergeRequestsController < Projects::ApplicationController
set_suggested_approvers
end
def create
@target_branches ||= []
@merge_request = MergeRequests::CreateService.new(project, current_user, merge_request_params).execute
......@@ -215,7 +220,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
@merge_request.update(merge_error: nil)
if params[:merge_when_build_succeeds].present? && @merge_request.ci_commit && @merge_request.ci_commit.active?
if params[:merge_when_build_succeeds].present? && @merge_request.pipeline && @merge_request.pipeline.active?
MergeRequests::MergeWhenBuildSucceedsService.new(@project, current_user, merge_params)
.execute(@merge_request)
@status = :merge_when_build_succeeds
......@@ -253,10 +258,10 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
def ci_status
ci_commit = @merge_request.ci_commit
if ci_commit
status = ci_commit.status
coverage = ci_commit.try(:coverage)
pipeline = @merge_request.pipeline
if pipeline
status = pipeline.status
coverage = pipeline.try(:coverage)
status ||= "preparing"
else
......@@ -351,8 +356,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
@merge_request_diff = @merge_request.merge_request_diff
@ci_commit = @merge_request.ci_commit
@statuses = @ci_commit.statuses if @ci_commit
@pipeline = @merge_request.pipeline
@statuses = @pipeline.statuses if @pipeline
if @merge_request.locked_long_ago?
@merge_request.unlock_mr
......@@ -361,8 +366,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
def define_widget_vars
@ci_commit = @merge_request.ci_commit
@ci_commits = [@ci_commit].compact
@pipeline = @merge_request.pipeline
@pipelines = [@pipeline].compact
closes_issues
end
......@@ -384,7 +389,6 @@ class Projects::MergeRequestsController < Projects::ApplicationController
params.require(:merge_request).permit(
:title, :assignee_id, :source_project_id, :source_branch,
:target_project_id, :target_branch, :milestone_id, :approver_ids,
:target_project_id, :target_branch, :milestone_id,
:state_event, :description, :task_num, :force_remove_source_branch,
label_ids: []
)
......
......@@ -7,7 +7,7 @@ class Projects::PipelinesController < Projects::ApplicationController
def index
@scope = params[:scope]
all_pipelines = project.ci_commits
all_pipelines = project.pipelines
@pipelines_count = all_pipelines.count
@running_or_pending_count = all_pipelines.running_or_pending.count
@pipelines = PipelinesFinder.new(project).execute(all_pipelines, @scope)
......@@ -15,7 +15,7 @@ class Projects::PipelinesController < Projects::ApplicationController
end
def new
@pipeline = project.ci_commits.new(ref: @project.default_branch)
@pipeline = project.pipelines.new(ref: @project.default_branch)
end
def create
......@@ -50,7 +50,7 @@ class Projects::PipelinesController < Projects::ApplicationController
end
def pipeline
@pipeline ||= project.ci_commits.find_by!(id: params[:id])
@pipeline ||= project.pipelines.find_by!(id: params[:id])
end
def commit
......
module CiStatusHelper
def ci_status_path(ci_commit)
project = ci_commit.project
builds_namespace_project_commit_path(project.namespace, project, ci_commit.sha)
def ci_status_path(pipeline)
project = pipeline.project
builds_namespace_project_commit_path(project.namespace, project, pipeline.sha)
end
def ci_status_with_icon(status, target = nil)
......
......@@ -8,14 +8,6 @@ module IssuablesHelper
"right-sidebar-#{sidebar_gutter_collapsed? ? 'collapsed' : 'expanded'}"
end
def issuables_count(issuable)
base_issuable_scope(issuable).maximum(:iid)
end
def next_issuable_for(issuable)
base_issuable_scope(issuable).where('iid > ?', issuable.iid).last
end
def multi_label_name(current_labels, default_label)
# current_labels may be a string from before
if current_labels.is_a?(Array)
......@@ -45,10 +37,6 @@ module IssuablesHelper
end
end
def prev_issuable_for(issuable)
base_issuable_scope(issuable).where('iid < ?', issuable.iid).first
end
def user_dropdown_label(user_id, default_label)
return default_label if user_id.nil?
return "Unassigned" if user_id == "0"
......
......@@ -45,8 +45,8 @@ module Ci
new_build.options = build.options
new_build.commands = build.commands
new_build.tag_list = build.tag_list
new_build.gl_project_id = build.gl_project_id
new_build.commit_id = build.commit_id
new_build.project = build.project
new_build.pipeline = build.pipeline
new_build.name = build.name
new_build.allow_failure = build.allow_failure
new_build.stage = build.stage
......@@ -66,7 +66,7 @@ module Ci
# We use around_transition to create builds for next stage as soon as possible, before the `after_*` is executed
around_transition any => [:success, :failed, :canceled] do |build, block|
block.call
build.commit.create_next_builds(build) if build.commit
build.pipeline.create_next_builds(build) if build.pipeline
end
after_transition any => [:success, :failed, :canceled] do |build|
......@@ -80,7 +80,7 @@ module Ci
end
def retried?
!self.commit.statuses.latest.include?(self)
!self.pipeline.statuses.latest.include?(self)
end
def retry
......@@ -89,7 +89,7 @@ module Ci
def depends_on_builds
# Get builds of the same type
latest_builds = self.commit.builds.latest
latest_builds = self.pipeline.builds.latest
# Return builds from previous stages
latest_builds.where('stage_idx < ?', stage_idx)
......@@ -114,11 +114,11 @@ module Ci
def merge_request
merge_requests = MergeRequest.includes(:merge_request_diff)
.where(source_branch: ref, source_project_id: commit.gl_project_id)
.where(source_branch: ref, source_project_id: pipeline.gl_project_id)
.reorder(iid: :asc)
merge_requests.find do |merge_request|
merge_request.commits.any? { |ci| ci.id == commit.sha }
merge_request.commits.any? { |ci| ci.id == pipeline.sha }
end
end
......@@ -361,8 +361,8 @@ module Ci
end
def global_yaml_variables
if commit.config_processor
commit.config_processor.global_variables.map do |key, value|
if pipeline.config_processor
pipeline.config_processor.global_variables.map do |key, value|
{ key: key, value: value, public: true }
end
else
......@@ -371,8 +371,8 @@ module Ci
end
def job_yaml_variables
if commit.config_processor
commit.config_processor.job_variables(name).map do |key, value|
if pipeline.config_processor
pipeline.config_processor.job_variables(name).map do |key, value|
{ key: key, value: value, public: true }
end
else
......
module Ci
class Commit < ActiveRecord::Base
class Pipeline < ActiveRecord::Base
extend Ci::Model
include Statuseable
self.table_name = 'ci_commits'
belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id
has_many :statuses, class_name: 'CommitStatus'
has_many :builds, class_name: 'Ci::Build'
has_many :trigger_requests, dependent: :destroy, class_name: 'Ci::TriggerRequest'
has_many :statuses, class_name: 'CommitStatus', foreign_key: :commit_id
has_many :builds, class_name: 'Ci::Build', foreign_key: :commit_id
has_many :trigger_requests, dependent: :destroy, class_name: 'Ci::TriggerRequest', foreign_key: :commit_id
validates_presence_of :sha
validates_presence_of :status
......@@ -21,7 +23,7 @@ module Ci
def self.stages
# We use pluck here due to problems with MySQL which doesn't allow LIMIT/OFFSET in queries
CommitStatus.where(commit: pluck(:id)).stages
CommitStatus.where(pipeline: pluck(:id)).stages
end
def project_id
......@@ -47,7 +49,7 @@ module Ci
end
def short_sha
Ci::Commit.truncate_sha(sha)
Ci::Pipeline.truncate_sha(sha)
end
def commit_data
......
......@@ -3,7 +3,7 @@ module Ci
extend Ci::Model
belongs_to :trigger, class_name: 'Ci::Trigger'
belongs_to :commit, class_name: 'Ci::Commit'
belongs_to :commit, class_name: 'Ci::Pipeline', foreign_key: :commit_id
has_many :builds, class_name: 'Ci::Build'
serialize :variables
......
......@@ -214,13 +214,13 @@ class Commit
@raw.short_id(7)
end
def ci_commits
@ci_commits ||= project.ci_commits.where(sha: sha)
def pipelines
@pipeline ||= project.pipelines.where(sha: sha)
end
def status
return @status if defined?(@status)
@status ||= ci_commits.status
@status ||= pipelines.status
end
def revert_branch_name
......
......@@ -4,10 +4,10 @@ class CommitStatus < ActiveRecord::Base
self.table_name = 'ci_builds'
belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id
belongs_to :commit, class_name: 'Ci::Commit', touch: true
belongs_to :pipeline, class_name: 'Ci::Pipeline', foreign_key: :commit_id, touch: true
belongs_to :user
validates :commit, presence: true
validates :pipeline, presence: true
validates_presence_of :name
......@@ -44,18 +44,18 @@ class CommitStatus < ActiveRecord::Base
end
after_transition [:pending, :running] => :success do |commit_status|
MergeRequests::MergeWhenBuildSucceedsService.new(commit_status.commit.project, nil).trigger(commit_status)
MergeRequests::MergeWhenBuildSucceedsService.new(commit_status.pipeline.project, nil).trigger(commit_status)
end
after_transition any => :failed do |commit_status|
MergeRequests::AddTodoWhenBuildFailsService.new(commit_status.commit.project, nil).execute(commit_status)
MergeRequests::AddTodoWhenBuildFailsService.new(commit_status.pipeline.project, nil).execute(commit_status)
end
end
delegate :sha, :short_sha, to: :commit
delegate :sha, :short_sha, to: :pipeline
def before_sha
commit.before_sha || Gitlab::Git::BLANK_SHA
pipeline.before_sha || Gitlab::Git::BLANK_SHA
end
def self.stages
......
......@@ -317,13 +317,6 @@ class MergeRequest < ActiveRecord::Base
)
end
# Returns the raw diff for this merge request
#
# see "git diff"
def to_diff
target_project.repository.diff_text(diff_base_commit.sha, source_sha)
end
# Returns the commit as a series of email patches.
#
# see "git format-patch"
......@@ -655,8 +648,8 @@ class MergeRequest < ActiveRecord::Base
diverged_commits_count > 0
end
def ci_commit
@ci_commit ||= source_project.ci_commit(last_commit.id, source_branch) if last_commit && source_project
def pipeline
@pipeline ||= source_project.pipeline(last_commit.id, source_branch) if last_commit && source_project
end
def diff_refs
......
......@@ -121,7 +121,7 @@ class Project < ActiveRecord::Base
has_one :import_data, dependent: :destroy, class_name: "ProjectImportData"
has_many :commit_statuses, dependent: :destroy, class_name: 'CommitStatus', foreign_key: :gl_project_id
has_many :ci_commits, dependent: :destroy, class_name: 'Ci::Commit', foreign_key: :gl_project_id
has_many :pipelines, dependent: :destroy, class_name: 'Ci::Pipeline', foreign_key: :gl_project_id
has_many :builds, class_name: 'Ci::Build', foreign_key: :gl_project_id # the builds are created from the commit_statuses
has_many :runner_projects, dependent: :destroy, class_name: 'Ci::RunnerProject', foreign_key: :gl_project_id
has_many :runners, through: :runner_projects, source: :runner, class_name: 'Ci::Runner'
......@@ -1066,12 +1066,12 @@ class Project < ActiveRecord::Base
!namespace.share_with_group_lock
end
def ci_commit(sha, ref)
ci_commits.order(id: :desc).find_by(sha: sha, ref: ref)
def pipeline(sha, ref)
pipelines.order(id: :desc).find_by(sha: sha, ref: ref)
end
def ensure_ci_commit(sha, ref)
ci_commit(sha, ref) || ci_commits.create(sha: sha, ref: ref)
def ensure_pipeline(sha, ref)
pipeline(sha, ref) || pipelines.create(sha: sha, ref: ref)
end
def enable_ci
......
module Ci
class CreateBuildsService
def initialize(commit)
@commit = commit
def initialize(pipeline)
@pipeline = pipeline
end
def execute(stage, user, status, trigger_request = nil)
builds_attrs = config_processor.builds_for_stage_and_ref(stage, @commit.ref, @commit.tag, trigger_request)
builds_attrs = config_processor.builds_for_stage_and_ref(stage, @pipeline.ref, @pipeline.tag, trigger_request)
# check when to create next build
builds_attrs = builds_attrs.select do |build_attrs|
......@@ -21,7 +21,7 @@ module Ci
builds_attrs.map do |build_attrs|
# don't create the same build twice
unless @commit.builds.find_by(ref: @commit.ref, tag: @commit.tag,
unless @pipeline.builds.find_by(ref: @pipeline.ref, tag: @pipeline.tag,
trigger_request: trigger_request, name: build_attrs[:name])
build_attrs.slice!(:name,
:commands,
......@@ -31,13 +31,13 @@ module Ci
:stage,
:stage_idx)
build_attrs.merge!(ref: @commit.ref,
tag: @commit.tag,
build_attrs.merge!(ref: @pipeline.ref,
tag: @pipeline.tag,
trigger_request: trigger_request,
user: user,
project: @commit.project)
project: @pipeline.project)
@commit.builds.create!(build_attrs)
@pipeline.builds.create!(build_attrs)
end
end
end
......@@ -45,7 +45,7 @@ module Ci
private
def config_processor
@config_processor ||= @commit.config_processor
@config_processor ||= @pipeline.config_processor
end
end
end
module Ci
class CreatePipelineService < BaseService
def execute
pipeline = project.ci_commits.new(params)
pipeline = project.pipelines.new(params)
unless ref_names.include?(params[:ref])
pipeline.errors.add(:base, 'Reference not found')
......@@ -19,7 +19,7 @@ module Ci
end
begin
Ci::Commit.transaction do
Ci::Pipeline.transaction do
pipeline.sha = commit.id
unless pipeline.config_processor
......
......@@ -7,14 +7,14 @@ module Ci
# check if ref is tag
tag = project.repository.find_tag(ref).present?
ci_commit = project.ci_commits.create(sha: commit.sha, ref: ref, tag: tag)
pipeline = project.pipelines.create(sha: commit.sha, ref: ref, tag: tag)
trigger_request = trigger.trigger_requests.create!(
variables: variables,
commit: ci_commit,
commit: pipeline,
)
if ci_commit.create_builds(nil, trigger_request)
if pipeline.create_builds(nil, trigger_request)
trigger_request
end
end
......
......@@ -3,9 +3,9 @@ module Ci
def execute(project, opts)
sha = opts[:sha] || ref_sha(project, opts[:ref])
ci_commits = project.ci_commits.where(sha: sha)
ci_commits = ci_commits.where(ref: opts[:ref]) if opts[:ref]
image_name = image_for_status(ci_commits.status)
pipelines = project.pipelines.where(sha: sha)
pipelines = pipelines.where(ref: opts[:ref]) if opts[:ref]
image_name = image_for_status(pipelines.status)
image_path = Rails.root.join('public/ci', image_name)
OpenStruct.new(path: image_path, name: image_name)
......
......@@ -21,23 +21,23 @@ class CreateCommitBuildsService
return false
end
commit = Ci::Commit.new(project: project, sha: sha, ref: ref, before_sha: before_sha, tag: tag)
pipeline = Ci::Pipeline.new(project: project, sha: sha, ref: ref, before_sha: before_sha, tag: tag)
# Skip creating ci_commit when no gitlab-ci.yml is found
unless commit.ci_yaml_file
# Skip creating pipeline when no gitlab-ci.yml is found
unless pipeline.ci_yaml_file
return false
end
# Create a new ci_commit
commit.save!
# Create a new pipeline
pipeline.save!
# Skip creating builds for commits that have [ci skip]
unless commit.skip_ci?
unless pipeline.skip_ci?
# Create builds for commit
commit.create_builds(user)
pipeline.create_builds(user)
end
commit.touch
commit
pipeline.touch
pipeline
end
end
......@@ -55,12 +55,12 @@ module MergeRequests
def each_merge_request(commit_status)
merge_request_from(commit_status).each do |merge_request|
ci_commit = merge_request.ci_commit
pipeline = merge_request.pipeline
next unless ci_commit
next unless ci_commit.sha == commit_status.sha
next unless pipeline
next unless pipeline.sha == commit_status.sha
yield merge_request, ci_commit
yield merge_request, pipeline
end
end
end
......
......@@ -20,10 +20,10 @@ module MergeRequests
# Triggers the automatic merge of merge_request once the build succeeds
def trigger(commit_status)
each_merge_request(commit_status) do |merge_request, ci_commit|
each_merge_request(commit_status) do |merge_request, pipeline|
next unless merge_request.merge_when_build_succeeds?
next unless merge_request.mergeable?
next unless ci_commit.success?
next unless pipeline.success?
MergeWorker.perform_async(merge_request.id, merge_request.merge_user_id, merge_request.merge_params)
end
......
......@@ -52,7 +52,7 @@ module Projects
def create_status
GenericCommitStatus.new(
project: project,
commit: build.commit,
pipeline: build.pipeline,
user: build.user,
ref: build.ref,
stage: 'deploy',
......
......@@ -99,8 +99,8 @@
%td.build-link
- if project
= link_to ci_status_path(build.commit) do
%strong #{build.commit.short_sha}
= link_to ci_status_path(build.pipeline) do
%strong #{build.pipeline.short_sha}
%td.timestamp
- if build.finished_at
......
.event-title
%span.author_name= link_to_author event
%span.event_label{class: event.action_name}
= event_action_name(event)
- if event.target
%strong= link_to event.target.reference_link_text, [event.project.namespace.becomes(Namespace), event.project, event.target], class: 'has-tooltip', title: event.target_title
= event.action_name
%strong
= link_to [event.project.namespace.becomes(Namespace), event.project, event.target], class: 'has-tooltip', title: event.target_title do
= event.target_type.titleize.downcase
= event.target.reference_link_text
- else
= event_action_name(event)
= event_preposition(event)
......
......@@ -4,6 +4,10 @@
%i.fa.fa-github
Import projects from GitHub
%p
%i.fa.fa-warning
To import GitHub pull requests, any pull request source branches that had been deleted are temporarily restored on GitHub. To prevent any connected CI services from being overloaded with dozens of irrelevant branches being created and deleted again, GitHub webhooks are temporarily disabled during the import process.
%p.light
Select projects you want to import.
%hr
......
......@@ -10,7 +10,7 @@
%p
Commit: #{link_to @build.short_sha, namespace_project_commit_url(@build.project.namespace, @build.project, @build.sha)}
%p
Author: #{@build.commit.git_author_name}
Author: #{@build.pipeline.git_author_name}
%p
Branch: #{@build.ref}
%p
......@@ -18,7 +18,7 @@
%p
Job: #{@build.name}
%p
Message: #{@build.commit.git_commit_message}
Message: #{@build.pipeline.git_commit_message}
%p
Build details: #{link_to "Build #{@build.id}", namespace_project_build_url(@build.project.namespace, @build.project, @build)}
Build failed for <%= @project.name %>
Status: <%= @build.status %>
Commit: <%= @build.commit.short_sha %>
Author: <%= @build.commit.git_author_name %>
Commit: <%= @build.pipeline.short_sha %>
Author: <%= @build.pipeline.git_author_name %>
Branch: <%= @build.ref %>
Stage: <%= @build.stage %>
Job: <%= @build.name %>
Message: <%= @build.commit.git_commit_message %>
Message: <%= @build.pipeline.git_commit_message %>
Url: <%= namespace_project_build_url(@build.project.namespace, @build.project, @build) %>
......@@ -10,7 +10,7 @@
%p
Commit: #{link_to @build.short_sha, namespace_project_commit_url(@build.project.namespace, @build.project, @build.sha)}
%p
Author: #{@build.commit.git_author_name}
Author: #{@build.pipeline.git_author_name}
%p
Branch: #{@build.ref}
%p
......@@ -18,7 +18,7 @@
%p
Job: #{@build.name}
%p
Message: #{@build.commit.git_commit_message}
Message: #{@build.pipeline.git_commit_message}
%p
Build details: #{link_to "Build #{@build.id}", namespace_project_build_url(@build.project.namespace, @build.project, @build)}
Build successful for <%= @project.name %>
Status: <%= @build.status %>
Commit: <%= @build.commit.short_sha %>
Author: <%= @build.commit.git_author_name %>
Commit: <%= @build.pipeline.short_sha %>
Author: <%= @build.pipeline.git_author_name %>
Branch: <%= @build.ref %>
Stage: <%= @build.stage %>
Job: <%= @build.name %>
Message: <%= @build.commit.git_commit_message %>
Message: <%= @build.pipeline.git_commit_message %>
Url: <%= namespace_project_build_url(@build.project.namespace, @build.project, @build) %>
......@@ -7,6 +7,12 @@
%li
%a.js-md-preview-button{ href: "#md-preview-holder", tabindex: -1 }
Preview
- if defined?(@issue) && @issue.confidential?
%li.confidential-issue-warning
= icon('warning')
%span This is a confidential issue. Your comment will not be visible to the public.
%li.pull-right
%button.zen-control.zen-control-full.js-zen-enter{ type: 'button', tabindex: -1 }
Go full screen
......
......@@ -4,7 +4,7 @@
.build-page
.row-content-block.top-block
Build ##{@build.id} for commit
%strong.monospace= link_to @build.commit.short_sha, ci_status_path(@build.commit)
%strong.monospace= link_to @build.pipeline.short_sha, ci_status_path(@build.pipeline)
from
= link_to @build.ref, namespace_project_commits_path(@project.namespace, @project, @build.ref)
- merge_request = @build.merge_request
......@@ -13,7 +13,7 @@
= link_to "merge request #{merge_request.to_reference}", merge_request_path(merge_request)
#up-build-trace
- builds = @build.commit.builds.latest.to_a
- builds = @build.pipeline.builds.latest.to_a
- if builds.size > 1
%ul.nav-links.no-top.no-bottom
- builds.each do |build|
......@@ -178,16 +178,16 @@
Commit
.pull-right
%small
= link_to @build.commit.short_sha, ci_status_path(@build.commit), class: "monospace"
= link_to @build.pipeline.short_sha, ci_status_path(@build.pipeline), class: "monospace"
%p
%span.attr-name Branch:
= link_to @build.ref, namespace_project_commits_path(@project.namespace, @project, @build.ref)
%p
%span.attr-name Author:
#{@build.commit.git_author_name}
#{@build.pipeline.git_author_name}
%p
%span.attr-name Message:
#{@build.commit.git_commit_message}
#{@build.pipeline.git_commit_message}
- if @build.tags.any?
.build-widget
......@@ -201,7 +201,7 @@
.build-widget
%h4.title #{pluralize(@builds.count(:id), "other build")} for
= succeed ":" do
= link_to @build.commit.short_sha, ci_status_path(@build.commit), class: "monospace"
= link_to @build.pipeline.short_sha, ci_status_path(@build.pipeline), class: "monospace"
%table.table.builds
- @builds.each_with_index do |build, i|
%tr.build
......
- status = commit.status
- status = pipeline.status
%tr.commit
%td.commit-link
= link_to namespace_project_pipeline_path(@project.namespace, @project, commit.id), class: "ci-status ci-#{status}" do
= link_to namespace_project_pipeline_path(@project.namespace, @project, pipeline.id), class: "ci-status ci-#{status}" do
= ci_icon_for_status(status)
%strong ##{commit.id}
%strong ##{pipeline.id}
%td
%div.branch-commit
- if commit.ref
= link_to commit.ref, namespace_project_commits_path(@project.namespace, @project, commit.ref), class: "monospace"
- if pipeline.ref
= link_to pipeline.ref, namespace_project_commits_path(@project.namespace, @project, pipeline.ref), class: "monospace"
&middot;
= link_to commit.short_sha, namespace_project_commit_path(@project.namespace, @project, commit.sha), class: "commit-id monospace"
= link_to pipeline.short_sha, namespace_project_commit_path(@project.namespace, @project, pipeline.sha), class: "commit-id monospace"
&nbsp;
- if commit.tag?
- if pipeline.tag?
%span.label.label-primary tag
- elsif commit.latest?
- elsif pipeline.latest?
%span.label.label-success.has-tooltip{ title: 'Latest build for this branch' } latest
- if commit.triggered?
- if pipeline.triggered?
%span.label.label-primary triggered
- if commit.yaml_errors.present?
%span.label.label-danger.has-tooltip{ title: "#{commit.yaml_errors}" } yaml invalid
- if commit.builds.any?(&:stuck?)
- if pipeline.yaml_errors.present?
%span.label.label-danger.has-tooltip{ title: "#{pipeline.yaml_errors}" } yaml invalid
- if pipeline.builds.any?(&:stuck?)
%span.label.label-warning stuck
%p.commit-title
- if commit_data = commit.commit_data
- if commit_data = pipeline.commit_data
= link_to_gfm truncate(commit_data.title, length: 60), namespace_project_commit_path(@project.namespace, @project, commit_data.id), class: "commit-row-message"
- else
Cant find HEAD commit for this branch
- stages_status = commit.statuses.stages_status
- stages_status = pipeline.statuses.stages_status
- stages.each do |stage|
%td
- status = stages_status[stage]
- tooltip = "#{stage.titleize}: #{status || 'not found'}"
- if status
= link_to namespace_project_pipeline_path(@project.namespace, @project, commit.id, anchor: stage), class: "has-tooltip ci-status-icon-#{status}", title: tooltip do
= link_to namespace_project_pipeline_path(@project.namespace, @project, pipeline.id, anchor: stage), class: "has-tooltip ci-status-icon-#{status}", title: tooltip do
= ci_icon_for_status(status)
- else
.light.has-tooltip{ title: tooltip }
\-
%td
- if commit.started_at && commit.finished_at
- if pipeline.started_at && pipeline.finished_at
%p.duration
#{duration_in_words(commit.finished_at, commit.started_at)}
#{duration_in_words(pipeline.finished_at, pipeline.started_at)}
%td
.controls.hidden-xs.pull-right
- artifacts = commit.builds.latest.select { |b| b.artifacts? }
- artifacts = pipeline.builds.latest.select { |b| b.artifacts? }
- if artifacts.present?
.dropdown.inline.build-artifacts
%button.dropdown-toggle.btn{type: 'button', 'data-toggle' => 'dropdown'}
......@@ -63,9 +63,9 @@
%span #{build.name}
- if can?(current_user, :update_pipeline, @project)
- if commit.retryable?
= link_to retry_namespace_project_pipeline_path(@project.namespace, @project, commit.id), class: 'btn has-tooltip', title: "Retry", method: :post do
- if pipeline.retryable?
= link_to retry_namespace_project_pipeline_path(@project.namespace, @project, pipeline.id), class: 'btn has-tooltip', title: "Retry", method: :post do
= icon("repeat")
- if commit.cancelable?
= link_to cancel_namespace_project_pipeline_path(@project.namespace, @project, commit.id), class: 'btn btn-remove has-tooltip', title: "Cancel", method: :post do
- if pipeline.cancelable?
= link_to cancel_namespace_project_pipeline_path(@project.namespace, @project, pipeline.id), class: 'btn btn-remove has-tooltip', title: "Cancel", method: :post do
= icon("remove")
- @ci_commits.each do |ci_commit|
= render "ci_commit", ci_commit: ci_commit, pipeline_details: true
- @pipelines.each do |pipeline|
= render "pipeline", pipeline: pipeline, pipeline_details: true
......@@ -53,13 +53,13 @@
- if @commit.status
.commit-info-row
Builds for
= pluralize(@commit.ci_commits.count, 'pipeline')
= pluralize(@commit.pipelines.count, 'pipeline')
= link_to builds_namespace_project_commit_path(@project.namespace, @project, @commit.id), class: "ci-status-link ci-status-icon-#{@commit.status}" do
= ci_icon_for_status(@commit.status)
= ci_label_for_status(@commit.status)
- if @commit.ci_commits.duration
- if @commit.pipelines.duration
in
= time_interval_in_words @commit.ci_commits.duration
= time_interval_in_words @commit.pipelines.duration
.commit-box.content-block
%h3.commit-title
......
.row-content-block.build-content.middle-block
.pull-right
- if can?(current_user, :update_pipeline, ci_commit.project)
- if ci_commit.builds.latest.failed.any?(&:retryable?)
= link_to "Retry failed", retry_namespace_project_pipeline_path(ci_commit.project.namespace, ci_commit.project, ci_commit.id), class: 'btn btn-grouped btn-primary', method: :post
- if can?(current_user, :update_pipeline, pipeline.project)
- if pipeline.builds.latest.failed.any?(&:retryable?)
= link_to "Retry failed", retry_namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id), class: 'btn btn-grouped btn-primary', method: :post
- if ci_commit.builds.running_or_pending.any?
= link_to "Cancel running", cancel_namespace_project_pipeline_path(ci_commit.project.namespace, ci_commit.project, ci_commit.id), data: { confirm: 'Are you sure?' }, class: 'btn btn-grouped btn-danger', method: :post
- if pipeline.builds.running_or_pending.any?
= link_to "Cancel running", cancel_namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id), data: { confirm: 'Are you sure?' }, class: 'btn btn-grouped btn-danger', method: :post
.oneline.clearfix
- if defined?(pipeline_details) && pipeline_details
Pipeline
= link_to "##{ci_commit.id}", namespace_project_pipeline_path(ci_commit.project.namespace, ci_commit.project, ci_commit.id), class: "monospace"
= link_to "##{pipeline.id}", namespace_project_pipeline_path(pipeline.project.namespace, pipeline.project, pipeline.id), class: "monospace"
with
= pluralize ci_commit.statuses.count(:id), "build"
- if ci_commit.ref
= pluralize pipeline.statuses.count(:id), "build"
- if pipeline.ref
for
= link_to ci_commit.ref, namespace_project_commits_path(ci_commit.project.namespace, ci_commit.project, ci_commit.ref), class: "monospace"
= link_to pipeline.ref, namespace_project_commits_path(pipeline.project.namespace, pipeline.project, pipeline.ref), class: "monospace"
- if defined?(link_to_commit) && link_to_commit
for commit
= link_to ci_commit.short_sha, namespace_project_commit_path(ci_commit.project.namespace, ci_commit.project, ci_commit.sha), class: "monospace"
- if ci_commit.duration
= link_to pipeline.short_sha, namespace_project_commit_path(pipeline.project.namespace, pipeline.project, pipeline.sha), class: "monospace"
- if pipeline.duration
in
= time_interval_in_words ci_commit.duration
= time_interval_in_words pipeline.duration
- if ci_commit.yaml_errors.present?
- if pipeline.yaml_errors.present?
.bs-callout.bs-callout-danger
%h4 Found errors in your .gitlab-ci.yml:
%ul
- ci_commit.yaml_errors.split(",").each do |error|
- pipeline.yaml_errors.split(",").each do |error|
%li= error
You can also test your .gitlab-ci.yml in the #{link_to "Lint", ci_lint_path}
- if ci_commit.project.builds_enabled? && !ci_commit.ci_yaml_file
- if pipeline.project.builds_enabled? && !pipeline.ci_yaml_file
.bs-callout.bs-callout-warning
\.gitlab-ci.yml not found in this commit
......@@ -45,8 +45,8 @@
%th Tags
%th Duration
%th Finished at
- if ci_commit.project.build_coverage_enabled?
- if pipeline.project.build_coverage_enabled?
%th Coverage
%th
- ci_commit.statuses.stages.each do |stage|
= render 'projects/commit/ci_stage', stage: stage, statuses: ci_commit.statuses.where(stage: stage)
- pipeline.statuses.stages.each do |stage|
= render 'projects/commit/ci_stage', stage: stage, statuses: pipeline.statuses.where(stage: stage)
......@@ -16,4 +16,4 @@
%li
Commits covered:
%strong
= @project.ci_commits.count(:all)
= @project.pipelines.count(:all)
......@@ -2,12 +2,12 @@
%h2.merge-requests-title
= pluralize(@merge_requests.count, 'Related Merge Request')
%ul.unstyled-list
- has_any_ci = @merge_requests.any?(&:ci_commit)
- has_any_ci = @merge_requests.any?(&:pipeline)
- @merge_requests.each do |merge_request|
%li
%span.merge-request-ci-status
- if merge_request.ci_commit
= render_pipeline_status(merge_request.ci_commit)
- if merge_request.pipeline
= render_pipeline_status(merge_request.pipeline)
- elsif has_any_ci
= icon('blank fw')
%span.merge-request-id
......
......@@ -5,10 +5,10 @@
- @related_branches.each do |branch|
%li
- sha = @project.repository.find_branch(branch).target
- ci_commit = @project.ci_commit(sha, branch) if sha
- if ci_commit
- pipeline = @project.pipeline(sha, branch) if sha
- if ci_copipelinemmit
%span.related-branch-ci-status
= render_pipeline_status(ci_commit)
= render_pipeline_status(pipeline)
%span.related-branch-info
%strong
= link_to namespace_project_compare_path(@project.namespace, @project, from: @project.default_branch, to: branch), class: "label-branch" do
......
......@@ -11,9 +11,9 @@
= icon('ban')
CLOSED
- if merge_request.ci_commit
- if merge_request.pipeline
%li
= render_pipeline_status(merge_request.ci_commit)
= render_pipeline_status(merge_request.pipeline)
- if merge_request.open? && merge_request.broken?
%li
......
......@@ -23,7 +23,7 @@
= link_to url_for(params), data: {target: 'div#commits', action: 'commits', toggle: 'tab'} do
Commits
%span.badge= @commits.size
- if @ci_commit
- if @pipeline
%li.builds-tab.active
= link_to url_for(params), data: {target: 'div#builds', action: 'builds', toggle: 'tab'} do
Builds
......@@ -43,7 +43,7 @@
%p To preserve performance the line changes are not shown.
- else
= render "projects/diffs/diffs", diffs: @diffs, project: @project, diff_refs: @merge_request.diff_refs, show_whitespace_toggle: false
- if @ci_commit
- if @pipeline
#builds.builds.tab-pane
= render "projects/merge_requests/show/builds"
......
......@@ -54,7 +54,7 @@
= link_to commits_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: 'div#commits', action: 'commits', toggle: 'tab'} do
Commits
%span.badge= @commits.size
- if @ci_commit
- if @pipeline
%li.builds-tab
= link_to builds_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), data: {target: '#builds', action: 'builds', toggle: 'tab'} do
Builds
......
= render "projects/commit/ci_commit", ci_commit: @ci_commit, link_to_commit: true
= render "projects/commit/pipeline", pipeline: @pipeline, link_to_commit: true
- if @ci_commit
- if @pipeline
.mr-widget-heading
- %w[success skipped canceled failed running pending].each do |status|
.ci_widget{ class: "ci-#{status}", style: ("display:none" unless @ci_commit.status == status) }
.ci_widget{ class: "ci-#{status}", style: ("display:none" unless @pipeline.status == status) }
= ci_icon_for_status(status)
%span
CI build
......@@ -9,7 +9,7 @@
for
- commit = @merge_request.last_commit
= succeed "." do
= link_to @ci_commit.short_sha, namespace_project_commit_path(@merge_request.source_project.namespace, @merge_request.source_project, @ci_commit.sha), class: "monospace"
= link_to @pipeline.short_sha, namespace_project_commit_path(@merge_request.source_project.namespace, @merge_request.source_project, @pipeline.sha), class: "monospace"
%span.ci-coverage
= link_to "View details", builds_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), class: "js-show-tab", data: {action: 'builds'}
......
......@@ -13,7 +13,7 @@
check_enable: #{@merge_request.unchecked? ? "true" : "false"},
ci_status_url: "#{ci_status_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}",
gitlab_icon: "#{asset_path 'gitlab_logo.png'}",
ci_status: "#{@merge_request.ci_commit ? @merge_request.ci_commit.status : ''}",
ci_status: "#{@merge_request.pipeline ? @merge_request.pipeline.status : ''}",
ci_message: {
normal: "Build {{status}} for \"{{title}}\"",
preparing: "{{status}} build for \"{{title}}\""
......
- status_class = @ci_commit ? " ci-#{@ci_commit.status}" : nil
- status_class = @pipeline ? " ci-#{@pipeline.status}" : nil
= form_for [:merge, @project.namespace.becomes(Namespace), @project, @merge_request], remote: true, method: :post, html: { class: 'accept-mr-form js-quick-submit js-requires-input' } do |f|
= hidden_field_tag :authenticity_token, form_authenticity_token
......@@ -6,7 +6,7 @@
.accept-merge-holder.clearfix.js-toggle-container
.clearfix
.accept-action
- if @ci_commit && @ci_commit.active?
- if @pipeline && @pipeline.active?
%span.btn-group
= button_tag class: "btn btn-create js-merge-button merge_when_build_succeeds" do
Merge When Build Succeeds
......
......@@ -19,15 +19,14 @@
.note-actions
- access = note.project.team.human_max_access(note.author.id)
- if access
%span.note-role
= access
%span.note-role.hidden-xs= access
- if note_editable
= link_to '#', title: 'Award Emoji', class: 'note-action-button note-emoji-button js-add-award js-note-emoji', data: { position: 'right' } do
= icon('spinner spin')
= icon('smile-o')
= link_to '#', title: 'Edit comment', class: 'note-action-button js-note-edit' do
= icon('pencil')
= link_to namespace_project_note_path(note.project.namespace, note.project, note), title: 'Remove comment', method: :delete, data: { confirm: 'Are you sure you want to remove this comment?' }, remote: true, class: 'note-action-button js-note-delete danger' do
= link_to namespace_project_note_path(note.project.namespace, note.project, note), title: 'Remove comment', method: :delete, data: { confirm: 'Are you sure you want to remove this comment?' }, remote: true, class: 'note-action-button hidden-xs js-note-delete danger' do
= icon('trash-o')
.note-body{class: note_editable ? 'js-task-list-container' : ''}
.note-text
......
......@@ -4,7 +4,7 @@
= link_to project_pipelines_path(@project), title: 'Pipelines', class: 'shortcuts-pipelines' do
%span
Pipelines
%span.badge.count.ci_counter= number_with_delimiter(@project.ci_commits.running_or_pending.count)
%span.badge.count.ci_counter= number_with_delimiter(@project.pipelines.running_or_pending.count)
- if project_nav_tab? :builds
= nav_link(controller: %w(builds)) do
......
......@@ -5,4 +5,4 @@
= render "projects/pipelines/info"
%div.block-connector
= render "projects/commit/ci_commit", ci_commit: @pipeline
= render "projects/commit/pipeline", pipeline: @pipeline
......@@ -18,7 +18,7 @@
You can view the #{link_to "most recent version", namespace_project_wiki_path(@project.namespace, @project, @page)} or browse the #{link_to "history", namespace_project_wiki_history_path(@project.namespace, @project, @page)}.
.wiki-holder.prepend-top-default
.wiki-holder.prepend-top-default.append-bottom-default
.wiki
= preserve do
= render_wiki_content(@page)
......@@ -2,23 +2,8 @@
.issuable-sidebar
- can_edit_issuable = can?(current_user, :"admin_#{issuable.to_ability_name}", @project)
.block.issuable-sidebar-header
%span.issuable-count.hide-collapsed.pull-left
= issuable.iid
of
= issuables_count(issuable)
%a.gutter-toggle.pull-right.js-sidebar-toggle{href: '#'}
= sidebar_gutter_toggle_icon
.issuable-nav.hide-collapsed.pull-right.btn-group{role: 'group', "aria-label" => '...'}
- if prev_issuable = prev_issuable_for(issuable)
= link_to 'Prev', [@project.namespace.becomes(Namespace), @project, prev_issuable], class: 'btn btn-default prev-btn issuable-pager'
- else
%a.btn.btn-default.issuable-pager.disabled{href: '#'}
Prev
- if next_issuable = next_issuable_for(issuable)
= link_to 'Next', [@project.namespace.becomes(Namespace), @project, next_issuable], class: 'btn btn-default next-btn issuable-pager'
- else
%a.btn.btn-default.issuable-pager.disabled{href: '#'}
Next
= form_for [@project.namespace.becomes(Namespace), @project, issuable], remote: true, format: :json, html: {class: 'issuable-context-form inline-update js-issuable-update'} do |f|
.block.assignee
......
......@@ -6,6 +6,10 @@
%ul.well-list
- @query.application_backtrace.each do |location|
%li
%strong
- if defined?(BetterErrors)
= link_to(location.path, BetterErrors.editor[location.path, location.line])
- else
= location.path
%small.light
= t('sherlock.line')
......
......@@ -11,13 +11,17 @@
= @query.duration.round(4)
= t('sherlock.milliseconds')
%li
- frame = @query.last_application_frame
%span.light
#{t('sherlock.origin')}:
%strong
= @query.last_application_frame.path
- if defined?(BetterErrors)
= link_to(frame.path, BetterErrors.editor[frame.path, frame.line])
- else
= frame.path
%small.light
= t('sherlock.line')
= @query.last_application_frame.line
= frame.line
.panel.panel-default
.panel-heading
......
---
# IGNORED GROUPS AND GEMS
- - :ignore_group
- development
- :who: Connor Shea
:why: Development gems are not distributed with the final product and are therefore exempt.
:versions: []
:when: 2016-04-17 21:27:01.054140000 Z
- - :ignore_group
- test
- :who: Connor Shea
:why: Test gems are not distributed with the final product and are therefore exempt.
:versions: []
:when: 2016-04-17 21:27:06.250326000 Z
- - :ignore
- bundler
- :who: Connor Shea
:why: Bundler is MIT licensed but will sometimes fail in CI.
:versions: []
:when: 2016-05-02 06:42:08.045090000 Z
# LICENSE WHITELIST
- - :whitelist
- MIT
- :who: Connor Shea
:why: http://choosealicense.com/licenses/mit/
:versions: []
:when: 2016-04-17 21:12:24.558441000 Z
- - :whitelist
- Apache 2.0
- :who: Connor Shea
:why: http://choosealicense.com/licenses/apache-2.0/
:versions: []
:when: 2016-05-02 05:27:43.762702000 Z
- - :whitelist
- ruby
- :who: Connor Shea
:why: https://github.com/ruby/ruby/blob/ruby_2_1/COPYING
:versions: []
:when: 2016-05-02 05:31:54.498490000 Z
- - :whitelist
- LGPL
- :who: Connor Shea
:why: http://www.gnu.org/licenses/license-list.html#LGPLv2.1
:versions: []
:when: 2016-05-02 05:32:48.645841000 Z
- - :whitelist
- ISC
- :who: Connor Shea
:why: http://www.gnu.org/licenses/license-list.html#ISC
:versions: []
:when: 2016-05-02 05:42:01.894452000 Z
- - :whitelist
- New BSD
- :who: Connor Shea
:why: https://opensource.org/licenses/BSD-3-Clause
:versions: []
:when: 2016-05-02 05:44:38.246021000 Z
- - :whitelist
- LGPL-2.1+
- :who: Connor Shea
:why: Equivalent to LGPL.
:versions: []
:when: 2016-05-02 05:52:56.303239000 Z
- - :whitelist
- BSD
- :who: Connor Shea
:why: https://opensource.org/licenses/BSD-2-Clause
:versions: []
:when: 2016-05-02 05:55:09.796363000 Z
# LICENSE BLACKLIST
- - :blacklist
- GPLv2
- :who: Connor Shea
:why: GPL-licensed libraries cannot be linked to from non-GPL projects.
:versions: []
:when: 2016-05-02 05:29:27.637336000 Z
- - :blacklist
- GPLv3
- :who: Connor Shea
:why: GPL-licensed libraries cannot be linked to from non-GPL projects.
:versions: []
:when: 2016-05-02 05:29:43.904715000 Z
# GEM LICENSES
- - :license
- raphael-rails
- MIT
- :who: Connor Shea
:why: https://github.com/mockdeep/raphael-rails/blob/master/license.txt
:versions: []
:when: 2016-04-17 21:30:07.575392000 Z
- - :license
- rouge
- MIT
- :who: Connor Shea
:why: https://github.com/jneen/rouge/blob/master/LICENSE
:versions: []
:when: 2016-04-17 21:31:29.490394000 Z
- - :license
- pyu-ruby-sasl
- MIT
- :who: Connor Shea
:why: https://github.com/pyu10055/ruby-sasl/blob/master/MIT-LICENSE
:versions: []
:when: 2016-04-17 21:41:55.266420000 Z
- - :license
- six
- MIT
- :who: Connor Shea
:why: https://github.com/randx/six/blob/master/LICENSE
:versions: []
:when: 2016-04-17 21:42:31.420186000 Z
- - :license
- rdoc
- ruby
- :who: Connor Shea
:why: https://github.com/rdoc/rdoc/blob/master/LICENSE.rdoc
:versions: []
:when: 2016-04-17 21:43:30.480413000 Z
- - :license
- expression_parser
- MIT
- :who: Connor Shea
:why: https://github.com/nricciar/expression_parser/blob/master/MIT-LICENSE
:versions: []
:when: 2016-04-17 21:45:41.829912000 Z
- - :license
- creole
- ruby
- :who: Connor Shea
:why: https://github.com/minad/creole#license
:versions: []
:when: 2016-04-17 21:49:10.329759000 Z
- - :license
- eventmachine
- ruby
- :who: Connor Shea
:why: https://github.com/eventmachine/eventmachine/blob/master/LICENSE
:versions: []
:when: 2016-04-17 21:49:10.329759001 Z
- - :license
- unicorn
- ruby
- :who: Connor Shea
:why: http://unicorn.bogomips.org/LICENSE.html
:versions: []
:when: 2016-05-02 05:45:28.817510000 Z
- - :license
- unicorn-worker-killer
- ruby
- :who: Connor Shea
:why: https://github.com/kzk/unicorn-worker-killer/blob/master/LICENSE
:versions: []
:when: 2016-05-02 05:45:38.323867000 Z
- - :license
- json
- ruby
- :who: Connor Shea
:why: https://github.com/flori/json/tree/master#license
:versions: []
:when: 2016-05-02 05:50:07.826564000 Z
- - :license
- unf
- BSD
- :who: Connor Shea
:why: https://github.com/knu/ruby-unf/blob/master/LICENSE
:versions: []
:when: 2016-05-02 05:51:46.886872000 Z
- - :license
- rubypants
- BSD
- :who: Connor Shea
:why: https://github.com/jmcnevin/rubypants/blob/master/LICENSE.rdoc
:versions: []
:when: 2016-05-02 05:56:50.696858000 Z
---
decisions_file: './config/dependency_decisions.yml'
......@@ -19,7 +19,7 @@ class Gitlab::Seeder::Builds
commits = @project.repository.commits('master', path: nil, limit: 5)
commits_sha = commits.map { |commit| commit.raw.id }
commits_sha.map do |sha|
@project.ensure_ci_commit(sha, 'master')
@project.ensure_pipeline(sha, 'master')
end
rescue
[]
......
......@@ -16,21 +16,21 @@ user = User.new(user_args)
user.skip_confirmation!
if user.save
puts "Administrator account created:".green
puts "Administrator account created:".color(:green)
puts
puts "login: root".green
puts "login: root".color(:green)
if user_args.key?(:password)
puts "password: #{user_args[:password]}".green
puts "password: #{user_args[:password]}".color(:green)
else
puts "password: You'll be prompted to create one on your first visit.".green
puts "password: You'll be prompted to create one on your first visit.".color(:green)
end
puts
else
puts "Could not create the default administrator account:".red
puts "Could not create the default administrator account:".color(:red)
puts
user.errors.full_messages.map do |message|
puts "--> #{message}".red
puts "--> #{message}".color(:red)
end
puts
......
class RemoveDuplicatedNotificationSettings < ActiveRecord::Migration
def up
execute <<-SQL
DELETE FROM notification_settings WHERE id NOT IN ( SELECT min_id from (SELECT MIN(id) as min_id FROM notification_settings GROUP BY user_id, source_type, source_id) as dups )
SQL
end
end
class AddIndexToNotificationSettings < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
disable_ddl_transaction!
def change
add_concurrent_index :notification_settings, [:user_id, :source_id, :source_type], { unique: true, name: "index_notifications_on_user_id_and_source_id_and_source_type" }
end
end
......@@ -7,6 +7,7 @@
- [Gotchas](gotchas.md) to avoid
- [How to dump production data to staging](db_dump.md)
- [Instrumentation](instrumentation.md)
- [Licensing](licensing.md) for ensuring license compliance
- [Migration Style Guide](migration_style_guide.md) for creating safe migrations
- [Performance guidelines](performance.md)
- [Rake tasks](rake_tasks.md) for development
......
# GitLab Licensing and Compatibility
GitLab CE is licensed under the terms of the MIT License. GitLab EE is licensed under "The GitLab Enterprise Edition (EE) license" wherein there are more restrictions. See their respective LICENSE files ([CE][CE], [EE][EE]) for more information.
## Automated Testing
In order to comply with the terms the libraries we use are licensed under, we have to make sure to check new gems for compatible licenses whenever they're added. To automate this process, we use the [license_finder][license_finder] gem by Pivotal. It runs every time a new commit is pushed and verifies that all gems in the bundle use a license that doesn't conflict with the licensing of either GitLab Community Edition or GitLab Enterprise Edition.
There are some limitations with the automated testing, however. CSS and JavaScript libraries, as well as any Ruby libraries not included by way of Bundler, must be verified manually and independently. Take care whenever one such library is used, as automated tests won't catch problematic licenses from them.
Some gems may not include their license information in their `gemspec` file. These won't be detected by License Finder, and will have to be verified manually.
### License Finder commands
There are a few basic commands License Finder provides that you'll need in order to manage license detection.
To verify that the checks are passing, and/or to see what dependencies are causing the checks to fail:
```
bundle exec license_finder
```
To whitelist a new license:
```
license_finder whitelist add MIT
```
To blacklist a new license:
```
license_finder blacklist add GPLv2
```
To tell License Finder about a dependency's license if it isn't auto-detected:
```
license_finder licenses add my_unknown_dependency MIT
```
For all of the above, please include `--why "Reason"` and `--who "My Name"` so the `decisions.yml` file can keep track of when, why, and who approved of a dependency.
More detailed information on how the gem and its commands work is available in the [License Finder README][license_finder].
## Acceptable Licenses
Libraries with the following licenses are acceptable for use:
- [The MIT License][MIT] (the MIT Expat License specifically): The MIT License requires that the license itself is included with all copies of the source. It is a permissive (non-copyleft) license as defined by the Open Source Initiative.
- [LGPL][LGPL] (version 2, version 3): GPL constraints regarding modification and redistribution under the same license are not required of projects using an LGPL library, only upon modification of the LGPL-licensed library itself.
- [Apache 2.0 License][apache-2]: A permissive license that also provides an express grant of patent rights from contributors to users.
- [Ruby 1.8 License][ruby-1.8]: Dual-licensed under either itself or the GPLv2, defer to the Ruby License itself. Acceptable because of point 3b: "You may distribute the software in object code or binary form, provided that you do at least ONE of the following: b) accompany the distribution with the machine-readable source of the software."
- [Ruby 1.9 License][ruby-1.9]: Dual-licensed under either itself or the BSD 2-Clause License, defer to BSD 2-Clause.
- [BSD 2-Clause License][BSD-2-Clause]: A permissive (non-copyleft) license as defined by the Open Source Initiative.
- [BSD 3-Clause License][BSD-3-Clause] (also known as New BSD or Modified BSD): A permissive (non-copyleft) license as defined by the Open Source Initiative
- [ISC License][ISC] (also known as the OpenBSD License): A permissive (non-copyleft) license as defined by the Open Source Initiative.
## Unacceptable Licenses
Libraries with the following licenses are unacceptable for use:
- [GNU GPL][GPL] (version 1, [version 2][GPLv2], [version 3][GPLv3], or any future versions): GPL-licensed libraries cannot be linked to from non-GPL projects.
- [GNU AGPLv3][AGPLv3]: AGPL-licensed libraries cannot be linked to from non-GPL projects.
## Notes
Decisions regarding the GNU GPL licenses are based on information provided by [The GNU Project][GNU-GPL-FAQ], as well as [the Open Source Initiative][OSI-GPL], which both state that linking GPL libraries makes the program itself GPL.
If a gem uses a license which is not listed above, open an issue and ask. If a license is not included in the "acceptable" list, operate under the assumption that it is not acceptable.
Keep in mind that each license has its own restrictions (typically defined in their body text). Please make sure to comply with those restrictions at all times whenever an external library is used.
Gems which are included only in the "development" or "test" groups by Bundler are exempt from license requirements, as they're not distributed for use in production.
**NOTE:** This document is **not** legal advice, nor is it comprehensive. It should not be taken as such.
[CE]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/LICENSE
[EE]: https://gitlab.com/gitlab-org/gitlab-ee/blob/master/LICENSE
[license_finder]: https://github.com/pivotal/LicenseFinder
[MIT]: http://choosealicense.com/licenses/mit/
[LGPL]: http://choosealicense.com/licenses/lgpl-3.0/
[apache-2]: http://choosealicense.com/licenses/apache-2.0/
[ruby-1.8]: https://github.com/ruby/ruby/blob/ruby_1_8_6/COPYING
[ruby-1.9]: https://www.ruby-lang.org/en/about/license.txt
[BSD-2-Clause]: https://opensource.org/licenses/BSD-2-Clause
[BSD-3-Clause]: https://opensource.org/licenses/BSD-3-Clause
[ISC]: https://opensource.org/licenses/ISC
[GPL]: http://choosealicense.com/licenses/gpl-3.0/
[GPLv2]: http://www.gnu.org/licenses/gpl-2.0.txt
[GPLv3]: http://www.gnu.org/licenses/gpl-3.0.txt
[AGPLv3]: http://choosealicense.com/licenses/agpl-3.0/
[GNU-GPL-FAQ]: http://www.gnu.org/licenses/gpl-faq.html#IfLibraryIsGPL
[OSI-GPL]: https://opensource.org/faq#linking-proprietary-code
......@@ -269,9 +269,9 @@ sudo usermod -aG redis git
### Clone the Source
# Clone GitLab repository
sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ee.git -b 8-8-stable-ee gitlab
sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ee.git -b 8-9-stable-ee gitlab
**Note:** You can change `8-8-stable-ee` to `master` if you want the *bleeding edge* version, but never install master on a production server!
**Note:** You can change `8-9-stable-ee` to `master` if you want the *bleeding edge* version, but never install master on a production server!
### Configure It
......@@ -397,7 +397,7 @@ GitLab Shell is an SSH access and repository management software developed speci
cd /home/git
sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-workhorse.git
cd gitlab-workhorse
sudo -u git -H git checkout v0.7.4
sudo -u git -H git checkout v0.7.5
sudo -u git -H make
### Initialize Database and Activate Advanced Features
......
# From 8.8 to 8.9
Make sure you view this update guide from the tag (version) of GitLab you would
like to install. In most cases this should be the highest numbered production
tag (without rc in it). You can select the tag in the version dropdown at the
top left corner of GitLab (below the menu bar).
If the highest number stable branch is unclear please check the
[GitLab Blog](https://about.gitlab.com/blog/archives.html) for installation
guide links by version.
### 1. Stop server
sudo service gitlab stop
### 2. Backup
```bash
cd /home/git/gitlab
sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
```
### 3. Get latest code
```bash
sudo -u git -H git fetch --all
sudo -u git -H git checkout -- db/schema.rb # local changes will be restored automatically
```
For GitLab Community Edition:
```bash
sudo -u git -H git checkout 8-9-stable
```
OR
For GitLab Enterprise Edition:
```bash
sudo -u git -H git checkout 8-9-stable-ee
```
### 4. Update gitlab-shell
```bash
cd /home/git/gitlab-shell
sudo -u git -H git fetch --all --tags
sudo -u git -H git checkout v3.0.0
```
### 5. Update gitlab-workhorse
Install and compile gitlab-workhorse. This requires
[Go 1.5](https://golang.org/dl) which should already be on your system from
GitLab 8.1.
```bash
cd /home/git/gitlab-workhorse
sudo -u git -H git fetch --all
sudo -u git -H git checkout v0.7.5
sudo -u git -H make
```
### 6. Install libs, migrations, etc.
```bash
cd /home/git/gitlab
# MySQL installations (note: the line below states '--without postgres')
sudo -u git -H bundle install --without postgres development test --deployment
# PostgreSQL installations (note: the line below states '--without mysql')
sudo -u git -H bundle install --without mysql development test --deployment
# Optional: clean up old gems
sudo -u git -H bundle clean
# Run database migrations
sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
# Clean up assets and cache
sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production
```
### 7. Update configuration files
#### New configuration options for `gitlab.yml`
There are new configuration options available for [`gitlab.yml`](config/gitlab.yml.example). View them with the command below and apply them manually to your current `gitlab.yml`:
```sh
git diff origin/8-8-stable:config/gitlab.yml.example origin/8-9-stable:config/gitlab.yml.example
```
#### Git configuration
Disable `git gc --auto` because GitLab runs `git gc` for us already.
```sh
sudo -u git -H git config --global gc.auto 0
```
#### Nginx configuration
Ensure you're still up-to-date with the latest NGINX configuration changes:
```sh
# For HTTPS configurations
git diff origin/8-8-stable:lib/support/nginx/gitlab-ssl origin/8-9-stable:lib/support/nginx/gitlab-ssl
# For HTTP configurations
git diff origin/8-8-stable:lib/support/nginx/gitlab origin/8-9-stable:lib/support/nginx/gitlab
```
If you are using Apache instead of NGINX please see the updated [Apache templates].
Also note that because Apache does not support upstreams behind Unix sockets you
will need to let gitlab-workhorse listen on a TCP port. You can do this
via [/etc/default/gitlab].
[Apache templates]: https://gitlab.com/gitlab-org/gitlab-recipes/tree/master/web-server/apache
[/etc/default/gitlab]: https://gitlab.com/gitlab-org/gitlab-ce/blob/8-8-stable/lib/support/init.d/gitlab.default.example#L37
#### Init script
Ensure you're still up-to-date with the latest init script changes:
sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab
### 8. Start application
sudo service gitlab start
sudo service nginx restart
### 9. Check application status
Check if GitLab and its environment are configured correctly:
sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production
To make sure you didn't miss anything run a more thorough check:
sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
If all items are green, then congratulations, the upgrade is complete!
## Things went south? Revert to previous version (8.7)
### 1. Revert the code to the previous version
Follow the [upgrade guide from 8.7 to 8.8](8.7-to-8.8.md), except for the
database migration (the backup is already migrated to the previous version).
### 2. Restore from the backup
```bash
cd /home/git/gitlab
sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production
```
If you have more than one backup `*.tar` file(s) please add `BACKUP=timestamp_of_backup` to the command above.
......@@ -25,13 +25,6 @@ Feature: Project Issues
Scenario: I visit issue page
Given I click link "Release 0.4"
Then I should see issue "Release 0.4"
And I should see "1 of 2" in the sidebar
Scenario: I navigate between issues
Given I click link "Release 0.4"
Then I click link "Next" in the sidebar
Then I should see issue "Tweet control"
And I should see "2 of 2" in the sidebar
@javascript
Scenario: I filter by author
......
......@@ -49,14 +49,12 @@ Feature: Project Merge Requests
Scenario: I visit an open merge request page
Given I click link "Bug NS-04"
Then I should see merge request "Bug NS-04"
And I should see "1 of 1" in the sidebar
Scenario: I visit a merged merge request page
Given project "Shop" have "Feature NS-05" merged merge request
And I click link "Merged"
And I click link "Feature NS-05"
Then I should see merge request "Feature NS-05"
And I should see "3 of 3" in the sidebar
Scenario: I close merge request page
Given I click link "Bug NS-04"
......@@ -76,18 +74,6 @@ Feature: Project Merge Requests
And I submit new merge request "Wiki Feature"
Then I should see merge request "Wiki Feature"
Scenario: I download a diff on a public merge request
Given public project "Community"
And "John Doe" owns public project "Community"
And project "Community" has "Bug CO-01" open merge request with diffs inside
Given I logout directly
And I visit merge request page "Bug CO-01"
And I click on "Email Patches"
Then I should see a patch diff
And I visit merge request page "Bug CO-01"
And I click on "Plain Diff"
Then I should see a patch diff
@javascript
Scenario: I comment on a merge request
Given I visit merge request page "Bug NS-04"
......
......@@ -164,12 +164,12 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps
step 'commit has ci status' do
@project.enable_ci
ci_commit = create :ci_commit, project: @project, sha: sample_commit.id
create :ci_build, commit: ci_commit
pipeline = create :ci_pipeline, project: @project, sha: sample_commit.id
create :ci_build, pipeline: pipeline
end
step 'repository contains ".gitlab-ci.yml" file' do
allow_any_instance_of(Ci::Commit).to receive(:ci_yaml_file).and_return(String.new)
allow_any_instance_of(Ci::Pipeline).to receive(:ci_yaml_file).and_return(String.new)
end
step 'I see commit ci info' do
......
......@@ -654,8 +654,8 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps
step '"Bug NS-05" has CI status' do
project = merge_request.source_project
project.enable_ci
ci_commit = create :ci_commit, project: project, sha: merge_request.last_commit.id, ref: merge_request.source_branch
create :ci_build, commit: ci_commit
pipeline = create :ci_pipeline, project: project, sha: merge_request.last_commit.id, ref: merge_request.source_branch
create :ci_build, pipeline: pipeline
end
step 'I should see merge request "Bug NS-05" with CI status' do
......
......@@ -27,10 +27,10 @@ class Spinach::Features::ProjectPages < Spinach::FeatureSteps
end
step 'pages are deployed' do
commit = @project.ensure_ci_commit(@project.commit('HEAD').sha, 'HEAD')
pipeline = @project.ensure_pipeline(@project.commit('HEAD').sha, 'HEAD')
build = build(:ci_build,
project: @project,
commit: commit,
pipeline: pipeline,
ref: 'HEAD',
artifacts_file: fixture_file_upload(Rails.root + 'spec/fixtures/pages.zip'),
artifacts_metadata: fixture_file_upload(Rails.root + 'spec/fixtures/pages.zip.meta')
......
......@@ -10,8 +10,8 @@ module SharedBuilds
end
step 'project has a recent build' do
@ci_commit = create(:ci_commit, project: @project, sha: @project.commit.sha, ref: 'master')
@build = create(:ci_build_with_coverage, commit: @ci_commit)
@pipeline = create(:ci_pipeline, project: @project, sha: @project.commit.sha, ref: 'master')
@build = create(:ci_build_with_coverage, pipeline: @pipeline)
end
step 'recent build is successful' do
......@@ -23,7 +23,7 @@ module SharedBuilds
end
step 'project has another build that is running' do
create(:ci_build, commit: @ci_commit, name: 'second build', status: 'running')
create(:ci_build, pipeline: @pipeline, name: 'second build', status: 'running')
end
step 'I visit recent build details page' do
......
......@@ -138,22 +138,6 @@ module SharedIssuable
end
end
step 'I should see "1 of 1" in the sidebar' do
expect_sidebar_content('1 of 1')
end
step 'I should see "1 of 2" in the sidebar' do
expect_sidebar_content('1 of 2')
end
step 'I should see "2 of 2" in the sidebar' do
expect_sidebar_content('2 of 2')
end
step 'I should see "3 of 3" in the sidebar' do
expect_sidebar_content('3 of 3')
end
step 'I click link "Next" in the sidebar' do
page.within '.issuable-sidebar' do
click_link 'Next'
......
......@@ -236,7 +236,7 @@ module SharedProject
step 'project "Shop" has CI build' do
project = Project.find_by(name: "Shop")
create :ci_commit, project: project, sha: project.commit.sha, ref: 'master', status: 'skipped'
create :ci_pipeline, project: project, sha: project.commit.sha, ref: 'master', status: 'skipped'
end
step 'I should see last commit with CI status' do
......
......@@ -33,7 +33,7 @@ module API
get ':id/repository/commits/:sha/builds' do
authorize_read_builds!
commit = user_project.ci_commits.find_by_sha(params[:sha])
commit = user_project.pipelines.find_by_sha(params[:sha])
return not_found! unless commit
builds = commit.builds.order('id DESC')
......
......@@ -22,8 +22,8 @@ module API
not_found!('Commit') unless user_project.commit(params[:sha])
ci_commits = user_project.ci_commits.where(sha: params[:sha])
statuses = ::CommitStatus.where(commit: ci_commits)
pipelines = user_project.pipelines.where(sha: params[:sha])
statuses = ::CommitStatus.where(pipeline: pipelines)
statuses = statuses.latest unless parse_boolean(params[:all])
statuses = statuses.where(ref: params[:ref]) if params[:ref].present?
statuses = statuses.where(stage: params[:stage]) if params[:stage].present?
......@@ -50,7 +50,7 @@ module API
commit = @project.commit(params[:sha])
not_found! 'Commit' unless commit
# Since the CommitStatus is attached to Ci::Commit (in the future Pipeline)
# Since the CommitStatus is attached to Ci::Pipeline (in the future Pipeline)
# We need to always have the pipeline object
# To have a valid pipeline object that can be attached to specific MR
# Other CI service needs to send `ref`
......@@ -64,11 +64,11 @@ module API
ref = branches.first
end
ci_commit = @project.ensure_ci_commit(commit.sha, ref)
pipeline = @project.ensure_pipeline(commit.sha, ref)
name = params[:name] || params[:context]
status = GenericCommitStatus.running_or_pending.find_by(commit: ci_commit, name: name, ref: params[:ref])
status ||= GenericCommitStatus.new(project: @project, commit: ci_commit, user: current_user)
status = GenericCommitStatus.running_or_pending.find_by(pipeline: pipeline, name: name, ref: params[:ref])
status ||= GenericCommitStatus.new(project: @project, pipeline: pipeline, user: current_user)
status.update(attrs)
case params[:state].to_s
......
......@@ -243,7 +243,7 @@ module API
should_remove_source_branch: params[:should_remove_source_branch]
}
if parse_boolean(params[:merge_when_build_succeeds]) && merge_request.ci_commit && merge_request.ci_commit.active?
if parse_boolean(params[:merge_when_build_succeeds]) && merge_request.pipeline && merge_request.pipeline.active?
::MergeRequests::MergeWhenBuildSucceedsService.new(merge_request.target_project, current_user, merge_params).
execute(merge_request)
else
......
......@@ -60,7 +60,7 @@ module Ci
class BuildTime < Chart
def collect
commits = project.ci_commits.last(30)
commits = project.pipelines.last(30)
commits.each do |commit|
@labels << commit.short_sha
......
......@@ -3,7 +3,7 @@ module Gitlab
class << self
def build(build)
project = build.project
commit = build.commit
commit = build.pipeline
user = build.user
data = {
......
......@@ -11,7 +11,7 @@ module Gitlab
# add_concurrent_index :users, :some_column
#
# See Rails' `add_index` for more info on the available arguments.
def add_concurrent_index(*args)
def add_concurrent_index(table_name, column_name, options = {})
if transaction_open?
raise 'add_concurrent_index can not be run inside a transaction, ' \
'you can disable transactions by calling disable_ddl_transaction! ' \
......@@ -19,10 +19,10 @@ module Gitlab
end
if Database.postgresql?
args << { algorithm: :concurrently }
options = options.merge({ algorithm: :concurrently })
end
add_index(*args)
add_index(table_name, column_name, options)
end
# Updates the value of a column in batches.
......
......@@ -9,6 +9,10 @@ module Gitlab
@formatter = Gitlab::ImportFormatter.new
end
def create!
self.klass.create!(self.attributes)
end
private
def gl_user_id(github_id)
......
......@@ -8,6 +8,7 @@ module Gitlab
commit_id: raw_data.commit_id,
line_code: line_code,
author_id: author_id,
type: type,
created_at: raw_data.created_at,
updated_at: raw_data.updated_at
}
......@@ -53,6 +54,10 @@ module Gitlab
def note
formatter.author_line(author) + body
end
def type
'LegacyDiffNote' if on_diff?
end
end
end
end
module Gitlab
module GithubImport
class HookFormatter
EVENTS = %w[* create delete pull_request push].freeze
attr_reader :raw
delegate :id, :name, :active, to: :raw
def initialize(raw)
@raw = raw
end
def config
raw.config.attrs
end
def valid?
(EVENTS & raw.events).any? && active
end
end
end
end
......@@ -3,6 +3,9 @@ module Gitlab
class Importer
include Gitlab::ShellAdapter
GITHUB_SAFE_REMAINING_REQUESTS = 100
GITHUB_SAFE_SLEEP_TIME = 500
attr_reader :client, :project, :repo, :repo_url
def initialize(project)
......@@ -25,14 +28,53 @@ module Gitlab
private
def turn_auto_pagination_off!
client.auto_paginate = false
end
def turn_auto_pagination_on!
client.auto_paginate = true
end
def rate_limit
client.rate_limit!
end
def rate_limit_exceed?
rate_limit.remaining <= GITHUB_SAFE_REMAINING_REQUESTS
end
def rate_limit_sleep_time
rate_limit.resets_in + GITHUB_SAFE_SLEEP_TIME
end
def paginate
turn_auto_pagination_off!
sleep rate_limit_sleep_time if rate_limit_exceed?
data = yield
last_response = client.last_response
while last_response.rels[:next]
sleep rate_limit_sleep_time if rate_limit_exceed?
last_response = last_response.rels[:next].get
data.concat(last_response.data) if last_response.data.is_a?(Array)
end
turn_auto_pagination_on!
data
end
def credentials
@credentials ||= project.import_data.credentials if project.import_data
end
def import_labels
client.labels(repo).each do |raw_data|
Label.create!(LabelFormatter.new(project, raw_data).attributes)
end
labels = paginate { client.labels(repo, per_page: 100) }
labels.each { |raw| LabelFormatter.new(project, raw).create! }
true
rescue ActiveRecord::RecordInvalid => e
......@@ -40,9 +82,8 @@ module Gitlab
end
def import_milestones
client.list_milestones(repo, state: :all).each do |raw_data|
Milestone.create!(MilestoneFormatter.new(project, raw_data).attributes)
end
milestones = paginate { client.milestones(repo, state: :all, per_page: 100) }
milestones.each { |raw| MilestoneFormatter.new(project, raw).create! }
true
rescue ActiveRecord::RecordInvalid => e
......@@ -50,16 +91,15 @@ module Gitlab
end
def import_issues
client.list_issues(repo, state: :all, sort: :created, direction: :asc).each do |raw_data|
gh_issue = IssueFormatter.new(project, raw_data)
data = paginate { client.issues(repo, state: :all, sort: :created, direction: :asc, per_page: 100) }
if gh_issue.valid?
issue = Issue.create!(gh_issue.attributes)
apply_labels(gh_issue.number, issue)
data.each do |raw|
gh_issue = IssueFormatter.new(project, raw)
if gh_issue.has_comments?
import_comments(gh_issue.number, issue)
end
if gh_issue.valid?
issue = gh_issue.create!
apply_labels(issue)
import_comments(issue) if gh_issue.has_comments?
end
end
......@@ -69,50 +109,68 @@ module Gitlab
end
def import_pull_requests
pull_requests = client.pull_requests(repo, state: :all, sort: :created, direction: :asc)
.map { |raw| PullRequestFormatter.new(project, raw) }
.select(&:valid?)
hooks = client.hooks(repo).map { |raw| HookFormatter.new(raw) }.select(&:valid?)
disable_webhooks(hooks)
pull_requests = paginate { client.pull_requests(repo, state: :all, sort: :created, direction: :asc, per_page: 100) }
pull_requests = pull_requests.map { |raw| PullRequestFormatter.new(project, raw) }.select(&:valid?)
source_branches_removed = pull_requests.reject(&:source_branch_exists?).map { |pr| [pr.source_branch_name, pr.source_branch_sha] }
target_branches_removed = pull_requests.reject(&:target_branch_exists?).map { |pr| [pr.target_branch_name, pr.target_branch_sha] }
branches_removed = source_branches_removed | target_branches_removed
create_refs(branches_removed)
restore_branches(branches_removed)
pull_requests.each do |pull_request|
merge_request = MergeRequest.new(pull_request.attributes)
if merge_request.save
apply_labels(pull_request.number, merge_request)
import_comments(pull_request.number, merge_request)
import_comments_on_diff(pull_request.number, merge_request)
end
merge_request = pull_request.create!
apply_labels(merge_request)
import_comments(merge_request)
import_comments_on_diff(merge_request)
end
true
rescue ActiveRecord::RecordInvalid => e
raise Projects::ImportService::Error, e.message
ensure
delete_refs(branches_removed)
clean_up_restored_branches(branches_removed)
clean_up_disabled_webhooks(hooks)
end
def disable_webhooks(hooks)
update_webhooks(hooks, active: false)
end
def clean_up_disabled_webhooks(hooks)
update_webhooks(hooks, active: true)
end
def create_refs(branches)
def update_webhooks(hooks, options)
hooks.each do |hook|
client.edit_hook(repo, hook.id, hook.name, hook.config, options)
end
end
def restore_branches(branches)
branches.each do |name, sha|
sleep rate_limit_sleep_time if rate_limit_exceed?
client.create_ref(repo, "refs/heads/#{name}", sha)
end
project.repository.fetch_ref(repo_url, '+refs/heads/*', 'refs/heads/*')
end
def delete_refs(branches)
def clean_up_restored_branches(branches)
branches.each do |name, _|
sleep rate_limit_sleep_time if rate_limit_exceed?
client.delete_ref(repo, "heads/#{name}")
project.repository.rm_branch(project.creator, name)
end
end
def apply_labels(number, issuable)
issue = client.issue(repo, number)
def apply_labels(issuable)
sleep rate_limit_sleep_time if rate_limit_exceed?
issue = client.issue(repo, issuable.iid)
if issue.labels.count > 0
label_ids = issue.labels.map do |raw|
......@@ -123,20 +181,20 @@ module Gitlab
end
end
def import_comments(issue_number, noteable)
comments = client.issue_comments(repo, issue_number)
create_comments(comments, noteable)
def import_comments(issuable)
comments = paginate { client.issue_comments(repo, issuable.iid, per_page: 100) }
create_comments(issuable, comments)
end
def import_comments_on_diff(pull_request_number, merge_request)
comments = client.pull_request_comments(repo, pull_request_number)
create_comments(comments, merge_request)
def import_comments_on_diff(merge_request)
comments = paginate { client.pull_request_comments(repo, merge_request.iid, per_page: 100) }
create_comments(merge_request, comments)
end
def create_comments(comments, noteable)
comments.each do |raw_data|
comment = CommentFormatter.new(project, raw_data)
noteable.notes.create!(comment.attributes)
def create_comments(issuable, comments)
comments.each do |raw|
comment = CommentFormatter.new(project, raw)
issuable.notes.create!(comment.attributes)
end
end
......
......@@ -20,6 +20,10 @@ module Gitlab
raw_data.comments > 0
end
def klass
Issue
end
def number
raw_data.number
end
......
......@@ -9,6 +9,10 @@ module Gitlab
}
end
def klass
Label
end
private
def color
......
......@@ -14,6 +14,10 @@ module Gitlab
}
end
def klass
Milestone
end
private
def number
......
......@@ -24,6 +24,10 @@ module Gitlab
}
end
def klass
MergeRequest
end
def number
raw_data.number
end
......
......@@ -30,6 +30,19 @@ module Gitlab
]
end
def send_git_diff(repository, from, to)
params = {
'RepoPath' => repository.path_to_repo,
'ShaFrom' => from,
'ShaTo' => to
}
[
SEND_DATA_HEADER,
"git-diff:#{encode(params)}"
]
end
protected
def encode(hash)
......
......@@ -19,7 +19,7 @@ namespace :gitlab do
Rake::Task["setup_postgresql"].invoke
Rake::Task["db:seed_fu"].invoke
rescue Gitlab::TaskAbortedByUserError
puts "Quitting...".red
puts "Quitting...".color(:red)
exit 1
end
end
......@@ -84,17 +84,14 @@ describe Projects::MergeRequestsController do
end
describe "as diff" do
include_examples "export merge as", :diff
let(:format) { :diff }
it "should really only be a git diff" do
it "triggers workhorse to serve the request" do
get(:show,
namespace_id: project.namespace.to_param,
project_id: project.to_param,
id: merge_request.iid,
format: format)
format: :diff)
expect(response.body).to start_with("diff --git")
expect(response.headers['Gitlab-Workhorse-Send-Data']).to start_with("git-diff:")
end
end
......@@ -250,7 +247,7 @@ describe Projects::MergeRequestsController do
end
before do
create(:ci_empty_commit, project: project, sha: merge_request.source_sha, ref: merge_request.source_branch)
create(:ci_empty_pipeline, project: project, sha: merge_request.source_sha, ref: merge_request.source_branch)
end
it 'returns :merge_when_build_succeeds' do
......
......@@ -16,7 +16,7 @@ FactoryGirl.define do
}
end
commit factory: :ci_commit
pipeline factory: :ci_pipeline
trait :success do
status 'success'
......@@ -43,7 +43,7 @@ FactoryGirl.define do
end
after(:build) do |build, evaluator|
build.project = build.commit.project
build.project = build.pipeline.project
end
factory :ci_not_started_build do
......
......@@ -17,30 +17,30 @@
#
FactoryGirl.define do
factory :ci_empty_commit, class: Ci::Commit do
factory :ci_empty_pipeline, class: Ci::Pipeline do
sha '97de212e80737a608d939f648d959671fb0a0142'
project factory: :empty_project
factory :ci_commit_without_jobs do
factory :ci_pipeline_without_jobs do
after(:build) do |commit|
allow(commit).to receive(:ci_yaml_file) { YAML.dump({}) }
end
end
factory :ci_commit_with_one_job do
factory :ci_pipeline_with_one_job do
after(:build) do |commit|
allow(commit).to receive(:ci_yaml_file) { YAML.dump({ rspec: { script: "ls" } }) }
end
end
factory :ci_commit_with_two_jobs do
factory :ci_pipeline_with_two_job do
after(:build) do |commit|
allow(commit).to receive(:ci_yaml_file) { YAML.dump({ rspec: { script: "ls" }, spinach: { script: "ls" } }) }
end
end
factory :ci_commit do
factory :ci_pipeline do
after(:build) do |commit|
allow(commit).to receive(:ci_yaml_file) { File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml')) }
end
......
......@@ -3,12 +3,12 @@ FactoryGirl.define do
name 'default'
status 'success'
description 'commit status'
commit factory: :ci_commit_with_one_job
pipeline factory: :ci_pipeline_with_one_job
started_at 'Tue, 26 Jan 2016 08:21:42 +0100'
finished_at 'Tue, 26 Jan 2016 08:23:42 +0100'
after(:build) do |build, evaluator|
build.project = build.commit.project
build.project = build.pipeline.project
end
factory :generic_commit_status, class: GenericCommitStatus do
......
......@@ -6,15 +6,15 @@ describe 'Admin Builds' do
end
describe 'GET /admin/builds' do
let(:commit) { create(:ci_commit) }
let(:pipeline) { create(:ci_pipeline) }
context 'All tab' do
context 'when have builds' do
it 'shows all builds' do
create(:ci_build, commit: commit, status: :pending)
create(:ci_build, commit: commit, status: :running)
create(:ci_build, commit: commit, status: :success)
create(:ci_build, commit: commit, status: :failed)
create(:ci_build, pipeline: pipeline, status: :pending)
create(:ci_build, pipeline: pipeline, status: :running)
create(:ci_build, pipeline: pipeline, status: :success)
create(:ci_build, pipeline: pipeline, status: :failed)
visit admin_builds_path
......@@ -39,9 +39,9 @@ describe 'Admin Builds' do
context 'Running tab' do
context 'when have running builds' do
it 'shows running builds' do
build1 = create(:ci_build, commit: commit, status: :pending)
build2 = create(:ci_build, commit: commit, status: :success)
build3 = create(:ci_build, commit: commit, status: :failed)
build1 = create(:ci_build, pipeline: pipeline, status: :pending)
build2 = create(:ci_build, pipeline: pipeline, status: :success)
build3 = create(:ci_build, pipeline: pipeline, status: :failed)
visit admin_builds_path(scope: :running)
......@@ -55,7 +55,7 @@ describe 'Admin Builds' do
context 'when have no builds running' do
it 'shows a message' do
create(:ci_build, commit: commit, status: :success)
create(:ci_build, pipeline: pipeline, status: :success)
visit admin_builds_path(scope: :running)
......@@ -69,9 +69,9 @@ describe 'Admin Builds' do
context 'Finished tab' do
context 'when have finished builds' do
it 'shows finished builds' do
build1 = create(:ci_build, commit: commit, status: :pending)
build2 = create(:ci_build, commit: commit, status: :running)
build3 = create(:ci_build, commit: commit, status: :success)
build1 = create(:ci_build, pipeline: pipeline, status: :pending)
build2 = create(:ci_build, pipeline: pipeline, status: :running)
build3 = create(:ci_build, pipeline: pipeline, status: :success)
visit admin_builds_path(scope: :finished)
......@@ -85,7 +85,7 @@ describe 'Admin Builds' do
context 'when have no builds finished' do
it 'shows a message' do
create(:ci_build, commit: commit, status: :running)
create(:ci_build, pipeline: pipeline, status: :running)
visit admin_builds_path(scope: :finished)
......
......@@ -8,8 +8,8 @@ describe "Admin Runners" do
describe "Runners page" do
before do
runner = FactoryGirl.create(:ci_runner)
commit = FactoryGirl.create(:ci_commit)
FactoryGirl.create(:ci_build, commit: commit, runner_id: runner.id)
pipeline = FactoryGirl.create(:ci_pipeline)
FactoryGirl.create(:ci_build, pipeline: pipeline, runner_id: runner.id)
visit admin_runners_path
end
......
......@@ -5,8 +5,8 @@ describe "Builds" do
before do
login_as(:user)
@commit = FactoryGirl.create :ci_commit
@build = FactoryGirl.create :ci_build, commit: @commit
@commit = FactoryGirl.create :ci_pipeline
@build = FactoryGirl.create :ci_build, pipeline: @commit
@build2 = FactoryGirl.create :ci_build
@project = @commit.project
@project.team << [@user, :developer]
......
......@@ -8,15 +8,15 @@ describe 'Commits' do
describe 'CI' do
before do
login_as :user
stub_ci_commit_to_return_yaml_file
stub_ci_pipeline_to_return_yaml_file
end
let!(:commit) do
FactoryGirl.create :ci_commit, project: project, sha: project.commit.sha
let!(:pipeline) do
FactoryGirl.create :ci_pipeline, project: project, sha: project.commit.sha
end
context 'commit status is Generic Commit Status' do
let!(:status) { FactoryGirl.create :generic_commit_status, commit: commit }
let!(:status) { FactoryGirl.create :generic_commit_status, pipeline: pipeline }
before do
project.team << [@user, :reporter]
......@@ -24,10 +24,10 @@ describe 'Commits' do
describe 'Commit builds' do
before do
visit ci_status_path(commit)
visit ci_status_path(pipeline)
end
it { expect(page).to have_content commit.sha[0..7] }
it { expect(page).to have_content pipeline.sha[0..7] }
it 'contains generic commit status build' do
page.within('.table-holder') do
......@@ -39,7 +39,7 @@ describe 'Commits' do
end
context 'commit status is Ci Build' do
let!(:build) { FactoryGirl.create :ci_build, commit: commit }
let!(:build) { FactoryGirl.create :ci_build, pipeline: pipeline }
let(:artifacts_file) { fixture_file_upload(Rails.root + 'spec/fixtures/banana_sample.gif', 'image/gif') }
context 'when logged as developer' do
......@@ -53,7 +53,7 @@ describe 'Commits' do
end
it 'should show build status' do
page.within("//li[@id='commit-#{commit.short_sha}']") do
page.within("//li[@id='commit-#{pipeline.short_sha}']") do
expect(page).to have_css(".ci-status-link")
end
end
......@@ -61,12 +61,12 @@ describe 'Commits' do
describe 'Commit builds' do
before do
visit ci_status_path(commit)
visit ci_status_path(pipeline)
end
it { expect(page).to have_content commit.sha[0..7] }
it { expect(page).to have_content commit.git_commit_message }
it { expect(page).to have_content commit.git_author_name }
it { expect(page).to have_content pipeline.sha[0..7] }
it { expect(page).to have_content pipeline.git_commit_message }
it { expect(page).to have_content pipeline.git_author_name }
end
context 'Download artifacts' do
......@@ -75,7 +75,7 @@ describe 'Commits' do
end
it do
visit ci_status_path(commit)
visit ci_status_path(pipeline)
click_on 'Download artifacts'
expect(page.response_headers['Content-Type']).to eq(artifacts_file.content_type)
end
......@@ -83,7 +83,7 @@ describe 'Commits' do
describe 'Cancel all builds' do
it 'cancels commit' do
visit ci_status_path(commit)
visit ci_status_path(pipeline)
click_on 'Cancel running'
expect(page).to have_content 'canceled'
end
......@@ -91,7 +91,7 @@ describe 'Commits' do
describe 'Cancel build' do
it 'cancels build' do
visit ci_status_path(commit)
visit ci_status_path(pipeline)
click_on 'Cancel'
expect(page).to have_content 'canceled'
end
......@@ -100,13 +100,13 @@ describe 'Commits' do
describe '.gitlab-ci.yml not found warning' do
context 'ci builds enabled' do
it "does not show warning" do
visit ci_status_path(commit)
visit ci_status_path(pipeline)
expect(page).not_to have_content '.gitlab-ci.yml not found in this commit'
end
it 'shows warning' do
stub_ci_commit_yaml_file(nil)
visit ci_status_path(commit)
stub_ci_pipeline_yaml_file(nil)
visit ci_status_path(pipeline)
expect(page).to have_content '.gitlab-ci.yml not found in this commit'
end
end
......@@ -114,8 +114,8 @@ describe 'Commits' do
context 'ci builds disabled' do
before do
stub_ci_builds_disabled
stub_ci_commit_yaml_file(nil)
visit ci_status_path(commit)
stub_ci_pipeline_yaml_file(nil)
visit ci_status_path(pipeline)
end
it 'does not show warning' do
......@@ -129,13 +129,13 @@ describe 'Commits' do
before do
project.team << [@user, :reporter]
build.update_attributes(artifacts_file: artifacts_file)
visit ci_status_path(commit)
visit ci_status_path(pipeline)
end
it do
expect(page).to have_content commit.sha[0..7]
expect(page).to have_content commit.git_commit_message
expect(page).to have_content commit.git_author_name
expect(page).to have_content pipeline.sha[0..7]
expect(page).to have_content pipeline.git_commit_message
expect(page).to have_content pipeline.git_author_name
expect(page).to have_link('Download artifacts')
expect(page).not_to have_link('Cancel running')
expect(page).not_to have_link('Retry failed')
......@@ -148,13 +148,13 @@ describe 'Commits' do
visibility_level: Gitlab::VisibilityLevel::INTERNAL,
public_builds: false)
build.update_attributes(artifacts_file: artifacts_file)
visit ci_status_path(commit)
visit ci_status_path(pipeline)
end
it do
expect(page).to have_content commit.sha[0..7]
expect(page).to have_content commit.git_commit_message
expect(page).to have_content commit.git_author_name
expect(page).to have_content pipeline.sha[0..7]
expect(page).to have_content pipeline.git_commit_message
expect(page).to have_content pipeline.git_author_name
expect(page).not_to have_link('Download artifacts')
expect(page).not_to have_link('Cancel running')
expect(page).not_to have_link('Retry failed')
......
......@@ -29,7 +29,7 @@ feature 'Merge request created from fork' do
include WaitForAjax
given(:pipeline) do
create(:ci_commit_with_two_jobs, project: fork_project,
create(:ci_pipeline_with_two_job, project: fork_project,
sha: merge_request.last_commit.id,
ref: merge_request.source_branch)
end
......
......@@ -12,8 +12,8 @@ feature 'Merge When Build Succeeds', feature: true, js: true do
end
context "Active build for Merge Request" do
let!(:ci_commit) { create(:ci_commit, project: project, sha: merge_request.last_commit.id, ref: merge_request.source_branch) }
let!(:ci_build) { create(:ci_build, commit: ci_commit) }
let!(:pipeline) { create(:ci_pipeline, project: project, sha: merge_request.last_commit.id, ref: merge_request.source_branch) }
let!(:ci_build) { create(:ci_build, pipeline: pipeline) }
before do
login_as user
......@@ -47,8 +47,8 @@ feature 'Merge When Build Succeeds', feature: true, js: true do
merge_user: user, title: "MepMep", merge_when_build_succeeds: true)
end
let!(:ci_commit) { create(:ci_commit, project: project, sha: merge_request.last_commit.id, ref: merge_request.source_branch) }
let!(:ci_build) { create(:ci_build, commit: ci_commit) }
let!(:pipeline) { create(:ci_pipeline, project: project, sha: merge_request.last_commit.id, ref: merge_request.source_branch) }
let!(:ci_build) { create(:ci_build, pipeline: pipeline) }
before do
login_as user
......
......@@ -12,7 +12,7 @@ describe "Pipelines" do
end
describe 'GET /:project/pipelines' do
let!(:pipeline) { create(:ci_commit, project: project, ref: 'master', status: 'running') }
let!(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', status: 'running') }
[:all, :running, :branches].each do |scope|
context "displaying #{scope}" do
......@@ -31,7 +31,7 @@ describe "Pipelines" do
end
context 'cancelable pipeline' do
let!(:running) { create(:ci_build, :running, commit: pipeline, stage: 'test', commands: 'test') }
let!(:running) { create(:ci_build, :running, pipeline: pipeline, stage: 'test', commands: 'test') }
before { visit namespace_project_pipelines_path(project.namespace, project) }
......@@ -47,7 +47,7 @@ describe "Pipelines" do
end
context 'retryable pipelines' do
let!(:failed) { create(:ci_build, :failed, commit: pipeline, stage: 'test', commands: 'test') }
let!(:failed) { create(:ci_build, :failed, pipeline: pipeline, stage: 'test', commands: 'test') }
before { visit namespace_project_pipelines_path(project.namespace, project) }
......@@ -64,7 +64,7 @@ describe "Pipelines" do
context 'for generic statuses' do
context 'when running' do
let!(:running) { create(:generic_commit_status, status: 'running', commit: pipeline, stage: 'test') }
let!(:running) { create(:generic_commit_status, status: 'running', pipeline: pipeline, stage: 'test') }
before { visit namespace_project_pipelines_path(project.namespace, project) }
......@@ -78,7 +78,7 @@ describe "Pipelines" do
end
context 'when failed' do
let!(:running) { create(:generic_commit_status, status: 'failed', commit: pipeline, stage: 'test') }
let!(:running) { create(:generic_commit_status, status: 'failed', pipeline: pipeline, stage: 'test') }
before { visit namespace_project_pipelines_path(project.namespace, project) }
......@@ -94,7 +94,7 @@ describe "Pipelines" do
context 'downloadable pipelines' do
context 'with artifacts' do
let!(:with_artifacts) { create(:ci_build, :artifacts, :success, commit: pipeline, name: 'rspec tests', stage: 'test') }
let!(:with_artifacts) { create(:ci_build, :artifacts, :success, pipeline: pipeline, name: 'rspec tests', stage: 'test') }
before { visit namespace_project_pipelines_path(project.namespace, project) }
......@@ -103,7 +103,7 @@ describe "Pipelines" do
end
context 'without artifacts' do
let!(:without_artifacts) { create(:ci_build, :success, commit: pipeline, name: 'rspec', stage: 'test') }
let!(:without_artifacts) { create(:ci_build, :success, pipeline: pipeline, name: 'rspec', stage: 'test') }
it { expect(page).not_to have_selector('.build-artifacts') }
end
......@@ -111,13 +111,13 @@ describe "Pipelines" do
end
describe 'GET /:project/pipelines/:id' do
let(:pipeline) { create(:ci_commit, project: project, ref: 'master') }
let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master') }
before do
@success = create(:ci_build, :success, commit: pipeline, stage: 'build', name: 'build')
@failed = create(:ci_build, :failed, commit: pipeline, stage: 'test', name: 'test', commands: 'test')
@running = create(:ci_build, :running, commit: pipeline, stage: 'deploy', name: 'deploy')
@external = create(:generic_commit_status, status: 'success', commit: pipeline, name: 'jenkins', stage: 'external')
@success = create(:ci_build, :success, pipeline: pipeline, stage: 'build', name: 'build')
@failed = create(:ci_build, :failed, pipeline: pipeline, stage: 'test', name: 'test', commands: 'test')
@running = create(:ci_build, :running, pipeline: pipeline, stage: 'deploy', name: 'deploy')
@external = create(:generic_commit_status, status: 'success', pipeline: pipeline, name: 'jenkins', stage: 'external')
end
before { visit namespace_project_pipeline_path(project.namespace, project, pipeline) }
......@@ -165,9 +165,9 @@ describe "Pipelines" do
before { fill_in('Create for', with: 'master') }
context 'with gitlab-ci.yml' do
before { stub_ci_commit_to_return_yaml_file }
before { stub_ci_pipeline_to_return_yaml_file }
it { expect{ click_on 'Create pipeline' }.to change{ Ci::Commit.count }.by(1) }
it { expect{ click_on 'Create pipeline' }.to change{ Ci::Pipeline.count }.by(1) }
end
context 'without gitlab-ci.yml' do
......
......@@ -11,7 +11,7 @@ feature 'project commit builds' do
context 'when no builds triggered yet' do
background do
create(:ci_commit, project: project,
create(:ci_pipeline, project: project,
sha: project.commit.sha,
ref: 'master')
end
......
......@@ -142,8 +142,8 @@ describe "Public Project Access", feature: true do
end
describe "GET /:project_path/builds/:id" do
let(:commit) { create(:ci_commit, project: project) }
let(:build) { create(:ci_build, commit: commit) }
let(:pipeline) { create(:ci_pipeline, project: project) }
let(:build) { create(:ci_build, pipeline: pipeline) }
subject { namespace_project_build_path(project.namespace, project, build.id) }
context "when allowed for public" do
......
......@@ -3,8 +3,8 @@ require 'spec_helper'
describe CiStatusHelper do
include IconsHelper
let(:success_commit) { double("Ci::Commit", status: 'success') }
let(:failed_commit) { double("Ci::Commit", status: 'failed') }
let(:success_commit) { double("Ci::Pipeline", status: 'success') }
let(:failed_commit) { double("Ci::Pipeline", status: 'failed') }
describe 'ci_icon_for_status' do
it { expect(helper.ci_icon_for_status(success_commit.status)).to include('fa-check') }
......
......@@ -5,7 +5,7 @@ describe MergeRequestsHelper do
let(:project) { create :project }
let(:merge_request) { MergeRequest.new }
let(:ci_service) { CiService.new }
let(:last_commit) { Ci::Commit.new({}) }
let(:last_commit) { Ci::Pipeline.new({}) }
before do
allow(merge_request).to receive(:source_project).and_return(project)
......
......@@ -4,19 +4,19 @@ describe Ci::Charts, lib: true do
context "build_times" do
before do
@commit = FactoryGirl.create(:ci_commit)
FactoryGirl.create(:ci_build, commit: @commit)
@pipeline = FactoryGirl.create(:ci_pipeline)
FactoryGirl.create(:ci_build, pipeline: @pipeline)
end
it 'should return build times in minutes' do
chart = Ci::Charts::BuildTime.new(@commit.project)
chart = Ci::Charts::BuildTime.new(@pipeline.project)
expect(chart.build_times).to eq([2])
end
it 'should handle nil build times' do
create(:ci_commit, duration: nil, project: @commit.project)
create(:ci_pipeline, duration: nil, project: @pipeline.project)
chart = Ci::Charts::BuildTime.new(@commit.project)
chart = Ci::Charts::BuildTime.new(@pipeline.project)
expect(chart.build_times).to eq([2, 0])
end
end
......
......@@ -109,11 +109,11 @@ describe Gitlab::Badge::Build do
end
def create_build(project, sha, branch)
ci_commit = create(:ci_commit, project: project,
pipeline = create(:ci_pipeline, project: project,
sha: sha,
ref: branch)
create(:ci_build, commit: ci_commit)
create(:ci_build, pipeline: pipeline)
end
def status_node(data, status)
......
......@@ -16,14 +16,21 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
end
context 'using PostgreSQL' do
it 'creates the index concurrently' do
expect(Gitlab::Database).to receive(:postgresql?).and_return(true)
before { expect(Gitlab::Database).to receive(:postgresql?).and_return(true) }
it 'creates the index concurrently' do
expect(model).to receive(:add_index).
with(:users, :foo, algorithm: :concurrently)
model.add_concurrent_index(:users, :foo)
end
it 'creates unique index concurrently' do
expect(model).to receive(:add_index).
with(:users, :foo, { algorithm: :concurrently, unique: true })
model.add_concurrent_index(:users, :foo, unique: true)
end
end
context 'using MySQL' do
......@@ -31,7 +38,7 @@ describe Gitlab::Database::MigrationHelpers, lib: true do
expect(Gitlab::Database).to receive(:postgresql?).and_return(false)
expect(model).to receive(:add_index).
with(:users, :foo)
with(:users, :foo, {})
model.add_concurrent_index(:users, :foo)
end
......
......@@ -29,6 +29,7 @@ describe Gitlab::GithubImport::CommentFormatter, lib: true do
commit_id: nil,
line_code: nil,
author_id: project.creator_id,
type: nil,
created_at: created_at,
updated_at: updated_at
}
......@@ -56,6 +57,7 @@ describe Gitlab::GithubImport::CommentFormatter, lib: true do
commit_id: '6dcb09b5b57875f334f61aebed695e2e4193db5e',
line_code: 'ce1be0ff4065a6e9415095c95f25f47a633cef2b_4_3',
author_id: project.creator_id,
type: 'LegacyDiffNote',
created_at: created_at,
updated_at: updated_at
}
......
require 'spec_helper'
describe Gitlab::GithubImport::HookFormatter, lib: true do
describe '#id' do
it 'returns raw id' do
raw = double(id: 100000)
formatter = described_class.new(raw)
expect(formatter.id).to eq 100000
end
end
describe '#name' do
it 'returns raw id' do
raw = double(name: 'web')
formatter = described_class.new(raw)
expect(formatter.name).to eq 'web'
end
end
describe '#config' do
it 'returns raw config.attrs' do
raw = double(config: double(attrs: { url: 'http://something.com/webhook' }))
formatter = described_class.new(raw)
expect(formatter.config).to eq({ url: 'http://something.com/webhook' })
end
end
describe '#valid?' do
it 'returns true when events contains the wildcard event' do
raw = double(events: ['*', 'commit_comment'], active: true)
formatter = described_class.new(raw)
expect(formatter.valid?).to eq true
end
it 'returns true when events contains the create event' do
raw = double(events: ['create', 'commit_comment'], active: true)
formatter = described_class.new(raw)
expect(formatter.valid?).to eq true
end
it 'returns true when events contains delete event' do
raw = double(events: ['delete', 'commit_comment'], active: true)
formatter = described_class.new(raw)
expect(formatter.valid?).to eq true
end
it 'returns true when events contains pull_request event' do
raw = double(events: ['pull_request', 'commit_comment'], active: true)
formatter = described_class.new(raw)
expect(formatter.valid?).to eq true
end
it 'returns false when events does not contains branch related events' do
raw = double(events: ['member', 'commit_comment'], active: true)
formatter = described_class.new(raw)
expect(formatter.valid?).to eq false
end
it 'returns false when hook is not active' do
raw = double(events: ['pull_request', 'commit_comment'], active: false)
formatter = described_class.new(raw)
expect(formatter.valid?).to eq false
end
end
end
......@@ -2,16 +2,16 @@ require 'spec_helper'
describe Ci::Build, models: true do
let(:project) { create(:project) }
let(:commit) { create(:ci_commit, project: project) }
let(:build) { create(:ci_build, commit: commit) }
let(:pipeline) { create(:ci_pipeline, project: project) }
let(:build) { create(:ci_build, pipeline: pipeline) }
it { is_expected.to validate_presence_of :ref }
it { is_expected.to respond_to :trace_html }
describe '#first_pending' do
let!(:first) { create(:ci_build, commit: commit, status: 'pending', created_at: Date.yesterday) }
let!(:second) { create(:ci_build, commit: commit, status: 'pending') }
let!(:first) { create(:ci_build, pipeline: pipeline, status: 'pending', created_at: Date.yesterday) }
let!(:second) { create(:ci_build, pipeline: pipeline, status: 'pending') }
subject { Ci::Build.first_pending }
it { is_expected.to be_a(Ci::Build) }
......@@ -97,7 +97,7 @@ describe Ci::Build, models: true do
# describe :timeout do
# subject { build.timeout }
#
# it { is_expected.to eq(commit.project.timeout) }
# it { is_expected.to eq(pipeline.project.timeout) }
# end
describe '#options' do
......@@ -124,13 +124,13 @@ describe Ci::Build, models: true do
describe '#project' do
subject { build.project }
it { is_expected.to eq(commit.project) }
it { is_expected.to eq(pipeline.project) }
end
describe '#project_id' do
subject { build.project_id }
it { is_expected.to eq(commit.project_id) }
it { is_expected.to eq(pipeline.project_id) }
end
describe '#project_name' do
......@@ -219,7 +219,7 @@ describe Ci::Build, models: true do
context 'and trigger variables' do
let(:trigger) { create(:ci_trigger, project: project) }
let(:trigger_request) { create(:ci_trigger_request_with_variables, commit: commit, trigger: trigger) }
let(:trigger_request) { create(:ci_trigger_request_with_variables, commit: pipeline, trigger: trigger) }
let(:trigger_variables) do
[
{ key: :TRIGGER_KEY, value: 'TRIGGER_VALUE', public: false }
......@@ -428,10 +428,10 @@ describe Ci::Build, models: true do
end
describe '#depends_on_builds' do
let!(:build) { create(:ci_build, commit: commit, name: 'build', stage_idx: 0, stage: 'build') }
let!(:rspec_test) { create(:ci_build, commit: commit, name: 'rspec', stage_idx: 1, stage: 'test') }
let!(:rubocop_test) { create(:ci_build, commit: commit, name: 'rubocop', stage_idx: 1, stage: 'test') }
let!(:staging) { create(:ci_build, commit: commit, name: 'staging', stage_idx: 2, stage: 'deploy') }
let!(:build) { create(:ci_build, pipeline: pipeline, name: 'build', stage_idx: 0, stage: 'build') }
let!(:rspec_test) { create(:ci_build, pipeline: pipeline, name: 'rspec', stage_idx: 1, stage: 'test') }
let!(:rubocop_test) { create(:ci_build, pipeline: pipeline, name: 'rubocop', stage_idx: 1, stage: 'test') }
let!(:staging) { create(:ci_build, pipeline: pipeline, name: 'staging', stage_idx: 2, stage: 'deploy') }
it 'to have no dependents if this is first build' do
expect(build.depends_on_builds).to be_empty
......@@ -451,19 +451,19 @@ describe Ci::Build, models: true do
end
end
def create_mr(build, commit, factory: :merge_request, created_at: Time.now)
create(factory, source_project_id: commit.gl_project_id,
target_project_id: commit.gl_project_id,
def create_mr(build, pipeline, factory: :merge_request, created_at: Time.now)
create(factory, source_project_id: pipeline.gl_project_id,
target_project_id: pipeline.gl_project_id,
source_branch: build.ref,
created_at: created_at)
end
describe '#merge_request' do
context 'when a MR has a reference to the commit' do
context 'when a MR has a reference to the pipeline' do
before do
@merge_request = create_mr(build, commit, factory: :merge_request)
@merge_request = create_mr(build, pipeline, factory: :merge_request)
commits = [double(id: commit.sha)]
commits = [double(id: pipeline.sha)]
allow(@merge_request).to receive(:commits).and_return(commits)
allow(MergeRequest).to receive_message_chain(:includes, :where, :reorder).and_return([@merge_request])
end
......@@ -473,19 +473,19 @@ describe Ci::Build, models: true do
end
end
context 'when there is not a MR referencing the commit' do
context 'when there is not a MR referencing the pipeline' do
it 'returns nil' do
expect(build.merge_request).to be_nil
end
end
context 'when more than one MR have a reference to the commit' do
context 'when more than one MR have a reference to the pipeline' do
before do
@merge_request = create_mr(build, commit, factory: :merge_request)
@merge_request = create_mr(build, pipeline, factory: :merge_request)
@merge_request.close!
@merge_request2 = create_mr(build, commit, factory: :merge_request)
@merge_request2 = create_mr(build, pipeline, factory: :merge_request)
commits = [double(id: commit.sha)]
commits = [double(id: pipeline.sha)]
allow(@merge_request).to receive(:commits).and_return(commits)
allow(@merge_request2).to receive(:commits).and_return(commits)
allow(MergeRequest).to receive_message_chain(:includes, :where, :reorder).and_return([@merge_request, @merge_request2])
......@@ -498,11 +498,11 @@ describe Ci::Build, models: true do
context 'when a Build is created after the MR' do
before do
@merge_request = create_mr(build, commit, factory: :merge_request_with_diffs)
commit2 = create(:ci_commit, project: project)
@build2 = create(:ci_build, commit: commit2)
@merge_request = create_mr(build, pipeline, factory: :merge_request_with_diffs)
pipeline2 = create(:ci_pipeline, project: project)
@build2 = create(:ci_build, pipeline: pipeline2)
commits = [double(id: commit.sha), double(id: commit2.sha)]
commits = [double(id: pipeline.sha), double(id: pipeline2.sha)]
allow(@merge_request).to receive(:commits).and_return(commits)
allow(MergeRequest).to receive_message_chain(:includes, :where, :reorder).and_return([@merge_request])
end
......
require 'spec_helper'
describe Ci::Commit, models: true do
describe Ci::Pipeline, models: true do
let(:project) { FactoryGirl.create :empty_project }
let(:commit) { FactoryGirl.create :ci_commit, project: project }
let(:pipeline) { FactoryGirl.create :ci_pipeline, project: project }
it { is_expected.to belong_to(:project) }
it { is_expected.to have_many(:statuses) }
......@@ -18,62 +18,62 @@ describe Ci::Commit, models: true do
describe :valid_commit_sha do
context 'commit.sha can not start with 00000000' do
before do
commit.sha = '0' * 40
commit.valid_commit_sha
pipeline.sha = '0' * 40
pipeline.valid_commit_sha
end
it('commit errors should not be empty') { expect(commit.errors).not_to be_empty }
it('commit errors should not be empty') { expect(pipeline.errors).not_to be_empty }
end
end
describe :short_sha do
subject { commit.short_sha }
subject { pipeline.short_sha }
it 'has 8 items' do
expect(subject.size).to eq(8)
end
it { expect(commit.sha).to start_with(subject) }
it { expect(pipeline.sha).to start_with(subject) }
end
describe :create_next_builds do
end
describe :retried do
subject { commit.retried }
subject { pipeline.retried }
before do
@commit1 = FactoryGirl.create :ci_build, commit: commit, name: 'deploy'
@commit2 = FactoryGirl.create :ci_build, commit: commit, name: 'deploy'
@build1 = FactoryGirl.create :ci_build, pipeline: pipeline, name: 'deploy'
@build2 = FactoryGirl.create :ci_build, pipeline: pipeline, name: 'deploy'
end
it 'returns old builds' do
is_expected.to contain_exactly(@commit1)
is_expected.to contain_exactly(@build1)
end
end
describe :create_builds do
let!(:commit) { FactoryGirl.create :ci_commit, project: project, ref: 'master', tag: false }
let!(:pipeline) { FactoryGirl.create :ci_pipeline, project: project, ref: 'master', tag: false }
def create_builds(trigger_request = nil)
commit.create_builds(nil, trigger_request)
pipeline.create_builds(nil, trigger_request)
end
def create_next_builds
commit.create_next_builds(commit.builds.order(:id).last)
pipeline.create_next_builds(pipeline.builds.order(:id).last)
end
it 'creates builds' do
expect(create_builds).to be_truthy
commit.builds.update_all(status: "success")
expect(commit.builds.count(:all)).to eq(2)
pipeline.builds.update_all(status: "success")
expect(pipeline.builds.count(:all)).to eq(2)
expect(create_next_builds).to be_truthy
commit.builds.update_all(status: "success")
expect(commit.builds.count(:all)).to eq(4)
pipeline.builds.update_all(status: "success")
expect(pipeline.builds.count(:all)).to eq(4)
expect(create_next_builds).to be_truthy
commit.builds.update_all(status: "success")
expect(commit.builds.count(:all)).to eq(5)
pipeline.builds.update_all(status: "success")
expect(pipeline.builds.count(:all)).to eq(5)
expect(create_next_builds).to be_falsey
end
......@@ -95,14 +95,14 @@ describe Ci::Commit, models: true do
end
before do
stub_ci_commit_yaml_file(YAML.dump(yaml))
stub_ci_pipeline_yaml_file(YAML.dump(yaml))
create_builds
end
it 'properly schedules builds' do
expect(commit.builds.pluck(:status)).to contain_exactly('pending')
commit.builds.running_or_pending.each(&:drop)
expect(commit.builds.pluck(:status)).to contain_exactly('pending', 'failed')
expect(pipeline.builds.pluck(:status)).to contain_exactly('pending')
pipeline.builds.running_or_pending.each(&:drop)
expect(pipeline.builds.pluck(:status)).to contain_exactly('pending', 'failed')
end
end
......@@ -136,183 +136,183 @@ describe Ci::Commit, models: true do
end
before do
stub_ci_commit_yaml_file(YAML.dump(yaml))
stub_ci_pipeline_yaml_file(YAML.dump(yaml))
end
context 'when builds are successful' do
it 'properly creates builds' do
expect(create_builds).to be_truthy
expect(commit.builds.pluck(:name)).to contain_exactly('build')
expect(commit.builds.pluck(:status)).to contain_exactly('pending')
commit.builds.running_or_pending.each(&:success)
expect(pipeline.builds.pluck(:name)).to contain_exactly('build')
expect(pipeline.builds.pluck(:status)).to contain_exactly('pending')
pipeline.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'pending')
commit.builds.running_or_pending.each(&:success)
expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test')
expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'pending')
pipeline.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'deploy')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'success', 'pending')
commit.builds.running_or_pending.each(&:success)
expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test', 'deploy')
expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'success', 'pending')
pipeline.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'deploy', 'cleanup')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'success', 'success', 'pending')
commit.builds.running_or_pending.each(&:success)
expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test', 'deploy', 'cleanup')
expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'success', 'success', 'pending')
pipeline.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'success', 'success', 'success')
commit.reload
expect(commit.status).to eq('success')
expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'success', 'success', 'success')
pipeline.reload
expect(pipeline.status).to eq('success')
end
end
context 'when test job fails' do
it 'properly creates builds' do
expect(create_builds).to be_truthy
expect(commit.builds.pluck(:name)).to contain_exactly('build')
expect(commit.builds.pluck(:status)).to contain_exactly('pending')
commit.builds.running_or_pending.each(&:success)
expect(pipeline.builds.pluck(:name)).to contain_exactly('build')
expect(pipeline.builds.pluck(:status)).to contain_exactly('pending')
pipeline.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'pending')
commit.builds.running_or_pending.each(&:drop)
expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test')
expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'pending')
pipeline.builds.running_or_pending.each(&:drop)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'failed', 'pending')
commit.builds.running_or_pending.each(&:success)
expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure')
expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'failed', 'pending')
pipeline.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure', 'cleanup')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'failed', 'success', 'pending')
commit.builds.running_or_pending.each(&:success)
expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure', 'cleanup')
expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'failed', 'success', 'pending')
pipeline.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'failed', 'success', 'success')
commit.reload
expect(commit.status).to eq('failed')
expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'failed', 'success', 'success')
pipeline.reload
expect(pipeline.status).to eq('failed')
end
end
context 'when test and test_failure jobs fail' do
it 'properly creates builds' do
expect(create_builds).to be_truthy
expect(commit.builds.pluck(:name)).to contain_exactly('build')
expect(commit.builds.pluck(:status)).to contain_exactly('pending')
commit.builds.running_or_pending.each(&:success)
expect(pipeline.builds.pluck(:name)).to contain_exactly('build')
expect(pipeline.builds.pluck(:status)).to contain_exactly('pending')
pipeline.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'pending')
commit.builds.running_or_pending.each(&:drop)
expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test')
expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'pending')
pipeline.builds.running_or_pending.each(&:drop)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'failed', 'pending')
commit.builds.running_or_pending.each(&:drop)
expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure')
expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'failed', 'pending')
pipeline.builds.running_or_pending.each(&:drop)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure', 'cleanup')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'failed', 'failed', 'pending')
commit.builds.running_or_pending.each(&:success)
expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure', 'cleanup')
expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'failed', 'failed', 'pending')
pipeline.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure', 'cleanup')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'failed', 'failed', 'success')
commit.reload
expect(commit.status).to eq('failed')
expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test', 'test_failure', 'cleanup')
expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'failed', 'failed', 'success')
pipeline.reload
expect(pipeline.status).to eq('failed')
end
end
context 'when deploy job fails' do
it 'properly creates builds' do
expect(create_builds).to be_truthy
expect(commit.builds.pluck(:name)).to contain_exactly('build')
expect(commit.builds.pluck(:status)).to contain_exactly('pending')
commit.builds.running_or_pending.each(&:success)
expect(pipeline.builds.pluck(:name)).to contain_exactly('build')
expect(pipeline.builds.pluck(:status)).to contain_exactly('pending')
pipeline.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'pending')
commit.builds.running_or_pending.each(&:success)
expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test')
expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'pending')
pipeline.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'deploy')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'success', 'pending')
commit.builds.running_or_pending.each(&:drop)
expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test', 'deploy')
expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'success', 'pending')
pipeline.builds.running_or_pending.each(&:drop)
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test', 'deploy', 'cleanup')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'success', 'failed', 'pending')
commit.builds.running_or_pending.each(&:success)
expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test', 'deploy', 'cleanup')
expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'success', 'failed', 'pending')
pipeline.builds.running_or_pending.each(&:success)
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'success', 'failed', 'success')
commit.reload
expect(commit.status).to eq('failed')
expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'success', 'failed', 'success')
pipeline.reload
expect(pipeline.status).to eq('failed')
end
end
context 'when build is canceled in the second stage' do
it 'does not schedule builds after build has been canceled' do
expect(create_builds).to be_truthy
expect(commit.builds.pluck(:name)).to contain_exactly('build')
expect(commit.builds.pluck(:status)).to contain_exactly('pending')
commit.builds.running_or_pending.each(&:success)
expect(pipeline.builds.pluck(:name)).to contain_exactly('build')
expect(pipeline.builds.pluck(:status)).to contain_exactly('pending')
pipeline.builds.running_or_pending.each(&:success)
expect(commit.builds.running_or_pending).not_to be_empty
expect(pipeline.builds.running_or_pending).not_to be_empty
expect(commit.builds.pluck(:name)).to contain_exactly('build', 'test')
expect(commit.builds.pluck(:status)).to contain_exactly('success', 'pending')
commit.builds.running_or_pending.each(&:cancel)
expect(pipeline.builds.pluck(:name)).to contain_exactly('build', 'test')
expect(pipeline.builds.pluck(:status)).to contain_exactly('success', 'pending')
pipeline.builds.running_or_pending.each(&:cancel)
expect(commit.builds.running_or_pending).to be_empty
expect(commit.reload.status).to eq('canceled')
expect(pipeline.builds.running_or_pending).to be_empty
expect(pipeline.reload.status).to eq('canceled')
end
end
end
end
describe "#finished_at" do
let(:commit) { FactoryGirl.create :ci_commit }
let(:pipeline) { FactoryGirl.create :ci_pipeline }
it "returns finished_at of latest build" do
build = FactoryGirl.create :ci_build, commit: commit, finished_at: Time.now - 60
FactoryGirl.create :ci_build, commit: commit, finished_at: Time.now - 120
build = FactoryGirl.create :ci_build, pipeline: pipeline, finished_at: Time.now - 60
FactoryGirl.create :ci_build, pipeline: pipeline, finished_at: Time.now - 120
expect(commit.finished_at.to_i).to eq(build.finished_at.to_i)
expect(pipeline.finished_at.to_i).to eq(build.finished_at.to_i)
end
it "returns nil if there is no finished build" do
FactoryGirl.create :ci_not_started_build, commit: commit
FactoryGirl.create :ci_not_started_build, pipeline: pipeline
expect(commit.finished_at).to be_nil
expect(pipeline.finished_at).to be_nil
end
end
describe "coverage" do
let(:project) { FactoryGirl.create :empty_project, build_coverage_regex: "/.*/" }
let(:commit) { FactoryGirl.create :ci_commit, project: project }
let(:pipeline) { FactoryGirl.create :ci_pipeline, project: project }
it "calculates average when there are two builds with coverage" do
FactoryGirl.create :ci_build, name: "rspec", coverage: 30, commit: commit
FactoryGirl.create :ci_build, name: "rubocop", coverage: 40, commit: commit
expect(commit.coverage).to eq("35.00")
FactoryGirl.create :ci_build, name: "rspec", coverage: 30, pipeline: pipeline
FactoryGirl.create :ci_build, name: "rubocop", coverage: 40, pipeline: pipeline
expect(pipeline.coverage).to eq("35.00")
end
it "calculates average when there are two builds with coverage and one with nil" do
FactoryGirl.create :ci_build, name: "rspec", coverage: 30, commit: commit
FactoryGirl.create :ci_build, name: "rubocop", coverage: 40, commit: commit
FactoryGirl.create :ci_build, commit: commit
expect(commit.coverage).to eq("35.00")
FactoryGirl.create :ci_build, name: "rspec", coverage: 30, pipeline: pipeline
FactoryGirl.create :ci_build, name: "rubocop", coverage: 40, pipeline: pipeline
FactoryGirl.create :ci_build, pipeline: pipeline
expect(pipeline.coverage).to eq("35.00")
end
it "calculates average when there are two builds with coverage and one is retried" do
FactoryGirl.create :ci_build, name: "rspec", coverage: 30, commit: commit
FactoryGirl.create :ci_build, name: "rubocop", coverage: 30, commit: commit
FactoryGirl.create :ci_build, name: "rubocop", coverage: 40, commit: commit
expect(commit.coverage).to eq("35.00")
FactoryGirl.create :ci_build, name: "rspec", coverage: 30, pipeline: pipeline
FactoryGirl.create :ci_build, name: "rubocop", coverage: 30, pipeline: pipeline
FactoryGirl.create :ci_build, name: "rubocop", coverage: 40, pipeline: pipeline
expect(pipeline.coverage).to eq("35.00")
end
it "calculates average when there is one build without coverage" do
FactoryGirl.create :ci_build, commit: commit
expect(commit.coverage).to be_nil
FactoryGirl.create :ci_build, pipeline: pipeline
expect(pipeline.coverage).to be_nil
end
end
describe '#retryable?' do
subject { commit.retryable? }
subject { pipeline.retryable? }
context 'no failed builds' do
before do
FactoryGirl.create :ci_build, name: "rspec", commit: commit, status: 'success'
FactoryGirl.create :ci_build, name: "rspec", pipeline: pipeline, status: 'success'
end
it 'be not retryable' do
......@@ -322,8 +322,8 @@ describe Ci::Commit, models: true do
context 'with failed builds' do
before do
FactoryGirl.create :ci_build, name: "rspec", commit: commit, status: 'running'
FactoryGirl.create :ci_build, name: "rubocop", commit: commit, status: 'failed'
FactoryGirl.create :ci_build, name: "rspec", pipeline: pipeline, status: 'running'
FactoryGirl.create :ci_build, name: "rubocop", pipeline: pipeline, status: 'failed'
end
it 'be retryable' do
......@@ -333,12 +333,12 @@ describe Ci::Commit, models: true do
end
describe '#stages' do
let(:commit2) { FactoryGirl.create :ci_commit, project: project }
subject { CommitStatus.where(commit: [commit, commit2]).stages }
let(:pipeline2) { FactoryGirl.create :ci_pipeline, project: project }
subject { CommitStatus.where(pipeline: [pipeline, pipeline2]).stages }
before do
FactoryGirl.create :ci_build, commit: commit2, stage: 'test', stage_idx: 1
FactoryGirl.create :ci_build, commit: commit, stage: 'build', stage_idx: 0
FactoryGirl.create :ci_build, pipeline: pipeline2, stage: 'test', stage_idx: 1
FactoryGirl.create :ci_build, pipeline: pipeline, stage: 'build', stage_idx: 0
end
it 'return all stages' do
......@@ -348,22 +348,22 @@ describe Ci::Commit, models: true do
describe '#update_state' do
it 'execute update_state after touching object' do
expect(commit).to receive(:update_state).and_return(true)
commit.touch
expect(pipeline).to receive(:update_state).and_return(true)
pipeline.touch
end
context 'dependent objects' do
let(:commit_status) { build :commit_status, commit: commit }
let(:commit_status) { build :commit_status, pipeline: pipeline }
it 'execute update_state after saving dependent object' do
expect(commit).to receive(:update_state).and_return(true)
expect(pipeline).to receive(:update_state).and_return(true)
commit_status.save
end
end
context 'update state' do
let(:current) { Time.now.change(usec: 0) }
let(:build) { FactoryGirl.create :ci_build, :success, commit: commit, started_at: current - 120, finished_at: current - 60 }
let(:build) { FactoryGirl.create :ci_build, :success, pipeline: pipeline, started_at: current - 120, finished_at: current - 60 }
before do
build
......@@ -371,18 +371,18 @@ describe Ci::Commit, models: true do
[:status, :started_at, :finished_at, :duration].each do |param|
it "update #{param}" do
expect(commit.send(param)).to eq(build.send(param))
expect(pipeline.send(param)).to eq(build.send(param))
end
end
end
end
describe '#branch?' do
subject { commit.branch? }
subject { pipeline.branch? }
context 'is not a tag' do
before do
commit.tag = false
pipeline.tag = false
end
it 'return true when tag is set to false' do
......@@ -392,7 +392,7 @@ describe Ci::Commit, models: true do
context 'is not a tag' do
before do
commit.tag = true
pipeline.tag = true
end
it 'return false when tag is set to true' do
......
require 'spec_helper'
describe CommitStatus, models: true do
let(:commit) { FactoryGirl.create :ci_commit }
let(:commit_status) { FactoryGirl.create :commit_status, commit: commit }
let(:pipeline) { FactoryGirl.create :ci_pipeline }
let(:commit_status) { FactoryGirl.create :commit_status, pipeline: pipeline }
it { is_expected.to belong_to(:commit) }
it { is_expected.to belong_to(:pipeline) }
it { is_expected.to belong_to(:user) }
it { is_expected.to belong_to(:project) }
it { is_expected.to validate_presence_of(:name) }
it { is_expected.to validate_inclusion_of(:status).in_array(%w(pending running failed success canceled)) }
it { is_expected.to delegate_method(:sha).to(:commit) }
it { is_expected.to delegate_method(:short_sha).to(:commit) }
it { is_expected.to delegate_method(:sha).to(:pipeline) }
it { is_expected.to delegate_method(:short_sha).to(:pipeline) }
it { is_expected.to respond_to :success? }
it { is_expected.to respond_to :failed? }
......@@ -121,11 +121,11 @@ describe CommitStatus, models: true do
subject { CommitStatus.latest.order(:id) }
before do
@commit1 = FactoryGirl.create :commit_status, commit: commit, name: 'aa', ref: 'bb', status: 'running'
@commit2 = FactoryGirl.create :commit_status, commit: commit, name: 'cc', ref: 'cc', status: 'pending'
@commit3 = FactoryGirl.create :commit_status, commit: commit, name: 'aa', ref: 'cc', status: 'success'
@commit4 = FactoryGirl.create :commit_status, commit: commit, name: 'cc', ref: 'bb', status: 'success'
@commit5 = FactoryGirl.create :commit_status, commit: commit, name: 'aa', ref: 'bb', status: 'success'
@commit1 = FactoryGirl.create :commit_status, pipeline: pipeline, name: 'aa', ref: 'bb', status: 'running'
@commit2 = FactoryGirl.create :commit_status, pipeline: pipeline, name: 'cc', ref: 'cc', status: 'pending'
@commit3 = FactoryGirl.create :commit_status, pipeline: pipeline, name: 'aa', ref: 'cc', status: 'success'
@commit4 = FactoryGirl.create :commit_status, pipeline: pipeline, name: 'cc', ref: 'bb', status: 'success'
@commit5 = FactoryGirl.create :commit_status, pipeline: pipeline, name: 'aa', ref: 'bb', status: 'success'
end
it 'return unique statuses' do
......@@ -137,11 +137,11 @@ describe CommitStatus, models: true do
subject { CommitStatus.running_or_pending.order(:id) }
before do
@commit1 = FactoryGirl.create :commit_status, commit: commit, name: 'aa', ref: 'bb', status: 'running'
@commit2 = FactoryGirl.create :commit_status, commit: commit, name: 'cc', ref: 'cc', status: 'pending'
@commit3 = FactoryGirl.create :commit_status, commit: commit, name: 'aa', ref: nil, status: 'success'
@commit4 = FactoryGirl.create :commit_status, commit: commit, name: 'dd', ref: nil, status: 'failed'
@commit5 = FactoryGirl.create :commit_status, commit: commit, name: 'ee', ref: nil, status: 'canceled'
@commit1 = FactoryGirl.create :commit_status, pipeline: pipeline, name: 'aa', ref: 'bb', status: 'running'
@commit2 = FactoryGirl.create :commit_status, pipeline: pipeline, name: 'cc', ref: 'cc', status: 'pending'
@commit3 = FactoryGirl.create :commit_status, pipeline: pipeline, name: 'aa', ref: nil, status: 'success'
@commit4 = FactoryGirl.create :commit_status, pipeline: pipeline, name: 'dd', ref: nil, status: 'failed'
@commit5 = FactoryGirl.create :commit_status, pipeline: pipeline, name: 'ee', ref: nil, status: 'canceled'
end
it 'return statuses that are running or pending' do
......@@ -152,17 +152,17 @@ describe CommitStatus, models: true do
describe '#before_sha' do
subject { commit_status.before_sha }
context 'when no before_sha is set for ci::commit' do
before { commit.before_sha = nil }
context 'when no before_sha is set for pipeline' do
before { pipeline.before_sha = nil }
it 'return blank sha' do
is_expected.to eq(Gitlab::Git::BLANK_SHA)
end
end
context 'for before_sha set for ci::commit' do
context 'for before_sha set for pipeline' do
let(:value) { '1234' }
before { commit.before_sha = value }
before { pipeline.before_sha = value }
it 'return the set value' do
is_expected.to eq(value)
......@@ -172,14 +172,14 @@ describe CommitStatus, models: true do
describe '#stages' do
before do
FactoryGirl.create :commit_status, commit: commit, stage: 'build', stage_idx: 0, status: 'success'
FactoryGirl.create :commit_status, commit: commit, stage: 'build', stage_idx: 0, status: 'failed'
FactoryGirl.create :commit_status, commit: commit, stage: 'deploy', stage_idx: 2, status: 'running'
FactoryGirl.create :commit_status, commit: commit, stage: 'test', stage_idx: 1, status: 'success'
FactoryGirl.create :commit_status, pipeline: pipeline, stage: 'build', stage_idx: 0, status: 'success'
FactoryGirl.create :commit_status, pipeline: pipeline, stage: 'build', stage_idx: 0, status: 'failed'
FactoryGirl.create :commit_status, pipeline: pipeline, stage: 'deploy', stage_idx: 2, status: 'running'
FactoryGirl.create :commit_status, pipeline: pipeline, stage: 'test', stage_idx: 1, status: 'success'
end
context 'stages list' do
subject { CommitStatus.where(commit: commit).stages }
subject { CommitStatus.where(pipeline: pipeline).stages }
it 'return ordered list of stages' do
is_expected.to eq(%w(build test deploy))
......@@ -187,7 +187,7 @@ describe CommitStatus, models: true do
end
context 'stages with statuses' do
subject { CommitStatus.where(commit: commit).stages_status }
subject { CommitStatus.where(pipeline: pipeline).stages_status }
it 'return list of stages with statuses' do
is_expected.to eq({
......
require 'spec_helper'
describe GenericCommitStatus, models: true do
let(:commit) { FactoryGirl.create :ci_commit }
let(:generic_commit_status) { FactoryGirl.create :generic_commit_status, commit: commit }
let(:pipeline) { FactoryGirl.create :ci_pipeline }
let(:generic_commit_status) { FactoryGirl.create :generic_commit_status, pipeline: pipeline }
describe :context do
subject { generic_commit_status.context }
......
......@@ -420,19 +420,19 @@ describe MergeRequest, models: true do
subject { create :merge_request, :simple }
end
describe '#ci_commit' do
describe '#pipeline' do
describe 'when the source project exists' do
it 'returns the latest commit' do
commit = double(:commit, id: '123abc')
ci_commit = double(:ci_commit, ref: 'master')
pipeline = double(:ci_pipeline, ref: 'master')
allow(subject).to receive(:last_commit).and_return(commit)
expect(subject.source_project).to receive(:ci_commit).
expect(subject.source_project).to receive(:pipeline).
with('123abc', 'master').
and_return(ci_commit)
and_return(pipeline)
expect(subject.ci_commit).to eq(ci_commit)
expect(subject.pipeline).to eq(pipeline)
end
end
......@@ -440,7 +440,7 @@ describe MergeRequest, models: true do
it 'returns nil' do
allow(subject).to receive(:source_project).and_return(nil)
expect(subject.ci_commit).to be_nil
expect(subject.pipeline).to be_nil
end
end
end
......
......@@ -22,7 +22,7 @@ describe Project, models: true do
it { is_expected.to have_one(:pushover_service).dependent(:destroy) }
it { is_expected.to have_one(:asana_service).dependent(:destroy) }
it { is_expected.to have_many(:commit_statuses) }
it { is_expected.to have_many(:ci_commits) }
it { is_expected.to have_many(:pipelines) }
it { is_expected.to have_many(:builds) }
it { is_expected.to have_many(:runner_projects) }
it { is_expected.to have_many(:runners) }
......@@ -438,23 +438,23 @@ describe Project, models: true do
end
end
describe :ci_commit do
describe :pipeline do
let(:project) { create :project }
let(:commit) { create :ci_commit, project: project, ref: 'master' }
let(:pipeline) { create :ci_pipeline, project: project, ref: 'master' }
subject { project.ci_commit(commit.sha, 'master') }
subject { project.pipeline(pipeline.sha, 'master') }
it { is_expected.to eq(commit) }
it { is_expected.to eq(pipeline) }
context 'return latest' do
let(:commit2) { create :ci_commit, project: project, ref: 'master' }
let(:pipeline2) { create :ci_pipeline, project: project, ref: 'master' }
before do
commit
commit2
pipeline
pipeline2
end
it { is_expected.to eq(commit2) }
it { is_expected.to eq(pipeline2) }
end
end
......
......@@ -9,8 +9,8 @@ describe API::API, api: true do
let!(:project) { create(:project, creator_id: user.id) }
let!(:developer) { create(:project_member, :developer, user: user, project: project) }
let!(:reporter) { create(:project_member, :reporter, user: user2, project: project) }
let(:commit) { create(:ci_commit, project: project)}
let(:build) { create(:ci_build, commit: commit) }
let(:pipeline) { create(:ci_pipeline, project: project)}
let(:build) { create(:ci_build, pipeline: pipeline) }
describe 'GET /projects/:id/builds ' do
let(:query) { '' }
......@@ -59,8 +59,8 @@ describe API::API, api: true do
describe 'GET /projects/:id/repository/commits/:sha/builds' do
before do
project.ensure_ci_commit(commit.sha, 'master')
get api("/projects/#{project.id}/repository/commits/#{commit.sha}/builds", api_user)
project.ensure_pipeline(pipeline.sha, 'master')
get api("/projects/#{project.id}/repository/commits/#{pipeline.sha}/builds", api_user)
end
context 'authorized user' do
......@@ -102,7 +102,7 @@ describe API::API, api: true do
before { get api("/projects/#{project.id}/builds/#{build.id}/artifacts", api_user) }
context 'build with artifacts' do
let(:build) { create(:ci_build, :artifacts, commit: commit) }
let(:build) { create(:ci_build, :artifacts, pipeline: pipeline) }
context 'authorized user' do
let(:download_headers) do
......@@ -131,7 +131,7 @@ describe API::API, api: true do
end
describe 'GET /projects/:id/builds/:build_id/trace' do
let(:build) { create(:ci_build, :trace, commit: commit) }
let(:build) { create(:ci_build, :trace, pipeline: pipeline) }
before { get api("/projects/#{project.id}/builds/#{build.id}/trace", api_user) }
......@@ -181,7 +181,7 @@ describe API::API, api: true do
end
describe 'POST /projects/:id/builds/:build_id/retry' do
let(:build) { create(:ci_build, :canceled, commit: commit) }
let(:build) { create(:ci_build, :canceled, pipeline: pipeline) }
before { post api("/projects/#{project.id}/builds/#{build.id}/retry", api_user) }
......@@ -218,7 +218,7 @@ describe API::API, api: true do
end
context 'build is erasable' do
let(:build) { create(:ci_build, :trace, :artifacts, :success, project: project, commit: commit) }
let(:build) { create(:ci_build, :trace, :artifacts, :success, project: project, pipeline: pipeline) }
it 'should erase build content' do
expect(response.status).to eq 201
......@@ -234,7 +234,7 @@ describe API::API, api: true do
end
context 'build is not erasable' do
let(:build) { create(:ci_build, :trace, project: project, commit: commit) }
let(:build) { create(:ci_build, :trace, project: project, pipeline: pipeline) }
it 'should respond with forbidden' do
expect(response.status).to eq 403
......
......@@ -5,7 +5,7 @@ describe API::CommitStatuses, api: true do
let!(:project) { create(:project) }
let(:commit) { project.repository.commit }
let(:commit_status) { create(:commit_status, commit: ci_commit) }
let(:commit_status) { create(:commit_status, pipeline: pipeline) }
let(:guest) { create_user(:guest) }
let(:reporter) { create_user(:reporter) }
let(:developer) { create_user(:developer) }
......@@ -16,8 +16,8 @@ describe API::CommitStatuses, api: true do
let(:get_url) { "/projects/#{project.id}/repository/commits/#{sha}/statuses" }
context 'ci commit exists' do
let!(:master) { project.ci_commits.create(sha: commit.id, ref: 'master') }
let!(:develop) { project.ci_commits.create(sha: commit.id, ref: 'develop') }
let!(:master) { project.pipelines.create(sha: commit.id, ref: 'master') }
let!(:develop) { project.pipelines.create(sha: commit.id, ref: 'develop') }
it_behaves_like 'a paginated resources' do
let(:request) { get api(get_url, reporter) }
......@@ -27,7 +27,7 @@ describe API::CommitStatuses, api: true do
let(:statuses_id) { json_response.map { |status| status['id'] } }
def create_status(commit, opts = {})
create(:commit_status, { commit: commit, ref: commit.ref }.merge(opts))
create(:commit_status, { pipeline: commit, ref: commit.ref }.merge(opts))
end
let!(:status1) { create_status(master, status: 'running') }
......
......@@ -90,10 +90,10 @@ describe API::API, api: true do
end
it "should return status for CI" do
ci_commit = project.ensure_ci_commit(project.repository.commit.sha, 'master')
pipeline = project.ensure_pipeline(project.repository.commit.sha, 'master')
get api("/projects/#{project.id}/repository/commits/#{project.repository.commit.id}", user)
expect(response.status).to eq(200)
expect(json_response['status']).to eq(ci_commit.status)
expect(json_response['status']).to eq(pipeline.status)
end
end
......
......@@ -387,7 +387,7 @@ describe API::API, api: true do
end
describe "PUT /projects/:id/merge_requests/:merge_request_id/merge" do
let(:ci_commit) { create(:ci_commit_without_jobs) }
let(:pipeline) { create(:ci_pipeline_without_jobs) }
it "should return merge_request in case of success" do
put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user)
......@@ -441,8 +441,8 @@ describe API::API, api: true do
end
it "enables merge when build succeeds if the ci is active" do
allow_any_instance_of(MergeRequest).to receive(:ci_commit).and_return(ci_commit)
allow(ci_commit).to receive(:active?).and_return(true)
allow_any_instance_of(MergeRequest).to receive(:pipeline).and_return(pipeline)
allow(pipeline).to receive(:active?).and_return(true)
put api("/projects/#{project.id}/merge_requests/#{merge_request.id}/merge", user), merge_when_build_succeeds: true
......
......@@ -23,7 +23,7 @@ describe API::API do
end
before do
stub_ci_commit_to_return_yaml_file
stub_ci_pipeline_to_return_yaml_file
end
context 'Handles errors' do
......@@ -44,13 +44,13 @@ describe API::API do
end
context 'Have a commit' do
let(:commit) { project.ci_commits.last }
let(:pipeline) { project.pipelines.last }
it 'should create builds' do
post api("/projects/#{project.id}/trigger/builds"), options.merge(ref: 'master')
expect(response.status).to eq(201)
commit.builds.reload
expect(commit.builds.size).to eq(2)
pipeline.builds.reload
expect(pipeline.builds.size).to eq(2)
end
it 'should return bad request with no builds created if there\'s no commit for that ref' do
......@@ -79,8 +79,8 @@ describe API::API do
it 'create trigger request with variables' do
post api("/projects/#{project.id}/trigger/builds"), options.merge(variables: variables, ref: 'master')
expect(response.status).to eq(201)
commit.builds.reload
expect(commit.builds.first.trigger_request.variables).to eq(variables)
pipeline.builds.reload
expect(pipeline.builds.first.trigger_request.variables).to eq(variables)
end
end
end
......
......@@ -7,7 +7,7 @@ describe Ci::API::API do
let(:project) { FactoryGirl.create(:empty_project) }
before do
stub_ci_commit_to_return_yaml_file
stub_ci_pipeline_to_return_yaml_file
end
describe "Builds API for runners" do
......@@ -20,9 +20,9 @@ describe Ci::API::API do
describe "POST /builds/register" do
it "should start a build" do
commit = FactoryGirl.create(:ci_commit, project: project, ref: 'master')
commit.create_builds(nil)
build = commit.builds.first
pipeline = FactoryGirl.create(:ci_pipeline, project: project, ref: 'master')
pipeline.create_builds(nil)
build = pipeline.builds.first
post ci_api("/builds/register"), token: runner.token, info: { platform: :darwin }
......@@ -38,8 +38,8 @@ describe Ci::API::API do
end
it "should return 404 error if no builds for specific runner" do
commit = FactoryGirl.create(:ci_commit, project: shared_project)
FactoryGirl.create(:ci_build, commit: commit, status: 'pending')
pipeline = FactoryGirl.create(:ci_pipeline, project: shared_project)
FactoryGirl.create(:ci_build, pipeline: pipeline, status: 'pending')
post ci_api("/builds/register"), token: runner.token
......@@ -47,8 +47,8 @@ describe Ci::API::API do
end
it "should return 404 error if no builds for shared runner" do
commit = FactoryGirl.create(:ci_commit, project: project)
FactoryGirl.create(:ci_build, commit: commit, status: 'pending')
pipeline = FactoryGirl.create(:ci_pipeline, project: project)
FactoryGirl.create(:ci_build, pipeline: pipeline, status: 'pending')
post ci_api("/builds/register"), token: shared_runner.token
......@@ -56,8 +56,8 @@ describe Ci::API::API do
end
it "returns options" do
commit = FactoryGirl.create(:ci_commit, project: project, ref: 'master')
commit.create_builds(nil)
pipeline = FactoryGirl.create(:ci_pipeline, project: project, ref: 'master')
pipeline.create_builds(nil)
post ci_api("/builds/register"), token: runner.token, info: { platform: :darwin }
......@@ -66,8 +66,8 @@ describe Ci::API::API do
end
it "returns variables" do
commit = FactoryGirl.create(:ci_commit, project: project, ref: 'master')
commit.create_builds(nil)
pipeline = FactoryGirl.create(:ci_pipeline, project: project, ref: 'master')
pipeline.create_builds(nil)
project.variables << Ci::Variable.new(key: "SECRET_KEY", value: "secret_value")
post ci_api("/builds/register"), token: runner.token, info: { platform: :darwin }
......@@ -83,10 +83,10 @@ describe Ci::API::API do
it "returns variables for triggers" do
trigger = FactoryGirl.create(:ci_trigger, project: project)
commit = FactoryGirl.create(:ci_commit, project: project, ref: 'master')
pipeline = FactoryGirl.create(:ci_pipeline, project: project, ref: 'master')
trigger_request = FactoryGirl.create(:ci_trigger_request_with_variables, commit: commit, trigger: trigger)
commit.create_builds(nil, trigger_request)
trigger_request = FactoryGirl.create(:ci_trigger_request_with_variables, commit: pipeline, trigger: trigger)
pipeline.create_builds(nil, trigger_request)
project.variables << Ci::Variable.new(key: "SECRET_KEY", value: "secret_value")
post ci_api("/builds/register"), token: runner.token, info: { platform: :darwin }
......@@ -103,9 +103,9 @@ describe Ci::API::API do
end
it "returns dependent builds" do
commit = FactoryGirl.create(:ci_commit, project: project, ref: 'master')
commit.create_builds(nil, nil)
commit.builds.where(stage: 'test').each(&:success)
pipeline = FactoryGirl.create(:ci_pipeline, project: project, ref: 'master')
pipeline.create_builds(nil, nil)
pipeline.builds.where(stage: 'test').each(&:success)
post ci_api("/builds/register"), token: runner.token, info: { platform: :darwin }
......@@ -131,8 +131,8 @@ describe Ci::API::API do
context 'when build has no tags' do
before do
commit = create(:ci_commit, project: project)
create(:ci_build, commit: commit, tags: [])
pipeline = create(:ci_pipeline, project: project)
create(:ci_build, pipeline: pipeline, tags: [])
end
context 'when runner is allowed to pick untagged builds' do
......@@ -163,8 +163,8 @@ describe Ci::API::API do
end
describe "PUT /builds/:id" do
let(:commit) {create(:ci_commit, project: project)}
let(:build) { create(:ci_build, :trace, commit: commit, runner_id: runner.id) }
let(:pipeline) {create(:ci_pipeline, project: project)}
let(:build) { create(:ci_build, :trace, pipeline: pipeline, runner_id: runner.id) }
before do
build.run!
......@@ -237,8 +237,8 @@ describe Ci::API::API do
context "Artifacts" do
let(:file_upload) { fixture_file_upload(Rails.root + 'spec/fixtures/banana_sample.gif', 'image/gif') }
let(:file_upload2) { fixture_file_upload(Rails.root + 'spec/fixtures/dk.png', 'image/gif') }
let(:commit) { create(:ci_commit, project: project) }
let(:build) { create(:ci_build, commit: commit, runner_id: runner.id) }
let(:pipeline) { create(:ci_pipeline, project: project) }
let(:build) { create(:ci_build, pipeline: pipeline, runner_id: runner.id) }
let(:authorize_url) { ci_api("/builds/#{build.id}/artifacts/authorize") }
let(:post_url) { ci_api("/builds/#{build.id}/artifacts") }
let(:delete_url) { ci_api("/builds/#{build.id}/artifacts") }
......
......@@ -15,7 +15,7 @@ describe Ci::API::API do
end
before do
stub_ci_commit_to_return_yaml_file
stub_ci_pipeline_to_return_yaml_file
end
context 'Handles errors' do
......@@ -36,13 +36,13 @@ describe Ci::API::API do
end
context 'Have a commit' do
let(:commit) { project.ci_commits.last }
let(:pipeline) { project.pipelines.last }
it 'should create builds' do
post ci_api("/projects/#{project.ci_id}/refs/master/trigger"), options
expect(response.status).to eq(201)
commit.builds.reload
expect(commit.builds.size).to eq(2)
pipeline.builds.reload
expect(pipeline.builds.size).to eq(2)
end
it 'should return bad request with no builds created if there\'s no commit for that ref' do
......@@ -71,8 +71,8 @@ describe Ci::API::API do
it 'create trigger request with variables' do
post ci_api("/projects/#{project.ci_id}/refs/master/trigger"), options.merge(variables: variables)
expect(response.status).to eq(201)
commit.builds.reload
expect(commit.builds.first.trigger_request.variables).to eq(variables)
pipeline.builds.reload
expect(pipeline.builds.first.trigger_request.variables).to eq(variables)
end
end
end
......
require 'spec_helper'
describe Ci::CreateBuildsService, services: true do
let(:commit) { create(:ci_commit, ref: 'master') }
let(:pipeline) { create(:ci_pipeline, ref: 'master') }
let(:user) { create(:user) }
describe '#execute' do
......@@ -9,7 +9,7 @@ describe Ci::CreateBuildsService, services: true do
#
subject do
described_class.new(commit).execute(commit, nil, user, status)
described_class.new(pipeline).execute('test', nil, user, status)
end
context 'next builds available' do
......
......@@ -6,7 +6,7 @@ describe Ci::CreateTriggerRequestService, services: true do
let(:trigger) { create(:ci_trigger, project: project) }
before do
stub_ci_commit_to_return_yaml_file
stub_ci_pipeline_to_return_yaml_file
end
describe :execute do
......@@ -27,8 +27,8 @@ describe Ci::CreateTriggerRequestService, services: true do
subject { service.execute(project, trigger, 'master') }
before do
stub_ci_commit_yaml_file('{}')
FactoryGirl.create :ci_commit, project: project
stub_ci_pipeline_yaml_file('{}')
FactoryGirl.create :ci_pipeline, project: project
end
it { expect(subject).to be_nil }
......
......@@ -5,8 +5,8 @@ module Ci
let(:service) { ImageForBuildService.new }
let(:project) { FactoryGirl.create(:empty_project) }
let(:commit_sha) { '01234567890123456789' }
let(:commit) { project.ensure_ci_commit(commit_sha, 'master') }
let(:build) { FactoryGirl.create(:ci_build, commit: commit) }
let(:commit) { project.ensure_pipeline(commit_sha, 'master') }
let(:build) { FactoryGirl.create(:ci_build, pipeline: commit) }
describe :execute do
before { build }
......
......@@ -4,8 +4,8 @@ module Ci
describe RegisterBuildService, services: true do
let!(:service) { RegisterBuildService.new }
let!(:project) { FactoryGirl.create :empty_project, shared_runners_enabled: false }
let!(:commit) { FactoryGirl.create :ci_commit, project: project }
let!(:pending_build) { FactoryGirl.create :ci_build, commit: commit }
let!(:pipeline) { FactoryGirl.create :ci_pipeline, project: project }
let!(:pending_build) { FactoryGirl.create :ci_build, pipeline: pipeline }
let!(:shared_runner) { FactoryGirl.create(:ci_runner, is_shared: true) }
let!(:specific_runner) { FactoryGirl.create(:ci_runner, is_shared: false) }
......
......@@ -6,12 +6,12 @@ describe CreateCommitBuildsService, services: true do
let(:user) { nil }
before do
stub_ci_commit_to_return_yaml_file
stub_ci_pipeline_to_return_yaml_file
end
describe :execute do
context 'valid params' do
let(:commit) do
let(:pipeline) do
service.execute(project, user,
ref: 'refs/heads/master',
before: '00000000',
......@@ -20,11 +20,11 @@ describe CreateCommitBuildsService, services: true do
)
end
it { expect(commit).to be_kind_of(Ci::Commit) }
it { expect(commit).to be_valid }
it { expect(commit).to be_persisted }
it { expect(commit).to eq(project.ci_commits.last) }
it { expect(commit.builds.first).to be_kind_of(Ci::Build) }
it { expect(pipeline).to be_kind_of(Ci::Pipeline) }
it { expect(pipeline).to be_valid }
it { expect(pipeline).to be_persisted }
it { expect(pipeline).to eq(project.pipelines.last) }
it { expect(pipeline.builds.first).to be_kind_of(Ci::Build) }
end
context "skip tag if there is no build for it" do
......@@ -40,7 +40,7 @@ describe CreateCommitBuildsService, services: true do
it "creates commit if there is no appropriate job but deploy job has right ref setting" do
config = YAML.dump({ deploy: { deploy: "ls", only: ["0_1"] } })
stub_ci_commit_yaml_file(config)
stub_ci_pipeline_yaml_file(config)
result = service.execute(project, user,
ref: 'refs/heads/0_1',
......@@ -52,8 +52,8 @@ describe CreateCommitBuildsService, services: true do
end
end
it 'skips creating ci_commit for refs without .gitlab-ci.yml' do
stub_ci_commit_yaml_file(nil)
it 'skips creating pipeline for refs without .gitlab-ci.yml' do
stub_ci_pipeline_yaml_file(nil)
result = service.execute(project, user,
ref: 'refs/heads/0_1',
before: '00000000',
......@@ -61,115 +61,115 @@ describe CreateCommitBuildsService, services: true do
commits: [{ message: 'Message' }]
)
expect(result).to be_falsey
expect(Ci::Commit.count).to eq(0)
expect(Ci::Pipeline.count).to eq(0)
end
it 'fails commits if yaml is invalid' do
message = 'message'
allow_any_instance_of(Ci::Commit).to receive(:git_commit_message) { message }
stub_ci_commit_yaml_file('invalid: file: file')
allow_any_instance_of(Ci::Pipeline).to receive(:git_commit_message) { message }
stub_ci_pipeline_yaml_file('invalid: file: file')
commits = [{ message: message }]
commit = service.execute(project, user,
pipeline = service.execute(project, user,
ref: 'refs/tags/0_1',
before: '00000000',
after: '31das312',
commits: commits
)
expect(commit).to be_persisted
expect(commit.builds.any?).to be false
expect(commit.status).to eq('failed')
expect(commit.yaml_errors).not_to be_nil
expect(pipeline).to be_persisted
expect(pipeline.builds.any?).to be false
expect(pipeline.status).to eq('failed')
expect(pipeline.yaml_errors).not_to be_nil
end
describe :ci_skip? do
let(:message) { "some message[ci skip]" }
before do
allow_any_instance_of(Ci::Commit).to receive(:git_commit_message) { message }
allow_any_instance_of(Ci::Pipeline).to receive(:git_commit_message) { message }
end
it "skips builds creation if there is [ci skip] tag in commit message" do
commits = [{ message: message }]
commit = service.execute(project, user,
pipeline = service.execute(project, user,
ref: 'refs/tags/0_1',
before: '00000000',
after: '31das312',
commits: commits
)
expect(commit).to be_persisted
expect(commit.builds.any?).to be false
expect(commit.status).to eq("skipped")
expect(pipeline).to be_persisted
expect(pipeline.builds.any?).to be false
expect(pipeline.status).to eq("skipped")
end
it "does not skips builds creation if there is no [ci skip] tag in commit message" do
allow_any_instance_of(Ci::Commit).to receive(:git_commit_message) { "some message" }
allow_any_instance_of(Ci::Pipeline).to receive(:git_commit_message) { "some message" }
commits = [{ message: "some message" }]
commit = service.execute(project, user,
pipeline = service.execute(project, user,
ref: 'refs/tags/0_1',
before: '00000000',
after: '31das312',
commits: commits
)
expect(commit).to be_persisted
expect(commit.builds.first.name).to eq("staging")
expect(pipeline).to be_persisted
expect(pipeline.builds.first.name).to eq("staging")
end
it "skips builds creation if there is [ci skip] tag in commit message and yaml is invalid" do
stub_ci_commit_yaml_file('invalid: file: fiile')
stub_ci_pipeline_yaml_file('invalid: file: fiile')
commits = [{ message: message }]
commit = service.execute(project, user,
pipeline = service.execute(project, user,
ref: 'refs/tags/0_1',
before: '00000000',
after: '31das312',
commits: commits
)
expect(commit).to be_persisted
expect(commit.builds.any?).to be false
expect(commit.status).to eq("skipped")
expect(commit.yaml_errors).to be_nil
expect(pipeline).to be_persisted
expect(pipeline.builds.any?).to be false
expect(pipeline.status).to eq("skipped")
expect(pipeline.yaml_errors).to be_nil
end
end
it "skips build creation if there are already builds" do
allow_any_instance_of(Ci::Commit).to receive(:ci_yaml_file) { gitlab_ci_yaml }
allow_any_instance_of(Ci::Pipeline).to receive(:ci_yaml_file) { gitlab_ci_yaml }
commits = [{ message: "message" }]
commit = service.execute(project, user,
pipeline = service.execute(project, user,
ref: 'refs/heads/master',
before: '00000000',
after: '31das312',
commits: commits
)
expect(commit).to be_persisted
expect(commit.builds.count(:all)).to eq(2)
expect(pipeline).to be_persisted
expect(pipeline.builds.count(:all)).to eq(2)
commit = service.execute(project, user,
pipeline = service.execute(project, user,
ref: 'refs/heads/master',
before: '00000000',
after: '31das312',
commits: commits
)
expect(commit).to be_persisted
expect(commit.builds.count(:all)).to eq(2)
expect(pipeline).to be_persisted
expect(pipeline.builds.count(:all)).to eq(2)
end
it "creates commit with failed status if yaml is invalid" do
stub_ci_commit_yaml_file('invalid: file')
stub_ci_pipeline_yaml_file('invalid: file')
commits = [{ message: "some message" }]
commit = service.execute(project, user,
pipeline = service.execute(project, user,
ref: 'refs/tags/0_1',
before: '00000000',
after: '31das312',
commits: commits
)
expect(commit).to be_persisted
expect(commit.status).to eq("failed")
expect(commit.builds.any?).to be false
expect(pipeline).to be_persisted
expect(pipeline.status).to eq("failed")
expect(pipeline.builds.any?).to be false
end
end
end
......@@ -6,7 +6,7 @@ describe MergeRequests::AddTodoWhenBuildFailsService do
let(:merge_request) { create(:merge_request) }
let(:project) { create(:project) }
let(:sha) { '1234567890abcdef1234567890abcdef12345678' }
let(:ci_commit) { create(:ci_commit_with_one_job, ref: merge_request.source_branch, project: project, sha: sha) }
let(:pipeline) { create(:ci_pipeline_with_one_job, ref: merge_request.source_branch, project: project, sha: sha) }
let(:service) { MergeRequests::AddTodoWhenBuildFailsService.new(project, user, commit_message: 'Awesome message') }
let(:todo_service) { TodoService.new }
......@@ -17,13 +17,13 @@ describe MergeRequests::AddTodoWhenBuildFailsService do
end
before do
allow_any_instance_of(MergeRequest).to receive(:ci_commit).and_return(ci_commit)
allow_any_instance_of(MergeRequest).to receive(:pipeline).and_return(pipeline)
allow(service).to receive(:todo_service).and_return(todo_service)
end
describe '#execute' do
context 'commit status with ref' do
let(:commit_status) { create(:generic_commit_status, ref: merge_request.source_branch, commit: ci_commit) }
let(:commit_status) { create(:generic_commit_status, ref: merge_request.source_branch, pipeline: pipeline) }
it 'notifies the todo service' do
expect(todo_service).to receive(:merge_request_build_failed).with(merge_request)
......@@ -52,7 +52,7 @@ describe MergeRequests::AddTodoWhenBuildFailsService do
describe '#close' do
context 'commit status with ref' do
let(:commit_status) { create(:generic_commit_status, ref: merge_request.source_branch, commit: ci_commit) }
let(:commit_status) { create(:generic_commit_status, ref: merge_request.source_branch, pipeline: pipeline) }
it 'notifies the todo service' do
expect(todo_service).to receive(:merge_request_build_retried).with(merge_request)
......
......@@ -10,7 +10,7 @@ describe MergeRequests::MergeWhenBuildSucceedsService do
source_project: project, target_project: project, state: "opened")
end
let(:ci_commit) { create(:ci_commit_with_one_job, ref: mr_merge_if_green_enabled.source_branch, project: project) }
let(:pipeline) { create(:ci_pipeline_with_one_job, ref: mr_merge_if_green_enabled.source_branch, project: project) }
let(:service) { MergeRequests::MergeWhenBuildSucceedsService.new(project, user, commit_message: 'Awesome message') }
describe "#execute" do
......@@ -21,7 +21,7 @@ describe MergeRequests::MergeWhenBuildSucceedsService do
context 'first time enabling' do
before do
allow(merge_request).to receive(:ci_commit).and_return(ci_commit)
allow(merge_request).to receive(:pipeline).and_return(pipeline)
service.execute(merge_request)
end
......@@ -43,9 +43,9 @@ describe MergeRequests::MergeWhenBuildSucceedsService do
let(:build) { create(:ci_build, ref: mr_merge_if_green_enabled.source_branch) }
before do
allow(mr_merge_if_green_enabled).to receive(:ci_commit).and_return(ci_commit)
allow(mr_merge_if_green_enabled).to receive(:pipeline).and_return(pipeline)
allow(mr_merge_if_green_enabled).to receive(:mergeable?).and_return(true)
allow(ci_commit).to receive(:success?).and_return(true)
allow(pipeline).to receive(:success?).and_return(true)
end
it 'updates the merge params' do
......@@ -62,8 +62,8 @@ describe MergeRequests::MergeWhenBuildSucceedsService do
let(:build) { create(:ci_build, ref: mr_merge_if_green_enabled.source_branch, status: "success") }
it "merges all merge requests with merge when build succeeds enabled" do
allow_any_instance_of(MergeRequest).to receive(:ci_commit).and_return(ci_commit)
allow(ci_commit).to receive(:success?).and_return(true)
allow_any_instance_of(MergeRequest).to receive(:pipeline).and_return(pipeline)
allow(pipeline).to receive(:success?).and_return(true)
expect(MergeWorker).to receive(:perform_async)
service.trigger(build)
......@@ -75,8 +75,8 @@ describe MergeRequests::MergeWhenBuildSucceedsService do
let(:build) { create(:ci_build, ref: mr_merge_if_green_enabled.source_branch, status: "success") }
it "merges all merge requests with merge when build succeeds enabled" do
allow_any_instance_of(MergeRequest).to receive(:ci_commit).and_return(ci_commit)
allow(ci_commit).to receive(:success?).and_return(true)
allow_any_instance_of(MergeRequest).to receive(:pipeline).and_return(pipeline)
allow(pipeline).to receive(:success?).and_return(true)
allow(old_build).to receive(:sha).and_return('1234abcdef')
expect(MergeWorker).not_to receive(:perform_async)
......@@ -99,9 +99,9 @@ describe MergeRequests::MergeWhenBuildSucceedsService do
it 'discovers branches and merges all merge requests when status is success' do
allow(project.repository).to receive(:branch_names_contains).
with(commit_status.sha).and_return([mr_merge_if_green_enabled.source_branch])
allow(ci_commit).to receive(:success?).and_return(true)
allow_any_instance_of(MergeRequest).to receive(:ci_commit).and_return(ci_commit)
allow(ci_commit).to receive(:success?).and_return(true)
allow(pipeline).to receive(:success?).and_return(true)
allow_any_instance_of(MergeRequest).to receive(:pipeline).and_return(pipeline)
allow(pipeline).to receive(:success?).and_return(true)
expect(MergeWorker).to receive(:perform_async)
service.trigger(commit_status)
......@@ -110,17 +110,17 @@ describe MergeRequests::MergeWhenBuildSucceedsService do
context 'properly handles multiple stages' do
let(:ref) { mr_merge_if_green_enabled.source_branch }
let(:build) { create(:ci_build, commit: ci_commit, ref: ref, name: 'build', stage: 'build') }
let(:test) { create(:ci_build, commit: ci_commit, ref: ref, name: 'test', stage: 'test') }
let(:build) { create(:ci_build, pipeline: pipeline, ref: ref, name: 'build', stage: 'build') }
let(:test) { create(:ci_build, pipeline: pipeline, ref: ref, name: 'test', stage: 'test') }
before do
# This behavior of MergeRequest: we instantiate a new object
allow_any_instance_of(MergeRequest).to receive(:ci_commit).and_wrap_original do
Ci::Commit.find(ci_commit.id)
allow_any_instance_of(MergeRequest).to receive(:pipeline).and_wrap_original do
Ci::Pipeline.find(pipeline.id)
end
# We create test after the build
allow(ci_commit).to receive(:create_next_builds).and_wrap_original do
allow(pipeline).to receive(:create_next_builds).and_wrap_original do
test
end
end
......
......@@ -2,8 +2,8 @@ require "spec_helper"
describe Projects::UpdatePagesService do
let(:project) { create :project }
let(:commit) { create :ci_commit, project: project, sha: project.commit('HEAD').sha }
let(:build) { create :ci_build, commit: commit, ref: 'HEAD' }
let(:pipeline) { create :ci_pipeline, project: project, sha: project.commit('HEAD').sha }
let(:build) { create :ci_build, pipeline: pipeline, ref: 'HEAD' }
let(:invalid_file) { fixture_file_upload(Rails.root + 'spec/fixtures/dk.png') }
subject { described_class.new(project, build) }
......@@ -47,7 +47,7 @@ describe Projects::UpdatePagesService do
end
it 'fails if sha on branch is not latest' do
commit.update_attributes(sha: 'old_sha')
pipeline.update_attributes(sha: 'old_sha')
build.update_attributes(artifacts_file: file)
expect(execute).not_to eq(:success)
end
......
......@@ -208,7 +208,7 @@ describe SystemNoteService, services: true do
end
describe '.merge_when_build_succeeds' do
let(:ci_commit) { build(:ci_commit_without_jobs )}
let(:pipeline) { build(:ci_pipeline_without_jobs )}
let(:noteable) do
create(:merge_request, source_project: project, target_project: project)
end
......@@ -223,7 +223,6 @@ describe SystemNoteService, services: true do
end
describe '.cancel_merge_when_build_succeeds' do
let(:ci_commit) { build(:ci_commit_without_jobs) }
let(:noteable) do
create(:merge_request, source_project: project, target_project: project)
end
......
......@@ -13,12 +13,12 @@ module StubGitlabCalls
allow_any_instance_of(Network).to receive(:projects) { project_hash_array }
end
def stub_ci_commit_to_return_yaml_file
stub_ci_commit_yaml_file(gitlab_ci_yaml)
def stub_ci_pipeline_to_return_yaml_file
stub_ci_pipeline_yaml_file(gitlab_ci_yaml)
end
def stub_ci_commit_yaml_file(ci_yaml)
allow_any_instance_of(Ci::Commit).to receive(:ci_yaml_file) { ci_yaml }
def stub_ci_pipeline_yaml_file(ci_yaml)
allow_any_instance_of(Ci::Pipeline).to receive(:ci_yaml_file) { ci_yaml }
end
def stub_ci_builds_disabled
......
......@@ -52,16 +52,16 @@ describe PostReceive do
context "gitlab-ci.yml" do
subject { PostReceive.new.perform(pwd(project), key_id, base64_changes) }
context "creates a Ci::Commit for every change" do
before { stub_ci_commit_to_return_yaml_file }
context "creates a Ci::Pipeline for every change" do
before { stub_ci_pipeline_to_return_yaml_file }
it { expect{ subject }.to change{ Ci::Commit.count }.by(2) }
it { expect{ subject }.to change{ Ci::Pipeline.count }.by(2) }
end
context "does not create a Ci::Commit" do
before { stub_ci_commit_yaml_file(nil) }
context "does not create a Ci::Pipeline" do
before { stub_ci_pipeline_yaml_file(nil) }
it { expect{ subject }.not_to change{ Ci::Commit.count } }
it { expect{ subject }.not_to change{ Ci::Pipeline.count } }
end
end
end
......
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