summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--CHANGELOG2
-rw-r--r--Gemfile20
-rw-r--r--Gemfile.lock31
-rw-r--r--app/assets/javascripts/merge_request_tabs.js.coffee8
-rw-r--r--app/assets/javascripts/shortcuts_navigation.coffee1
-rw-r--r--app/controllers/projects/builds_controller.rb25
-rw-r--r--app/controllers/projects/refs_controller.rb7
-rw-r--r--app/helpers/gitlab_routing_helper.rb4
-rw-r--r--app/helpers/merge_requests_helper.rb2
-rw-r--r--app/helpers/projects_helper.rb4
-rw-r--r--app/helpers/runners_helper.rb13
-rw-r--r--app/models/ability.rb2
-rw-r--r--app/models/ci/commit.rb2
-rw-r--r--app/models/ci/project.rb2
-rw-r--r--app/models/ci/runner.rb4
-rw-r--r--app/models/commit_status.rb1
-rw-r--r--app/models/project.rb2
-rw-r--r--app/views/help/_shortcuts.html.haml6
-rw-r--r--app/views/layouts/nav/_project.html.haml10
-rw-r--r--app/views/projects/builds/_build.html.haml50
-rw-r--r--app/views/projects/builds/index.html.haml52
-rw-r--r--config/gitlab.yml.example24
-rw-r--r--config/initializers/1_settings.rb6
-rw-r--r--config/mail_room.yml39
-rw-r--r--config/mail_room.yml.example39
-rw-r--r--config/routes.rb10
-rw-r--r--doc/incoming_email/README.md299
-rw-r--r--features/project/source/browse_files.feature6
-rw-r--r--features/steps/project/commits/commits.rb2
-rw-r--r--features/steps/project/source/browse_files.rb13
-rw-r--r--lib/gitlab/incoming_email.rb4
-rw-r--r--lib/tasks/gitlab/check.rake37
-rw-r--r--spec/features/builds_spec.rb48
-rw-r--r--spec/models/ci/commit_spec.rb18
-rw-r--r--spec/models/ci/project_spec.rb18
-rw-r--r--spec/models/ci/runner_spec.rb2
-rw-r--r--spec/support/test_env.rb2
38 files changed, 485 insertions, 331 deletions
diff --git a/.gitignore b/.gitignore
index 2a97eacad48..73bde4cc761 100644
--- a/.gitignore
+++ b/.gitignore
@@ -25,7 +25,6 @@ config/initializers/rack_attack.rb
config/initializers/smtp_settings.rb
config/resque.yml
config/unicorn.rb
-config/mail_room.yml
config/secrets.yml
coverage/*
db/*.sqlite3
diff --git a/CHANGELOG b/CHANGELOG
index 07ff3d6de42..792ec4fbe29 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
Please view this file on the master branch, on stable branches it's out of date.
v 8.1.0 (unreleased)
+ - Fix error preventing displaying of commit data for a directory with a leading dot (Stan Hu)
- Make diff file view easier to use on mobile screens (Stan Hu)
- Add support for creating directories from Files page (Stan Hu)
- Allow removing of project without confirmation when JavaScript is disabled (Stan Hu)
@@ -17,6 +18,7 @@ v 8.1.0 (unreleased)
- Fix cases where Markdown did not render links in activity feed (Stan Hu)
- Add first and last to pagination (Zeger-Jan van de Weg)
- Added Commit Status API
+ - Added Builds View
- Show CI status on commit page
- Added CI_BUILD_TAG, _STAGE, _NAME and _TRIGGERED to CI builds
- Show CI status on Your projects page and Starred projects page
diff --git a/Gemfile b/Gemfile
index 567211cd9c0..29d9db05f42 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,13 +1,5 @@
source "https://rubygems.org"
-def darwin_only(require_as)
- RUBY_PLATFORM.include?('darwin') && require_as
-end
-
-def linux_only(require_as)
- RUBY_PLATFORM.include?('linux') && require_as
-end
-
gem 'rails', '4.1.12'
# Specify a sprockets version due to security issue
@@ -196,7 +188,7 @@ gem 'charlock_holmes', '~> 0.6.9.4'
gem "sass-rails", '~> 4.0.5'
gem "coffee-rails", '~> 4.1.0'
-gem "uglifier", '~> 2.3.2'
+gem "uglifier", '~> 2.7.2'
gem 'turbolinks', '~> 2.5.0'
gem 'jquery-turbolinks', '~> 2.0.1'
@@ -290,7 +282,7 @@ gem 'newrelic-grape'
gem 'octokit', '~> 3.7.0'
-gem "mail_room", "~> 0.6.0"
+gem "mail_room", "~> 0.6.1"
gem 'email_reply_parser', '~> 0.5.8'
@@ -304,11 +296,3 @@ gem 'oauth2', '~> 1.0.0'
# Soft deletion
gem "paranoia", "~> 2.0"
-
-group :development, :test do
- gem 'guard-rspec', '~> 4.2.0'
-
- gem 'rb-fsevent', require: darwin_only('rb-fsevent')
- gem 'growl', require: darwin_only('growl')
- gem 'rb-inotify', require: linux_only('rb-inotify')
-end
diff --git a/Gemfile.lock b/Gemfile.lock
index b06d3f37ed0..ee545f366f4 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -314,19 +314,6 @@ GEM
grape-entity (0.4.8)
activesupport
multi_json (>= 1.3.2)
- growl (1.0.3)
- guard (2.13.0)
- formatador (>= 0.2.4)
- listen (>= 2.7, <= 4.0)
- lumberjack (~> 1.0)
- nenv (~> 0.1)
- notiffany (~> 0.0)
- pry (>= 0.9.12)
- shellany (~> 0.0)
- thor (>= 0.18.1)
- guard-rspec (4.2.10)
- guard (~> 2.1)
- rspec (>= 2.14, < 4.0)
haml (4.0.7)
tilt
haml-rails (0.9.0)
@@ -387,12 +374,11 @@ GEM
celluloid (~> 0.16.0)
rb-fsevent (>= 0.9.3)
rb-inotify (>= 0.9)
- lumberjack (1.0.9)
macaddr (1.7.1)
systemu (~> 2.6.2)
mail (2.6.3)
mime-types (>= 1.16, < 3)
- mail_room (0.6.0)
+ mail_room (0.6.1)
method_source (0.8.2)
mime-types (1.25.1)
mimemagic (0.3.0)
@@ -403,7 +389,6 @@ GEM
multi_xml (0.5.5)
multipart-post (2.0.0)
mysql2 (0.3.20)
- nenv (0.2.0)
nested_form (0.3.2)
net-ldap (0.11)
net-scp (1.2.1)
@@ -416,9 +401,6 @@ GEM
newrelic_rpm (3.9.4.245)
nokogiri (1.6.6.2)
mini_portile (~> 0.6.0)
- notiffany (0.0.7)
- nenv (~> 0.1)
- shellany (~> 0.0)
nprogress-rails (0.1.2.3)
oauth (0.4.7)
oauth2 (1.0.0)
@@ -647,7 +629,6 @@ GEM
sexp_processor (4.6.0)
sham_rack (1.3.6)
rack
- shellany (0.0.1)
shoulda-matchers (2.8.0)
activesupport (>= 3.0.0)
sidekiq (3.3.0)
@@ -741,7 +722,7 @@ GEM
simple_oauth (~> 0.1.4)
tzinfo (1.2.2)
thread_safe (~> 0.1)
- uglifier (2.3.3)
+ uglifier (2.7.2)
execjs (>= 0.3.0)
json (>= 1.8.0)
underscore-rails (1.4.4)
@@ -841,8 +822,6 @@ DEPENDENCIES
gon (~> 5.0.0)
grape (~> 0.6.1)
grape-entity (~> 0.4.2)
- growl
- guard-rspec (~> 4.2.0)
haml-rails (~> 0.9.0)
hipchat (~> 1.5.0)
html-pipeline (~> 1.11.0)
@@ -854,7 +833,7 @@ DEPENDENCIES
jquery-ui-rails (~> 4.2.1)
kaminari (~> 0.16.3)
letter_opener (~> 1.1.2)
- mail_room (~> 0.6.0)
+ mail_room (~> 0.6.1)
minitest (~> 5.7.0)
mousetrap-rails (~> 1.4.6)
mysql2 (~> 0.3.16)
@@ -886,8 +865,6 @@ DEPENDENCIES
rack-oauth2 (~> 1.0.5)
rails (= 4.1.12)
raphael-rails (~> 2.1.2)
- rb-fsevent
- rb-inotify
rdoc (~> 3.6)
redcarpet (~> 3.3.2)
redis-rails (~> 4.0.0)
@@ -926,7 +903,7 @@ DEPENDENCIES
thin (~> 1.6.1)
tinder (~> 1.10.0)
turbolinks (~> 2.5.0)
- uglifier (~> 2.3.2)
+ uglifier (~> 2.7.2)
underscore-rails (~> 1.4.4)
unf (~> 0.1.4)
unicorn (~> 4.8.2)
diff --git a/app/assets/javascripts/merge_request_tabs.js.coffee b/app/assets/javascripts/merge_request_tabs.js.coffee
index 3e77ea515f8..593a8f42130 100644
--- a/app/assets/javascripts/merge_request_tabs.js.coffee
+++ b/app/assets/javascripts/merge_request_tabs.js.coffee
@@ -68,8 +68,8 @@ class @MergeRequestTabs
scrollToElement: (container) ->
if window.location.hash
- top = $(container + " " + window.location.hash).offset().top
- $('body').scrollTo(top)
+ $el = $("#{container} #{window.location.hash}")
+ $('body').scrollTo($el.offset().top) if $el.length
# Activate a tab based on the current action
activateTab: (action) ->
@@ -127,7 +127,7 @@ class @MergeRequestTabs
document.getElementById('commits').innerHTML = data.html
$('.js-timeago').timeago()
@commitsLoaded = true
- @scrollToElement(".commits")
+ @scrollToElement("#commits")
loadDiff: (source) ->
return if @diffsLoaded
@@ -137,7 +137,7 @@ class @MergeRequestTabs
success: (data) =>
document.getElementById('diffs').innerHTML = data.html
@diffsLoaded = true
- @scrollToElement(".diffs")
+ @scrollToElement("#diffs")
# Show or hide the loading spinner
#
diff --git a/app/assets/javascripts/shortcuts_navigation.coffee b/app/assets/javascripts/shortcuts_navigation.coffee
index 5b6f9e7e3f2..8decaedd87b 100644
--- a/app/assets/javascripts/shortcuts_navigation.coffee
+++ b/app/assets/javascripts/shortcuts_navigation.coffee
@@ -7,6 +7,7 @@ class @ShortcutsNavigation extends Shortcuts
Mousetrap.bind('g e', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-project-activity'))
Mousetrap.bind('g f', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-tree'))
Mousetrap.bind('g c', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-commits'))
+ Mousetrap.bind('g b', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-builds'))
Mousetrap.bind('g n', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-network'))
Mousetrap.bind('g g', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-graphs'))
Mousetrap.bind('g i', -> ShortcutsNavigation.findAndFollowLink('.shortcuts-issues'))
diff --git a/app/controllers/projects/builds_controller.rb b/app/controllers/projects/builds_controller.rb
index 4e4ac6689d3..54c01ddf238 100644
--- a/app/controllers/projects/builds_controller.rb
+++ b/app/controllers/projects/builds_controller.rb
@@ -1,11 +1,32 @@
class Projects::BuildsController < Projects::ApplicationController
before_action :ci_project
- before_action :build
+ before_action :build, except: [:index, :cancel_all]
- before_action :authorize_admin_project!, except: [:show, :status]
+ before_action :authorize_admin_project!, except: [:index, :show, :status]
layout "project"
+ def index
+ @scope = params[:scope]
+ @all_builds = project.ci_builds.order('created_at DESC').page(params[:page]).per(30)
+
+ @builds =
+ case @scope
+ when 'all'
+ @all_builds
+ when 'finished'
+ @all_builds.finished
+ else
+ @all_builds.running_or_pending
+ end
+ end
+
+ def cancel_all
+ @project.ci_builds.running_or_pending.each(&:cancel)
+
+ redirect_to namespace_project_builds_path(project.namespace, project)
+ end
+
def show
@builds = @ci_project.commits.find_by_sha(@build.sha).builds.order('id DESC')
@builds = @builds.where("id not in (?)", @build.id).page(params[:page]).per(20)
diff --git a/app/controllers/projects/refs_controller.rb b/app/controllers/projects/refs_controller.rb
index 6080c849c8d..c4e18c17077 100644
--- a/app/controllers/projects/refs_controller.rb
+++ b/app/controllers/projects/refs_controller.rb
@@ -3,6 +3,7 @@ class Projects::RefsController < Projects::ApplicationController
include TreeHelper
before_action :require_non_empty_project
+ before_action :validate_ref_id
before_action :assign_ref_vars
before_action :authorize_download_code!
@@ -71,4 +72,10 @@ class Projects::RefsController < Projects::ApplicationController
format.js
end
end
+
+ private
+
+ def validate_ref_id
+ return not_found! if params[:id].present? && params[:id] !~ Gitlab::Regex.git_reference_regex
+ end
end
diff --git a/app/helpers/gitlab_routing_helper.rb b/app/helpers/gitlab_routing_helper.rb
index 4d9da6ff837..b0b536d4649 100644
--- a/app/helpers/gitlab_routing_helper.rb
+++ b/app/helpers/gitlab_routing_helper.rb
@@ -25,6 +25,10 @@ module GitlabRoutingHelper
namespace_project_commits_path(project.namespace, project, @ref || project.repository.root_ref)
end
+ def project_builds_path(project, *args)
+ namespace_project_builds_path(project.namespace, project, *args)
+ end
+
def activity_project_path(project, *args)
activity_namespace_project_path(project.namespace, project, *args)
end
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index 81773e7afcf..728d877ace2 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -47,7 +47,7 @@ module MergeRequestsHelper
end
def issues_sentence(issues)
- issues.map { |i| "##{i.iid}" }.to_sentence
+ issues.map(&:to_reference).to_sentence
end
def mr_change_branches_path(merge_request)
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index a0220af4c30..b7965aee875 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -113,6 +113,10 @@ module ProjectsHelper
nav_tabs << :merge_requests
end
+ if can?(current_user, :read_build, project)
+ nav_tabs << :builds
+ end
+
if can?(current_user, :admin_project, project)
nav_tabs << :settings
end
diff --git a/app/helpers/runners_helper.rb b/app/helpers/runners_helper.rb
index 5afebab88e1..bf551778cb3 100644
--- a/app/helpers/runners_helper.rb
+++ b/app/helpers/runners_helper.rb
@@ -13,4 +13,17 @@ module RunnersHelper
title: "Runner is #{status}, last contact was #{time_ago_in_words(runner.contacted_at)} ago"
end
end
+
+ def runner_link(runner)
+ display_name = truncate(runner.display_name, length: 20)
+ id = "\##{runner.id}"
+
+ if current_user && current_user.admin
+ link_to ci_admin_runner_path(runner) do
+ display_name + id
+ end
+ else
+ display_name + id
+ end
+ end
end
diff --git a/app/models/ability.rb b/app/models/ability.rb
index 77c121ca5e8..38bc2086683 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -41,6 +41,7 @@ class Ability
:read_project_member,
:read_merge_request,
:read_note,
+ :read_build,
:download_code
]
@@ -127,6 +128,7 @@ class Ability
:read_project_member,
:read_merge_request,
:read_note,
+ :read_build,
:create_project,
:create_issue,
:create_note
diff --git a/app/models/ci/commit.rb b/app/models/ci/commit.rb
index 68864edfbbf..cd45366b34e 100644
--- a/app/models/ci/commit.rb
+++ b/app/models/ci/commit.rb
@@ -24,6 +24,8 @@ module Ci
has_many :builds, class_name: 'Ci::Build'
has_many :trigger_requests, dependent: :destroy, class_name: 'Ci::TriggerRequest'
+ scope :ordered, -> { order('CASE WHEN ci_commits.committed_at IS NULL THEN 0 ELSE 1 END', :committed_at, :id) }
+
validates_presence_of :sha
validate :valid_commit_sha
diff --git a/app/models/ci/project.rb b/app/models/ci/project.rb
index ef28353a30c..eb65c773570 100644
--- a/app/models/ci/project.rb
+++ b/app/models/ci/project.rb
@@ -205,7 +205,7 @@ module Ci
end
def commits
- gl_project.ci_commits
+ gl_project.ci_commits.ordered
end
def builds
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index 02a3e9db1fa..1b3669f1b7a 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -59,7 +59,7 @@ module Ci
end
def display_name
- return token unless !description.blank?
+ return short_sha unless !description.blank?
description
end
@@ -95,7 +95,7 @@ module Ci
end
def short_sha
- token[0...10]
+ token[0...8] if token
end
end
end
diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb
index 92905c618eb..0b71838d515 100644
--- a/app/models/commit_status.rb
+++ b/app/models/commit_status.rb
@@ -16,6 +16,7 @@ class CommitStatus < ActiveRecord::Base
scope :success, -> { where(status: 'success') }
scope :failed, -> { where(status: 'failed') }
scope :running_or_pending, -> { where(status:[:running, :pending]) }
+ scope :finished, -> { where(status:[:success, :failed, :canceled]) }
scope :latest, -> { where(id: unscope(:select).select('max(id)').group(:name, :ref)) }
scope :ordered, -> { order(:ref, :stage_idx, :name) }
scope :for_ref, ->(ref) { where(ref: ref) }
diff --git a/app/models/project.rb b/app/models/project.rb
index cd30467fae3..88cd88dcb5a 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -119,7 +119,7 @@ class Project < ActiveRecord::Base
has_many :deploy_keys, through: :deploy_keys_projects
has_many :users_star_projects, dependent: :destroy
has_many :starrers, through: :users_star_projects, source: :user
- has_many :ci_commits, ->() { order('CASE WHEN ci_commits.committed_at IS NULL THEN 0 ELSE 1 END', :committed_at, :id) }, dependent: :destroy, class_name: 'Ci::Commit', foreign_key: :gl_project_id
+ has_many :ci_commits, dependent: :destroy, class_name: 'Ci::Commit', foreign_key: :gl_project_id
has_many :ci_builds, through: :ci_commits, source: :builds, dependent: :destroy, class_name: 'Ci::Build'
has_one :import_data, dependent: :destroy, class_name: "ProjectImportData"
diff --git a/app/views/help/_shortcuts.html.haml b/app/views/help/_shortcuts.html.haml
index e809d99ba71..67349fcbd78 100644
--- a/app/views/help/_shortcuts.html.haml
+++ b/app/views/help/_shortcuts.html.haml
@@ -102,6 +102,12 @@
%tr
%td.shortcut
.key g
+ .key b
+ %td
+ Go to builds
+ %tr
+ %td.shortcut
+ .key g
.key n
%td
Go to network graph
diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml
index e4c285d8023..53a913fe8f3 100644
--- a/app/views/layouts/nav/_project.html.haml
+++ b/app/views/layouts/nav/_project.html.haml
@@ -32,12 +32,20 @@
Files
- if project_nav_tab? :commits
- = nav_link(controller: %w(commit commits compare repositories tags branches builds)) do
+ = nav_link(controller: %w(commit commits compare repositories tags branches)) do
= link_to project_commits_path(@project), title: 'Commits', class: 'shortcuts-commits', data: {placement: 'right'} do
= icon('history fw')
%span
Commits
+ - if project_nav_tab? :builds
+ = nav_link(controller: %w(builds)) do
+ = link_to project_builds_path(@project), title: 'Builds', class: 'shortcuts-builds', data: {placement: 'right'} do
+ = icon('cubes fw')
+ %span
+ Builds
+ %span.count.builds_counter= @project.ci_builds.running_or_pending.count(:all)
+
- if project_nav_tab? :network
= nav_link(controller: %w(network)) do
= link_to namespace_project_network_path(@project.namespace, @project, current_ref), title: 'Network', class: 'shortcuts-network', data: {placement: 'right'} do
diff --git a/app/views/projects/builds/_build.html.haml b/app/views/projects/builds/_build.html.haml
new file mode 100644
index 00000000000..ff146f7389b
--- /dev/null
+++ b/app/views/projects/builds/_build.html.haml
@@ -0,0 +1,50 @@
+%tr.build
+ %td.status
+ = ci_status_with_icon(build.status)
+
+ %td.commit_status-link
+ - if build.target_url
+ = link_to build.target_url do
+ %strong Build ##{build.id}
+ - else
+ %strong Build ##{build.id}
+
+ %td
+ = link_to build.short_sha, namespace_project_commit_path(@project.namespace, @project, build.sha)
+
+ %td
+ = link_to build.ref, namespace_project_commits_path(@project.namespace, @project, build.ref)
+
+ %td
+ - if build.runner
+ = runner_link(build.runner)
+ - else
+ .light none
+
+ %td
+ = build.name
+
+ .pull-right
+ - if build.tags.any?
+ - build.tags.each do |tag|
+ %span.label.label-primary
+ = tag
+ - if build.trigger_request
+ %span.label.label-info triggered
+ - if build.allow_failure
+ %span.label.label-danger allowed to fail
+
+ %td.duration
+ - if build.duration
+ #{duration_in_words(build.finished_at, build.started_at)}
+
+ %td.timestamp
+ - if build.finished_at
+ %span #{time_ago_in_words build.finished_at} ago
+
+ %td
+ .pull-right
+ - if current_user && can?(current_user, :manage_builds, @project)
+ - if build.cancel_url
+ = link_to build.cancel_url, title: 'Cancel' do
+ %i.fa.fa-remove.cred
diff --git a/app/views/projects/builds/index.html.haml b/app/views/projects/builds/index.html.haml
new file mode 100644
index 00000000000..b04784025f1
--- /dev/null
+++ b/app/views/projects/builds/index.html.haml
@@ -0,0 +1,52 @@
+- page_title "Builds"
+- header_title project_title(@project, "Builds", project_builds_path(@project))
+
+.project-issuable-filter
+ .controls
+ - if @ci_project && current_user && can?(current_user, :manage_builds, @project)
+ .pull-left.hidden-xs
+ - if @all_builds.running_or_pending.any?
+ = link_to 'Cancel all', cancel_all_namespace_project_builds_path(@project.namespace, @project), data: { confirm: 'Are you sure?' }, class: 'btn btn-danger'
+
+ %ul.center-top-menu
+ %li{class: ('active' if @scope.nil?)}
+ = link_to project_builds_path(@project) do
+ Running
+ %span.badge.js-running-count= @all_builds.running_or_pending.size
+
+ %li{class: ('active' if @scope == 'finished')}
+ = link_to project_builds_path(@project, scope: :finished) do
+ Finished
+ %span.badge.js-running-count= @all_builds.finished.size
+
+ %li{class: ('active' if @scope == 'all')}
+ = link_to project_builds_path(@project, scope: :all) do
+ All
+ %span.badge.js-totalbuilds-count= @all_builds.size
+
+.gray-content-block
+ List of #{@scope || 'running'} builds from this project
+
+%ul.content-list
+ - if @builds.blank?
+ %li
+ .nothing-here-block No builds to show
+ - else
+ %table.table.builds
+ %thead
+ %tr
+ %th Status
+ %th Build ID
+ %th Commit
+ %th Ref
+ %th Runner
+ %th Name
+ %th Duration
+ %th Finished at
+ %th
+
+ - @builds.each do |build|
+ = render 'projects/builds/build', build: build
+
+ = paginate @builds
+
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index 4f7f0b6ef19..8b85981497a 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -99,7 +99,29 @@ production: &base
# For documentation on how to set this up, see http://doc.gitlab.com/ce/incoming_email/README.html
incoming_email:
enabled: false
- address: "incoming+%{key}@gitlab.example.com"
+
+ # The email address including the `%{key}` placeholder that will be replaced to reference the item being replied to.
+ # The `%{key}` placeholder is added after the user part, after a `+` character, before the `@`.
+ address: "gitlab-incoming+%{key}@gmail.com"
+
+ # Email account username
+ # With third party providers, this is usually the full email address.
+ # With self-hosted email servers, this is usually the user part of the email address.
+ user: "gitlab-incoming@gmail.com"
+ # Email account password
+ password: "[REDACTED]"
+
+ # IMAP server host
+ host: "imap.gmail.com"
+ # IMAP server port
+ port: 993
+ # Whether the IMAP server uses SSL
+ ssl: true
+ # Whether the IMAP server uses StartTLS
+ start_tls: false
+
+ # The mailbox where incoming mail will end up. Usually "inbox".
+ mailbox: "inbox"
## Gravatar
## For Libravatar see: http://doc.gitlab.com/ce/customization/libravatar.html
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index 4c78bd6e2fa..d5493ca038d 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -187,7 +187,11 @@ Settings.gitlab_ci['builds_path'] = File.expand_path(Settings.gitlab_ci[
# Reply by email
#
Settings['incoming_email'] ||= Settingslogic.new({})
-Settings.incoming_email['enabled'] = false if Settings.incoming_email['enabled'].nil?
+Settings.incoming_email['enabled'] = false if Settings.incoming_email['enabled'].nil?
+Settings.incoming_email['port'] = 143 if Settings.incoming_email['port'].nil?
+Settings.incoming_email['ssl'] = 143 if Settings.incoming_email['ssl'].nil?
+Settings.incoming_email['start_tls'] = 143 if Settings.incoming_email['start_tls'].nil?
+Settings.incoming_email['mailbox'] = "inbox" if Settings.incoming_email['mailbox'].nil?
#
# Gravatar
diff --git a/config/mail_room.yml b/config/mail_room.yml
new file mode 100644
index 00000000000..42f6f74c465
--- /dev/null
+++ b/config/mail_room.yml
@@ -0,0 +1,39 @@
+:mailboxes:
+<%
+require_relative 'config/environment.rb'
+
+if Gitlab::IncomingEmail.enabled?
+ config = Gitlab::IncomingEmail.config
+
+ redis_config_file = "config/resque.yml"
+ redis_url =
+ if File.exists?(redis_config_file)
+ YAML.load_file(redis_config_file)[Rails.env]
+ else
+ "redis://localhost:6379"
+ end
+ %>
+ -
+ :host: <%= config.host.to_json %>
+ :port: <%= config.port.to_json %>
+ :ssl: <%= config.ssl.to_json %>
+ :start_tls: <%= config.start_tls.to_json %>
+ :email: <%= config.user.to_json %>
+ :password: <%= config.password.to_json %>
+
+ :name: <%= config.mailbox.to_json %>
+
+ :delete_after_delivery: true
+
+ :delivery_method: sidekiq
+ :delivery_options:
+ :redis_url: <%= redis_url.to_json %>
+ :namespace: resque:gitlab
+ :queue: incoming_email
+ :worker: EmailReceiverWorker
+
+ :arbitration_method: redis
+ :arbitration_options:
+ :redis_url: <%= redis_url.to_json %>
+ :namespace: mail_room:gitlab
+<% end %>
diff --git a/config/mail_room.yml.example b/config/mail_room.yml.example
deleted file mode 100644
index bb624e8a187..00000000000
--- a/config/mail_room.yml.example
+++ /dev/null
@@ -1,39 +0,0 @@
-:mailboxes:
- -
- # # IMAP server host
- # :host: "imap.gmail.com"
- # # IMAP server port
- # :port: 993
- # # Whether the IMAP server uses SSL
- # :ssl: true
- # # Whether the IMAP server uses StartTLS
- # :start_tls: false
- # # Email account username. Usually the full email address.
- # :email: "gitlab-incoming@gmail.com"
- # # Email account password
- # :password: "password"
-
- # # The name of the mailbox where incoming mail will end up. Usually "inbox".
- # :name: "inbox"
-
- # # Always "sidekiq".
- # :delivery_method: sidekiq
- # # Always true.
- # :delete_after_delivery: true
- # :delivery_options:
- # # The URL to the Redis server used by Sidekiq. Should match the URL in config/resque.yml.
- # :redis_url: redis://localhost:6379
- # # Always "resque:gitlab".
- # :namespace: resque:gitlab
- # # Always "incoming_email".
- # :queue: incoming_email
- # # Always "EmailReceiverWorker".
- # :worker: EmailReceiverWorker
-
- # # Always "redis".
- # :arbitration_method: redis
- # :arbitration_options:
- # # The URL to the Redis server. Should match the URL in config/resque.yml.
- # :redis_url: redis://localhost:6379
- # # Always "mail_room:gitlab".
- # :namespace: mail_room:gitlab
diff --git a/config/routes.rb b/config/routes.rb
index 8e6fbf6340c..3dbe2c4dfcc 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -543,8 +543,10 @@ Gitlab::Application.routes.draw do
member do
# tree viewer logs
get 'logs_tree', constraints: { id: Gitlab::Regex.git_reference_regex }
+ # Directories with leading dots erroneously get rejected if git
+ # ref regex used in constraints. Regex verification now done in controller.
get 'logs_tree/*path' => 'refs#logs_tree', as: :logs_file, constraints: {
- id: Gitlab::Regex.git_reference_regex,
+ id: /.*/,
path: /.*/
}
end
@@ -585,7 +587,11 @@ Gitlab::Application.routes.draw do
end
end
- resources :builds, only: [:show] do
+ resources :builds, only: [:index, :show] do
+ collection do
+ get :cancel_all
+ end
+
member do
get :cancel
get :status
diff --git a/doc/incoming_email/README.md b/doc/incoming_email/README.md
index aafa2345fab..86d205ba7a5 100644
--- a/doc/incoming_email/README.md
+++ b/doc/incoming_email/README.md
@@ -4,9 +4,9 @@ GitLab can be set up to allow users to comment on issues and merge requests by r
## Get a mailbox
-Reply by email requires an IMAP-enabled email account, with a provider or server that supports [email sub-addressing](https://en.wikipedia.org/wiki/Email_address#Sub-addressing). Sub-addressing is a feature where any email to `user+some_arbitrary_tag@example.com` will end up in the mailbox for `user@example.com`, and is supported by providers such as Gmail, Yahoo! Mail, Outlook.com and iCloud, as well as the Postfix mail server which you can run on-premises.
+Reply by email requires an IMAP-enabled email account, with a provider or server that supports [email sub-addressing](https://en.wikipedia.org/wiki/Email_address#Sub-addressing). Sub-addressing is a feature where any email to `user+some_arbitrary_tag@example.com` will end up in the mailbox for `user@example.com`, and is supported by providers such as Gmail, Google Apps, Yahoo! Mail, Outlook.com and iCloud, as well as the Postfix mail server which you can run on-premises.
-If you want to use Gmail with Reply by email, make sure you have [IMAP access enabled](https://support.google.com/mail/troubleshooter/1668960?hl=en#ts=1665018) and [allow less secure apps to access the account](https://support.google.com/accounts/answer/6010255).
+If you want to use Gmail / Google Apps with Reply by email, make sure you have [IMAP access enabled](https://support.google.com/mail/troubleshooter/1668960?hl=en#ts=1665018) and [allow less secure apps to access the account](https://support.google.com/accounts/answer/6010255).
To set up a basic Postfix mail server with IMAP access on Ubuntu, follow [these instructions](./postfix.md).
@@ -14,30 +14,62 @@ To set up a basic Postfix mail server with IMAP access on Ubuntu, follow [these
### Omnibus package installations
-1. Find the `incoming_email` section in `/etc/gitlab/gitlab.rb`, enable the feature, enter the email address including a placeholder for the `key` that references the item being replied to and fill in the details for your specific IMAP server and email account:
+1. Find the `incoming_email` section in `/etc/gitlab/gitlab.rb`, enable the feature and fill in the details for your specific IMAP server and email account:
```ruby
- # Postfix mail server, assumes mailbox incoming@gitlab.example.com
+ # Configuration for Postfix mail server, assumes mailbox incoming@gitlab.example.com
gitlab_rails['incoming_email_enabled'] = true
+
+ # The email address including a placeholder for the key that references the item being replied to.
+ # The `%{key}` placeholder is added after the user part, before the `@`.
gitlab_rails['incoming_email_address'] = "incoming+%{key}@gitlab.example.com"
- gitlab_rails['incoming_email_host'] = "gitlab.example.com" # IMAP server host
- gitlab_rails['incoming_email_port'] = 143 # IMAP server port
- gitlab_rails['incoming_email_ssl'] = false # Whether the IMAP server uses SSL
- gitlab_rails['incoming_email_email'] = "incoming" # Email account username. Usually the full email address.
- gitlab_rails['incoming_email_password'] = "[REDACTED]" # Email account password
- gitlab_rails['incoming_email_mailbox_name'] = "inbox" # The name of the mailbox where incoming mail will end up. Usually "inbox".
+
+ # Email account username
+ # With third party providers, this is usually the full email address.
+ # With self-hosted email servers, this is usually the user part of the email address.
+ gitlab_rails['incoming_email_email'] = "incoming"
+ # Email account password
+ gitlab_rails['incoming_email_password'] = "[REDACTED]"
+
+ # IMAP server host
+ gitlab_rails['incoming_email_host'] = "gitlab.example.com"
+ # IMAP server port
+ gitlab_rails['incoming_email_port'] = 143
+ # Whether the IMAP server uses SSL
+ gitlab_rails['incoming_email_ssl'] = false
+ # Whether the IMAP server uses StartTLS
+ gitlab_rails['incoming_email_start_tls'] = false
+
+ # The mailbox where incoming mail will end up. Usually "inbox".
+ gitlab_rails['incoming_email_mailbox_name'] = "inbox"
```
```ruby
- # Gmail / Google Apps, assumes mailbox gitlab-incoming@gmail.com
+ # Configuration for Gmail / Google Apps, assumes mailbox gitlab-incoming@gmail.com
gitlab_rails['incoming_email_enabled'] = true
+
+ # The email address including the `%{key}` placeholder that will be replaced to reference the item being replied to.
+ # The `%{key}` placeholder is added after the user part, after a `+` character, before the `@`.
gitlab_rails['incoming_email_address'] = "gitlab-incoming+%{key}@gmail.com"
- gitlab_rails['incoming_email_host'] = "imap.gmail.com" # IMAP server host
- gitlab_rails['incoming_email_port'] = 993 # IMAP server port
- gitlab_rails['incoming_email_ssl'] = true # Whether the IMAP server uses SSL
- gitlab_rails['incoming_email_email'] = "gitlab-incoming@gmail.com" # Email account username. Usually the full email address.
- gitlab_rails['incoming_email_password'] = "[REDACTED]" # Email account password
- gitlab_rails['incoming_email_mailbox_name'] = "inbox" # The name of the mailbox where incoming mail will end up. Usually "inbox".
+
+ # Email account username
+ # With third party providers, this is usually the full email address.
+ # With self-hosted email servers, this is usually the user part of the email address.
+ gitlab_rails['incoming_email_email'] = "gitlab-incoming@gmail.com"
+ # Email account password
+ gitlab_rails['incoming_email_password'] = "[REDACTED]"
+
+ # IMAP server host
+ gitlab_rails['incoming_email_host'] = "imap.gmail.com"
+ # IMAP server port
+ gitlab_rails['incoming_email_port'] = 993
+ # Whether the IMAP server uses SSL
+ gitlab_rails['incoming_email_ssl'] = true
+ # Whether the IMAP server uses StartTLS
+ gitlab_rails['incoming_email_start_tls'] = false
+
+ # The mailbox where incoming mail will end up. Usually "inbox".
+ gitlab_rails['incoming_email_mailbox_name'] = "inbox"
```
As mentioned, the part after `+` in the address is ignored, and any email sent here will end up in the mailbox for `incoming@gitlab.example.com`/`gitlab-incoming@gmail.com`.
@@ -64,229 +96,146 @@ To set up a basic Postfix mail server with IMAP access on Ubuntu, follow [these
cd /home/git/gitlab
```
-1. Find the `incoming_email` section in `config/gitlab.yml`, enable the feature and enter the email address including a placeholder for the `key` that references the item being replied to:
+1. Find the `incoming_email` section in `config/gitlab.yml`, enable the feature and fill in the details for your specific IMAP server and email account:
```sh
sudo editor config/gitlab.yml
```
```yaml
- # Postfix mail server, assumes mailbox incoming@gitlab.example.com
+ # Configuration for Postfix mail server, assumes mailbox incoming@gitlab.example.com
incoming_email:
enabled: true
+
+ # The email address including the `%{key}` placeholder that will be replaced to reference the item being replied to.
+ # The `%{key}` placeholder is added after the user part, after a `+` character, before the `@`.
address: "incoming+%{key}@gitlab.example.com"
+
+ # Email account username
+ # With third party providers, this is usually the full email address.
+ # With self-hosted email servers, this is usually the user part of the email address.
+ user: "incoming"
+ # Email account password
+ password: "[REDACTED]"
+
+ # IMAP server host
+ host: "gitlab.example.com"
+ # IMAP server port
+ port: 143
+ # Whether the IMAP server uses SSL
+ ssl: false
+ # Whether the IMAP server uses StartTLS
+ start_tls: false
+
+ # The mailbox where incoming mail will end up. Usually "inbox".
+ mailbox: "inbox"
```
```yaml
- # Gmail / Google Apps, assumes mailbox gitlab-incoming@gmail.com
+ # Configuration for Gmail / Google Apps, assumes mailbox gitlab-incoming@gmail.com
incoming_email:
enabled: true
- address: "gitlab-incoming+%{key}@gmail.com"
- ```
-
- As mentioned, the part after `+` in the address is ignored, and any email sent here will end up in the mailbox for `incoming@gitlab.example.com`/`gitlab-incoming@gmail.com`.
-2. Copy `config/mail_room.yml.example` to `config/mail_room.yml`:
+ # The email address including the `%{key}` placeholder that will be replaced to reference the item being replied to.
+ # The `%{key}` placeholder is added after the user part, after a `+` character, before the `@`.
+ address: "gitlab-incoming+%{key}@gmail.com"
- ```sh
- sudo cp config/mail_room.yml.example config/mail_room.yml
- ```
+ # Email account username
+ # With third party providers, this is usually the full email address.
+ # With self-hosted email servers, this is usually the user part of the email address.
+ user: "gitlab-incoming@gmail.com"
+ # Email account password
+ password: "[REDACTED]"
-3. Uncomment the configuration options in `config/mail_room.yml` and fill in the details for your specific IMAP server and email account:
+ # IMAP server host
+ host: "imap.gmail.com"
+ # IMAP server port
+ port: 993
+ # Whether the IMAP server uses SSL
+ ssl: true
+ # Whether the IMAP server uses StartTLS
+ start_tls: false
- ```sh
- sudo editor config/mail_room.yml
- ```
-
- ```yaml
- # Postfix mail server
- :mailboxes:
- -
- # IMAP server host
- :host: "gitlab.example.com"
- # IMAP server port
- :port: 143
- # Whether the IMAP server uses SSL
- :ssl: false
- # Whether the IMAP server uses StartTLS
- :start_tls: false
- # Email account username. Usually the full email address.
- :email: "incoming"
- # Email account password
- :password: "[REDACTED]"
-
- # The name of the mailbox where incoming mail will end up. Usually "inbox".
- :name: "inbox"
-
- # Always "sidekiq".
- :delivery_method: sidekiq
- # Always true.
- :delete_after_delivery: true
- :delivery_options:
- # The URL to the Redis server used by Sidekiq. Should match the URL in config/resque.yml.
- :redis_url: redis://localhost:6379
- # Always "resque:gitlab".
- :namespace: resque:gitlab
- # Always "incoming_email".
- :queue: incoming_email
- # Always "EmailReceiverWorker"
- :worker: EmailReceiverWorker
-
- # Always "redis".
- :arbitration_method: redis
- :arbitration_options:
- # The URL to the Redis server. Should match the URL in config/resque.yml.
- :redis_url: redis://localhost:6379
- # Always "mail_room:gitlab".
- :namespace: mail_room:gitlab
+ # The mailbox where incoming mail will end up. Usually "inbox".
+ mailbox: "inbox"
```
- ```yaml
- # Gmail / Google Apps
- :mailboxes:
- -
- # IMAP server host
- :host: "imap.gmail.com"
- # IMAP server port
- :port: 993
- # Whether the IMAP server uses SSL
- :ssl: true
- # Whether the IMAP server uses StartTLS
- :start_tls: false
- # Email account username. Usually the full email address.
- :email: "gitlab-incoming@gmail.com"
- # Email account password
- :password: "[REDACTED]"
-
- # The name of the mailbox where incoming mail will end up. Usually "inbox".
- :name: "inbox"
-
- # Always "sidekiq".
- :delivery_method: sidekiq
- # Always true.
- :delete_after_delivery: true
- :delivery_options:
- # The URL to the Redis server used by Sidekiq. Should match the URL in config/resque.yml.
- :redis_url: redis://localhost:6379
- # Always "resque:gitlab".
- :namespace: resque:gitlab
- # Always "incoming_email".
- :queue: incoming_email
- # Always "EmailReceiverWorker"
- :worker: EmailReceiverWorker
-
- # Always "redis".
- :arbitration_method: redis
- :arbitration_options:
- # The URL to the Redis server. Should match the URL in config/resque.yml.
- :redis_url: redis://localhost:6379
- # Always "mail_room:gitlab".
- :namespace: mail_room:gitlab
- ```
+ As mentioned, the part after `+` in the address is ignored, and any email sent here will end up in the mailbox for `incoming@gitlab.example.com`/`gitlab-incoming@gmail.com`.
-5. Edit the init script configuration at `/etc/default/gitlab` to enable `mail_room`:
+1. Enable `mail_room` in the init script at `/etc/default/gitlab`:
```sh
sudo mkdir -p /etc/default
echo 'mail_room_enabled=true' | sudo tee -a /etc/default/gitlab
```
-6. Restart GitLab:
+1. Restart GitLab:
```sh
sudo service gitlab restart
```
-7. Verify that everything is configured correctly:
+1. Verify that everything is configured correctly:
```sh
sudo -u git -H bundle exec rake gitlab:incoming_email:check RAILS_ENV=production
```
-8. Reply by email should now be working.
+1. Reply by email should now be working.
### Development
1. Go to the GitLab installation directory.
-1. Find the `incoming_email` section in `config/gitlab.yml`, enable the feature and enter the email address including a placeholder for the `key` that references the item being replied to:
+1. Find the `incoming_email` section in `config/gitlab.yml`, enable the feature and fill in the details for your specific IMAP server and email account:
```yaml
- # Gmail / Google Apps, assumes mailbox gitlab-incoming@gmail.com
+ # Configuration for Gmail / Google Apps, assumes mailbox gitlab-incoming@gmail.com
incoming_email:
enabled: true
+
+ # The email address including a placeholder for the key that references the item being replied to.
+ # The `%{key}` placeholder is added after the user part, before the `@`.
address: "gitlab-incoming+%{key}@gmail.com"
- ```
- As mentioned, the part after `+` is ignored, and this will end up in the mailbox for `gitlab-incoming@gmail.com`.
+ # Email account username
+ # With third party providers, this is usually the full email address.
+ # With self-hosted email servers, this is usually the user part of the email address.
+ user: "gitlab-incoming@gmail.com"
+ # Email account password
+ password: "[REDACTED]"
-2. Copy `config/mail_room.yml.example` to `config/mail_room.yml`:
+ # IMAP server host
+ host: "imap.gmail.com"
+ # IMAP server port
+ port: 993
+ # Whether the IMAP server uses SSL
+ ssl: true
+ # Whether the IMAP server uses StartTLS
+ start_tls: false
- ```sh
- sudo cp config/mail_room.yml.example config/mail_room.yml
+ # The mailbox where incoming mail will end up. Usually "inbox".
+ mailbox: "inbox"
```
-3. Uncomment the configuration options in `config/mail_room.yml` and fill in the details for your specific IMAP server and email account:
-
- ```yaml
- # Gmail / Google Apps, assumes mailbox gitlab-incoming@gmail.com
- :mailboxes:
- -
- # IMAP server host
- :host: "imap.gmail.com"
- # IMAP server port
- :port: 993
- # Whether the IMAP server uses SSL
- :ssl: true
- # Whether the IMAP server uses StartTLS
- :start_tls: false
- # Email account username. Usually the full email address.
- :email: "gitlab-incoming@gmail.com"
- # Email account password
- :password: "[REDACTED]"
-
- # The name of the mailbox where incoming mail will end up. Usually "inbox".
- :name: "inbox"
-
- # Always "sidekiq".
- :delivery_method: sidekiq
- # Always true.
- :delete_after_delivery: true
- :delivery_options:
- # The URL to the Redis server used by Sidekiq. Should match the URL in config/resque.yml.
- :redis_url: redis://localhost:6379
- # Always "resque:gitlab".
- :namespace: resque:gitlab
- # Always "incoming_email".
- :queue: incoming_email
- # Always "EmailReceiverWorker"
- :worker: EmailReceiverWorker
-
- # Always "redis".
- :arbitration_method: redis
- :arbitration_options:
- # The URL to the Redis server. Should match the URL in config/resque.yml.
- :redis_url: redis://localhost:6379
- # Always "mail_room:gitlab".
- :namespace: mail_room:gitlab
- ```
+ As mentioned, the part after `+` is ignored, and this will end up in the mailbox for `gitlab-incoming@gmail.com`.
-4. Uncomment the `mail_room` line in your `Procfile`:
+1. Uncomment the `mail_room` line in your `Procfile`:
```yaml
mail_room: bundle exec mail_room -q -c config/mail_room.yml
```
-6. Restart GitLab:
+1. Restart GitLab:
```sh
bundle exec foreman start
```
-7. Verify that everything is configured correctly:
+1. Verify that everything is configured correctly:
```sh
bundle exec rake gitlab:incoming_email:check RAILS_ENV=development
```
-8. Reply by email should now be working.
+1. Reply by email should now be working.
diff --git a/features/project/source/browse_files.feature b/features/project/source/browse_files.feature
index 377c5e1a9a7..6b0484b6a38 100644
--- a/features/project/source/browse_files.feature
+++ b/features/project/source/browse_files.feature
@@ -205,3 +205,9 @@ Feature: Project Source Browse Files
And I see the ref 'test' has been selected
And I visit the 'test' tree
Then I see the commit data
+
+ @javascript
+ Scenario: I browse code with a leading dot in the directory
+ Given I switch ref to fix
+ And I visit the fix tree
+ Then I see the commit data for a directory with a leading dot
diff --git a/features/steps/project/commits/commits.rb b/features/steps/project/commits/commits.rb
index a3cb83880e3..e5b3f27135d 100644
--- a/features/steps/project/commits/commits.rb
+++ b/features/steps/project/commits/commits.rb
@@ -113,7 +113,7 @@ class Spinach::Features::ProjectCommits < Spinach::FeatureSteps
end
step 'I click status link' do
- click_link "Builds"
+ find('.commit-ci-menu').click_link "Builds"
end
step 'I see builds list' do
diff --git a/features/steps/project/source/browse_files.rb b/features/steps/project/source/browse_files.rb
index cb100ca0f54..1b27500497a 100644
--- a/features/steps/project/source/browse_files.rb
+++ b/features/steps/project/source/browse_files.rb
@@ -286,6 +286,10 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
select "'test'", from: 'ref'
end
+ step "I switch ref to fix" do
+ select "fix", from: 'ref'
+ end
+
step "I see the ref 'test' has been selected" do
expect(page).to have_selector '.select2-chosen', text: "'test'"
end
@@ -294,11 +298,20 @@ class Spinach::Features::ProjectSourceBrowseFiles < Spinach::FeatureSteps
visit namespace_project_tree_path(@project.namespace, @project, "'test'")
end
+ step "I visit the fix tree" do
+ visit namespace_project_tree_path(@project.namespace, @project, "fix/.testdir")
+ end
+
step 'I see the commit data' do
expect(page).to have_css('.tree-commit-link', visible: true)
expect(page).not_to have_content('Loading commit data...')
end
+ step 'I see the commit data for a directory with a leading dot' do
+ expect(page).to have_css('.tree-commit-link', visible: true)
+ expect(page).not_to have_content('Loading commit data...')
+ end
+
private
def set_new_content
diff --git a/lib/gitlab/incoming_email.rb b/lib/gitlab/incoming_email.rb
index 856ccc71084..9068d79c95e 100644
--- a/lib/gitlab/incoming_email.rb
+++ b/lib/gitlab/incoming_email.rb
@@ -24,12 +24,12 @@ module Gitlab
match[1]
end
- private
-
def config
Gitlab.config.incoming_email
end
+ private
+
def address_regex
wildcard_address = config.address
return nil unless wildcard_address
diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake
index 66f1ecf385f..606bf241db7 100644
--- a/lib/tasks/gitlab/check.rake
+++ b/lib/tasks/gitlab/check.rake
@@ -642,7 +642,6 @@ namespace :gitlab do
if Gitlab.config.incoming_email.enabled
check_address_formatted_correctly
- check_mail_room_config_exists
check_imap_authentication
if Rails.env.production?
@@ -744,42 +743,16 @@ namespace :gitlab do
end
end
- def check_mail_room_config_exists
- print "MailRoom config exists? ... "
-
- mail_room_config_file = Rails.root.join("config", "mail_room.yml")
-
- if File.exists?(mail_room_config_file)
- puts "yes".green
- else
- puts "no".red
- try_fixing_it(
- "Copy config/mail_room.yml.example to config/mail_room.yml",
- "Check that the information in config/mail_room.yml is correct"
- )
- for_more_information(
- "doc/incoming_email/README.md"
- )
- fix_and_rerun
- end
- end
-
def check_imap_authentication
print "IMAP server credentials are correct? ... "
- mail_room_config_file = Rails.root.join("config", "mail_room.yml")
-
- unless File.exists?(mail_room_config_file)
- puts "can't check because of previous errors".magenta
- return
- end
-
- config = YAML.load_file(mail_room_config_file)[:mailboxes].first rescue nil
+ config = Gitlab.config.incoming_email
if config
begin
- imap = Net::IMAP.new(config[:host], port: config[:port], ssl: config[:ssl])
- imap.login(config[:email], config[:password])
+ imap = Net::IMAP.new(config.host, port: config.port, ssl: config.ssl)
+ imap.starttls if config.start_tls
+ imap.login(config.user, config.password)
connected = true
rescue
connected = false
@@ -791,7 +764,7 @@ namespace :gitlab do
else
puts "no".red
try_fixing_it(
- "Check that the information in config/mail_room.yml is correct"
+ "Check that the information in config/gitlab.yml is correct"
)
for_more_information(
"doc/incoming_email/README.md"
diff --git a/spec/features/builds_spec.rb b/spec/features/builds_spec.rb
index 924047a0d8f..154857e77fe 100644
--- a/spec/features/builds_spec.rb
+++ b/spec/features/builds_spec.rb
@@ -9,6 +9,54 @@ describe "Builds" do
@gl_project.team << [@user, :master]
end
+ describe "GET /:project/builds" do
+ context "Running scope" do
+ before do
+ @build.run!
+ visit namespace_project_builds_path(@gl_project.namespace, @gl_project)
+ end
+
+ it { expect(page).to have_content 'Running' }
+ it { expect(page).to have_content 'Cancel all' }
+ it { expect(page).to have_content @build.short_sha }
+ it { expect(page).to have_content @build.ref }
+ it { expect(page).to have_content @build.name }
+ end
+
+ context "Finished scope" do
+ before do
+ @build.run!
+ visit namespace_project_builds_path(@gl_project.namespace, @gl_project, scope: :finished)
+ end
+
+ it { expect(page).to have_content 'No builds to show' }
+ it { expect(page).to have_content 'Cancel all' }
+ end
+
+ context "All builds" do
+ before do
+ @gl_project.ci_builds.running_or_pending.each(&:success)
+ visit namespace_project_builds_path(@gl_project.namespace, @gl_project, scope: :all)
+ end
+
+ it { expect(page).to have_content 'All' }
+ it { expect(page).to have_content @build.short_sha }
+ it { expect(page).to have_content @build.ref }
+ it { expect(page).to have_content @build.name }
+ it { expect(page).to_not have_content 'Cancel all' }
+ end
+ end
+
+ describe "GET /:project/builds/:id/cancel_all" do
+ before do
+ @build.run!
+ visit cancel_all_namespace_project_builds_path(@gl_project.namespace, @gl_project)
+ end
+
+ it { expect(page).to have_content 'No builds to show' }
+ it { expect(page).to_not have_content 'Cancel all' }
+ end
+
describe "GET /:project/builds/:id" do
before do
visit namespace_project_build_path(@gl_project.namespace, @gl_project, @build)
diff --git a/spec/models/ci/commit_spec.rb b/spec/models/ci/commit_spec.rb
index 330971174fb..d1cecce5a6d 100644
--- a/spec/models/ci/commit_spec.rb
+++ b/spec/models/ci/commit_spec.rb
@@ -32,6 +32,24 @@ describe Ci::Commit do
it { is_expected.to respond_to :git_author_email }
it { is_expected.to respond_to :short_sha }
+ describe :ordered do
+ let(:project) { FactoryGirl.create :empty_project }
+
+ it 'returns ordered list of commits' do
+ commit1 = FactoryGirl.create :ci_commit, committed_at: 1.hour.ago, gl_project: project
+ commit2 = FactoryGirl.create :ci_commit, committed_at: 2.hour.ago, gl_project: project
+ expect(project.ci_commits.ordered).to eq([commit2, commit1])
+ end
+
+ it 'returns commits ordered by committed_at and id, with nulls last' do
+ commit1 = FactoryGirl.create :ci_commit, committed_at: 1.hour.ago, gl_project: project
+ commit2 = FactoryGirl.create :ci_commit, committed_at: nil, gl_project: project
+ commit3 = FactoryGirl.create :ci_commit, committed_at: 2.hour.ago, gl_project: project
+ commit4 = FactoryGirl.create :ci_commit, committed_at: nil, gl_project: project
+ expect(project.ci_commits.ordered).to eq([commit2, commit4, commit3, commit1])
+ end
+ end
+
describe :last_build do
subject { commit.last_build }
before do
diff --git a/spec/models/ci/project_spec.rb b/spec/models/ci/project_spec.rb
index c1605d68859..490c6a67982 100644
--- a/spec/models/ci/project_spec.rb
+++ b/spec/models/ci/project_spec.rb
@@ -131,24 +131,6 @@ describe Ci::Project do
end
end
- describe 'ordered commits' do
- let(:project) { FactoryGirl.create :empty_project }
-
- it 'returns ordered list of commits' do
- commit1 = FactoryGirl.create :ci_commit, committed_at: 1.hour.ago, gl_project: project
- commit2 = FactoryGirl.create :ci_commit, committed_at: 2.hour.ago, gl_project: project
- expect(project.ci_commits).to eq([commit2, commit1])
- end
-
- it 'returns commits ordered by committed_at and id, with nulls last' do
- commit1 = FactoryGirl.create :ci_commit, committed_at: 1.hour.ago, gl_project: project
- commit2 = FactoryGirl.create :ci_commit, committed_at: nil, gl_project: project
- commit3 = FactoryGirl.create :ci_commit, committed_at: 2.hour.ago, gl_project: project
- commit4 = FactoryGirl.create :ci_commit, committed_at: nil, gl_project: project
- expect(project.ci_commits).to eq([commit2, commit4, commit3, commit1])
- end
- end
-
context :valid_project do
let(:commit) { FactoryGirl.create(:ci_commit) }
diff --git a/spec/models/ci/runner_spec.rb b/spec/models/ci/runner_spec.rb
index 536a737a33d..f8a51c29dc2 100644
--- a/spec/models/ci/runner_spec.rb
+++ b/spec/models/ci/runner_spec.rb
@@ -32,7 +32,7 @@ describe Ci::Runner do
end
it 'should return the token if the description is an empty string' do
- runner = FactoryGirl.build(:ci_runner, description: '')
+ runner = FactoryGirl.build(:ci_runner, description: '', token: 'token')
expect(runner.display_name).to eq runner.token
end
end
diff --git a/spec/support/test_env.rb b/spec/support/test_env.rb
index 3eab74ba986..d12ba25b71b 100644
--- a/spec/support/test_env.rb
+++ b/spec/support/test_env.rb
@@ -9,7 +9,7 @@ module TestEnv
'flatten-dir' => 'e56497b',
'feature' => '0b4bc9a',
'feature_conflict' => 'bb5206f',
- 'fix' => '12d65c8',
+ 'fix' => '48f0be4',
'improve/awesome' => '5937ac0',
'markdown' => '0ed8c6c',
'master' => '5937ac0',