From 546a3c6561fbe967cc37ccc3229b71893cd20c34 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Fri, 2 Oct 2015 13:46:38 +0200 Subject: Refactor commit and build --- app/controllers/ci/builds_controller.rb | 2 +- app/controllers/ci/commits_controller.rb | 6 +- app/controllers/ci/projects_controller.rb | 3 +- app/helpers/ci/commits_helper.rb | 2 +- app/helpers/ci/gitlab_helper.rb | 2 +- app/helpers/ci_status_helper.rb | 2 +- app/models/ci/build.rb | 16 +++ app/models/ci/commit.rb | 137 +++++++-------------- app/models/ci/project_status.rb | 12 -- app/models/project.rb | 6 +- app/models/project_services/ci/hip_chat_message.rb | 2 +- app/models/project_services/ci/mail_service.rb | 2 +- app/models/project_services/ci/slack_message.rb | 2 +- app/models/project_services/gitlab_ci_service.rb | 4 +- app/services/ci/create_builds_service.rb | 27 ++++ app/services/ci/create_commit_service.rb | 39 +++--- app/services/ci/create_trigger_request_service.rb | 6 +- app/views/ci/builds/_build.html.haml | 4 + app/views/ci/builds/show.html.haml | 6 +- app/views/ci/commits/_commit.html.haml | 4 +- app/views/ci/commits/show.html.haml | 57 +++++---- app/views/ci/notify/build_fail_email.html.haml | 2 +- app/views/ci/notify/build_fail_email.text.erb | 2 +- app/views/ci/notify/build_success_email.html.haml | 2 +- app/views/ci/notify/build_success_email.text.erb | 2 +- config/routes.rb | 10 +- .../20151002112914_add_stage_idx_to_builds.rb | 5 + .../20151002121400_add_index_for_build_name.rb | 5 + .../20151002122929_add_sha_and_ref_to_builds.rb | 7 ++ .../20151002122943_migrate_sha_and_ref_to_build.rb | 7 ++ lib/ci/gitlab_ci_yaml_processor.rb | 1 + spec/requests/ci/commits_spec.rb | 2 +- 32 files changed, 193 insertions(+), 193 deletions(-) create mode 100644 app/services/ci/create_builds_service.rb create mode 100644 db/migrate/20151002112914_add_stage_idx_to_builds.rb create mode 100644 db/migrate/20151002121400_add_index_for_build_name.rb create mode 100644 db/migrate/20151002122929_add_sha_and_ref_to_builds.rb create mode 100644 db/migrate/20151002122943_migrate_sha_and_ref_to_build.rb diff --git a/app/controllers/ci/builds_controller.rb b/app/controllers/ci/builds_controller.rb index 80ee8666792..bf87f81439a 100644 --- a/app/controllers/ci/builds_controller.rb +++ b/app/controllers/ci/builds_controller.rb @@ -18,7 +18,7 @@ module Ci if commit # Redirect to commit page - redirect_to ci_project_ref_commit_path(@project, @build.commit.ref, @build.commit.sha) + redirect_to ci_project_commit_path(@project, @build.commit) return end end diff --git a/app/controllers/ci/commits_controller.rb b/app/controllers/ci/commits_controller.rb index 7a0a500fbe6..acf9189572c 100644 --- a/app/controllers/ci/commits_controller.rb +++ b/app/controllers/ci/commits_controller.rb @@ -13,7 +13,7 @@ module Ci end def status - commit = Ci::Project.find(params[:project_id]).commits.find_by_sha_and_ref!(params[:id], params[:ref_id]) + commit = Ci::Project.find(params[:project_id]).commits.find_by_sha!(params[:id], params[:ref_id]) render json: commit.to_json(only: [:id, :sha], methods: [:status, :coverage]) rescue ActiveRecord::RecordNotFound render json: { status: "not_found" } @@ -22,7 +22,7 @@ module Ci def cancel commit.builds.running_or_pending.each(&:cancel) - redirect_to ci_project_ref_commits_path(project, commit.ref, commit.sha) + redirect_to ci_project_commits_path(project, commit.sha) end private @@ -32,7 +32,7 @@ module Ci end def commit - @commit ||= Ci::Project.find(params[:project_id]).commits.find_by_sha_and_ref!(params[:id], params[:ref_id]) + @commit ||= Ci::Project.find(params[:project_id]).commits.find_by_sha!(params[:id]) end end end diff --git a/app/controllers/ci/projects_controller.rb b/app/controllers/ci/projects_controller.rb index e8788955eba..20e6c2c2ba7 100644 --- a/app/controllers/ci/projects_controller.rb +++ b/app/controllers/ci/projects_controller.rb @@ -19,7 +19,8 @@ module Ci @ref = params[:ref] @commits = @project.commits.reverse_order - @commits = @commits.where(ref: @ref) if @ref + # TODO: this is broken + # @commits = @commits.where(ref: @ref) if @ref @commits = @commits.page(params[:page]).per(20) end diff --git a/app/helpers/ci/commits_helper.rb b/app/helpers/ci/commits_helper.rb index 9069aed5b4d..a0df4c3d72d 100644 --- a/app/helpers/ci/commits_helper.rb +++ b/app/helpers/ci/commits_helper.rb @@ -1,7 +1,7 @@ module Ci module CommitsHelper def ci_commit_path(commit) - ci_project_ref_commits_path(commit.project, commit.ref, commit.sha) + ci_project_commits_path(commit.project, commit) end def commit_link(commit) diff --git a/app/helpers/ci/gitlab_helper.rb b/app/helpers/ci/gitlab_helper.rb index 13e4d0fd9c3..baddbc806f2 100644 --- a/app/helpers/ci/gitlab_helper.rb +++ b/app/helpers/ci/gitlab_helper.rb @@ -26,7 +26,7 @@ module Ci def yaml_web_editor_link(project) commits = project.commits - if commits.any? && commits.last.push_data[:ci_yaml_file] + if commits.any? && commits.last.ci_yaml_file "#{project.gitlab_url}/edit/master/.gitlab-ci.yml" else "#{project.gitlab_url}/new/master" diff --git a/app/helpers/ci_status_helper.rb b/app/helpers/ci_status_helper.rb index 3a88ed7107e..794bdc2530e 100644 --- a/app/helpers/ci_status_helper.rb +++ b/app/helpers/ci_status_helper.rb @@ -1,6 +1,6 @@ module CiStatusHelper def ci_status_path(ci_commit) - ci_project_ref_commits_path(ci_commit.project, ci_commit.ref, ci_commit) + ci_project_commits_path(ci_commit.project, ci_commit) end def ci_status_icon(ci_commit) diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 645ad68e1b3..bf3e8915205 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -34,10 +34,12 @@ module Ci belongs_to :trigger_request, class_name: 'Ci::TriggerRequest' serialize :options + serialize :push_data validates :commit, presence: true validates :status, presence: true validates :coverage, numericality: true, allow_blank: true + validates_presence_of :ref scope :running, ->() { where(status: "running") } scope :pending, ->() { where(status: "pending") } @@ -45,6 +47,9 @@ module Ci scope :failed, ->() { where(status: "failed") } scope :unstarted, ->() { where(runner_id: nil) } scope :running_or_pending, ->() { where(status:[:running, :pending]) } + scope :latest, ->() { group(:name).order(stage_idx: :asc, created_at: :desc) } + scope :ignore_failures, ->() { where(allow_failure: false) } + scope :for_ref, ->(ref) { where(ref: ref) } acts_as_taggable @@ -82,6 +87,7 @@ module Ci new_build.name = build.name new_build.allow_failure = build.allow_failure new_build.stage = build.stage + new_build.stage_idx = build.stage_idx new_build.trigger_request = build.trigger_request new_build.save new_build @@ -187,6 +193,16 @@ module Ci project.name end + def project_recipients + recipients = project.email_recipients.split(' ') + + if project.email_add_pusher? && push_data[:user_email].present? + recipients << push_data[:user_email] + end + + recipients.uniq + end + def repo_url project.repo_url_with_auth end diff --git a/app/models/ci/commit.rb b/app/models/ci/commit.rb index 6d048779cde..35134b6628e 100644 --- a/app/models/ci/commit.rb +++ b/app/models/ci/commit.rb @@ -23,9 +23,7 @@ module Ci has_many :builds, dependent: :destroy, class_name: 'Ci::Build' has_many :trigger_requests, dependent: :destroy, class_name: 'Ci::TriggerRequest' - serialize :push_data - - validates_presence_of :ref, :sha, :before_sha, :push_data + validates_presence_of :sha validate :valid_commit_sha def self.truncate_sha(sha) @@ -69,15 +67,15 @@ module Ci end def git_author_name - commit_data[:author][:name] if commit_data && commit_data[:author] + commit_data.author_name if commit_data end def git_author_email - commit_data[:author][:email] if commit_data && commit_data[:author] + commit_data.author_email if commit_data end def git_commit_message - commit_data[:message] if commit_data && commit_data[:message] + commit_data.message if commit_data end def short_before_sha @@ -89,84 +87,31 @@ module Ci end def commit_data - push_data[:commits].find do |commit| - commit[:id] == sha - end + @commit ||= gl_project.commit(sha) rescue nil end - def project_recipients - recipients = project.email_recipients.split(' ') - - if project.email_add_pusher? && push_data[:user_email].present? - recipients << push_data[:user_email] - end - - recipients.uniq - end - def stage - return unless config_processor - stages = builds_without_retry.select(&:active?).map(&:stage) - config_processor.stages.find { |stage| stages.include? stage } + builds_without_retry.group(:stage_idx).select(:stage).last end - def create_builds_for_stage(stage, trigger_request) + def create_builds(ref, tag, push_data, trigger_request = nil) return if skip_ci? && trigger_request.blank? return unless config_processor - - builds_attrs = config_processor.builds_for_stage_and_ref(stage, ref, tag) - builds_attrs.map do |build_attrs| - builds.create!({ - name: build_attrs[:name], - commands: build_attrs[:script], - tag_list: build_attrs[:tags], - options: build_attrs[:options], - allow_failure: build_attrs[:allow_failure], - stage: build_attrs[:stage], - trigger_request: trigger_request, - }) - end + CreateBuildsService.new.execute(self, config_processor, ref, tag, push_data, trigger_request) end - def create_next_builds(trigger_request) - return if skip_ci? && trigger_request.blank? - return unless config_processor - - stages = builds.where(trigger_request: trigger_request).group_by(&:stage) - - config_processor.stages.any? do |stage| - !stages.include?(stage) && create_builds_for_stage(stage, trigger_request).present? - end + def refs + builds.group(:ref).pluck(:ref) end - def create_builds(trigger_request = nil) - return if skip_ci? && trigger_request.blank? - return unless config_processor - - config_processor.stages.any? do |stage| - create_builds_for_stage(stage, trigger_request).present? - end + def last_ref + builds.latest.first.try(:ref) end def builds_without_retry - @builds_without_retry ||= - begin - grouped_builds = builds.group_by(&:name) - grouped_builds.map do |name, builds| - builds.sort_by(&:id).last - end - end - end - - def builds_without_retry_sorted - return builds_without_retry unless config_processor - - stages = config_processor.stages - builds_without_retry.sort_by do |build| - [stages.index(build.stage) || -1, build.name || ""] - end + builds.latest end def retried_builds @@ -180,35 +125,32 @@ module Ci return 'failed' elsif builds.none? return 'skipped' - elsif success? - 'success' - elsif pending? - 'pending' - elsif running? - 'running' - elsif canceled? - 'canceled' + end + + statuses = builds_without_retry.ignore_failures.pluck(:status) + if statuses.all? { |status| status == 'success' } + return 'success' + elsif statuses.all? { |status| status == 'pending' } + return 'pending' + elsif statuses.include?('running') || statuses.include?('pending') + return 'running' + elsif statuses.all? { |status| status == 'canceled' } + return 'canceled' else - 'failed' + return 'failed' end end def pending? - builds_without_retry.all? do |build| - build.pending? - end + status == 'pending' end def running? - builds_without_retry.any? do |build| - build.running? || build.pending? - end + status == 'running' end def success? - builds_without_retry.all? do |build| - build.success? || build.ignored? - end + status == 'success' end def failed? @@ -216,15 +158,17 @@ module Ci end def canceled? - builds_without_retry.all? do |build| - build.canceled? - end + status == 'canceled' end def duration @duration ||= builds_without_retry.select(&:duration).sum(&:duration).to_i end + def duration_for_ref(ref) + builds_without_retry.for_ref(ref).select(&:duration).sum(&:duration).to_i + end + def finished_at @finished_at ||= builds.order('finished_at DESC').first.try(:finished_at) end @@ -238,12 +182,12 @@ module Ci end end - def matrix? - builds_without_retry.size > 1 + def matrix_for_ref?(ref) + builds_without_retry.for_ref(ref).pluck(:id).size > 1 end def config_processor - @config_processor ||= Ci::GitlabCiYamlProcessor.new(push_data[:ci_yaml_file]) + @config_processor ||= Ci::GitlabCiYamlProcessor.new(ci_yaml_file) rescue Ci::GitlabCiYamlProcessor::ValidationError => e save_yaml_error(e.message) nil @@ -253,10 +197,15 @@ module Ci nil end + def ci_yaml_file + gl_project.repository.blob_at(sha, '.gitlab-ci.yml') + rescue + nil + end + def skip_ci? return false if builds.any? - commits = push_data[:commits] - commits.present? && commits.last[:message] =~ /(\[ci skip\])/ + git_commit_message =~ /(\[ci skip\])/ if git_commit_message end def update_committed! diff --git a/app/models/ci/project_status.rb b/app/models/ci/project_status.rb index 6d5cafe81a2..b66f1212f23 100644 --- a/app/models/ci/project_status.rb +++ b/app/models/ci/project_status.rb @@ -28,18 +28,6 @@ module Ci status end - # only check for toggling build status within same ref. - def last_commit_changed_status? - ref = last_commit.ref - last_commits = commits.where(ref: ref).last(2) - - if last_commits.size < 2 - false - else - last_commits[0].status != last_commits[1].status - end - end - def last_commit_for_ref(ref) commits.where(ref: ref).last end diff --git a/app/models/project.rb b/app/models/project.rb index b90a82da9f2..bb47b9abb03 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -744,7 +744,11 @@ class Project < ActiveRecord::Base end def ci_commit(sha) - gitlab_ci_project.commits.find_by(sha: sha) if gitlab_ci? + ci_commits.find_by(sha: sha) + end + + def ensure_ci_commit(sha) + ci_commit(sha) || ci_commits.create(sha: sha) end def ensure_gitlab_ci_project diff --git a/app/models/project_services/ci/hip_chat_message.rb b/app/models/project_services/ci/hip_chat_message.rb index 25c72033eac..73fdbe801c0 100644 --- a/app/models/project_services/ci/hip_chat_message.rb +++ b/app/models/project_services/ci/hip_chat_message.rb @@ -13,7 +13,7 @@ module Ci lines.push("#{project.name} - ") if commit.matrix? - lines.push("Commit ##{commit.id}
") + lines.push("Commit ##{commit.id}
") else first_build = commit.builds_without_retry.first lines.push("Build '#{first_build.name}' ##{first_build.id}
") diff --git a/app/models/project_services/ci/mail_service.rb b/app/models/project_services/ci/mail_service.rb index 1bd2f33612b..11a2743f969 100644 --- a/app/models/project_services/ci/mail_service.rb +++ b/app/models/project_services/ci/mail_service.rb @@ -61,7 +61,7 @@ module Ci end def execute(build) - build.commit.project_recipients.each do |recipient| + build.project_recipients.each do |recipient| case build.status.to_sym when :success mailer.build_success_email(build.id, recipient) diff --git a/app/models/project_services/ci/slack_message.rb b/app/models/project_services/ci/slack_message.rb index 757b1961143..7d254836fb5 100644 --- a/app/models/project_services/ci/slack_message.rb +++ b/app/models/project_services/ci/slack_message.rb @@ -48,7 +48,7 @@ module Ci def attachment_message out = "<#{ci_project_url(project)}|#{project_name}>: " if commit.matrix? - out << "Commit <#{ci_project_ref_commits_url(project, commit.ref, commit.sha)}|\##{commit.id}> " + out << "Commit <#{ci_project_commits_url(project, commit.sha)}|\##{commit.id}> " else build = commit.builds_without_retry.first out << "Build <#{ci_project_build_url(project, build)}|\##{build.id}> " diff --git a/app/models/project_services/gitlab_ci_service.rb b/app/models/project_services/gitlab_ci_service.rb index 6d2cf79b691..fd108516530 100644 --- a/app/models/project_services/gitlab_ci_service.rb +++ b/app/models/project_services/gitlab_ci_service.rb @@ -63,7 +63,7 @@ class GitlabCiService < CiService end def get_ci_commit(sha, ref) - Ci::Project.find(project.gitlab_ci_project).commits.find_by_sha_and_ref!(sha, ref) + Ci::Project.find(project.gitlab_ci_project).commits.find_by_sha!(sha) end def commit_status(sha, ref) @@ -80,7 +80,7 @@ class GitlabCiService < CiService def build_page(sha, ref) if project.gitlab_ci_project.present? - ci_project_ref_commits_url(project.gitlab_ci_project, ref, sha) + ci_project_commits_url(project.gitlab_ci_project, sha) end end diff --git a/app/services/ci/create_builds_service.rb b/app/services/ci/create_builds_service.rb new file mode 100644 index 00000000000..e9c85410e5c --- /dev/null +++ b/app/services/ci/create_builds_service.rb @@ -0,0 +1,27 @@ +module Ci + class CreateBuildsService + def execute(commit, ref, tag, push_data, config_processor, trigger_request) + config_processor.stages.any? do |stage| + builds_attrs = config_processor.builds_for_stage_and_ref(stage, ref, tag) + builds_attrs.map do |build_attrs| + # don't create the same build twice + unless commit.builds.find_by_name_and_trigger_request(name: build_attrs[:name], ref: ref, tag: tag, trigger_request: trigger_request) + commit.builds.create!({ + name: build_attrs[:name], + commands: build_attrs[:script], + tag_list: build_attrs[:tags], + options: build_attrs[:options], + allow_failure: build_attrs[:allow_failure], + stage: build_attrs[:stage], + stage_idx: build_attrs[:stage_idx], + trigger_request: trigger_request, + ref: ref, + tag: tag, + push_data: push_data, + }) + end + end + end + end + end +end diff --git a/app/services/ci/create_commit_service.rb b/app/services/ci/create_commit_service.rb index 0a1abf89a95..9120a82edcd 100644 --- a/app/services/ci/create_commit_service.rb +++ b/app/services/ci/create_commit_service.rb @@ -16,33 +16,22 @@ module Ci return false end - commit = project.commits.find_by_sha_and_ref(sha, ref) - - # Create commit if not exists yet - unless commit - data = { - ref: ref, - sha: sha, - tag: origin_ref.start_with?('refs/tags/'), - before_sha: before_sha, - push_data: { - before: before_sha, - after: sha, - ref: ref, - user_name: params[:user_name], - user_email: params[:user_email], - repository: params[:repository], - commits: params[:commits], - total_commits_count: params[:total_commits_count], - ci_yaml_file: params[:ci_yaml_file] - } - } - - commit = project.commits.create(data) - end + tag = origin_ref.start_with?('refs/tags/') + push_data = { + before: before_sha, + after: sha, + ref: ref, + user_name: params[:user_name], + user_email: params[:user_email], + repository: params[:repository], + commits: params[:commits], + total_commits_count: params[:total_commits_count], + ci_yaml_file: params[:ci_yaml_file] + } + commit = project.gl_project.ensure_ci_commit(sha) commit.update_committed! - commit.create_builds unless commit.builds.any? + commit.create_builds(ref, tag, push_data) commit end diff --git a/app/services/ci/create_trigger_request_service.rb b/app/services/ci/create_trigger_request_service.rb index 9bad09f2f54..f13ed787ed2 100644 --- a/app/services/ci/create_trigger_request_service.rb +++ b/app/services/ci/create_trigger_request_service.rb @@ -1,15 +1,15 @@ module Ci class CreateTriggerRequestService def execute(project, trigger, ref, variables = nil) - commit = project.commits.where(ref: ref).last + commit = project.gl_project.commit(ref) return unless commit + ci_commit = project.gl_project.ensure_ci_commit(commit.sha) trigger_request = trigger.trigger_requests.create!( - commit: commit, variables: variables ) - if commit.create_builds(trigger_request) + if ci_commit.create_builds(ref, tag, nil, trigger_request) trigger_request end end diff --git a/app/views/ci/builds/_build.html.haml b/app/views/ci/builds/_build.html.haml index 515b862e992..8ccc0dff2fb 100644 --- a/app/views/ci/builds/_build.html.haml +++ b/app/views/ci/builds/_build.html.haml @@ -6,6 +6,10 @@ = link_to ci_project_build_path(build.project, build) do %strong Build ##{build.id} + - if defined?(ref) + %td + = build.ref + %td = build.stage diff --git a/app/views/ci/builds/show.html.haml b/app/views/ci/builds/show.html.haml index 839dbf5c554..f941143e2e0 100644 --- a/app/views/ci/builds/show.html.haml +++ b/app/views/ci/builds/show.html.haml @@ -1,7 +1,7 @@ #up-build-trace -- if @commit.matrix? +- if @commit.matrix_for_ref?(@build.ref) %ul.center-top-menu - - @commit.builds_without_retry_sorted.each do |build| + - @commit.builds_without_retry.for_ref(build.ref).each do |build| %li{class: ('active' if build == @build) } = link_to ci_project_build_url(@project, build) do = ci_icon_for_status(build.status) @@ -12,7 +12,7 @@ = build.id - - unless @commit.builds_without_retry.include?(@build) + - unless @commit.builds_without_retry.for_ref(@build.ref).include?(@build) %li.active %a Build ##{@build.id} diff --git a/app/views/ci/commits/_commit.html.haml b/app/views/ci/commits/_commit.html.haml index 1eacfca944f..f8a1fa50851 100644 --- a/app/views/ci/commits/_commit.html.haml +++ b/app/views/ci/commits/_commit.html.haml @@ -7,7 +7,7 @@ %td.build-link - = link_to ci_project_ref_commits_path(commit.project, commit.ref, commit.sha) do + = link_to ci_project_commits_path(commit.project, commit.sha) do %strong #{commit.short_sha} %td.build-message @@ -16,7 +16,7 @@ %td.build-branch - unless @ref %span - = link_to truncate(commit.ref, length: 25), ci_project_path(@project, ref: commit.ref) + = link_to truncate(commit.last_ref, length: 25), ci_project_path(@project, ref: commit.last_ref) %td.duration - if commit.duration > 0 diff --git a/app/views/ci/commits/show.html.haml b/app/views/ci/commits/show.html.haml index 8f38aa84676..4badb671287 100644 --- a/app/views/ci/commits/show.html.haml +++ b/app/views/ci/commits/show.html.haml @@ -17,14 +17,11 @@ %p %span.attr-name Commit: #{gitlab_commit_link(@project, @commit.sha)} - - %p - %span.attr-name Branch: - #{gitlab_ref_link(@project, @commit.ref)} .col-sm-6 - %p - %span.attr-name Author: - #{@commit.git_author_name} (#{@commit.git_author_email}) + - if @commit.git_author_name || @commit.git_author_email + %p + %span.attr-name Author: + #{@commit.git_author_name} (#{@commit.git_author_email}) - if @commit.created_at %p %span.attr-name Created at: @@ -33,7 +30,7 @@ - if current_user && can?(current_user, :manage_builds, gl_project) .pull-right - if @commit.builds.running_or_pending.any? - = link_to "Cancel", cancel_ci_project_ref_commits_path(@project, @commit.ref, @commit.sha), class: 'btn btn-sm btn-danger' + = link_to "Cancel", cancel_ci_project_commits_path(@project, @commit), class: 'btn btn-sm btn-danger' - if @commit.yaml_errors.present? @@ -43,30 +40,31 @@ - @commit.yaml_errors.split(",").each do |error| %li= error -- unless @commit.push_data[:ci_yaml_file] +- unless @commit.ci_yaml_file .bs-callout.bs-callout-warning \.gitlab-ci.yml not found in this commit -%h3 - Builds - - if @commit.duration > 0 - %small.pull-right - %i.fa.fa-time - #{time_interval_in_words @commit.duration} +- @commit.refs.each do |ref| + %h3 + Builds for #{ref} + - if @commit.duration_for_ref(ref) > 0 + %small.pull-right + %i.fa.fa-time + #{time_interval_in_words @commit.duration_for_ref(ref)} -%table.table.builds - %thead - %tr - %th Status - %th Build ID - %th Stage - %th Name - %th Duration - %th Finished at - - if @project.coverage_enabled? - %th Coverage - %th - = render @commit.builds_without_retry_sorted, controls: true + %table.table.builds + %thead + %tr + %th Status + %th Build ID + %th Stage + %th Name + %th Duration + %th Finished at + - if @project.coverage_enabled? + %th Coverage + %th + = render @commit.builds_without_retry.for_ref(ref), controls: true - if @commit.retried_builds.any? %h3 @@ -77,6 +75,7 @@ %tr %th Status %th Build ID + %th Ref %th Stage %th Name %th Duration @@ -84,4 +83,4 @@ - if @project.coverage_enabled? %th Coverage %th - = render @commit.retried_builds + = render @commit.retried_builds, ref: true diff --git a/app/views/ci/notify/build_fail_email.html.haml b/app/views/ci/notify/build_fail_email.html.haml index d818e8b6756..4ebdfa1b6c0 100644 --- a/app/views/ci/notify/build_fail_email.html.haml +++ b/app/views/ci/notify/build_fail_email.html.haml @@ -11,7 +11,7 @@ %p Author: #{@build.commit.git_author_name} %p - Branch: #{@build.commit.ref} + Branch: #{@build.ref} %p Message: #{@build.commit.git_commit_message} diff --git a/app/views/ci/notify/build_fail_email.text.erb b/app/views/ci/notify/build_fail_email.text.erb index 1add215a1c8..177827f9a3c 100644 --- a/app/views/ci/notify/build_fail_email.text.erb +++ b/app/views/ci/notify/build_fail_email.text.erb @@ -3,7 +3,7 @@ Build failed for <%= @project.name %> Status: <%= @build.status %> Commit: <%= @build.commit.short_sha %> Author: <%= @build.commit.git_author_name %> -Branch: <%= @build.commit.ref %> +Branch: <%= @build.ref %> Message: <%= @build.commit.git_commit_message %> Url: <%= ci_project_build_url(@build.project, @build) %> diff --git a/app/views/ci/notify/build_success_email.html.haml b/app/views/ci/notify/build_success_email.html.haml index a20dcaee24e..7cc43300e88 100644 --- a/app/views/ci/notify/build_success_email.html.haml +++ b/app/views/ci/notify/build_success_email.html.haml @@ -12,7 +12,7 @@ %p Author: #{@build.commit.git_author_name} %p - Branch: #{@build.commit.ref} + Branch: #{@build.ref} %p Message: #{@build.commit.git_commit_message} diff --git a/app/views/ci/notify/build_success_email.text.erb b/app/views/ci/notify/build_success_email.text.erb index 7ebd17e7270..4d55c39b0fb 100644 --- a/app/views/ci/notify/build_success_email.text.erb +++ b/app/views/ci/notify/build_success_email.text.erb @@ -3,7 +3,7 @@ Build successful for <%= @project.name %> Status: <%= @build.status %> Commit: <%= @build.commit.short_sha %> Author: <%= @build.commit.git_author_name %> -Branch: <%= @build.commit.ref %> +Branch: <%= @build.ref %> Message: <%= @build.commit.git_commit_message %> Url: <%= ci_project_build_url(@build.project, @build) %> diff --git a/config/routes.rb b/config/routes.rb index 6d96d8801cd..56087e489f5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -30,12 +30,10 @@ Gitlab::Application.routes.draw do resource :charts, only: [:show] - resources :refs, constraints: { ref_id: /.*/ }, only: [] do - resources :commits, only: [:show] do - member do - get :status - get :cancel - end + resources :commits, only: [:show] do + member do + get :status + get :cancel end end diff --git a/db/migrate/20151002112914_add_stage_idx_to_builds.rb b/db/migrate/20151002112914_add_stage_idx_to_builds.rb new file mode 100644 index 00000000000..68a745ffef4 --- /dev/null +++ b/db/migrate/20151002112914_add_stage_idx_to_builds.rb @@ -0,0 +1,5 @@ +class AddStageIdxToBuilds < ActiveRecord::Migration + def change + add_column :ci_builds, :stage_idx, :integer + end +end diff --git a/db/migrate/20151002121400_add_index_for_build_name.rb b/db/migrate/20151002121400_add_index_for_build_name.rb new file mode 100644 index 00000000000..c6a81d74661 --- /dev/null +++ b/db/migrate/20151002121400_add_index_for_build_name.rb @@ -0,0 +1,5 @@ +class AddIndexForBuildName < ActiveRecord::Migration + def up + add_index :ci_builds, [:commit_id, :stage_idx, :created_at] + end +end diff --git a/db/migrate/20151002122929_add_sha_and_ref_to_builds.rb b/db/migrate/20151002122929_add_sha_and_ref_to_builds.rb new file mode 100644 index 00000000000..fc367341f1d --- /dev/null +++ b/db/migrate/20151002122929_add_sha_and_ref_to_builds.rb @@ -0,0 +1,7 @@ +class AddShaAndRefToBuilds < ActiveRecord::Migration + def change + add_column :ci_builds, :tag, :boolean + add_column :ci_builds, :ref, :string + add_column :ci_builds, :push_data, :text + end +end diff --git a/db/migrate/20151002122943_migrate_sha_and_ref_to_build.rb b/db/migrate/20151002122943_migrate_sha_and_ref_to_build.rb new file mode 100644 index 00000000000..b80808946d8 --- /dev/null +++ b/db/migrate/20151002122943_migrate_sha_and_ref_to_build.rb @@ -0,0 +1,7 @@ +class MigrateShaAndRefToBuild < ActiveRecord::Migration + def change + execute('UPDATE ci_builds SET ref=(SELECT ref FROM ci_commits WHERE ci_commits.id = ci_builds.commit_id) WHERE ref IS NULL') + execute('UPDATE ci_builds SET push_data=(SELECT push_data FROM ci_commits WHERE ci_commits.id = ci_builds.commit_id) WHERE push_data IS NULL') + execute('UPDATE ci_builds SET tag=(SELECT tag FROM ci_commits WHERE ci_commits.id = ci_builds.commit_id) WHERE tag IS NULL') + end +end diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb index e625e790df8..861da770d3c 100644 --- a/lib/ci/gitlab_ci_yaml_processor.rb +++ b/lib/ci/gitlab_ci_yaml_processor.rb @@ -85,6 +85,7 @@ module Ci def build_job(name, job) { + stage_idx: stages.index(job[:stage]), stage: job[:stage], script: "#{@before_script.join("\n")}\n#{normalize_script(job[:script])}", tags: job[:tags] || [], diff --git a/spec/requests/ci/commits_spec.rb b/spec/requests/ci/commits_spec.rb index 3ab8c915dfd..f43a3982d71 100644 --- a/spec/requests/ci/commits_spec.rb +++ b/spec/requests/ci/commits_spec.rb @@ -7,7 +7,7 @@ describe "Commits" do describe "GET /:project/refs/:ref_name/commits/:id/status.json" do before do - get status_ci_project_ref_commits_path(@commit.project, @commit.ref, @commit.sha), format: :json + get status_ci_project_commits_path(@commit.project, @commit.sha), format: :json end it { expect(response.status).to eq(200) } -- cgit v1.2.1 From e3d870d7fc282a1f0a1028996c8b44e5d32b9cbf Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Mon, 5 Oct 2015 10:14:33 +0200 Subject: Add user to Ci::Build to have pusher email address --- app/models/ci/build.rb | 6 ++-- app/models/ci/commit.rb | 4 +-- app/models/project_services/gitlab_ci_service.rb | 2 +- app/models/user.rb | 1 + app/services/ci/create_builds_service.rb | 4 +-- app/services/ci/create_commit_service.rb | 16 ++------- .../20151002121400_add_index_for_build_name.rb | 5 --- db/migrate/20151002121400_add_index_for_builds.rb | 5 +++ .../20151002122929_add_ref_and_tag_to_builds.rb | 6 ++++ .../20151002122929_add_sha_and_ref_to_builds.rb | 7 ---- .../20151002122943_migrate_ref_and_tag_to_build.rb | 6 ++++ .../20151002122943_migrate_sha_and_ref_to_build.rb | 7 ---- db/migrate/20151005075649_add_user_id_to_build.rb | 5 +++ lib/ci/api/commits.rb | 2 +- spec/factories/ci/builds.rb | 7 +++- spec/factories/ci/commits.rb | 40 ++-------------------- 16 files changed, 43 insertions(+), 80 deletions(-) delete mode 100644 db/migrate/20151002121400_add_index_for_build_name.rb create mode 100644 db/migrate/20151002121400_add_index_for_builds.rb create mode 100644 db/migrate/20151002122929_add_ref_and_tag_to_builds.rb delete mode 100644 db/migrate/20151002122929_add_sha_and_ref_to_builds.rb create mode 100644 db/migrate/20151002122943_migrate_ref_and_tag_to_build.rb delete mode 100644 db/migrate/20151002122943_migrate_sha_and_ref_to_build.rb create mode 100644 db/migrate/20151005075649_add_user_id_to_build.rb diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index bf3e8915205..bfdc1c7486e 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -32,9 +32,9 @@ module Ci belongs_to :commit, class_name: 'Ci::Commit' belongs_to :runner, class_name: 'Ci::Runner' belongs_to :trigger_request, class_name: 'Ci::TriggerRequest' + belongs_to :user serialize :options - serialize :push_data validates :commit, presence: true validates :status, presence: true @@ -196,8 +196,8 @@ module Ci def project_recipients recipients = project.email_recipients.split(' ') - if project.email_add_pusher? && push_data[:user_email].present? - recipients << push_data[:user_email] + if project.email_add_pusher? && user.present? && user.notification_email.present? + recipients << user.notification_email end recipients.uniq diff --git a/app/models/ci/commit.rb b/app/models/ci/commit.rb index 35134b6628e..3c577e3f081 100644 --- a/app/models/ci/commit.rb +++ b/app/models/ci/commit.rb @@ -96,10 +96,10 @@ module Ci builds_without_retry.group(:stage_idx).select(:stage).last end - def create_builds(ref, tag, push_data, trigger_request = nil) + def create_builds(ref, tag, user, trigger_request = nil) return if skip_ci? && trigger_request.blank? return unless config_processor - CreateBuildsService.new.execute(self, config_processor, ref, tag, push_data, trigger_request) + CreateBuildsService.new.execute(self, config_processor, ref, tag, user, trigger_request) end def refs diff --git a/app/models/project_services/gitlab_ci_service.rb b/app/models/project_services/gitlab_ci_service.rb index fd108516530..8e2b395494e 100644 --- a/app/models/project_services/gitlab_ci_service.rb +++ b/app/models/project_services/gitlab_ci_service.rb @@ -52,7 +52,7 @@ class GitlabCiService < CiService ci_project = Ci::Project.find_by(gitlab_id: project.id) if ci_project - Ci::CreateCommitService.new.execute(ci_project, data) + Ci::CreateCommitService.new.execute(ci_project, data, current_user) end end diff --git a/app/models/user.rb b/app/models/user.rb index 1069f8e3664..c7e3992b6a1 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -130,6 +130,7 @@ class User < ActiveRecord::Base has_many :assigned_merge_requests, dependent: :destroy, foreign_key: :assignee_id, class_name: "MergeRequest" has_many :oauth_applications, class_name: 'Doorkeeper::Application', as: :owner, dependent: :destroy has_one :abuse_report, dependent: :destroy + has_many :ci_builds, dependent: :nullify, class_name: 'Ci::Build' # diff --git a/app/services/ci/create_builds_service.rb b/app/services/ci/create_builds_service.rb index e9c85410e5c..77a4305071c 100644 --- a/app/services/ci/create_builds_service.rb +++ b/app/services/ci/create_builds_service.rb @@ -1,6 +1,6 @@ module Ci class CreateBuildsService - def execute(commit, ref, tag, push_data, config_processor, trigger_request) + def execute(commit, ref, tag, user, config_processor, trigger_request) config_processor.stages.any? do |stage| builds_attrs = config_processor.builds_for_stage_and_ref(stage, ref, tag) builds_attrs.map do |build_attrs| @@ -17,7 +17,7 @@ module Ci trigger_request: trigger_request, ref: ref, tag: tag, - push_data: push_data, + user: user, }) end end diff --git a/app/services/ci/create_commit_service.rb b/app/services/ci/create_commit_service.rb index 9120a82edcd..edbb07580c9 100644 --- a/app/services/ci/create_commit_service.rb +++ b/app/services/ci/create_commit_service.rb @@ -1,6 +1,6 @@ module Ci class CreateCommitService - def execute(project, params) + def execute(project, params, user) before_sha = params[:before] sha = params[:checkout_sha] || params[:after] origin_ref = params[:ref] @@ -17,21 +17,9 @@ module Ci end tag = origin_ref.start_with?('refs/tags/') - push_data = { - before: before_sha, - after: sha, - ref: ref, - user_name: params[:user_name], - user_email: params[:user_email], - repository: params[:repository], - commits: params[:commits], - total_commits_count: params[:total_commits_count], - ci_yaml_file: params[:ci_yaml_file] - } - commit = project.gl_project.ensure_ci_commit(sha) commit.update_committed! - commit.create_builds(ref, tag, push_data) + commit.create_builds(ref, tag, user) commit end diff --git a/db/migrate/20151002121400_add_index_for_build_name.rb b/db/migrate/20151002121400_add_index_for_build_name.rb deleted file mode 100644 index c6a81d74661..00000000000 --- a/db/migrate/20151002121400_add_index_for_build_name.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddIndexForBuildName < ActiveRecord::Migration - def up - add_index :ci_builds, [:commit_id, :stage_idx, :created_at] - end -end diff --git a/db/migrate/20151002121400_add_index_for_builds.rb b/db/migrate/20151002121400_add_index_for_builds.rb new file mode 100644 index 00000000000..4ffc1363910 --- /dev/null +++ b/db/migrate/20151002121400_add_index_for_builds.rb @@ -0,0 +1,5 @@ +class AddIndexForBuilds < ActiveRecord::Migration + def up + add_index :ci_builds, [:commit_id, :stage_idx, :created_at] + end +end diff --git a/db/migrate/20151002122929_add_ref_and_tag_to_builds.rb b/db/migrate/20151002122929_add_ref_and_tag_to_builds.rb new file mode 100644 index 00000000000..e3d2ac1cea5 --- /dev/null +++ b/db/migrate/20151002122929_add_ref_and_tag_to_builds.rb @@ -0,0 +1,6 @@ +class AddRefAndTagToBuilds < ActiveRecord::Migration + def change + add_column :ci_builds, :tag, :boolean + add_column :ci_builds, :ref, :string + end +end diff --git a/db/migrate/20151002122929_add_sha_and_ref_to_builds.rb b/db/migrate/20151002122929_add_sha_and_ref_to_builds.rb deleted file mode 100644 index fc367341f1d..00000000000 --- a/db/migrate/20151002122929_add_sha_and_ref_to_builds.rb +++ /dev/null @@ -1,7 +0,0 @@ -class AddShaAndRefToBuilds < ActiveRecord::Migration - def change - add_column :ci_builds, :tag, :boolean - add_column :ci_builds, :ref, :string - add_column :ci_builds, :push_data, :text - end -end diff --git a/db/migrate/20151002122943_migrate_ref_and_tag_to_build.rb b/db/migrate/20151002122943_migrate_ref_and_tag_to_build.rb new file mode 100644 index 00000000000..01d7b3f6773 --- /dev/null +++ b/db/migrate/20151002122943_migrate_ref_and_tag_to_build.rb @@ -0,0 +1,6 @@ +class MigrateRefAndTagToBuild < ActiveRecord::Migration + def change + execute('UPDATE ci_builds SET ref=(SELECT ref FROM ci_commits WHERE ci_commits.id = ci_builds.commit_id) WHERE ref IS NULL') + execute('UPDATE ci_builds SET tag=(SELECT tag FROM ci_commits WHERE ci_commits.id = ci_builds.commit_id) WHERE tag IS NULL') + end +end diff --git a/db/migrate/20151002122943_migrate_sha_and_ref_to_build.rb b/db/migrate/20151002122943_migrate_sha_and_ref_to_build.rb deleted file mode 100644 index b80808946d8..00000000000 --- a/db/migrate/20151002122943_migrate_sha_and_ref_to_build.rb +++ /dev/null @@ -1,7 +0,0 @@ -class MigrateShaAndRefToBuild < ActiveRecord::Migration - def change - execute('UPDATE ci_builds SET ref=(SELECT ref FROM ci_commits WHERE ci_commits.id = ci_builds.commit_id) WHERE ref IS NULL') - execute('UPDATE ci_builds SET push_data=(SELECT push_data FROM ci_commits WHERE ci_commits.id = ci_builds.commit_id) WHERE push_data IS NULL') - execute('UPDATE ci_builds SET tag=(SELECT tag FROM ci_commits WHERE ci_commits.id = ci_builds.commit_id) WHERE tag IS NULL') - end -end diff --git a/db/migrate/20151005075649_add_user_id_to_build.rb b/db/migrate/20151005075649_add_user_id_to_build.rb new file mode 100644 index 00000000000..0f4b92b8b79 --- /dev/null +++ b/db/migrate/20151005075649_add_user_id_to_build.rb @@ -0,0 +1,5 @@ +class AddUserIdToBuild < ActiveRecord::Migration + def change + add_column :ci_builds, :user_id, :integer + end +end diff --git a/lib/ci/api/commits.rb b/lib/ci/api/commits.rb index bac463a5909..6a5b52b17de 100644 --- a/lib/ci/api/commits.rb +++ b/lib/ci/api/commits.rb @@ -51,7 +51,7 @@ module Ci required_attributes! [:project_id, :data, :project_token] project = Ci::Project.find(params[:project_id]) authenticate_project_token!(project) - commit = Ci::CreateCommitService.new.execute(project, params[:data]) + commit = Ci::CreateCommitService.new.execute(project, params[:data], current_user) if commit.persisted? present commit, with: Entities::CommitWithBuilds diff --git a/spec/factories/ci/builds.rb b/spec/factories/ci/builds.rb index 99da5a18776..8e2496398a6 100644 --- a/spec/factories/ci/builds.rb +++ b/spec/factories/ci/builds.rb @@ -27,9 +27,10 @@ FactoryGirl.define do factory :ci_build, class: Ci::Build do + ref 'master' + tag false started_at 'Di 29. Okt 09:51:28 CET 2013' finished_at 'Di 29. Okt 09:53:28 CET 2013' - commands 'ls -a' options do { image: "ruby:2.1", @@ -43,5 +44,9 @@ FactoryGirl.define do started_at nil finished_at nil end + + factory :ci_build_tag do + tag true + end end end diff --git a/spec/factories/ci/commits.rb b/spec/factories/ci/commits.rb index 9c7a0e9cbe0..b74aae795aa 100644 --- a/spec/factories/ci/commits.rb +++ b/spec/factories/ci/commits.rb @@ -18,59 +18,25 @@ # Read about factories at https://github.com/thoughtbot/factory_girl FactoryGirl.define do factory :ci_commit, class: Ci::Commit do - ref 'master' - before_sha '76de212e80737a608d939f648d959671fb0a0142' sha '97de212e80737a608d939f648d959671fb0a0142' - push_data do - { - ref: 'refs/heads/master', - before: '76de212e80737a608d939f648d959671fb0a0142', - after: '97de212e80737a608d939f648d959671fb0a0142', - user_name: 'Git User', - user_email: 'git@example.com', - repository: { - name: 'test-data', - url: 'ssh://git@gitlab.com/test/test-data.git', - description: '', - homepage: 'http://gitlab.com/test/test-data' - }, - commits: [ - { - id: '97de212e80737a608d939f648d959671fb0a0142', - message: 'Test commit message', - timestamp: '2014-09-23T13:12:25+02:00', - url: 'https://gitlab.com/test/test-data/commit/97de212e80737a608d939f648d959671fb0a0142', - author: { - name: 'Git User', - email: 'git@user.com' - } - } - ], - total_commits_count: 1, - ci_yaml_file: File.read(Rails.root.join('spec/support/gitlab_stubs/gitlab_ci.yml')) - } - end gl_project factory: :empty_project factory :ci_commit_without_jobs do after(:create) do |commit, evaluator| - commit.push_data[:ci_yaml_file] = YAML.dump({}) - commit.save + allow(commit).to receive(:ci_yaml_file) { YAML.dump({}) } end end factory :ci_commit_with_one_job do after(:create) do |commit, evaluator| - commit.push_data[:ci_yaml_file] = YAML.dump({ rspec: { script: "ls" } }) - commit.save + allow(commit).to receive(:ci_yaml_file) { YAML.dump({ rspec: { script: "ls" } }) } end end factory :ci_commit_with_two_jobs do after(:create) do |commit, evaluator| - commit.push_data[:ci_yaml_file] = YAML.dump({ rspec: { script: "ls" }, spinach: { script: "ls" } }) - commit.save + allow(commit).to receive(:ci_yaml_file) { YAML.dump({ rspec: { script: "ls" }, spinach: { script: "ls" } }) } end end end -- cgit v1.2.1 From 317a7469545d0e9a70e54a87a540b8aabe4c418b Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Mon, 5 Oct 2015 12:02:26 +0200 Subject: Make commit_spec run --- app/models/ci/build.rb | 4 +- app/models/ci/commit.rb | 75 ++++---- app/services/ci/create_builds_service.rb | 39 ++--- app/services/ci/web_hook_service.rb | 2 - app/views/ci/builds/show.html.haml | 5 - app/views/ci/commits/show.html.haml | 11 +- db/schema.rb | 101 +++++++---- lib/ci/gitlab_ci_yaml_processor.rb | 4 +- spec/factories/ci/commits.rb | 16 +- spec/models/ci/build_spec.rb | 51 ++++-- spec/models/ci/commit_spec.rb | 122 +++++-------- spec/models/ci/mail_service_spec.rb | 190 --------------------- .../ci/project_services/mail_service_spec.rb | 190 +++++++++++++++++++++ spec/spec_helper.rb | 4 + 14 files changed, 416 insertions(+), 398 deletions(-) delete mode 100644 spec/models/ci/mail_service_spec.rb create mode 100644 spec/models/ci/project_services/mail_service_spec.rb diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index bfdc1c7486e..79f040b8954 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -80,6 +80,8 @@ module Ci def retry(build) new_build = Ci::Build.new(status: :pending) + new_build.ref = build.ref + new_build.tag = build.tag new_build.options = build.options new_build.commands = build.commands new_build.tag_list = build.tag_list @@ -141,7 +143,7 @@ module Ci state :canceled, value: 'canceled' end - delegate :sha, :short_sha, :before_sha, :ref, :project, + delegate :sha, :short_sha, :project, to: :commit, prefix: false def trace_html diff --git a/app/models/ci/commit.rb b/app/models/ci/commit.rb index 3c577e3f081..59d4932d434 100644 --- a/app/models/ci/commit.rb +++ b/app/models/ci/commit.rb @@ -58,14 +58,6 @@ module Ci end end - def new_branch? - before_sha == Ci::Git::BLANK_SHA - end - - def compare? - !new_branch? - end - def git_author_name commit_data.author_name if commit_data end @@ -78,10 +70,6 @@ module Ci commit_data.message if commit_data end - def short_before_sha - Ci::Commit.truncate_sha(before_sha) - end - def short_sha Ci::Commit.truncate_sha(sha) end @@ -99,7 +87,22 @@ module Ci def create_builds(ref, tag, user, trigger_request = nil) return if skip_ci? && trigger_request.blank? return unless config_processor - CreateBuildsService.new.execute(self, config_processor, ref, tag, user, trigger_request) + config_processor.stages.any? do |stage| + CreateBuildsService.new.execute(self, stage, ref, tag, user, trigger_request).present? + end + end + + def create_next_builds(ref, tag, user, trigger_request) + return if skip_ci? && trigger_request.blank? + return unless config_processor + + stages = builds.where(ref: ref, tag: tag, trigger_request: trigger_request).group_by(&:stage) + + config_processor.stages.any? do |stage| + unless stages.include?(stage) + CreateBuildsService.new.execute(self, stage, ref, tag, user, trigger_request).present? + end + end end def refs @@ -111,7 +114,14 @@ module Ci end def builds_without_retry - builds.latest + @builds_without_retry ||= + begin + grouped_builds = builds.group_by(&:name) + latest_builds = grouped_builds.map do |name, builds| + builds.sort_by(&:id).last + end + latest_builds.sort_by(&:stage_idx) + end end def retried_builds @@ -125,32 +135,35 @@ module Ci return 'failed' elsif builds.none? return 'skipped' - end - - statuses = builds_without_retry.ignore_failures.pluck(:status) - if statuses.all? { |status| status == 'success' } - return 'success' - elsif statuses.all? { |status| status == 'pending' } - return 'pending' - elsif statuses.include?('running') || statuses.include?('pending') - return 'running' - elsif statuses.all? { |status| status == 'canceled' } - return 'canceled' + elsif success? + 'success' + elsif pending? + 'pending' + elsif running? + 'running' + elsif canceled? + 'canceled' else - return 'failed' + 'failed' end end def pending? - status == 'pending' + builds_without_retry.all? do |build| + build.pending? + end end def running? - status == 'running' + builds_without_retry.any? do |build| + build.running? || build.pending? + end end def success? - status == 'success' + builds_without_retry.all? do |build| + build.success? || build.ignored? + end end def failed? @@ -158,7 +171,9 @@ module Ci end def canceled? - status == 'canceled' + builds_without_retry.all? do |build| + build.canceled? + end end def duration diff --git a/app/services/ci/create_builds_service.rb b/app/services/ci/create_builds_service.rb index 77a4305071c..255fdc41103 100644 --- a/app/services/ci/create_builds_service.rb +++ b/app/services/ci/create_builds_service.rb @@ -1,26 +1,23 @@ module Ci class CreateBuildsService - def execute(commit, ref, tag, user, config_processor, trigger_request) - config_processor.stages.any? do |stage| - builds_attrs = config_processor.builds_for_stage_and_ref(stage, ref, tag) - builds_attrs.map do |build_attrs| - # don't create the same build twice - unless commit.builds.find_by_name_and_trigger_request(name: build_attrs[:name], ref: ref, tag: tag, trigger_request: trigger_request) - commit.builds.create!({ - name: build_attrs[:name], - commands: build_attrs[:script], - tag_list: build_attrs[:tags], - options: build_attrs[:options], - allow_failure: build_attrs[:allow_failure], - stage: build_attrs[:stage], - stage_idx: build_attrs[:stage_idx], - trigger_request: trigger_request, - ref: ref, - tag: tag, - user: user, - }) - end - end + def execute(commit, stage, ref, tag, user, trigger_request) + builds_attrs = commit.config_processor.builds_for_stage_and_ref(stage, ref, tag) + + builds_attrs.map do |build_attrs| + build_attrs.slice!(:name, + :commands, + :tag_list, + :options, + :allow_failure, + :stage, + :stage_idx) + + build_attrs.merge!(ref: ref, + tag: tag, + trigger_request: trigger_request, + user: user) + + commit.builds.create!(build_attrs) end end end diff --git a/app/services/ci/web_hook_service.rb b/app/services/ci/web_hook_service.rb index 87984b20fa1..4bbca5c7da1 100644 --- a/app/services/ci/web_hook_service.rb +++ b/app/services/ci/web_hook_service.rb @@ -28,8 +28,6 @@ module Ci gitlab_url: project.gitlab_url, ref: build.ref, sha: build.sha, - before_sha: build.before_sha, - push_data: build.commit.push_data }) end end diff --git a/app/views/ci/builds/show.html.haml b/app/views/ci/builds/show.html.haml index f941143e2e0..e4ec190ada5 100644 --- a/app/views/ci/builds/show.html.haml +++ b/app/views/ci/builds/show.html.haml @@ -122,11 +122,6 @@ Commit .pull-right %small #{build_commit_link @build} - - - if @build.commit.compare? - %p - %span.attr-name Compare: - #{build_compare_link @build} %p %span.attr-name Branch: #{build_ref_link @build} diff --git a/app/views/ci/commits/show.html.haml b/app/views/ci/commits/show.html.haml index 4badb671287..69487320175 100644 --- a/app/views/ci/commits/show.html.haml +++ b/app/views/ci/commits/show.html.haml @@ -9,14 +9,9 @@ .gray-content-block.second-block .row .col-sm-6 - - if @commit.compare? - %p - %span.attr-name Compare: - #{gitlab_compare_link(@project, @commit.short_before_sha, @commit.short_sha)} - - else - %p - %span.attr-name Commit: - #{gitlab_commit_link(@project, @commit.sha)} + %p + %span.attr-name Commit: + #{gitlab_commit_link(@project, @commit.sha)} .col-sm-6 - if @commit.git_author_name || @commit.git_author_email %p diff --git a/db/schema.rb b/db/schema.rb index 72609da93f1..f2bda91f799 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,10 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150930095736) do - - # These are extensions that must be enabled in order to support this database - enable_extension "plpgsql" +ActiveRecord::Schema.define(version: 20151005075649) do create_table "abuse_reports", force: true do |t| t.integer "reporter_id" @@ -45,8 +42,8 @@ ActiveRecord::Schema.define(version: 20150930095736) do t.string "after_sign_out_path" t.integer "session_expire_delay", default: 10080, null: false t.text "import_sources" - t.text "help_page_text" t.boolean "ci_enabled", default: true, null: false + t.text "help_page_text" end create_table "audit_events", force: true do |t| @@ -85,37 +82,60 @@ ActiveRecord::Schema.define(version: 20150930095736) do t.integer "project_id" t.string "status" t.datetime "finished_at" - t.text "trace" + t.text "trace", limit: 2147483647 t.datetime "created_at" t.datetime "updated_at" t.datetime "started_at" t.integer "runner_id" - t.float "coverage" + t.float "coverage", limit: 24 t.integer "commit_id" t.text "commands" t.integer "job_id" t.string "name" - t.boolean "deploy", default: false + t.boolean "deploy", default: false t.text "options" - t.boolean "allow_failure", default: false, null: false + t.boolean "allow_failure", default: false, null: false t.string "stage" t.integer "trigger_request_id" + t.integer "gl_project_id" + t.integer "stage_idx" + t.boolean "tag" + t.string "ref" + t.text "push_data" + t.integer "user_id" end + add_index "ci_builds", ["commit_id", "name"], name: "index_ci_builds_on_commit_id_and_name", using: :btree + add_index "ci_builds", ["commit_id", "stage_idx", "created_at"], name: "index_ci_builds_on_commit_id_and_stage_idx_and_created_at", using: :btree add_index "ci_builds", ["commit_id"], name: "index_ci_builds_on_commit_id", using: :btree add_index "ci_builds", ["project_id", "commit_id"], name: "index_ci_builds_on_project_id_and_commit_id", using: :btree add_index "ci_builds", ["project_id"], name: "index_ci_builds_on_project_id", using: :btree add_index "ci_builds", ["runner_id"], name: "index_ci_builds_on_runner_id", using: :btree + create_table "ci_commit_statuses", force: true do |t| + t.integer "commit_id" + t.string "sha" + t.string "ref" + t.string "state" + t.string "target_url" + t.string "description" + t.string "context", default: "default" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "ci_commit_statuses", ["commit_id", "context", "ref"], name: "index_ci_commit_statuses_on_commit_id_and_context_and_ref", using: :btree + add_index "ci_commit_statuses", ["commit_id", "ref"], name: "index_ci_commit_statuses_on_commit_id_and_ref", using: :btree + create_table "ci_commits", force: true do |t| t.integer "project_id" t.string "ref" t.string "sha" t.string "before_sha" - t.text "push_data" + t.text "push_data", limit: 16777215 t.datetime "created_at" t.datetime "updated_at" - t.boolean "tag", default: false + t.boolean "tag", default: false t.text "yaml_errors" t.datetime "committed_at" t.integer "gl_project_id" @@ -134,6 +154,7 @@ ActiveRecord::Schema.define(version: 20150930095736) do t.text "description" t.datetime "created_at" t.datetime "updated_at" + t.integer "gl_project_id" end add_index "ci_events", ["created_at"], name: "index_ci_events_on_created_at", using: :btree @@ -181,10 +202,11 @@ ActiveRecord::Schema.define(version: 20150930095736) do end create_table "ci_runner_projects", force: true do |t| - t.integer "runner_id", null: false - t.integer "project_id", null: false + t.integer "runner_id", null: false + t.integer "project_id", null: false t.datetime "created_at" t.datetime "updated_at" + t.integer "gl_project_id" end add_index "ci_runner_projects", ["project_id"], name: "index_ci_runner_projects_on_project_id", using: :btree @@ -208,11 +230,12 @@ ActiveRecord::Schema.define(version: 20150930095736) do create_table "ci_services", force: true do |t| t.string "type" t.string "title" - t.integer "project_id", null: false + t.integer "project_id", null: false t.datetime "created_at" t.datetime "updated_at" - t.boolean "active", default: false, null: false + t.boolean "active", default: false, null: false t.text "properties" + t.integer "gl_project_id" end add_index "ci_services", ["project_id"], name: "index_ci_services_on_project_id", using: :btree @@ -257,10 +280,11 @@ ActiveRecord::Schema.define(version: 20150930095736) do create_table "ci_triggers", force: true do |t| t.string "token" - t.integer "project_id", null: false + t.integer "project_id", null: false t.datetime "deleted_at" t.datetime "created_at" t.datetime "updated_at" + t.integer "gl_project_id" end add_index "ci_triggers", ["deleted_at"], name: "index_ci_triggers_on_deleted_at", using: :btree @@ -272,15 +296,17 @@ ActiveRecord::Schema.define(version: 20150930095736) do t.text "encrypted_value" t.string "encrypted_value_salt" t.string "encrypted_value_iv" + t.integer "gl_project_id" end add_index "ci_variables", ["project_id"], name: "index_ci_variables_on_project_id", using: :btree create_table "ci_web_hooks", force: true do |t| - t.string "url", null: false - t.integer "project_id", null: false + t.string "url", null: false + t.integer "project_id", null: false t.datetime "created_at" t.datetime "updated_at" + t.integer "gl_project_id" end create_table "deploy_keys_projects", force: true do |t| @@ -426,9 +452,9 @@ ActiveRecord::Schema.define(version: 20150930095736) do create_table "merge_request_diffs", force: true do |t| t.string "state" - t.text "st_commits" - t.text "st_diffs" - t.integer "merge_request_id", null: false + t.text "st_commits", limit: 2147483647 + t.text "st_diffs", limit: 2147483647 + t.integer "merge_request_id", null: false t.datetime "created_at" t.datetime "updated_at" end @@ -511,8 +537,8 @@ ActiveRecord::Schema.define(version: 20150930095736) do t.string "line_code" t.string "commit_id" t.integer "noteable_id" - t.boolean "system", default: false, null: false - t.text "st_diff" + t.boolean "system", default: false, null: false + t.text "st_diff", limit: 2147483647 t.integer "updated_by_id" end @@ -581,25 +607,26 @@ ActiveRecord::Schema.define(version: 20150930095736) do t.datetime "created_at" t.datetime "updated_at" t.integer "creator_id" - t.boolean "issues_enabled", default: true, null: false - t.boolean "wall_enabled", default: true, null: false - t.boolean "merge_requests_enabled", default: true, null: false - t.boolean "wiki_enabled", default: true, null: false + t.boolean "issues_enabled", default: true, null: false + t.boolean "wall_enabled", default: true, null: false + t.boolean "merge_requests_enabled", default: true, null: false + t.boolean "wiki_enabled", default: true, null: false t.integer "namespace_id" - t.string "issues_tracker", default: "gitlab", null: false + t.string "issues_tracker", default: "gitlab", null: false t.string "issues_tracker_id" - t.boolean "snippets_enabled", default: true, null: false + t.boolean "snippets_enabled", default: true, null: false t.datetime "last_activity_at" t.string "import_url" - t.integer "visibility_level", default: 0, null: false - t.boolean "archived", default: false, null: false + t.integer "visibility_level", default: 0, null: false + t.boolean "archived", default: false, null: false t.string "avatar" t.string "import_status" - t.float "repository_size", default: 0.0 - t.integer "star_count", default: 0, null: false + t.float "repository_size", limit: 24, default: 0.0 + t.integer "star_count", default: 0, null: false t.string "import_type" t.string "import_source" - t.integer "commit_count", default: 0 + t.integer "commit_count", default: 0 + t.boolean "shared_runners_enabled", default: false end add_index "projects", ["created_at", "id"], name: "index_projects_on_created_at_and_id", using: :btree @@ -651,15 +678,15 @@ ActiveRecord::Schema.define(version: 20150930095736) do create_table "snippets", force: true do |t| t.string "title" - t.text "content" - t.integer "author_id", null: false + t.text "content", limit: 2147483647 + t.integer "author_id", null: false t.integer "project_id" t.datetime "created_at" t.datetime "updated_at" t.string "file_name" t.datetime "expires_at" t.string "type" - t.integer "visibility_level", default: 0, null: false + t.integer "visibility_level", default: 0, null: false end add_index "snippets", ["author_id"], name: "index_snippets_on_author_id", using: :btree diff --git a/lib/ci/gitlab_ci_yaml_processor.rb b/lib/ci/gitlab_ci_yaml_processor.rb index 861da770d3c..c47951bc5d1 100644 --- a/lib/ci/gitlab_ci_yaml_processor.rb +++ b/lib/ci/gitlab_ci_yaml_processor.rb @@ -87,8 +87,8 @@ module Ci { stage_idx: stages.index(job[:stage]), stage: job[:stage], - script: "#{@before_script.join("\n")}\n#{normalize_script(job[:script])}", - tags: job[:tags] || [], + commands: "#{@before_script.join("\n")}\n#{normalize_script(job[:script])}", + tag_list: job[:tags] || [], name: name, only: job[:only], except: job[:except], diff --git a/spec/factories/ci/commits.rb b/spec/factories/ci/commits.rb index b74aae795aa..9226e04a7b3 100644 --- a/spec/factories/ci/commits.rb +++ b/spec/factories/ci/commits.rb @@ -23,20 +23,26 @@ FactoryGirl.define do gl_project factory: :empty_project factory :ci_commit_without_jobs do - after(:create) do |commit, evaluator| + after(:build) do |commit| allow(commit).to receive(:ci_yaml_file) { YAML.dump({}) } end end factory :ci_commit_with_one_job do - after(:create) do |commit, evaluator| - allow(commit).to receive(:ci_yaml_file) { YAML.dump({ rspec: { script: "ls" } }) } + 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 - after(:create) do |commit, evaluator| - allow(commit).to receive(:ci_yaml_file) { YAML.dump({ rspec: { script: "ls" }, spinach: { script: "ls" } }) } + after(:build) do |commit| + allow(commit).to receive(:ci_yaml_file) { YAML.dump({rspec: {script: "ls"}, spinach: {script: "ls"}}) } + end + end + + factory :ci_commit_yaml_stub 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 end end diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index ca070a14975..d74063e5782 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -28,11 +28,14 @@ require 'spec_helper' describe Ci::Build do let(:project) { FactoryGirl.create :ci_project } let(:gl_project) { FactoryGirl.create :empty_project, gitlab_ci_project: project } - let(:commit) { FactoryGirl.create :ci_commit, gl_project: gl_project } + let(:commit) { FactoryGirl.create :ci_commit_yaml_stub, gl_project: gl_project } let(:build) { FactoryGirl.create :ci_build, commit: commit } + subject { build } it { is_expected.to belong_to(:commit) } + it { is_expected.to belong_to(:user) } it { is_expected.to validate_presence_of :status } + it { is_expected.to validate_presence_of :ref } it { is_expected.to respond_to :success? } it { is_expected.to respond_to :failed? } @@ -236,12 +239,6 @@ describe Ci::Build do it { is_expected.to eq(options) } end - describe :ref do - subject { build.ref } - - it { is_expected.to eq(commit.ref) } - end - describe :sha do subject { build.sha } @@ -254,12 +251,6 @@ describe Ci::Build do it { is_expected.to eq(commit.short_sha) } end - describe :before_sha do - subject { build.before_sha } - - it { is_expected.to eq(commit.before_sha) } - end - describe :allow_git_fetch do subject { build.allow_git_fetch } @@ -359,4 +350,38 @@ describe Ci::Build do end end end + + describe :project_recipients do + let (:pusher_email) { 'pusher@gitlab.test' } + let (:user) { User.new(notification_email: pusher_email) } + subject { build.project_recipients } + + before do + build.update_attributes(user: user) + end + + it 'should return pusher_email as only recipient when no additional recipients are given' do + project.update_attributes(email_add_pusher: true, + email_recipients: '') + is_expected.to eq([pusher_email]) + end + + it 'should return pusher_email and additional recipients' do + project.update_attributes(email_add_pusher: true, + email_recipients: 'rec1 rec2') + is_expected.to eq(['rec1', 'rec2', pusher_email]) + end + + it 'should return recipients' do + project.update_attributes(email_add_pusher: false, + email_recipients: 'rec1 rec2') + is_expected.to eq(['rec1', 'rec2']) + end + + it 'should return unique recipients only' do + project.update_attributes(email_add_pusher: true, + email_recipients: "rec1 rec1 #{pusher_email}") + is_expected.to eq(['rec1', pusher_email]) + end + end end diff --git a/spec/models/ci/commit_spec.rb b/spec/models/ci/commit_spec.rb index c04bbcbadc7..63602e89e37 100644 --- a/spec/models/ci/commit_spec.rb +++ b/spec/models/ci/commit_spec.rb @@ -21,15 +21,10 @@ describe Ci::Commit do let(:project) { FactoryGirl.create :ci_project } let(:gl_project) { FactoryGirl.create :empty_project, gitlab_ci_project: project } let(:commit) { FactoryGirl.create :ci_commit, gl_project: gl_project } - let(:commit_with_project) { FactoryGirl.create :ci_commit, gl_project: gl_project } - let(:config_processor) { Ci::GitlabCiYamlProcessor.new(gitlab_ci_yaml) } it { is_expected.to belong_to(:gl_project) } it { is_expected.to have_many(:builds) } - it { is_expected.to validate_presence_of :before_sha } it { is_expected.to validate_presence_of :sha } - it { is_expected.to validate_presence_of :ref } - it { is_expected.to validate_presence_of :push_data } it { is_expected.to respond_to :git_author_name } it { is_expected.to respond_to :git_author_email } @@ -59,53 +54,6 @@ describe Ci::Commit do end end - describe :project_recipients do - - context 'always sending notification' do - it 'should return commit_pusher_email as only recipient when no additional recipients are given' do - project = FactoryGirl.create :ci_project, - email_add_pusher: true, - email_recipients: '' - gl_project = FactoryGirl.create :empty_project, gitlab_ci_project: project - commit = FactoryGirl.create :ci_commit, gl_project: gl_project - expected = 'commit_pusher_email' - allow(commit).to receive(:push_data) { { user_email: expected } } - expect(commit.project_recipients).to eq([expected]) - end - - it 'should return commit_pusher_email and additional recipients' do - project = FactoryGirl.create :ci_project, - email_add_pusher: true, - email_recipients: 'rec1 rec2' - gl_project = FactoryGirl.create :empty_project, gitlab_ci_project: project - commit = FactoryGirl.create :ci_commit, gl_project: gl_project - expected = 'commit_pusher_email' - allow(commit).to receive(:push_data) { { user_email: expected } } - expect(commit.project_recipients).to eq(['rec1', 'rec2', expected]) - end - - it 'should return recipients' do - project = FactoryGirl.create :ci_project, - email_add_pusher: false, - email_recipients: 'rec1 rec2' - gl_project = FactoryGirl.create :empty_project, gitlab_ci_project: project - commit = FactoryGirl.create :ci_commit, gl_project: gl_project - expect(commit.project_recipients).to eq(['rec1', 'rec2']) - end - - it 'should return unique recipients only' do - project = FactoryGirl.create :ci_project, - email_add_pusher: true, - email_recipients: 'rec1 rec1 rec2' - gl_project = FactoryGirl.create :empty_project, gitlab_ci_project: project - commit = FactoryGirl.create :ci_commit, gl_project: gl_project - expected = 'rec2' - allow(commit).to receive(:push_data) { { user_email: expected } } - expect(commit.project_recipients).to eq(['rec1', 'rec2']) - end - end - end - describe :valid_commit_sha do context 'commit.sha can not start with 00000000' do before do @@ -117,14 +65,6 @@ describe Ci::Commit do end end - describe :compare? do - subject { commit_with_project.compare? } - - context 'if commit.before_sha are not nil' do - it { is_expected.to be_truthy } - end - end - describe :short_sha do subject { commit.short_before_sha } @@ -144,36 +84,51 @@ describe Ci::Commit do end describe :create_next_builds do - before do - allow(commit).to receive(:config_processor).and_return(config_processor) + end + + describe :create_builds do + let(:commit) { FactoryGirl.create :ci_commit_yaml_stub, gl_project: gl_project } + + def create_builds(trigger_request = nil) + commit.create_builds('master', false, nil, trigger_request) end - it "creates builds for next type" do - expect(commit.create_builds).to be_truthy + def create_next_builds(trigger_request = nil) + commit.create_next_builds('master', false, nil, trigger_request) + end + + it 'creates builds' do + expect(create_builds).to be_truthy commit.builds.reload expect(commit.builds.size).to eq(2) - expect(commit.create_next_builds(nil)).to be_truthy + expect(create_next_builds).to be_truthy commit.builds.reload expect(commit.builds.size).to eq(4) - expect(commit.create_next_builds(nil)).to be_truthy + expect(create_next_builds).to be_truthy commit.builds.reload expect(commit.builds.size).to eq(5) - expect(commit.create_next_builds(nil)).to be_falsey + expect(create_next_builds).to be_falsey end - end - describe :create_builds do - before do - allow(commit).to receive(:config_processor).and_return(config_processor) - end + context 'for different ref' do + def create_develop_builds + commit.create_builds('develop', false, nil, nil) + end - it 'creates builds' do - expect(commit.create_builds).to be_truthy - commit.builds.reload - expect(commit.builds.size).to eq(2) + it 'creates builds' do + expect(create_builds).to be_truthy + commit.builds.reload + expect(commit.builds.size).to eq(2) + + expect(create_develop_builds).to be_truthy + commit.builds.reload + expect(commit.builds.size).to eq(4) + expect(commit.refs.size).to eq(2) + expect(commit.builds.pluck(:name).uniq.size).to eq(2) + end end context 'for build triggers' do @@ -181,40 +136,39 @@ describe Ci::Commit do let(:trigger_request) { FactoryGirl.create :ci_trigger_request, commit: commit, trigger: trigger } it 'creates builds' do - expect(commit.create_builds(trigger_request)).to be_truthy + expect(create_builds(trigger_request)).to be_truthy commit.builds.reload expect(commit.builds.size).to eq(2) end it 'rebuilds commit' do - expect(commit.create_builds).to be_truthy + expect(create_builds).to be_truthy commit.builds.reload expect(commit.builds.size).to eq(2) - expect(commit.create_builds(trigger_request)).to be_truthy + expect(create_builds(trigger_request)).to be_truthy commit.builds.reload expect(commit.builds.size).to eq(4) end it 'creates next builds' do - expect(commit.create_builds(trigger_request)).to be_truthy + expect(create_builds(trigger_request)).to be_truthy commit.builds.reload expect(commit.builds.size).to eq(2) - expect(commit.create_next_builds(trigger_request)).to be_truthy + expect(create_next_builds(trigger_request)).to be_truthy commit.builds.reload expect(commit.builds.size).to eq(4) end context 'for [ci skip]' do before do - commit.push_data[:commits][0][:message] = 'skip this commit [ci skip]' - commit.save + allow(commit).to receive(:git_commit_message) { 'message [ci skip]' } end it 'rebuilds commit' do expect(commit.status).to eq('skipped') - expect(commit.create_builds(trigger_request)).to be_truthy + expect(create_builds(trigger_request)).to be_truthy commit.builds.reload expect(commit.builds.size).to eq(2) expect(commit.status).to eq('pending') diff --git a/spec/models/ci/mail_service_spec.rb b/spec/models/ci/mail_service_spec.rb deleted file mode 100644 index 0d9f85959ba..00000000000 --- a/spec/models/ci/mail_service_spec.rb +++ /dev/null @@ -1,190 +0,0 @@ -# == Schema Information -# -# Table name: services -# -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer not null -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text -# - -require 'spec_helper' - -describe Ci::MailService do - describe "Associations" do - it { is_expected.to belong_to :project } - end - - describe "Validations" do - context "active" do - before do - subject.active = true - end - end - end - - describe 'Sends email for' do - let(:mail) { Ci::MailService.new } - - describe 'failed build' do - let(:project) { FactoryGirl.create(:ci_project, email_add_pusher: true) } - let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } - let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } - let(:build) { FactoryGirl.create(:ci_build, status: :failed, commit: commit) } - - before do - allow(mail).to receive_messages( - project: project - ) - end - - it do - should_email("git@example.com") - mail.execute(build) - end - - def should_email(email) - expect(Ci::Notify).to receive(:build_fail_email).with(build.id, email) - expect(Ci::Notify).not_to receive(:build_success_email).with(build.id, email) - end - end - - describe 'successfull build' do - let(:project) { FactoryGirl.create(:ci_project, email_add_pusher: true, email_only_broken_builds: false) } - let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } - let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } - let(:build) { FactoryGirl.create(:ci_build, status: :success, commit: commit) } - - before do - allow(mail).to receive_messages( - project: project - ) - end - - it do - should_email("git@example.com") - mail.execute(build) - end - - def should_email(email) - expect(Ci::Notify).to receive(:build_success_email).with(build.id, email) - expect(Ci::Notify).not_to receive(:build_fail_email).with(build.id, email) - end - end - - describe 'successfull build and project has email_recipients' do - let(:project) do - FactoryGirl.create(:ci_project, - email_add_pusher: true, - email_only_broken_builds: false, - email_recipients: "jeroen@example.com") - end - let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } - let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } - let(:build) { FactoryGirl.create(:ci_build, status: :success, commit: commit) } - - before do - allow(mail).to receive_messages( - project: project - ) - end - - it do - should_email("git@example.com") - should_email("jeroen@example.com") - mail.execute(build) - end - - def should_email(email) - expect(Ci::Notify).to receive(:build_success_email).with(build.id, email) - expect(Ci::Notify).not_to receive(:build_fail_email).with(build.id, email) - end - end - - describe 'successful build and notify only broken builds' do - let(:project) do - FactoryGirl.create(:ci_project, - email_add_pusher: true, - email_only_broken_builds: true, - email_recipients: "jeroen@example.com") - end - let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } - let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } - let(:build) { FactoryGirl.create(:ci_build, status: :success, commit: commit) } - - before do - allow(mail).to receive_messages( - project: project - ) - end - - it do - should_email(commit.git_author_email) - should_email("jeroen@example.com") - mail.execute(build) if mail.can_execute?(build) - end - - def should_email(email) - expect(Ci::Notify).not_to receive(:build_success_email).with(build.id, email) - expect(Ci::Notify).not_to receive(:build_fail_email).with(build.id, email) - end - end - - describe 'successful build and can test service' do - let(:project) do - FactoryGirl.create(:ci_project, - email_add_pusher: true, - email_only_broken_builds: false, - email_recipients: "jeroen@example.com") - end - let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } - let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } - let(:build) { FactoryGirl.create(:ci_build, status: :success, commit: commit) } - - before do - allow(mail).to receive_messages( - project: project - ) - build - end - - it do - expect(mail.can_test?).to eq(true) - end - end - - describe 'retried build should not receive email' do - let(:project) do - FactoryGirl.create(:ci_project, - email_add_pusher: true, - email_only_broken_builds: true, - email_recipients: "jeroen@example.com") - end - let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } - let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } - let(:build) { FactoryGirl.create(:ci_build, status: :failed, commit: commit) } - - before do - allow(mail).to receive_messages( - project: project - ) - end - - it do - Ci::Build.retry(build) - should_email(commit.git_author_email) - should_email("jeroen@example.com") - mail.execute(build) if mail.can_execute?(build) - end - - def should_email(email) - expect(Ci::Notify).not_to receive(:build_success_email).with(build.id, email) - expect(Ci::Notify).not_to receive(:build_fail_email).with(build.id, email) - end - end - end -end diff --git a/spec/models/ci/project_services/mail_service_spec.rb b/spec/models/ci/project_services/mail_service_spec.rb new file mode 100644 index 00000000000..0d9f85959ba --- /dev/null +++ b/spec/models/ci/project_services/mail_service_spec.rb @@ -0,0 +1,190 @@ +# == Schema Information +# +# Table name: services +# +# id :integer not null, primary key +# type :string(255) +# title :string(255) +# project_id :integer not null +# created_at :datetime +# updated_at :datetime +# active :boolean default(FALSE), not null +# properties :text +# + +require 'spec_helper' + +describe Ci::MailService do + describe "Associations" do + it { is_expected.to belong_to :project } + end + + describe "Validations" do + context "active" do + before do + subject.active = true + end + end + end + + describe 'Sends email for' do + let(:mail) { Ci::MailService.new } + + describe 'failed build' do + let(:project) { FactoryGirl.create(:ci_project, email_add_pusher: true) } + let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } + let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } + let(:build) { FactoryGirl.create(:ci_build, status: :failed, commit: commit) } + + before do + allow(mail).to receive_messages( + project: project + ) + end + + it do + should_email("git@example.com") + mail.execute(build) + end + + def should_email(email) + expect(Ci::Notify).to receive(:build_fail_email).with(build.id, email) + expect(Ci::Notify).not_to receive(:build_success_email).with(build.id, email) + end + end + + describe 'successfull build' do + let(:project) { FactoryGirl.create(:ci_project, email_add_pusher: true, email_only_broken_builds: false) } + let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } + let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } + let(:build) { FactoryGirl.create(:ci_build, status: :success, commit: commit) } + + before do + allow(mail).to receive_messages( + project: project + ) + end + + it do + should_email("git@example.com") + mail.execute(build) + end + + def should_email(email) + expect(Ci::Notify).to receive(:build_success_email).with(build.id, email) + expect(Ci::Notify).not_to receive(:build_fail_email).with(build.id, email) + end + end + + describe 'successfull build and project has email_recipients' do + let(:project) do + FactoryGirl.create(:ci_project, + email_add_pusher: true, + email_only_broken_builds: false, + email_recipients: "jeroen@example.com") + end + let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } + let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } + let(:build) { FactoryGirl.create(:ci_build, status: :success, commit: commit) } + + before do + allow(mail).to receive_messages( + project: project + ) + end + + it do + should_email("git@example.com") + should_email("jeroen@example.com") + mail.execute(build) + end + + def should_email(email) + expect(Ci::Notify).to receive(:build_success_email).with(build.id, email) + expect(Ci::Notify).not_to receive(:build_fail_email).with(build.id, email) + end + end + + describe 'successful build and notify only broken builds' do + let(:project) do + FactoryGirl.create(:ci_project, + email_add_pusher: true, + email_only_broken_builds: true, + email_recipients: "jeroen@example.com") + end + let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } + let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } + let(:build) { FactoryGirl.create(:ci_build, status: :success, commit: commit) } + + before do + allow(mail).to receive_messages( + project: project + ) + end + + it do + should_email(commit.git_author_email) + should_email("jeroen@example.com") + mail.execute(build) if mail.can_execute?(build) + end + + def should_email(email) + expect(Ci::Notify).not_to receive(:build_success_email).with(build.id, email) + expect(Ci::Notify).not_to receive(:build_fail_email).with(build.id, email) + end + end + + describe 'successful build and can test service' do + let(:project) do + FactoryGirl.create(:ci_project, + email_add_pusher: true, + email_only_broken_builds: false, + email_recipients: "jeroen@example.com") + end + let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } + let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } + let(:build) { FactoryGirl.create(:ci_build, status: :success, commit: commit) } + + before do + allow(mail).to receive_messages( + project: project + ) + build + end + + it do + expect(mail.can_test?).to eq(true) + end + end + + describe 'retried build should not receive email' do + let(:project) do + FactoryGirl.create(:ci_project, + email_add_pusher: true, + email_only_broken_builds: true, + email_recipients: "jeroen@example.com") + end + let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } + let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } + let(:build) { FactoryGirl.create(:ci_build, status: :failed, commit: commit) } + + before do + allow(mail).to receive_messages( + project: project + ) + end + + it do + Ci::Build.retry(build) + should_email(commit.git_author_email) + should_email("jeroen@example.com") + mail.execute(build) if mail.can_execute?(build) + end + + def should_email(email) + expect(Ci::Notify).not_to receive(:build_success_email).with(build.id, email) + expect(Ci::Notify).not_to receive(:build_fail_email).with(build.id, email) + end + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index dfe855926c6..67f31ef54f6 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -42,4 +42,8 @@ RSpec.configure do |config| end end +FactoryGirl::SyntaxRunner.class_eval do + include RSpec::Mocks::ExampleMethods +end + ActiveRecord::Migration.maintain_test_schema! -- cgit v1.2.1 From 361dc3641dd28c4ecefbda94f7a8dad299c349aa Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Mon, 5 Oct 2015 12:38:00 +0200 Subject: Fix builds_without_retry --- app/models/ci/build.rb | 2 +- app/models/ci/commit.rb | 17 +++++++---------- app/views/ci/builds/show.html.haml | 4 ++-- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 79f040b8954..30a8b5aa816 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -47,7 +47,7 @@ module Ci scope :failed, ->() { where(status: "failed") } scope :unstarted, ->() { where(runner_id: nil) } scope :running_or_pending, ->() { where(status:[:running, :pending]) } - scope :latest, ->() { group(:name).order(stage_idx: :asc, created_at: :desc) } + scope :latest, ->() { where(id: unscope(:select).select('max(id)').group(:name)).order(stage_idx: :asc) } scope :ignore_failures, ->() { where(allow_failure: false) } scope :for_ref, ->(ref) { where(ref: ref) } diff --git a/app/models/ci/commit.rb b/app/models/ci/commit.rb index 59d4932d434..31da7e8f2b6 100644 --- a/app/models/ci/commit.rb +++ b/app/models/ci/commit.rb @@ -114,14 +114,11 @@ module Ci end def builds_without_retry - @builds_without_retry ||= - begin - grouped_builds = builds.group_by(&:name) - latest_builds = grouped_builds.map do |name, builds| - builds.sort_by(&:id).last - end - latest_builds.sort_by(&:stage_idx) - end + builds.latest + end + + def builds_without_retry_for_ref(ref) + builds.for_ref(ref).latest end def retried_builds @@ -181,7 +178,7 @@ module Ci end def duration_for_ref(ref) - builds_without_retry.for_ref(ref).select(&:duration).sum(&:duration).to_i + builds_without_retry_for_ref(ref).select(&:duration).sum(&:duration).to_i end def finished_at @@ -198,7 +195,7 @@ module Ci end def matrix_for_ref?(ref) - builds_without_retry.for_ref(ref).pluck(:id).size > 1 + builds_without_retry_for_ref(ref).pluck(:id).size > 1 end def config_processor diff --git a/app/views/ci/builds/show.html.haml b/app/views/ci/builds/show.html.haml index e4ec190ada5..c42d11bf05d 100644 --- a/app/views/ci/builds/show.html.haml +++ b/app/views/ci/builds/show.html.haml @@ -1,7 +1,7 @@ #up-build-trace - if @commit.matrix_for_ref?(@build.ref) %ul.center-top-menu - - @commit.builds_without_retry.for_ref(build.ref).each do |build| + - @commit.builds_without_retry_for_ref(build.ref).each do |build| %li{class: ('active' if build == @build) } = link_to ci_project_build_url(@project, build) do = ci_icon_for_status(build.status) @@ -12,7 +12,7 @@ = build.id - - unless @commit.builds_without_retry.for_ref(@build.ref).include?(@build) + - unless @commit.builds_without_retry_for_ref(@build.ref).include?(@build) %li.active %a Build ##{@build.id} -- cgit v1.2.1 From d2d2df0738f3cd8311963c34d90ebc8ce4081aa6 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Mon, 5 Oct 2015 13:12:00 +0200 Subject: Fix next round of tests --- app/controllers/ci/commits_controller.rb | 2 +- app/helpers/builds_helper.rb | 4 -- app/models/project_services/ci/hip_chat_message.rb | 9 +---- app/models/project_services/ci/slack_message.rb | 23 ++++------- app/models/project_services/gitlab_ci_service.rb | 2 +- app/services/ci/create_builds_service.rb | 27 +++++++------ app/services/ci/create_commit_service.rb | 3 +- app/views/ci/commits/show.html.haml | 6 +-- lib/ci/api/commits.rb | 2 +- spec/factories/ci/commits.rb | 4 +- spec/features/ci/commits_spec.rb | 5 +-- spec/lib/ci/gitlab_ci_yaml_processor_spec.rb | 12 +++--- spec/models/ci/build_spec.rb | 6 +-- spec/models/ci/commit_spec.rb | 11 +---- .../ci/project_services/hip_chat_message_spec.rb | 6 +-- .../ci/project_services/mail_service_spec.rb | 13 +++--- .../ci/project_services/slack_message_spec.rb | 6 +-- spec/requests/ci/api/builds_spec.rb | 8 ++-- spec/services/ci/create_commit_service_spec.rb | 47 +++++++++++++++------- spec/support/stub_gitlab_calls.rb | 8 ++++ 20 files changed, 103 insertions(+), 101 deletions(-) diff --git a/app/controllers/ci/commits_controller.rb b/app/controllers/ci/commits_controller.rb index acf9189572c..887e92f84cf 100644 --- a/app/controllers/ci/commits_controller.rb +++ b/app/controllers/ci/commits_controller.rb @@ -13,7 +13,7 @@ module Ci end def status - commit = Ci::Project.find(params[:project_id]).commits.find_by_sha!(params[:id], params[:ref_id]) + commit = Ci::Project.find(params[:project_id]).commits.find_by_sha!(params[:id]) render json: commit.to_json(only: [:id, :sha], methods: [:status, :coverage]) rescue ActiveRecord::RecordNotFound render json: { status: "not_found" } diff --git a/app/helpers/builds_helper.rb b/app/helpers/builds_helper.rb index b6658e52d09..626f4e2f4c0 100644 --- a/app/helpers/builds_helper.rb +++ b/app/helpers/builds_helper.rb @@ -3,10 +3,6 @@ module BuildsHelper gitlab_ref_link build.project, build.ref end - def build_compare_link build - gitlab_compare_link build.project, build.commit.short_before_sha, build.short_sha - end - def build_commit_link build gitlab_commit_link build.project, build.short_sha end diff --git a/app/models/project_services/ci/hip_chat_message.rb b/app/models/project_services/ci/hip_chat_message.rb index 73fdbe801c0..0bf448d47f2 100644 --- a/app/models/project_services/ci/hip_chat_message.rb +++ b/app/models/project_services/ci/hip_chat_message.rb @@ -11,14 +11,7 @@ module Ci def to_s lines = Array.new lines.push("#{project.name} - ") - - if commit.matrix? - lines.push("Commit ##{commit.id}
") - else - first_build = commit.builds_without_retry.first - lines.push("Build '#{first_build.name}' ##{first_build.id}
") - end - + lines.push("Commit ##{commit.id}
") lines.push("#{commit.short_sha} #{commit.git_author_name} - #{commit.git_commit_message}
") lines.push("#{humanized_status(commit_status)} in #{commit.duration} second(s).") lines.join('') diff --git a/app/models/project_services/ci/slack_message.rb b/app/models/project_services/ci/slack_message.rb index 7d254836fb5..a89c01517b7 100644 --- a/app/models/project_services/ci/slack_message.rb +++ b/app/models/project_services/ci/slack_message.rb @@ -23,15 +23,13 @@ module Ci def attachments fields = [] - if commit.matrix? - commit.builds_without_retry.each do |build| - next if build.allow_failure? - next unless build.failed? - fields << { - title: build.name, - value: "Build <#{ci_project_build_url(project, build)}|\##{build.id}> failed in #{build.duration.to_i} second(s)." - } - end + commit.builds_without_retry.each do |build| + next if build.allow_failure? + next unless build.failed? + fields << { + title: build.name, + value: "Build <#{ci_project_build_url(project, build)}|\##{build.id}> failed in #{build.duration.to_i} second(s)." + } end [{ @@ -47,12 +45,7 @@ module Ci def attachment_message out = "<#{ci_project_url(project)}|#{project_name}>: " - if commit.matrix? - out << "Commit <#{ci_project_commits_url(project, commit.sha)}|\##{commit.id}> " - else - build = commit.builds_without_retry.first - out << "Build <#{ci_project_build_url(project, build)}|\##{build.id}> " - end + out << "Commit <#{ci_project_commits_url(project, commit.sha)}|\##{commit.id}> " out << "(<#{commit_sha_link}|#{commit.short_sha}>) " out << "of <#{commit_ref_link}|#{commit.ref}> " out << "by #{commit.git_author_name} " if commit.git_author_name diff --git a/app/models/project_services/gitlab_ci_service.rb b/app/models/project_services/gitlab_ci_service.rb index 8e2b395494e..17d1ef71945 100644 --- a/app/models/project_services/gitlab_ci_service.rb +++ b/app/models/project_services/gitlab_ci_service.rb @@ -52,7 +52,7 @@ class GitlabCiService < CiService ci_project = Ci::Project.find_by(gitlab_id: project.id) if ci_project - Ci::CreateCommitService.new.execute(ci_project, data, current_user) + Ci::CreateCommitService.new.execute(ci_project, current_user, data) end end diff --git a/app/services/ci/create_builds_service.rb b/app/services/ci/create_builds_service.rb index 255fdc41103..c420f3268fd 100644 --- a/app/services/ci/create_builds_service.rb +++ b/app/services/ci/create_builds_service.rb @@ -4,20 +4,23 @@ module Ci builds_attrs = commit.config_processor.builds_for_stage_and_ref(stage, ref, tag) builds_attrs.map do |build_attrs| - build_attrs.slice!(:name, - :commands, - :tag_list, - :options, - :allow_failure, - :stage, - :stage_idx) + # don't create the same build twice + unless commit.builds.find_by(ref: ref, tag: tag, trigger_request: trigger_request, name: build_attrs[:name]) + build_attrs.slice!(:name, + :commands, + :tag_list, + :options, + :allow_failure, + :stage, + :stage_idx) - build_attrs.merge!(ref: ref, - tag: tag, - trigger_request: trigger_request, - user: user) + build_attrs.merge!(ref: ref, + tag: tag, + trigger_request: trigger_request, + user: user) - commit.builds.create!(build_attrs) + commit.builds.create!(build_attrs) + end end end end diff --git a/app/services/ci/create_commit_service.rb b/app/services/ci/create_commit_service.rb index edbb07580c9..fc1ae5774d5 100644 --- a/app/services/ci/create_commit_service.rb +++ b/app/services/ci/create_commit_service.rb @@ -1,7 +1,6 @@ module Ci class CreateCommitService - def execute(project, params, user) - before_sha = params[:before] + def execute(project, user, params) sha = params[:checkout_sha] || params[:after] origin_ref = params[:ref] diff --git a/app/views/ci/commits/show.html.haml b/app/views/ci/commits/show.html.haml index 69487320175..7217671fe95 100644 --- a/app/views/ci/commits/show.html.haml +++ b/app/views/ci/commits/show.html.haml @@ -9,9 +9,9 @@ .gray-content-block.second-block .row .col-sm-6 - %p - %span.attr-name Commit: - #{gitlab_commit_link(@project, @commit.sha)} + %p + %span.attr-name Commit: + #{gitlab_commit_link(@project, @commit.sha)} .col-sm-6 - if @commit.git_author_name || @commit.git_author_email %p diff --git a/lib/ci/api/commits.rb b/lib/ci/api/commits.rb index 6a5b52b17de..a60769d8305 100644 --- a/lib/ci/api/commits.rb +++ b/lib/ci/api/commits.rb @@ -51,7 +51,7 @@ module Ci required_attributes! [:project_id, :data, :project_token] project = Ci::Project.find(params[:project_id]) authenticate_project_token!(project) - commit = Ci::CreateCommitService.new.execute(project, params[:data], current_user) + commit = Ci::CreateCommitService.new.execute(project, current_user, params[:data]) if commit.persisted? present commit, with: Entities::CommitWithBuilds diff --git a/spec/factories/ci/commits.rb b/spec/factories/ci/commits.rb index 9226e04a7b3..0c67e579a79 100644 --- a/spec/factories/ci/commits.rb +++ b/spec/factories/ci/commits.rb @@ -17,7 +17,7 @@ # Read about factories at https://github.com/thoughtbot/factory_girl FactoryGirl.define do - factory :ci_commit, class: Ci::Commit do + factory :ci_empty_commit, class: Ci::Commit do sha '97de212e80737a608d939f648d959671fb0a0142' gl_project factory: :empty_project @@ -40,7 +40,7 @@ FactoryGirl.define do end end - factory :ci_commit_yaml_stub do + factory :ci_commit 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 diff --git a/spec/features/ci/commits_spec.rb b/spec/features/ci/commits_spec.rb index 657a9dabe9e..712a6137260 100644 --- a/spec/features/ci/commits_spec.rb +++ b/spec/features/ci/commits_spec.rb @@ -38,10 +38,9 @@ describe "Commits" do end it "shows warning" do - @commit.push_data[:ci_yaml_file] = nil - @commit.save + @commit_no_yaml = FactoryGirl.create :ci_empty_commit - visit ci_commit_path(@commit) + visit ci_commit_path(@commit_no_yaml) expect(page).to have_content ".gitlab-ci.yml not found in this commit" end diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb index 49482ac2b12..93568904d85 100644 --- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb +++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb @@ -20,8 +20,8 @@ module Ci except: nil, name: :rspec, only: nil, - script: "pwd\nrspec", - tags: [], + commands: "pwd\nrspec", + tag_list: [], options: {}, allow_failure: false }) @@ -117,8 +117,8 @@ module Ci stage: "test", name: :rspec, only: nil, - script: "pwd\nrspec", - tags: [], + commands: "pwd\nrspec", + tag_list: [], options: { image: "ruby:2.1", services: ["mysql"] @@ -143,8 +143,8 @@ module Ci stage: "test", name: :rspec, only: nil, - script: "pwd\nrspec", - tags: [], + commands: "pwd\nrspec", + tag_list: [], options: { image: "ruby:2.5", services: ["postgresql"] diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index d74063e5782..da56f6e31ae 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -28,7 +28,7 @@ require 'spec_helper' describe Ci::Build do let(:project) { FactoryGirl.create :ci_project } let(:gl_project) { FactoryGirl.create :empty_project, gitlab_ci_project: project } - let(:commit) { FactoryGirl.create :ci_commit_yaml_stub, gl_project: gl_project } + let(:commit) { FactoryGirl.create :ci_commit, gl_project: gl_project } let(:build) { FactoryGirl.create :ci_build, commit: commit } subject { build } @@ -352,8 +352,8 @@ describe Ci::Build do end describe :project_recipients do - let (:pusher_email) { 'pusher@gitlab.test' } - let (:user) { User.new(notification_email: pusher_email) } + let(:pusher_email) { 'pusher@gitlab.test' } + let(:user) { User.new(notification_email: pusher_email) } subject { build.project_recipients } before do diff --git a/spec/models/ci/commit_spec.rb b/spec/models/ci/commit_spec.rb index 63602e89e37..d18220f119b 100644 --- a/spec/models/ci/commit_spec.rb +++ b/spec/models/ci/commit_spec.rb @@ -65,15 +65,6 @@ describe Ci::Commit do end end - describe :short_sha do - subject { commit.short_before_sha } - - it 'has 8 items' do - expect(subject.size).to eq(8) - end - it { expect(commit.before_sha).to start_with(subject) } - end - describe :short_sha do subject { commit.short_sha } @@ -87,7 +78,7 @@ describe Ci::Commit do end describe :create_builds do - let(:commit) { FactoryGirl.create :ci_commit_yaml_stub, gl_project: gl_project } + let(:commit) { FactoryGirl.create :ci_commit, gl_project: gl_project } def create_builds(trigger_request = nil) commit.create_builds('master', false, nil, trigger_request) diff --git a/spec/models/ci/project_services/hip_chat_message_spec.rb b/spec/models/ci/project_services/hip_chat_message_spec.rb index 1903c036924..6d257638359 100644 --- a/spec/models/ci/project_services/hip_chat_message_spec.rb +++ b/spec/models/ci/project_services/hip_chat_message_spec.rb @@ -7,7 +7,7 @@ describe Ci::HipChatMessage do let(:commit) { FactoryGirl.create(:ci_commit_with_one_job) } let(:build) do - commit.create_builds + commit.create_builds('master', false, nil) commit.builds.first end @@ -43,7 +43,7 @@ describe Ci::HipChatMessage do context 'when all matrix builds succeed' do it 'returns a successful message' do - commit.create_builds + commit.create_builds('master', false, nil) commit.builds.update_all(status: "success") commit.reload @@ -56,7 +56,7 @@ describe Ci::HipChatMessage do context 'when at least one matrix build fails' do it 'returns a failure message' do - commit.create_builds + commit.create_builds('master', false, nil) first_build = commit.builds.first second_build = commit.builds.last first_build.update(status: "success") diff --git a/spec/models/ci/project_services/mail_service_spec.rb b/spec/models/ci/project_services/mail_service_spec.rb index 0d9f85959ba..04e870dce7f 100644 --- a/spec/models/ci/project_services/mail_service_spec.rb +++ b/spec/models/ci/project_services/mail_service_spec.rb @@ -29,12 +29,13 @@ describe Ci::MailService do describe 'Sends email for' do let(:mail) { Ci::MailService.new } + let(:user) { User.new(notification_email: 'git@example.com')} describe 'failed build' do let(:project) { FactoryGirl.create(:ci_project, email_add_pusher: true) } let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } - let(:build) { FactoryGirl.create(:ci_build, status: :failed, commit: commit) } + let(:build) { FactoryGirl.create(:ci_build, status: :failed, commit: commit, user: user) } before do allow(mail).to receive_messages( @@ -57,7 +58,7 @@ describe Ci::MailService do let(:project) { FactoryGirl.create(:ci_project, email_add_pusher: true, email_only_broken_builds: false) } let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } - let(:build) { FactoryGirl.create(:ci_build, status: :success, commit: commit) } + let(:build) { FactoryGirl.create(:ci_build, status: :success, commit: commit, user: user) } before do allow(mail).to receive_messages( @@ -85,7 +86,7 @@ describe Ci::MailService do end let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } - let(:build) { FactoryGirl.create(:ci_build, status: :success, commit: commit) } + let(:build) { FactoryGirl.create(:ci_build, status: :success, commit: commit, user: user) } before do allow(mail).to receive_messages( @@ -114,7 +115,7 @@ describe Ci::MailService do end let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } - let(:build) { FactoryGirl.create(:ci_build, status: :success, commit: commit) } + let(:build) { FactoryGirl.create(:ci_build, status: :success, commit: commit, user: user) } before do allow(mail).to receive_messages( @@ -143,7 +144,7 @@ describe Ci::MailService do end let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } - let(:build) { FactoryGirl.create(:ci_build, status: :success, commit: commit) } + let(:build) { FactoryGirl.create(:ci_build, status: :success, commit: commit, user: user) } before do allow(mail).to receive_messages( @@ -166,7 +167,7 @@ describe Ci::MailService do end let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } let(:commit) { FactoryGirl.create(:ci_commit, gl_project: gl_project) } - let(:build) { FactoryGirl.create(:ci_build, status: :failed, commit: commit) } + let(:build) { FactoryGirl.create(:ci_build, status: :failed, commit: commit, user: user) } before do allow(mail).to receive_messages( diff --git a/spec/models/ci/project_services/slack_message_spec.rb b/spec/models/ci/project_services/slack_message_spec.rb index 7b541802d7d..0870276c78f 100644 --- a/spec/models/ci/project_services/slack_message_spec.rb +++ b/spec/models/ci/project_services/slack_message_spec.rb @@ -7,7 +7,7 @@ describe Ci::SlackMessage do let(:commit) { FactoryGirl.create(:ci_commit_with_one_job) } let(:build) do - commit.create_builds + commit.create_builds('master', false, nil) commit.builds.first end @@ -47,7 +47,7 @@ describe Ci::SlackMessage do let(:color) { 'good' } it 'returns a message with success' do - commit.create_builds + commit.create_builds('master', false, nil) commit.builds.update_all(status: "success") commit.reload @@ -63,7 +63,7 @@ describe Ci::SlackMessage do let(:color) { 'danger' } it 'returns a message with information about failed build' do - commit.create_builds + commit.create_builds('master', false, nil) first_build = commit.builds.first second_build = commit.builds.last first_build.update(status: "success") diff --git a/spec/requests/ci/api/builds_spec.rb b/spec/requests/ci/api/builds_spec.rb index bad250fbf48..576b0a11b9e 100644 --- a/spec/requests/ci/api/builds_spec.rb +++ b/spec/requests/ci/api/builds_spec.rb @@ -19,7 +19,7 @@ describe Ci::API::API do describe "POST /builds/register" do it "should start a build" do commit = FactoryGirl.create(:ci_commit, gl_project: gl_project) - commit.create_builds + commit.create_builds('master', false, nil) build = commit.builds.first post ci_api("/builds/register"), token: runner.token, info: { platform: :darwin } @@ -55,7 +55,7 @@ describe Ci::API::API do it "returns options" do commit = FactoryGirl.create(:ci_commit, gl_project: gl_project) - commit.create_builds + commit.create_builds('master', false, nil) post ci_api("/builds/register"), token: runner.token, info: { platform: :darwin } @@ -65,7 +65,7 @@ describe Ci::API::API do it "returns variables" do commit = FactoryGirl.create(:ci_commit, gl_project: gl_project) - commit.create_builds + commit.create_builds('master', false, nil) project.variables << Ci::Variable.new(key: "SECRET_KEY", value: "secret_value") post ci_api("/builds/register"), token: runner.token, info: { platform: :darwin } @@ -82,7 +82,7 @@ describe Ci::API::API do commit = FactoryGirl.create(:ci_commit, gl_project: gl_project) trigger_request = FactoryGirl.create(:ci_trigger_request_with_variables, commit: commit, trigger: trigger) - commit.create_builds(trigger_request) + commit.create_builds('master', false, 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 } diff --git a/spec/services/ci/create_commit_service_spec.rb b/spec/services/ci/create_commit_service_spec.rb index 84ab0a615dd..a797f73565e 100644 --- a/spec/services/ci/create_commit_service_spec.rb +++ b/spec/services/ci/create_commit_service_spec.rb @@ -4,11 +4,16 @@ module Ci describe CreateCommitService do let(:service) { CreateCommitService.new } let(:project) { FactoryGirl.create(:ci_project) } + let(:user) { nil } + + before do + stub_ci_commit_to_return_yaml_file + end describe :execute do context 'valid params' do let(:commit) do - service.execute(project, + service.execute(project, user, ref: 'refs/heads/master', before: '00000000', after: '31das312', @@ -26,7 +31,7 @@ module Ci context "skip tag if there is no build for it" do it "creates commit if there is appropriate job" do - result = service.execute(project, + result = service.execute(project, user, ref: 'refs/tags/0_1', before: '00000000', after: '31das312', @@ -38,8 +43,9 @@ module Ci 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) - result = service.execute(project, + result = service.execute(project, user, ref: 'refs/heads/0_1', before: '00000000', after: '31das312', @@ -51,11 +57,12 @@ module Ci end it 'fails commits without .gitlab-ci.yml' do - result = service.execute(project, + stub_ci_commit_yaml_file(nil) + result = service.execute(project, user, ref: 'refs/heads/0_1', before: '00000000', after: '31das312', - ci_yaml_file: config, + ci_yaml_file: nil, commits: [ { message: 'Message' } ] ) expect(result).to be_persisted @@ -64,9 +71,15 @@ module Ci 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 } + end + it "skips builds creation if there is [ci skip] tag in commit message" do - commits = [{ message: "some message[ci skip]" }] - commit = service.execute(project, + commits = [{ message: message }] + commit = service.execute(project, user, ref: 'refs/tags/0_1', before: '00000000', after: '31das312', @@ -78,9 +91,10 @@ module Ci end it "does not skips builds creation if there is no [ci skip] tag in commit message" do - commits = [{ message: "some message" }] + allow_any_instance_of(Ci::Commit).to receive(:git_commit_message) { "some message" } - commit = service.execute(project, + commits = [{ message: "some message" }] + commit = service.execute(project, user, ref: 'refs/tags/0_1', before: '00000000', after: '31das312', @@ -92,8 +106,9 @@ module Ci end it "skips builds creation if there is [ci skip] tag in commit message and yaml is invalid" do - commits = [{ message: "some message[ci skip]" }] - commit = service.execute(project, + stub_ci_commit_yaml_file('invalid: file') + commits = [{ message: message }] + commit = service.execute(project, user, ref: 'refs/tags/0_1', before: '00000000', after: '31das312', @@ -106,8 +121,10 @@ module Ci 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 } + commits = [{ message: "message" }] - commit = service.execute(project, + commit = service.execute(project, user, ref: 'refs/heads/master', before: '00000000', after: '31das312', @@ -116,7 +133,7 @@ module Ci ) expect(commit.builds.count(:all)).to eq(2) - commit = service.execute(project, + commit = service.execute(project, user, ref: 'refs/heads/master', before: '00000000', after: '31das312', @@ -127,9 +144,11 @@ module Ci end it "creates commit with failed status if yaml is invalid" do + stub_ci_commit_yaml_file('invalid: file') + commits = [{ message: "some message" }] - commit = service.execute(project, + commit = service.execute(project, user, ref: 'refs/tags/0_1', before: '00000000', after: '31das312', diff --git a/spec/support/stub_gitlab_calls.rb b/spec/support/stub_gitlab_calls.rb index 5e6744afda1..5b3eb1bfc5f 100644 --- a/spec/support/stub_gitlab_calls.rb +++ b/spec/support/stub_gitlab_calls.rb @@ -13,6 +13,14 @@ 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) + end + + def stub_ci_commit_yaml_file(ci_yaml) + allow_any_instance_of(Ci::Commit).to receive(:ci_yaml_file) { ci_yaml } + end + private def gitlab_url -- cgit v1.2.1 From 782c8f9aa0a32def807da126e9f07f278772b6a2 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Mon, 5 Oct 2015 13:37:50 +0200 Subject: Fix triggers spec --- app/services/ci/create_trigger_request_service.rb | 10 ++++--- .../ci/create_trigger_request_service_spec.rb | 31 ++++++---------------- 2 files changed, 15 insertions(+), 26 deletions(-) diff --git a/app/services/ci/create_trigger_request_service.rb b/app/services/ci/create_trigger_request_service.rb index f13ed787ed2..3597372528b 100644 --- a/app/services/ci/create_trigger_request_service.rb +++ b/app/services/ci/create_trigger_request_service.rb @@ -1,10 +1,14 @@ module Ci class CreateTriggerRequestService def execute(project, trigger, ref, variables = nil) - commit = project.gl_project.commit(ref) - return unless commit + target = project.gl_project.repository.rev_parse_target(ref) + return unless target - ci_commit = project.gl_project.ensure_ci_commit(commit.sha) + # check if ref is tag + sha = target.oid + tag = target.is_a?(Rugged::Tag) || target.is_a?(Rugged::Tag::Annotation) + + ci_commit = project.gl_project.ensure_ci_commit(sha) trigger_request = trigger.trigger_requests.create!( variables: variables ) diff --git a/spec/services/ci/create_trigger_request_service_spec.rb b/spec/services/ci/create_trigger_request_service_spec.rb index 525a24cc200..7aa1912b2a3 100644 --- a/spec/services/ci/create_trigger_request_service_spec.rb +++ b/spec/services/ci/create_trigger_request_service_spec.rb @@ -3,19 +3,19 @@ require 'spec_helper' describe Ci::CreateTriggerRequestService do let(:service) { Ci::CreateTriggerRequestService.new } let(:project) { FactoryGirl.create :ci_project } - let(:gl_project) { FactoryGirl.create :empty_project, gitlab_ci_project: project } + let(:gl_project) { FactoryGirl.create :project, gitlab_ci_project: project } let(:trigger) { FactoryGirl.create :ci_trigger, project: project } + before do + stub_ci_commit_to_return_yaml_file + end + describe :execute do context 'valid params' do subject { service.execute(project, trigger, 'master') } - before do - @commit = FactoryGirl.create :ci_commit, gl_project: gl_project - end - it { expect(subject).to be_kind_of(Ci::TriggerRequest) } - it { expect(subject.commit).to eq(@commit) } + it { expect(subject.commit).to be_kind_of(Ci::Commit) } end context 'no commit for ref' do @@ -28,26 +28,11 @@ describe Ci::CreateTriggerRequestService do subject { service.execute(project, trigger, 'master') } before do - FactoryGirl.create :ci_commit_without_jobs, gl_project: gl_project + stub_ci_commit_yaml_file('{}') + FactoryGirl.create :ci_commit, gl_project: gl_project end it { expect(subject).to be_nil } end - - context 'for multiple commits' do - subject { service.execute(project, trigger, 'master') } - - before do - @commit1 = FactoryGirl.create :ci_commit, committed_at: 2.hour.ago, gl_project: gl_project - @commit2 = FactoryGirl.create :ci_commit, committed_at: 1.hour.ago, gl_project: gl_project - @commit3 = FactoryGirl.create :ci_commit, committed_at: 3.hour.ago, gl_project: gl_project - end - - context 'retries latest one' do - it { expect(subject).to be_kind_of(Ci::TriggerRequest) } - it { expect(subject).to be_persisted } - it { expect(subject.commit).to eq(@commit2) } - end - end end end -- cgit v1.2.1 From 5064c9038c1ae2fa6c48bc46c58f49c72ff1963a Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Mon, 5 Oct 2015 13:51:28 +0200 Subject: Fix next bunch of tests --- app/models/ci/build.rb | 4 ++++ app/services/ci/create_trigger_request_service.rb | 7 +++++-- spec/requests/ci/api/builds_spec.rb | 4 ++++ spec/requests/ci/api/triggers_spec.rb | 18 ++++++++++-------- 4 files changed, 23 insertions(+), 10 deletions(-) diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 30a8b5aa816..89af83d8efc 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -146,6 +146,10 @@ module Ci delegate :sha, :short_sha, :project, to: :commit, prefix: false + def before_sha + Gitlab::Git::BLANK_SHA + end + def trace_html html = Ci::Ansi2html::convert(trace) if trace.present? html || '' diff --git a/app/services/ci/create_trigger_request_service.rb b/app/services/ci/create_trigger_request_service.rb index 3597372528b..083cea77202 100644 --- a/app/services/ci/create_trigger_request_service.rb +++ b/app/services/ci/create_trigger_request_service.rb @@ -1,10 +1,11 @@ module Ci class CreateTriggerRequestService def execute(project, trigger, ref, variables = nil) - target = project.gl_project.repository.rev_parse_target(ref) - return unless target + return unless project.gl_project + return unless project.gl_project.repository # check if ref is tag + target = project.gl_project.repository.rev_parse_target(ref) sha = target.oid tag = target.is_a?(Rugged::Tag) || target.is_a?(Rugged::Tag::Annotation) @@ -16,6 +17,8 @@ module Ci if ci_commit.create_builds(ref, tag, nil, trigger_request) trigger_request end + rescue Rugged::OdbError + nil end end end diff --git a/spec/requests/ci/api/builds_spec.rb b/spec/requests/ci/api/builds_spec.rb index 576b0a11b9e..54c1d0199f6 100644 --- a/spec/requests/ci/api/builds_spec.rb +++ b/spec/requests/ci/api/builds_spec.rb @@ -7,6 +7,10 @@ describe Ci::API::API do let(:project) { FactoryGirl.create(:ci_project) } let(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } + before do + stub_ci_commit_to_return_yaml_file + end + describe "Builds API for runners" do let(:shared_runner) { FactoryGirl.create(:ci_runner, token: "SharedRunner") } let(:shared_project) { FactoryGirl.create(:ci_project, name: "SharedProject") } diff --git a/spec/requests/ci/api/triggers_spec.rb b/spec/requests/ci/api/triggers_spec.rb index bbe98e7dacd..c98a74dcc2c 100644 --- a/spec/requests/ci/api/triggers_spec.rb +++ b/spec/requests/ci/api/triggers_spec.rb @@ -6,7 +6,7 @@ describe Ci::API::API do describe 'POST /projects/:project_id/refs/:ref/trigger' do let!(:trigger_token) { 'secure token' } let!(:project) { FactoryGirl.create(:ci_project) } - let!(:gl_project) { FactoryGirl.create(:empty_project, gitlab_ci_project: project) } + let!(:gl_project) { FactoryGirl.create(:project, gitlab_ci_project: project) } let!(:project2) { FactoryGirl.create(:ci_project) } let!(:trigger) { FactoryGirl.create(:ci_trigger, project: project, token: trigger_token) } let(:options) do @@ -15,6 +15,10 @@ describe Ci::API::API do } end + before do + stub_ci_commit_to_return_yaml_file + end + context 'Handles errors' do it 'should return bad request if token is missing' do post ci_api("/projects/#{project.id}/refs/master/trigger") @@ -33,15 +37,13 @@ describe Ci::API::API do end context 'Have a commit' do - before do - @commit = FactoryGirl.create(:ci_commit, gl_project: gl_project) - end + let(:commit) { project.commits.last } it 'should create builds' do post ci_api("/projects/#{project.id}/refs/master/trigger"), options expect(response.status).to eq(201) - @commit.builds.reload - expect(@commit.builds.size).to eq(2) + commit.builds.reload + expect(commit.builds.size).to eq(2) end it 'should return bad request with no builds created if there\'s no commit for that ref' do @@ -70,8 +72,8 @@ describe Ci::API::API do it 'create trigger request with variables' do post ci_api("/projects/#{project.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) + commit.builds.reload + expect(commit.builds.first.trigger_request.variables).to eq(variables) end end end -- cgit v1.2.1 From 0367dbf04392a200b5a2e0fcbab6269ff283fa54 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Mon, 5 Oct 2015 14:15:15 +0200 Subject: Fix build pipelining --- app/models/ci/build.rb | 5 ++-- app/models/ci/commit.rb | 10 ++++++++ spec/models/ci/commit_spec.rb | 55 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 89af83d8efc..f35224916ed 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -50,6 +50,7 @@ module Ci scope :latest, ->() { where(id: unscope(:select).select('max(id)').group(:name)).order(stage_idx: :asc) } scope :ignore_failures, ->() { where(allow_failure: false) } scope :for_ref, ->(ref) { where(ref: ref) } + scope :similar, ->(build) { where(ref: build.ref, tag: build.tag, trigger_request_id: build.trigger_request_id) } acts_as_taggable @@ -125,8 +126,8 @@ module Ci Ci::WebHookService.new.build_end(build) end - if build.commit.success? - build.commit.create_next_builds(build.trigger_request) + if build.commit.should_create_next_builds?(build) + build.commit.create_next_builds(build.ref, build.tag, build.user, build.trigger_request) end project.execute_services(build) diff --git a/app/models/ci/commit.rb b/app/models/ci/commit.rb index 31da7e8f2b6..c77921979a6 100644 --- a/app/models/ci/commit.rb +++ b/app/models/ci/commit.rb @@ -224,6 +224,16 @@ module Ci update!(committed_at: DateTime.now) end + def should_create_next_builds?(build) + # don't create other builds if this one is retried + other_builds = builds.similar(build).latest + return false unless other_builds.include?(build) + + other_builds.all? do |build| + build.success? || build.ignored? + end + end + private def save_yaml_error(error) diff --git a/spec/models/ci/commit_spec.rb b/spec/models/ci/commit_spec.rb index d18220f119b..91cf96a6666 100644 --- a/spec/models/ci/commit_spec.rb +++ b/spec/models/ci/commit_spec.rb @@ -215,4 +215,59 @@ describe Ci::Commit do expect(commit.coverage).to be_nil end end + + describe :should_create_next_builds? do + before do + @build1 = FactoryGirl.create :ci_build, commit: commit, name: 'build1', ref: 'master', tag: false, status: :success + @build2 = FactoryGirl.create :ci_build, commit: commit, name: 'build1', ref: 'develop', tag: false, status: :failed + @build3 = FactoryGirl.create :ci_build, commit: commit, name: 'build1', ref: 'master', tag: true, status: :failed + @build4 = FactoryGirl.create :ci_build, commit: commit, name: 'build4', ref: 'master', tag: false, status: :success + end + + context 'for success' do + it 'to create if all succeeded' do + expect(commit.should_create_next_builds?(@build4)).to be_truthy + end + end + + context 'for failed' do + before do + @build4.update_attributes(status: :failed) + end + + it 'to not create' do + expect(commit.should_create_next_builds?(@build4)).to be_falsey + end + + context 'and ignore failures for current' do + before do + @build4.update_attributes(allow_failure: true) + end + + it 'to create' do + expect(commit.should_create_next_builds?(@build4)).to be_truthy + end + end + end + + context 'for running' do + before do + @build4.update_attributes(status: :running) + end + + it 'to not create' do + expect(commit.should_create_next_builds?(@build4)).to be_falsey + end + end + + context 'for retried' do + before do + @build5 = FactoryGirl.create :ci_build, commit: commit, name: 'build4', ref: 'master', tag: false, status: :failed + end + + it 'to not create' do + expect(commit.should_create_next_builds?(@build4)).to be_falsey + end + end + end end -- cgit v1.2.1 From f42078f7c14b3a8a32f486ab0e3ec7ef791fc097 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Mon, 5 Oct 2015 14:31:51 +0200 Subject: Fix rest of tests --- app/services/ci/create_trigger_request_service.rb | 13 ++- app/services/ci/web_hook_service.rb | 1 + spec/factories/ci/builds.rb | 1 + spec/features/ci/commits_spec.rb | 8 +- .../ci/project_services/hip_chat_message_spec.rb | 83 ++++++------------ .../ci/project_services/slack_message_spec.rb | 97 +++++++--------------- 6 files changed, 67 insertions(+), 136 deletions(-) diff --git a/app/services/ci/create_trigger_request_service.rb b/app/services/ci/create_trigger_request_service.rb index 083cea77202..ea82dbb2bf4 100644 --- a/app/services/ci/create_trigger_request_service.rb +++ b/app/services/ci/create_trigger_request_service.rb @@ -1,15 +1,14 @@ module Ci class CreateTriggerRequestService def execute(project, trigger, ref, variables = nil) - return unless project.gl_project - return unless project.gl_project.repository + commit = project.gl_project.commit(ref) + return unless commit # check if ref is tag - target = project.gl_project.repository.rev_parse_target(ref) - sha = target.oid - tag = target.is_a?(Rugged::Tag) || target.is_a?(Rugged::Tag::Annotation) + tag = project.gl_project.repository.find_tag(ref).present? + + ci_commit = project.gl_project.ensure_ci_commit(commit.sha) - ci_commit = project.gl_project.ensure_ci_commit(sha) trigger_request = trigger.trigger_requests.create!( variables: variables ) @@ -17,8 +16,6 @@ module Ci if ci_commit.create_builds(ref, tag, nil, trigger_request) trigger_request end - rescue Rugged::OdbError - nil end end end diff --git a/app/services/ci/web_hook_service.rb b/app/services/ci/web_hook_service.rb index 4bbca5c7da1..92e6df442b4 100644 --- a/app/services/ci/web_hook_service.rb +++ b/app/services/ci/web_hook_service.rb @@ -27,6 +27,7 @@ module Ci project_name: project.name, gitlab_url: project.gitlab_url, ref: build.ref, + before_sha: build.before_sha, sha: build.sha, }) end diff --git a/spec/factories/ci/builds.rb b/spec/factories/ci/builds.rb index 8e2496398a6..21b582afba4 100644 --- a/spec/factories/ci/builds.rb +++ b/spec/factories/ci/builds.rb @@ -31,6 +31,7 @@ FactoryGirl.define do tag false started_at 'Di 29. Okt 09:51:28 CET 2013' finished_at 'Di 29. Okt 09:53:28 CET 2013' + commands 'ls -a' options do { image: "ruby:2.1", diff --git a/spec/features/ci/commits_spec.rb b/spec/features/ci/commits_spec.rb index 712a6137260..b4236e1e589 100644 --- a/spec/features/ci/commits_spec.rb +++ b/spec/features/ci/commits_spec.rb @@ -11,6 +11,10 @@ describe "Commits" do @commit.project.gl_project.team << [@user, :master] end + before do + stub_ci_commit_to_return_yaml_file + end + describe "GET /:project/commits/:sha" do before do visit ci_commit_path(@commit) @@ -38,9 +42,9 @@ describe "Commits" do end it "shows warning" do - @commit_no_yaml = FactoryGirl.create :ci_empty_commit + stub_ci_commit_yaml_file(nil) - visit ci_commit_path(@commit_no_yaml) + visit ci_commit_path(@commit) expect(page).to have_content ".gitlab-ci.yml not found in this commit" end diff --git a/spec/models/ci/project_services/hip_chat_message_spec.rb b/spec/models/ci/project_services/hip_chat_message_spec.rb index 6d257638359..e23d6ae2c28 100644 --- a/spec/models/ci/project_services/hip_chat_message_spec.rb +++ b/spec/models/ci/project_services/hip_chat_message_spec.rb @@ -3,70 +3,37 @@ require 'spec_helper' describe Ci::HipChatMessage do subject { Ci::HipChatMessage.new(build) } - context "One build" do - let(:commit) { FactoryGirl.create(:ci_commit_with_one_job) } + let(:commit) { FactoryGirl.create(:ci_commit_with_two_jobs) } - let(:build) do - commit.create_builds('master', false, nil) - commit.builds.first - end - - context 'when build succeeds' do - it 'returns a successful message' do - build.update(status: "success") - - expect( subject.status_color ).to eq 'green' - expect( subject.notify? ).to be_falsey - expect( subject.to_s ).to match(/Build '[^']+' #\d+/) - expect( subject.to_s ).to match(/Successful in \d+ second\(s\)\./) - end - end - - context 'when build fails' do - it 'returns a failure message' do - build.update(status: "failed") - - expect( subject.status_color ).to eq 'red' - expect( subject.notify? ).to be_truthy - expect( subject.to_s ).to match(/Build '[^']+' #\d+/) - expect( subject.to_s ).to match(/Failed in \d+ second\(s\)\./) - end - end + let(:build) do + commit.builds.first end - context "Several builds" do - let(:commit) { FactoryGirl.create(:ci_commit_with_two_jobs) } - - let(:build) do - commit.builds.first - end - - context 'when all matrix builds succeed' do - it 'returns a successful message' do - commit.create_builds('master', false, nil) - commit.builds.update_all(status: "success") - commit.reload + context 'when all matrix builds succeed' do + it 'returns a successful message' do + commit.create_builds('master', false, nil) + commit.builds.update_all(status: "success") + commit.reload - expect( subject.status_color ).to eq 'green' - expect( subject.notify? ).to be_falsey - expect( subject.to_s ).to match(/Commit #\d+/) - expect( subject.to_s ).to match(/Successful in \d+ second\(s\)\./) - end + expect(subject.status_color).to eq 'green' + expect(subject.notify?).to be_falsey + expect(subject.to_s).to match(/Commit #\d+/) + expect(subject.to_s).to match(/Successful in \d+ second\(s\)\./) end + end - context 'when at least one matrix build fails' do - it 'returns a failure message' do - commit.create_builds('master', false, nil) - first_build = commit.builds.first - second_build = commit.builds.last - first_build.update(status: "success") - second_build.update(status: "failed") - - expect( subject.status_color ).to eq 'red' - expect( subject.notify? ).to be_truthy - expect( subject.to_s ).to match(/Commit #\d+/) - expect( subject.to_s ).to match(/Failed in \d+ second\(s\)\./) - end + context 'when at least one matrix build fails' do + it 'returns a failure message' do + commit.create_builds('master', false, nil) + first_build = commit.builds.first + second_build = commit.builds.last + first_build.update(status: "success") + second_build.update(status: "failed") + + expect(subject.status_color).to eq 'red' + expect(subject.notify?).to be_truthy + expect(subject.to_s).to match(/Commit #\d+/) + expect(subject.to_s).to match(/Failed in \d+ second\(s\)\./) end end end diff --git a/spec/models/ci/project_services/slack_message_spec.rb b/spec/models/ci/project_services/slack_message_spec.rb index 0870276c78f..8adda6c86cc 100644 --- a/spec/models/ci/project_services/slack_message_spec.rb +++ b/spec/models/ci/project_services/slack_message_spec.rb @@ -3,80 +3,41 @@ require 'spec_helper' describe Ci::SlackMessage do subject { Ci::SlackMessage.new(commit) } - context "One build" do - let(:commit) { FactoryGirl.create(:ci_commit_with_one_job) } + let(:commit) { FactoryGirl.create(:ci_commit_with_two_jobs) } - let(:build) do - commit.create_builds('master', false, nil) - commit.builds.first - end - - context 'when build succeeded' do - let(:color) { 'good' } - - it 'returns a message with succeeded build' do - build.update(status: "success") - - expect(subject.color).to eq(color) - expect(subject.fallback).to include('Build') - expect(subject.fallback).to include("\##{build.id}") - expect(subject.fallback).to include('succeeded') - expect(subject.attachments.first[:fields]).to be_empty - end - end - - context 'when build failed' do - let(:color) { 'danger' } - - it 'returns a message with failed build' do - build.update(status: "failed") + context 'when all matrix builds succeeded' do + let(:color) { 'good' } - expect(subject.color).to eq(color) - expect(subject.fallback).to include('Build') - expect(subject.fallback).to include("\##{build.id}") - expect(subject.fallback).to include('failed') - expect(subject.attachments.first[:fields]).to be_empty - end + it 'returns a message with success' do + commit.create_builds('master', false, nil) + commit.builds.update_all(status: "success") + commit.reload + + expect(subject.color).to eq(color) + expect(subject.fallback).to include('Commit') + expect(subject.fallback).to include("\##{commit.id}") + expect(subject.fallback).to include('succeeded') + expect(subject.attachments.first[:fields]).to be_empty end end - context "Several builds" do - let(:commit) { FactoryGirl.create(:ci_commit_with_two_jobs) } - - context 'when all matrix builds succeeded' do - let(:color) { 'good' } - - it 'returns a message with success' do - commit.create_builds('master', false, nil) - commit.builds.update_all(status: "success") - commit.reload - - expect(subject.color).to eq(color) - expect(subject.fallback).to include('Commit') - expect(subject.fallback).to include("\##{commit.id}") - expect(subject.fallback).to include('succeeded') - expect(subject.attachments.first[:fields]).to be_empty - end - end - - context 'when one of matrix builds failed' do - let(:color) { 'danger' } + context 'when one of matrix builds failed' do + let(:color) { 'danger' } - it 'returns a message with information about failed build' do - commit.create_builds('master', false, nil) - first_build = commit.builds.first - second_build = commit.builds.last - first_build.update(status: "success") - second_build.update(status: "failed") - - expect(subject.color).to eq(color) - expect(subject.fallback).to include('Commit') - expect(subject.fallback).to include("\##{commit.id}") - expect(subject.fallback).to include('failed') - expect(subject.attachments.first[:fields].size).to eq(1) - expect(subject.attachments.first[:fields].first[:title]).to eq(second_build.name) - expect(subject.attachments.first[:fields].first[:value]).to include("\##{second_build.id}") - end + it 'returns a message with information about failed build' do + commit.create_builds('master', false, nil) + first_build = commit.builds.first + second_build = commit.builds.last + first_build.update(status: "success") + second_build.update(status: "failed") + + expect(subject.color).to eq(color) + expect(subject.fallback).to include('Commit') + expect(subject.fallback).to include("\##{commit.id}") + expect(subject.fallback).to include('failed') + expect(subject.attachments.first[:fields].size).to eq(1) + expect(subject.attachments.first[:fields].first[:title]).to eq(second_build.name) + expect(subject.attachments.first[:fields].first[:value]).to include("\##{second_build.id}") end end end -- cgit v1.2.1 From 198f4b703d98892e062525a37e2420429d83369d Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Mon, 5 Oct 2015 14:37:42 +0200 Subject: Fix db/schema.rb --- db/schema.rb | 94 +++++++++++++++++++++++------------------------------------- 1 file changed, 36 insertions(+), 58 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index f2bda91f799..0e8d54fb267 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -13,6 +13,9 @@ ActiveRecord::Schema.define(version: 20151005075649) do + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" + create_table "abuse_reports", force: true do |t| t.integer "reporter_id" t.integer "user_id" @@ -42,8 +45,8 @@ ActiveRecord::Schema.define(version: 20151005075649) do t.string "after_sign_out_path" t.integer "session_expire_delay", default: 10080, null: false t.text "import_sources" - t.boolean "ci_enabled", default: true, null: false t.text "help_page_text" + t.boolean "ci_enabled", default: true, null: false end create_table "audit_events", force: true do |t| @@ -82,60 +85,42 @@ ActiveRecord::Schema.define(version: 20151005075649) do t.integer "project_id" t.string "status" t.datetime "finished_at" - t.text "trace", limit: 2147483647 + t.text "trace" t.datetime "created_at" t.datetime "updated_at" t.datetime "started_at" t.integer "runner_id" - t.float "coverage", limit: 24 + t.float "coverage" t.integer "commit_id" t.text "commands" t.integer "job_id" t.string "name" - t.boolean "deploy", default: false + t.boolean "deploy", default: false t.text "options" - t.boolean "allow_failure", default: false, null: false + t.boolean "allow_failure", default: false, null: false t.string "stage" t.integer "trigger_request_id" - t.integer "gl_project_id" t.integer "stage_idx" t.boolean "tag" t.string "ref" - t.text "push_data" t.integer "user_id" end - add_index "ci_builds", ["commit_id", "name"], name: "index_ci_builds_on_commit_id_and_name", using: :btree add_index "ci_builds", ["commit_id", "stage_idx", "created_at"], name: "index_ci_builds_on_commit_id_and_stage_idx_and_created_at", using: :btree add_index "ci_builds", ["commit_id"], name: "index_ci_builds_on_commit_id", using: :btree add_index "ci_builds", ["project_id", "commit_id"], name: "index_ci_builds_on_project_id_and_commit_id", using: :btree add_index "ci_builds", ["project_id"], name: "index_ci_builds_on_project_id", using: :btree add_index "ci_builds", ["runner_id"], name: "index_ci_builds_on_runner_id", using: :btree - create_table "ci_commit_statuses", force: true do |t| - t.integer "commit_id" - t.string "sha" - t.string "ref" - t.string "state" - t.string "target_url" - t.string "description" - t.string "context", default: "default" - t.datetime "created_at" - t.datetime "updated_at" - end - - add_index "ci_commit_statuses", ["commit_id", "context", "ref"], name: "index_ci_commit_statuses_on_commit_id_and_context_and_ref", using: :btree - add_index "ci_commit_statuses", ["commit_id", "ref"], name: "index_ci_commit_statuses_on_commit_id_and_ref", using: :btree - create_table "ci_commits", force: true do |t| t.integer "project_id" t.string "ref" t.string "sha" t.string "before_sha" - t.text "push_data", limit: 16777215 + t.text "push_data" t.datetime "created_at" t.datetime "updated_at" - t.boolean "tag", default: false + t.boolean "tag", default: false t.text "yaml_errors" t.datetime "committed_at" t.integer "gl_project_id" @@ -154,7 +139,6 @@ ActiveRecord::Schema.define(version: 20151005075649) do t.text "description" t.datetime "created_at" t.datetime "updated_at" - t.integer "gl_project_id" end add_index "ci_events", ["created_at"], name: "index_ci_events_on_created_at", using: :btree @@ -202,11 +186,10 @@ ActiveRecord::Schema.define(version: 20151005075649) do end create_table "ci_runner_projects", force: true do |t| - t.integer "runner_id", null: false - t.integer "project_id", null: false + t.integer "runner_id", null: false + t.integer "project_id", null: false t.datetime "created_at" t.datetime "updated_at" - t.integer "gl_project_id" end add_index "ci_runner_projects", ["project_id"], name: "index_ci_runner_projects_on_project_id", using: :btree @@ -230,12 +213,11 @@ ActiveRecord::Schema.define(version: 20151005075649) do create_table "ci_services", force: true do |t| t.string "type" t.string "title" - t.integer "project_id", null: false + t.integer "project_id", null: false t.datetime "created_at" t.datetime "updated_at" - t.boolean "active", default: false, null: false + t.boolean "active", default: false, null: false t.text "properties" - t.integer "gl_project_id" end add_index "ci_services", ["project_id"], name: "index_ci_services_on_project_id", using: :btree @@ -280,11 +262,10 @@ ActiveRecord::Schema.define(version: 20151005075649) do create_table "ci_triggers", force: true do |t| t.string "token" - t.integer "project_id", null: false + t.integer "project_id", null: false t.datetime "deleted_at" t.datetime "created_at" t.datetime "updated_at" - t.integer "gl_project_id" end add_index "ci_triggers", ["deleted_at"], name: "index_ci_triggers_on_deleted_at", using: :btree @@ -296,17 +277,15 @@ ActiveRecord::Schema.define(version: 20151005075649) do t.text "encrypted_value" t.string "encrypted_value_salt" t.string "encrypted_value_iv" - t.integer "gl_project_id" end add_index "ci_variables", ["project_id"], name: "index_ci_variables_on_project_id", using: :btree create_table "ci_web_hooks", force: true do |t| - t.string "url", null: false - t.integer "project_id", null: false + t.string "url", null: false + t.integer "project_id", null: false t.datetime "created_at" t.datetime "updated_at" - t.integer "gl_project_id" end create_table "deploy_keys_projects", force: true do |t| @@ -452,9 +431,9 @@ ActiveRecord::Schema.define(version: 20151005075649) do create_table "merge_request_diffs", force: true do |t| t.string "state" - t.text "st_commits", limit: 2147483647 - t.text "st_diffs", limit: 2147483647 - t.integer "merge_request_id", null: false + t.text "st_commits" + t.text "st_diffs" + t.integer "merge_request_id", null: false t.datetime "created_at" t.datetime "updated_at" end @@ -537,8 +516,8 @@ ActiveRecord::Schema.define(version: 20151005075649) do t.string "line_code" t.string "commit_id" t.integer "noteable_id" - t.boolean "system", default: false, null: false - t.text "st_diff", limit: 2147483647 + t.boolean "system", default: false, null: false + t.text "st_diff" t.integer "updated_by_id" end @@ -607,26 +586,25 @@ ActiveRecord::Schema.define(version: 20151005075649) do t.datetime "created_at" t.datetime "updated_at" t.integer "creator_id" - t.boolean "issues_enabled", default: true, null: false - t.boolean "wall_enabled", default: true, null: false - t.boolean "merge_requests_enabled", default: true, null: false - t.boolean "wiki_enabled", default: true, null: false + t.boolean "issues_enabled", default: true, null: false + t.boolean "wall_enabled", default: true, null: false + t.boolean "merge_requests_enabled", default: true, null: false + t.boolean "wiki_enabled", default: true, null: false t.integer "namespace_id" - t.string "issues_tracker", default: "gitlab", null: false + t.string "issues_tracker", default: "gitlab", null: false t.string "issues_tracker_id" - t.boolean "snippets_enabled", default: true, null: false + t.boolean "snippets_enabled", default: true, null: false t.datetime "last_activity_at" t.string "import_url" - t.integer "visibility_level", default: 0, null: false - t.boolean "archived", default: false, null: false + t.integer "visibility_level", default: 0, null: false + t.boolean "archived", default: false, null: false t.string "avatar" t.string "import_status" - t.float "repository_size", limit: 24, default: 0.0 - t.integer "star_count", default: 0, null: false + t.float "repository_size", default: 0.0 + t.integer "star_count", default: 0, null: false t.string "import_type" t.string "import_source" - t.integer "commit_count", default: 0 - t.boolean "shared_runners_enabled", default: false + t.integer "commit_count", default: 0 end add_index "projects", ["created_at", "id"], name: "index_projects_on_created_at_and_id", using: :btree @@ -678,15 +656,15 @@ ActiveRecord::Schema.define(version: 20151005075649) do create_table "snippets", force: true do |t| t.string "title" - t.text "content", limit: 2147483647 - t.integer "author_id", null: false + t.text "content" + t.integer "author_id", null: false t.integer "project_id" t.datetime "created_at" t.datetime "updated_at" t.string "file_name" t.datetime "expires_at" t.string "type" - t.integer "visibility_level", default: 0, null: false + t.integer "visibility_level", default: 0, null: false end add_index "snippets", ["author_id"], name: "index_snippets_on_author_id", using: :btree -- cgit v1.2.1 From fb12b81b422e0d17751f4b63462baa503996cd37 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Mon, 5 Oct 2015 14:39:56 +0200 Subject: Make rubocop happy --- spec/factories/ci/commits.rb | 4 ++-- spec/services/ci/create_commit_service_spec.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/factories/ci/commits.rb b/spec/factories/ci/commits.rb index 0c67e579a79..79e000b7ccb 100644 --- a/spec/factories/ci/commits.rb +++ b/spec/factories/ci/commits.rb @@ -30,13 +30,13 @@ FactoryGirl.define do factory :ci_commit_with_one_job do after(:build) do |commit| - allow(commit).to receive(:ci_yaml_file) { YAML.dump({rspec: {script: "ls"}}) } + allow(commit).to receive(:ci_yaml_file) { YAML.dump({ rspec: { script: "ls" } }) } end end factory :ci_commit_with_two_jobs do after(:build) do |commit| - allow(commit).to receive(:ci_yaml_file) { YAML.dump({rspec: {script: "ls"}, spinach: {script: "ls"}}) } + allow(commit).to receive(:ci_yaml_file) { YAML.dump({ rspec: { script: "ls" }, spinach: { script: "ls" } }) } end end diff --git a/spec/services/ci/create_commit_service_spec.rb b/spec/services/ci/create_commit_service_spec.rb index a797f73565e..707fe779dcc 100644 --- a/spec/services/ci/create_commit_service_spec.rb +++ b/spec/services/ci/create_commit_service_spec.rb @@ -71,7 +71,7 @@ module Ci end describe :ci_skip? do - let (:message) { "some message[ci skip]" } + let(:message) { "some message[ci skip]" } before do allow_any_instance_of(Ci::Commit).to receive(:git_commit_message) { message } -- cgit v1.2.1 From c9853897229ca5585c69c4675cbeefd9ca53147d Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Mon, 5 Oct 2015 15:59:31 +0200 Subject: Add stage tests --- app/models/ci/commit.rb | 3 ++- spec/models/ci/commit_spec.rb | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/app/models/ci/commit.rb b/app/models/ci/commit.rb index c77921979a6..46370034f9a 100644 --- a/app/models/ci/commit.rb +++ b/app/models/ci/commit.rb @@ -81,7 +81,8 @@ module Ci end def stage - builds_without_retry.group(:stage_idx).select(:stage).last + running_or_pending = builds_without_retry.running_or_pending + running_or_pending.limit(1).pluck(:stage).first end def create_builds(ref, tag, user, trigger_request = nil) diff --git a/spec/models/ci/commit_spec.rb b/spec/models/ci/commit_spec.rb index 91cf96a6666..acff1ddf0fc 100644 --- a/spec/models/ci/commit_spec.rb +++ b/spec/models/ci/commit_spec.rb @@ -74,6 +74,40 @@ describe Ci::Commit do it { expect(commit.sha).to start_with(subject) } end + describe :stage do + subject { commit.stage } + + before do + @second = FactoryGirl.create :ci_build, commit: commit, name: 'deploy', stage: 'deploy', stage_idx: 1, status: :pending + @first = FactoryGirl.create :ci_build, commit: commit, name: 'test', stage: 'test', stage_idx: 0, status: :pending + end + + it 'returns first running stage' do + is_expected.to eq('test') + end + + context 'first build succeeded' do + before do + @first.update_attributes(status: :success) + end + + it 'returns last running stage' do + is_expected.to eq('deploy') + end + end + + context 'all builds succeeded' do + before do + @first.update_attributes(status: :success) + @second.update_attributes(status: :success) + end + + it 'returns nil' do + is_expected.to be_nil + end + end + end + describe :create_next_builds do end -- cgit v1.2.1 From 29a7c6796e75d3a36c613622c7c7507646fd93a0 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Mon, 5 Oct 2015 16:06:35 +0200 Subject: Fix GitLabCiService and remove ci_yaml_file from CI push data --- app/models/project_services/gitlab_ci_service.rb | 23 ++-------------------- .../project_services/gitlab_ci_service_spec.rb | 8 ++++---- spec/requests/ci/api/commits_spec.rb | 3 +-- spec/services/ci/create_commit_service_spec.rb | 22 ++++++--------------- 4 files changed, 13 insertions(+), 43 deletions(-) diff --git a/app/models/project_services/gitlab_ci_service.rb b/app/models/project_services/gitlab_ci_service.rb index 17d1ef71945..b63a75cf3af 100644 --- a/app/models/project_services/gitlab_ci_service.rb +++ b/app/models/project_services/gitlab_ci_service.rb @@ -40,18 +40,9 @@ class GitlabCiService < CiService def execute(data) return unless supported_events.include?(data[:object_kind]) - sha = data[:checkout_sha] - - if sha.present? - file = ci_yaml_file(sha) - - if file && file.data - data.merge!(ci_yaml_file: file.data) - end - end - - ci_project = Ci::Project.find_by(gitlab_id: project.id) + ci_project = project.gitlab_ci_project if ci_project + current_user = User.find_by(id: data[:user_id]) Ci::CreateCommitService.new.execute(ci_project, current_user, data) end end @@ -99,14 +90,4 @@ class GitlabCiService < CiService def fields [] end - - private - - def ci_yaml_file(sha) - repository.blob_at(sha, '.gitlab-ci.yml') - end - - def repository - project.repository - end end diff --git a/spec/models/project_services/gitlab_ci_service_spec.rb b/spec/models/project_services/gitlab_ci_service_spec.rb index 683a403a907..c0b8a144c3a 100644 --- a/spec/models/project_services/gitlab_ci_service_spec.rb +++ b/spec/models/project_services/gitlab_ci_service_spec.rb @@ -39,8 +39,8 @@ describe GitlabCiService do end describe :build_page do - it { expect(@service.build_page("2ab7834c", 'master')).to eq("http://localhost/ci/projects/#{@ci_project.id}/refs/master/commits/2ab7834c")} - it { expect(@service.build_page("issue#2", 'master')).to eq("http://localhost/ci/projects/#{@ci_project.id}/refs/master/commits/issue%232")} + it { expect(@service.build_page("2ab7834c", 'master')).to eq("http://localhost/ci/projects/#{@ci_project.id}/commits/2ab7834c")} + it { expect(@service.build_page("issue#2", 'master')).to eq("http://localhost/ci/projects/#{@ci_project.id}/commits/issue%232")} end describe "execute" do @@ -48,8 +48,8 @@ describe GitlabCiService do let(:project) { create(:project, name: 'project') } let(:push_sample_data) { Gitlab::PushDataBuilder.build_sample(project, user) } - it "calls ci_yaml_file" do - expect(@service).to receive(:ci_yaml_file).with(push_sample_data[:checkout_sha]) + it "calls CreateCommitService" do + expect_any_instance_of(Ci::CreateCommitService).to receive(:execute).with(@ci_project, user, push_sample_data) @service.execute(push_sample_data) end diff --git a/spec/requests/ci/api/commits_spec.rb b/spec/requests/ci/api/commits_spec.rb index a41c321a300..6049135fd10 100644 --- a/spec/requests/ci/api/commits_spec.rb +++ b/spec/requests/ci/api/commits_spec.rb @@ -44,8 +44,7 @@ describe Ci::API::API, 'Commits' do "email" => "jordi@softcatala.org", } } - ], - ci_yaml_file: gitlab_ci_yaml + ] } end diff --git a/spec/services/ci/create_commit_service_spec.rb b/spec/services/ci/create_commit_service_spec.rb index 707fe779dcc..e3a8fe9681b 100644 --- a/spec/services/ci/create_commit_service_spec.rb +++ b/spec/services/ci/create_commit_service_spec.rb @@ -17,7 +17,6 @@ module Ci ref: 'refs/heads/master', before: '00000000', after: '31das312', - ci_yaml_file: gitlab_ci_yaml, commits: [ { message: "Message" } ] ) end @@ -35,7 +34,6 @@ module Ci ref: 'refs/tags/0_1', before: '00000000', after: '31das312', - ci_yaml_file: gitlab_ci_yaml, commits: [ { message: "Message" } ] ) expect(result).to be_persisted @@ -49,7 +47,6 @@ module Ci ref: 'refs/heads/0_1', before: '00000000', after: '31das312', - ci_yaml_file: config, commits: [ { message: "Message" } ] ) expect(result).to be_persisted @@ -62,7 +59,6 @@ module Ci ref: 'refs/heads/0_1', before: '00000000', after: '31das312', - ci_yaml_file: nil, commits: [ { message: 'Message' } ] ) expect(result).to be_persisted @@ -83,8 +79,7 @@ module Ci ref: 'refs/tags/0_1', before: '00000000', after: '31das312', - commits: commits, - ci_yaml_file: gitlab_ci_yaml + commits: commits ) expect(commit.builds.any?).to be false expect(commit.status).to eq("skipped") @@ -98,8 +93,7 @@ module Ci ref: 'refs/tags/0_1', before: '00000000', after: '31das312', - commits: commits, - ci_yaml_file: gitlab_ci_yaml + commits: commits ) expect(commit.builds.first.name).to eq("staging") @@ -112,8 +106,7 @@ module Ci ref: 'refs/tags/0_1', before: '00000000', after: '31das312', - commits: commits, - ci_yaml_file: "invalid: file" + commits: commits ) expect(commit.builds.any?).to be false expect(commit.status).to eq("skipped") @@ -128,8 +121,7 @@ module Ci ref: 'refs/heads/master', before: '00000000', after: '31das312', - commits: commits, - ci_yaml_file: gitlab_ci_yaml + commits: commits ) expect(commit.builds.count(:all)).to eq(2) @@ -137,8 +129,7 @@ module Ci ref: 'refs/heads/master', before: '00000000', after: '31das312', - commits: commits, - ci_yaml_file: gitlab_ci_yaml + commits: commits ) expect(commit.builds.count(:all)).to eq(2) end @@ -152,8 +143,7 @@ module Ci ref: 'refs/tags/0_1', before: '00000000', after: '31das312', - commits: commits, - ci_yaml_file: "invalid: file" + commits: commits ) expect(commit.status).to eq("failed") -- cgit v1.2.1 From 517815f40f8c88e543279e259d0b983e70c5a49e Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Mon, 5 Oct 2015 16:07:50 +0200 Subject: Fix gitlab_ci_yaml_processor specs --- spec/lib/ci/gitlab_ci_yaml_processor_spec.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb index 93568904d85..aba957da488 100644 --- a/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb +++ b/spec/lib/ci/gitlab_ci_yaml_processor_spec.rb @@ -17,6 +17,7 @@ module Ci expect(config_processor.builds_for_stage_and_ref(type, "master").size).to eq(1) expect(config_processor.builds_for_stage_and_ref(type, "master").first).to eq({ stage: "test", + stage_idx: 1, except: nil, name: :rspec, only: nil, @@ -115,6 +116,7 @@ module Ci expect(config_processor.builds_for_stage_and_ref("test", "master").first).to eq({ except: nil, stage: "test", + stage_idx: 1, name: :rspec, only: nil, commands: "pwd\nrspec", @@ -141,6 +143,7 @@ module Ci expect(config_processor.builds_for_stage_and_ref("test", "master").first).to eq({ except: nil, stage: "test", + stage_idx: 1, name: :rspec, only: nil, commands: "pwd\nrspec", -- cgit v1.2.1 From 97a11136d3e7d7ed57c7571d296d7b50617dce16 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Mon, 5 Oct 2015 16:21:18 +0200 Subject: Fix create_trigger_request_service_spec --- app/services/ci/create_trigger_request_service.rb | 3 ++- spec/requests/ci/api/triggers_spec.rb | 4 ++-- spec/services/ci/create_trigger_request_service_spec.rb | 8 ++++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/app/services/ci/create_trigger_request_service.rb b/app/services/ci/create_trigger_request_service.rb index ea82dbb2bf4..4b86cb0a1f5 100644 --- a/app/services/ci/create_trigger_request_service.rb +++ b/app/services/ci/create_trigger_request_service.rb @@ -10,7 +10,8 @@ module Ci ci_commit = project.gl_project.ensure_ci_commit(commit.sha) trigger_request = trigger.trigger_requests.create!( - variables: variables + variables: variables, + commit: ci_commit, ) if ci_commit.create_builds(ref, tag, nil, trigger_request) diff --git a/spec/requests/ci/api/triggers_spec.rb b/spec/requests/ci/api/triggers_spec.rb index c98a74dcc2c..93617fc4b3f 100644 --- a/spec/requests/ci/api/triggers_spec.rb +++ b/spec/requests/ci/api/triggers_spec.rb @@ -5,8 +5,8 @@ describe Ci::API::API do describe 'POST /projects/:project_id/refs/:ref/trigger' do let!(:trigger_token) { 'secure token' } - let!(:project) { FactoryGirl.create(:ci_project) } - let!(:gl_project) { FactoryGirl.create(:project, gitlab_ci_project: project) } + let!(:gl_project) { FactoryGirl.create(:project) } + let!(:project) { FactoryGirl.create(:ci_project, gl_project: gl_project) } let!(:project2) { FactoryGirl.create(:ci_project) } let!(:trigger) { FactoryGirl.create(:ci_trigger, project: project, token: trigger_token) } let(:options) do diff --git a/spec/services/ci/create_trigger_request_service_spec.rb b/spec/services/ci/create_trigger_request_service_spec.rb index 7aa1912b2a3..fcafae38644 100644 --- a/spec/services/ci/create_trigger_request_service_spec.rb +++ b/spec/services/ci/create_trigger_request_service_spec.rb @@ -2,9 +2,9 @@ require 'spec_helper' describe Ci::CreateTriggerRequestService do let(:service) { Ci::CreateTriggerRequestService.new } - let(:project) { FactoryGirl.create :ci_project } - let(:gl_project) { FactoryGirl.create :project, gitlab_ci_project: project } - let(:trigger) { FactoryGirl.create :ci_trigger, project: project } + let(:gl_project) { create(:project) } + let(:project) { create(:ci_project, gl_project: gl_project) } + let(:trigger) { create(:ci_trigger, project: project) } before do stub_ci_commit_to_return_yaml_file @@ -15,7 +15,7 @@ describe Ci::CreateTriggerRequestService do subject { service.execute(project, trigger, 'master') } it { expect(subject).to be_kind_of(Ci::TriggerRequest) } - it { expect(subject.commit).to be_kind_of(Ci::Commit) } + it { expect(subject.builds.first).to be_kind_of(Ci::Build) } end context 'no commit for ref' do -- cgit v1.2.1