mirror of
https://github.com/wahyd4/gitlabhq.git
synced 2026-08-18 00:56:41 +10:00
Merge branch 'master' into 8-0-stable
This commit is contained in:
@@ -22,7 +22,7 @@ gem "mysql2", '~> 0.3.16', group: :mysql
|
||||
gem "pg", '~> 0.18.2', group: :postgres
|
||||
|
||||
# Authentication libraries
|
||||
gem "devise", '~> 3.2.4'
|
||||
gem "devise", '~> 3.5.2'
|
||||
gem "devise-async", '~> 0.9.0'
|
||||
gem 'omniauth', "~> 1.2.2"
|
||||
gem 'omniauth-google-oauth2', '~> 0.2.5'
|
||||
@@ -38,7 +38,7 @@ gem 'omniauth_crowd'
|
||||
gem "rack-oauth2", "~> 1.0.5"
|
||||
|
||||
# Two-factor authentication
|
||||
gem 'devise-two-factor', '~> 1.0.1'
|
||||
gem 'devise-two-factor', '~> 2.0.0'
|
||||
gem 'rqrcode-rails3', '~> 0.1.7'
|
||||
gem 'attr_encrypted', '~> 1.3.4'
|
||||
|
||||
|
||||
+13
-8
@@ -136,21 +136,21 @@ GEM
|
||||
activerecord (>= 3.2.0, < 5.0)
|
||||
descendants_tracker (0.0.4)
|
||||
thread_safe (~> 0.3, >= 0.3.1)
|
||||
devise (3.2.4)
|
||||
devise (3.5.2)
|
||||
bcrypt (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (>= 3.2.6, < 5)
|
||||
responders
|
||||
thread_safe (~> 0.1)
|
||||
warden (~> 1.2.3)
|
||||
devise-async (0.9.0)
|
||||
devise (~> 3.2)
|
||||
devise-two-factor (1.0.2)
|
||||
activemodel
|
||||
devise-two-factor (2.0.0)
|
||||
activesupport
|
||||
attr_encrypted (~> 1.3.2)
|
||||
devise (>= 3.2.4, < 3.5)
|
||||
devise (~> 3.5.0)
|
||||
railties
|
||||
rotp (< 2)
|
||||
rotp (~> 2)
|
||||
diff-lcs (1.2.5)
|
||||
diffy (3.0.7)
|
||||
docile (1.1.5)
|
||||
@@ -558,12 +558,14 @@ GEM
|
||||
request_store (1.2.0)
|
||||
rerun (0.10.0)
|
||||
listen (~> 2.7, >= 2.7.3)
|
||||
responders (1.1.2)
|
||||
railties (>= 3.2, < 4.2)
|
||||
rest-client (1.8.0)
|
||||
http-cookie (>= 1.0.2, < 2.0)
|
||||
mime-types (>= 1.16, < 3.0)
|
||||
netrc (~> 0.7)
|
||||
rinku (1.7.3)
|
||||
rotp (1.6.1)
|
||||
rotp (2.1.1)
|
||||
rouge (1.10.1)
|
||||
rqrcode (0.7.0)
|
||||
chunky_png
|
||||
@@ -806,9 +808,9 @@ DEPENDENCIES
|
||||
d3_rails (~> 3.5.5)
|
||||
database_cleaner (~> 1.4.0)
|
||||
default_value_for (~> 3.0.0)
|
||||
devise (~> 3.2.4)
|
||||
devise (~> 3.5.2)
|
||||
devise-async (~> 0.9.0)
|
||||
devise-two-factor (~> 1.0.1)
|
||||
devise-two-factor (~> 2.0.0)
|
||||
diffy (~> 3.0.3)
|
||||
doorkeeper (~> 2.1.3)
|
||||
dropzonejs-rails (~> 0.7.1)
|
||||
@@ -928,3 +930,6 @@ DEPENDENCIES
|
||||
webmock (~> 1.21.0)
|
||||
whenever (~> 0.8.4)
|
||||
wikicloth (= 0.8.1)
|
||||
|
||||
BUNDLED WITH
|
||||
1.10.6
|
||||
|
||||
@@ -11,12 +11,13 @@ class @IssuableContext
|
||||
$(this).submit()
|
||||
|
||||
$('.issuable-details').waitForImages ->
|
||||
$('.issuable-affix').on 'affix.bs.affix', ->
|
||||
$(@).width($(@).outerWidth())
|
||||
.on 'affixed-top.bs.affix affixed-bottom.bs.affix', ->
|
||||
$(@).width('')
|
||||
|
||||
$('.issuable-affix').affix offset:
|
||||
top: ->
|
||||
@top = ($('.issuable-affix').offset().top - 70)
|
||||
bottom: ->
|
||||
@bottom = $('.footer').outerHeight(true)
|
||||
$('.issuable-affix').on 'affix.bs.affix', ->
|
||||
$(@).width($(@).outerWidth())
|
||||
.on 'affixed-top.bs.affix affixed-bottom.bs.affix', ->
|
||||
$(@).width('')
|
||||
|
||||
@@ -65,20 +65,20 @@ $legend-color: $text-color;
|
||||
//
|
||||
//##
|
||||
|
||||
$pagination-color: #fff;
|
||||
$pagination-bg: $brand-success;
|
||||
$pagination-color: $gl-gray;
|
||||
$pagination-bg: $background-color;
|
||||
$pagination-border: transparent;
|
||||
|
||||
$pagination-hover-color: #fff;
|
||||
$pagination-hover-bg: darken($brand-success, 15%);
|
||||
$pagination-hover-bg: $brand-info;
|
||||
$pagination-hover-border: transparent;
|
||||
|
||||
$pagination-active-color: #fff;
|
||||
$pagination-active-bg: darken($brand-success, 15%);
|
||||
$pagination-active-bg: $brand-info;
|
||||
$pagination-active-border: transparent;
|
||||
|
||||
$pagination-disabled-color: #b4bcc2;
|
||||
$pagination-disabled-bg: lighten($brand-success, 15%);
|
||||
$pagination-disabled-color: #fff;
|
||||
$pagination-disabled-bg: lighten($brand-info, 15%);
|
||||
$pagination-disabled-border: transparent;
|
||||
|
||||
|
||||
|
||||
@@ -13,31 +13,6 @@
|
||||
|
||||
.builds,
|
||||
.projects-table {
|
||||
.alert-success {
|
||||
background-color: #6fc995;
|
||||
border-color: #5bba83;
|
||||
}
|
||||
|
||||
.alert-danger {
|
||||
background-color: #eb897f;
|
||||
border-color: #d4776e;
|
||||
}
|
||||
|
||||
.alert-info {
|
||||
background-color: #3498db;
|
||||
border-color: #2e8ece;
|
||||
}
|
||||
|
||||
.alert-warning {
|
||||
background-color: #EB974E;
|
||||
border-color: #E87E04;
|
||||
}
|
||||
|
||||
.alert-disabled {
|
||||
background: $background-color;
|
||||
border-color: $border-color;
|
||||
}
|
||||
|
||||
.light {
|
||||
border-color: $border-color;
|
||||
}
|
||||
@@ -47,8 +22,8 @@
|
||||
}
|
||||
|
||||
td {
|
||||
color: $gl-gray;
|
||||
vertical-align: middle !important;
|
||||
border-color: inherit !important;
|
||||
|
||||
a {
|
||||
font-weight: normal;
|
||||
@@ -58,23 +33,16 @@
|
||||
}
|
||||
|
||||
.commit-info {
|
||||
font-size: 14px;
|
||||
|
||||
.attr-name {
|
||||
font-weight: 300;
|
||||
color: #666;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
pre.commit-message {
|
||||
font-size: 14px;
|
||||
background: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border: none;
|
||||
margin: 20px 0;
|
||||
border-bottom: 1px solid #EEE;
|
||||
padding-bottom: 20px;
|
||||
border-radius: 0;
|
||||
}
|
||||
}
|
||||
@@ -88,4 +56,38 @@
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.ci-status {
|
||||
padding: 2px 7px;
|
||||
margin-right: 5px;
|
||||
border: 1px solid #EEE;
|
||||
white-space: nowrap;
|
||||
@include border-radius(4px);
|
||||
|
||||
&.ci-failed {
|
||||
color: $gl-danger;
|
||||
border-color: $gl-danger;
|
||||
}
|
||||
|
||||
&.ci-success {
|
||||
color: $gl-success;
|
||||
border-color: $gl-success;
|
||||
}
|
||||
|
||||
&.ci-info {
|
||||
color: $gl-info;
|
||||
border-color: $gl-info;
|
||||
}
|
||||
|
||||
&.ci-disabled {
|
||||
color: $gl-gray;
|
||||
border-color: $gl-gray;
|
||||
}
|
||||
|
||||
&.ci-pending,
|
||||
&.ci-running {
|
||||
color: $gl-warning;
|
||||
border-color: $gl-warning;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
|
||||
.gray-content-block {
|
||||
margin: -$gl-padding;
|
||||
background-color: #f8fafc;
|
||||
background-color: $background-color;
|
||||
padding: $gl-padding;
|
||||
margin-bottom: 0px;
|
||||
border-top: 1px solid #e7e9ed;
|
||||
border-bottom: 1px solid #e7e9ed;
|
||||
border-top: 1px solid $border-color;
|
||||
border-bottom: 1px solid $border-color;
|
||||
color: $gl-gray;
|
||||
|
||||
&.top-block {
|
||||
@@ -48,6 +48,7 @@
|
||||
|
||||
&.footer-block {
|
||||
margin-top: 0;
|
||||
border-bottom: none;
|
||||
margin-bottom: -$gl-padding;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Callouts from Bootstrap3 docs
|
||||
*
|
||||
* Not quite alerts, but custom and helpful notes for folks reading the docs.
|
||||
* Requires a base and modifier class.
|
||||
*/
|
||||
|
||||
/* Common styles for all types */
|
||||
.bs-callout {
|
||||
margin: 20px 0;
|
||||
padding: 20px;
|
||||
border-left: 3px solid #eee;
|
||||
color: #666;
|
||||
background: #f9f9f9;
|
||||
}
|
||||
.bs-callout h4 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.bs-callout p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Variations */
|
||||
.bs-callout-danger {
|
||||
background-color: #fdf7f7;
|
||||
border-color: #eed3d7;
|
||||
color: #b94a48;
|
||||
}
|
||||
.bs-callout-warning {
|
||||
background-color: #faf8f0;
|
||||
border-color: #faebcc;
|
||||
color: #8a6d3b;
|
||||
}
|
||||
.bs-callout-info {
|
||||
background-color: #f4f8fa;
|
||||
border-color: #bce8f1;
|
||||
color: #34789a;
|
||||
}
|
||||
.bs-callout-success {
|
||||
background-color: #dff0d8;
|
||||
border-color: #5cA64d;
|
||||
color: #3c763d;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
.gl-pagination {
|
||||
border-top: 1px solid $border-color;
|
||||
background-color: $background-color;
|
||||
margin: -$gl-padding;
|
||||
margin-top: 0;
|
||||
|
||||
.pagination {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: block;
|
||||
|
||||
li.next,
|
||||
li.prev {
|
||||
> a {
|
||||
color: $link-color;
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
li > a,
|
||||
li > span {
|
||||
border: none;
|
||||
margin: 0;
|
||||
@include border-radius(0 !important);
|
||||
padding: 13px 19px;
|
||||
border-right: 1px solid $border-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -56,7 +56,7 @@ class Admin::UsersController < Admin::ApplicationController
|
||||
end
|
||||
|
||||
def confirm
|
||||
if user.confirm!
|
||||
if user.confirm
|
||||
redirect_to :back, notice: "Successfully confirmed"
|
||||
else
|
||||
redirect_to :back, alert: "Error occurred. User was not confirmed"
|
||||
|
||||
@@ -9,7 +9,7 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
|
||||
end
|
||||
|
||||
def create
|
||||
if current_user.valid_otp?(params[:pin_code])
|
||||
if current_user.validate_and_consume_otp!(params[:pin_code])
|
||||
current_user.two_factor_enabled = true
|
||||
@codes = current_user.generate_otp_backup_codes!
|
||||
current_user.save!
|
||||
|
||||
@@ -99,7 +99,7 @@ class SessionsController < Devise::SessionsController
|
||||
end
|
||||
|
||||
def valid_otp_attempt?(user)
|
||||
user.valid_otp?(user_params[:otp_attempt]) ||
|
||||
user.validate_and_consume_otp!(user_params[:otp_attempt]) ||
|
||||
user.invalidate_otp_backup_code!(user_params[:otp_attempt])
|
||||
end
|
||||
|
||||
|
||||
@@ -28,5 +28,27 @@ module Ci
|
||||
"#{pluralize(seconds, "second")}"
|
||||
end
|
||||
end
|
||||
|
||||
def ci_icon_for_status(status)
|
||||
icon_name =
|
||||
case status
|
||||
when 'success'
|
||||
'check-square'
|
||||
when 'failed'
|
||||
'close'
|
||||
when 'running', 'pending'
|
||||
'clock-o'
|
||||
else
|
||||
'circle'
|
||||
end
|
||||
|
||||
icon(icon_name)
|
||||
end
|
||||
|
||||
def ci_status_with_icon(status)
|
||||
content_tag :span, class: "ci-status ci-#{status}" do
|
||||
ci_icon_for_status(status) + ' '.html_safe + status
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -15,27 +15,5 @@ module Ci
|
||||
def build_url(build)
|
||||
ci_project_build_url(build.project, build)
|
||||
end
|
||||
|
||||
def build_status_alert_class(build)
|
||||
if build.success?
|
||||
'alert-success'
|
||||
elsif build.failed?
|
||||
'alert-danger'
|
||||
elsif build.canceled?
|
||||
'alert-disabled'
|
||||
else
|
||||
'alert-warning'
|
||||
end
|
||||
end
|
||||
|
||||
def build_icon_css_class(build)
|
||||
if build.success?
|
||||
'fa-circle cgreen'
|
||||
elsif build.failed?
|
||||
'fa-circle cred'
|
||||
else
|
||||
'fa-circle light'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,20 +1,5 @@
|
||||
module Ci
|
||||
module CommitsHelper
|
||||
def commit_status_alert_class(commit)
|
||||
return 'alert-info' unless commit
|
||||
|
||||
case commit.status
|
||||
when 'success'
|
||||
'alert-success'
|
||||
when 'failed', 'canceled'
|
||||
'alert-danger'
|
||||
when 'skipped'
|
||||
'alert-disabled'
|
||||
else
|
||||
'alert-warning'
|
||||
end
|
||||
end
|
||||
|
||||
def ci_commit_path(commit)
|
||||
ci_project_ref_commits_path(commit.project, commit.ref, commit.sha)
|
||||
end
|
||||
|
||||
@@ -12,7 +12,7 @@ module Emails
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@commit.title} (#{@commit.short_id})"))
|
||||
|
||||
SentNotification.record(@commit, recipient_id, reply_key)
|
||||
SentNotification.record_note(@note, recipient_id, reply_key)
|
||||
end
|
||||
|
||||
def note_issue_email(recipient_id, note_id)
|
||||
@@ -27,7 +27,7 @@ module Emails
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@issue.title} (##{@issue.iid})"))
|
||||
|
||||
SentNotification.record(@issue, recipient_id, reply_key)
|
||||
SentNotification.record_note(@note, recipient_id, reply_key)
|
||||
end
|
||||
|
||||
def note_merge_request_email(recipient_id, note_id)
|
||||
@@ -43,7 +43,7 @@ module Emails
|
||||
to: recipient(recipient_id),
|
||||
subject: subject("#{@merge_request.title} (##{@merge_request.iid})"))
|
||||
|
||||
SentNotification.record(@merge_request, recipient_id, reply_key)
|
||||
SentNotification.record_note(@note, recipient_id, reply_key)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -428,7 +428,7 @@ class Project < ActiveRecord::Base
|
||||
end
|
||||
|
||||
def gitlab_ci?
|
||||
gitlab_ci_service && gitlab_ci_service.active
|
||||
gitlab_ci_service && gitlab_ci_service.active && gitlab_ci_project.present?
|
||||
end
|
||||
|
||||
def ci_services
|
||||
|
||||
@@ -26,7 +26,7 @@ class DroneCiService < CiService
|
||||
format: { with: /\A#{URI.regexp(%w(http https))}\z/, message: "should be a valid url" }, if: :activated?
|
||||
validates :token,
|
||||
presence: true,
|
||||
format: { with: /\A([A-Za-z0-9]+)\z/ }, if: :activated?
|
||||
if: :activated?
|
||||
|
||||
after_save :compose_service_hook, if: :activated?
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
# noteable_type :string(255)
|
||||
# recipient_id :integer
|
||||
# commit_id :string(255)
|
||||
# line_code :string(255)
|
||||
# reply_key :string(255) not null
|
||||
#
|
||||
|
||||
@@ -21,13 +22,14 @@ class SentNotification < ActiveRecord::Base
|
||||
|
||||
validates :noteable_id, presence: true, unless: :for_commit?
|
||||
validates :commit_id, presence: true, if: :for_commit?
|
||||
validates :line_code, format: { with: /\A[a-z0-9]+_\d+_\d+\Z/ }, allow_blank: true
|
||||
|
||||
class << self
|
||||
def for(reply_key)
|
||||
find_by(reply_key: reply_key)
|
||||
end
|
||||
|
||||
def record(noteable, recipient_id, reply_key)
|
||||
def record(noteable, recipient_id, reply_key, params = {})
|
||||
return unless reply_key
|
||||
|
||||
noteable_id = nil
|
||||
@@ -38,7 +40,7 @@ class SentNotification < ActiveRecord::Base
|
||||
noteable_id = noteable.id
|
||||
end
|
||||
|
||||
create(
|
||||
params.reverse_merge!(
|
||||
project: noteable.project,
|
||||
noteable_type: noteable.class.name,
|
||||
noteable_id: noteable_id,
|
||||
@@ -46,6 +48,14 @@ class SentNotification < ActiveRecord::Base
|
||||
recipient_id: recipient_id,
|
||||
reply_key: reply_key
|
||||
)
|
||||
|
||||
create(params)
|
||||
end
|
||||
|
||||
def record_note(note, recipient_id, reply_key, params = {})
|
||||
params[:line_code] = note.line_code
|
||||
|
||||
record(note.noteable, recipient_id, reply_key, params)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
- if build.commit && build.project
|
||||
%tr.build.alert{class: build_status_alert_class(build)}
|
||||
%tr.build
|
||||
%td.build-link
|
||||
= link_to ci_project_build_url(build.project, build) do
|
||||
%strong #{build.id}
|
||||
|
||||
%td.status
|
||||
= build.status
|
||||
= ci_status_with_icon(build.status)
|
||||
|
||||
%td.commit-link
|
||||
= commit_link(build.commit)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
- last_commit = project.last_commit
|
||||
%tr.alert{class: commit_status_alert_class(last_commit) }
|
||||
%tr
|
||||
%td
|
||||
= project.id
|
||||
%td
|
||||
@@ -7,8 +7,9 @@
|
||||
%strong= project.name
|
||||
%td
|
||||
- if last_commit
|
||||
#{last_commit.status} (#{commit_link(last_commit)})
|
||||
= ci_status_with_icon(last_commit.status)
|
||||
- if project.last_commit_date
|
||||
·
|
||||
= time_ago_in_words project.last_commit_date
|
||||
ago
|
||||
- else
|
||||
|
||||
@@ -102,9 +102,9 @@
|
||||
%th Finished at
|
||||
|
||||
- @builds.each do |build|
|
||||
%tr.build.alert{class: build_status_alert_class(build)}
|
||||
%tr.build
|
||||
%td.status
|
||||
= build.status
|
||||
= ci_status_with_icon(build.status)
|
||||
|
||||
%td.status
|
||||
= build.project.name
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%tr.build.alert{class: build_status_alert_class(build)}
|
||||
%tr.build
|
||||
%td.status
|
||||
= build.status
|
||||
= ci_status_with_icon(build.status)
|
||||
|
||||
%td.build-link
|
||||
= link_to ci_project_build_path(build.project, build) do
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
#up-build-trace
|
||||
- if @commit.matrix?
|
||||
%ul.nav.nav-tabs.append-bottom-10
|
||||
%ul.center-top-menu
|
||||
- @commit.builds_without_retry_sorted.each do |build|
|
||||
%li{class: ('active' if build == @build) }
|
||||
= link_to ci_project_build_url(@project, build) do
|
||||
%i{class: build_icon_css_class(build)}
|
||||
= ci_icon_for_status(build.status)
|
||||
%span
|
||||
Build ##{build.id}
|
||||
- if build.name
|
||||
·
|
||||
= build.name
|
||||
- else
|
||||
= build.id
|
||||
|
||||
|
||||
- unless @commit.builds_without_retry.include?(@build)
|
||||
%li.active
|
||||
@@ -19,34 +20,33 @@
|
||||
%i.fa.fa-warning-sign
|
||||
This build was retried.
|
||||
|
||||
.row
|
||||
.col-md-9
|
||||
.build-head.alert{class: build_status_alert_class(@build)}
|
||||
%h4
|
||||
- if @build.commit.tag?
|
||||
Build for tag
|
||||
%code #{@build.ref}
|
||||
- else
|
||||
Build for commit
|
||||
%code #{@build.short_sha}
|
||||
from
|
||||
.gray-content-block
|
||||
.build-head
|
||||
%h4
|
||||
- if @build.commit.tag?
|
||||
Build for tag
|
||||
%code #{@build.ref}
|
||||
- else
|
||||
Build for commit
|
||||
%strong.monospace= commit_link(@build.commit)
|
||||
from
|
||||
|
||||
= link_to ci_project_path(@build.project, ref: @build.ref) do
|
||||
%span.label.label-primary= "#{@build.ref}"
|
||||
= link_to ci_project_path(@build.project, ref: @build.ref) do
|
||||
%strong.monospace= "#{@build.ref}"
|
||||
|
||||
- if @build.duration
|
||||
.pull-right
|
||||
%span
|
||||
%i.fa.fa-time
|
||||
#{duration_in_words(@build.finished_at, @build.started_at)}
|
||||
|
||||
.clearfix
|
||||
= @build.status
|
||||
- if @build.duration
|
||||
.pull-right
|
||||
= @build.updated_at.stamp('19:00 Aug 27')
|
||||
|
||||
%span
|
||||
%i.fa.fa-time
|
||||
#{duration_in_words(@build.finished_at, @build.started_at)}
|
||||
|
||||
.clearfix
|
||||
= ci_status_with_icon(@build.status)
|
||||
.pull-right
|
||||
= @build.updated_at.stamp('19:00 Aug 27')
|
||||
|
||||
.row.prepend-top-default
|
||||
.col-md-9
|
||||
.clearfix
|
||||
- if @build.active?
|
||||
.autoscroll-container
|
||||
@@ -150,13 +150,16 @@
|
||||
%h4.title #{pluralize(@builds.count, "other build")} for #{@build.short_sha}:
|
||||
%table.builds
|
||||
- @builds.each_with_index do |build, i|
|
||||
%tr.build.alert{class: build_status_alert_class(build)}
|
||||
%tr.build
|
||||
%td
|
||||
= ci_icon_for_status(build.status)
|
||||
%td
|
||||
= link_to ci_project_build_url(@project, build) do
|
||||
%span ##{build.id}
|
||||
%td
|
||||
- if build.name
|
||||
= build.name
|
||||
- if build.name
|
||||
= build.name
|
||||
- else
|
||||
%span ##{build.id}
|
||||
|
||||
%td.status= build.status
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
%tr.build.alert{class: commit_status_alert_class(commit)}
|
||||
%tr.build
|
||||
%td.status
|
||||
= commit.status
|
||||
= ci_status_with_icon(commit.status)
|
||||
- if commit.running?
|
||||
·
|
||||
= commit.stage
|
||||
|
||||
@@ -1,29 +1,34 @@
|
||||
.commit-info
|
||||
%pre.commit-message
|
||||
#{@commit.git_commit_message}
|
||||
.append-bottom-20
|
||||
= ci_status_with_icon(@commit.status)
|
||||
|
||||
.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)}
|
||||
.gray-content-block.middle-block
|
||||
%pre.commit-message
|
||||
#{@commit.git_commit_message}
|
||||
|
||||
.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 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.created_at
|
||||
%p
|
||||
%span.attr-name Created at:
|
||||
#{@commit.created_at.to_s(:short)}
|
||||
%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.created_at
|
||||
%p
|
||||
%span.attr-name Created at:
|
||||
#{@commit.created_at.to_s(:short)}
|
||||
|
||||
- if current_user && can?(current_user, :manage_builds, gl_project)
|
||||
.pull-right
|
||||
@@ -42,12 +47,6 @@
|
||||
.bs-callout.bs-callout-warning
|
||||
\.gitlab-ci.yml not found in this commit
|
||||
|
||||
%h3 Status
|
||||
|
||||
.build.alert{class: commit_status_alert_class(@commit)}
|
||||
.status
|
||||
= @commit.status.titleize
|
||||
|
||||
%h3
|
||||
Builds
|
||||
- if @commit.duration > 0
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
- if project.gitlab_ci_project
|
||||
- ci_project = project.gitlab_ci_project
|
||||
- last_commit = ci_project.last_commit
|
||||
%tr.alert{class: commit_status_alert_class(last_commit) }
|
||||
%tr
|
||||
%td
|
||||
= link_to [:ci, ci_project] do
|
||||
= ci_project.name
|
||||
%td
|
||||
- if last_commit
|
||||
#{last_commit.status} (#{commit_link(last_commit)})
|
||||
= ci_status_with_icon(last_commit.status)
|
||||
= commit_link(last_commit)
|
||||
·
|
||||
- if ci_project.last_commit_date
|
||||
= time_ago_in_words ci_project.last_commit_date
|
||||
ago
|
||||
@@ -33,4 +35,3 @@
|
||||
= form_tag ci_projects_path do
|
||||
= hidden_field_tag :project, project.to_json(methods: [:name_with_namespace, :path_with_namespace, :ssh_url_to_repo])
|
||||
= submit_tag 'Add project to CI', class: 'btn btn-default btn-sm'
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
-# paginator: the paginator that renders the pagination tags inside
|
||||
= paginator.render do
|
||||
%div.gl-pagination
|
||||
%ul.pagination
|
||||
%ul.pagination.clearfix
|
||||
= prev_page_tag unless current_page.first?
|
||||
- each_page do |page|
|
||||
- if page.left_outer? || page.right_outer? || page.inside_window?
|
||||
|
||||
@@ -96,7 +96,7 @@ production: &base
|
||||
|
||||
## Reply by email
|
||||
# Allow users to comment on issues and merge requests by replying to notification emails.
|
||||
# For documentation on how to set this up, see http://doc.gitlab.com/ce/reply_by_email/README.md
|
||||
# For documentation on how to set this up, see http://doc.gitlab.com/ce/reply_by_email/README.html
|
||||
reply_by_email:
|
||||
enabled: false
|
||||
address: "replies+%{reply_key}@gitlab.example.com"
|
||||
|
||||
@@ -19,7 +19,7 @@ admin = User.create(
|
||||
admin.projects_limit = 10000
|
||||
admin.admin = true
|
||||
admin.save!
|
||||
admin.confirm!
|
||||
admin.confirm
|
||||
|
||||
if admin.valid?
|
||||
puts %Q[
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class DeduplicateUserIdentities < ActiveRecord::Migration
|
||||
def change
|
||||
execute 'DROP TABLE IF EXISTS tt_migration_DeduplicateUserIdentities;'
|
||||
execute 'CREATE TEMPORARY TABLE tt_migration_DeduplicateUserIdentities AS SELECT id,provider,user_id FROM identities;'
|
||||
execute 'CREATE TABLE tt_migration_DeduplicateUserIdentities AS SELECT id,provider,user_id FROM identities;'
|
||||
execute 'DELETE FROM identities WHERE id NOT IN ( SELECT MIN(id) FROM tt_migration_DeduplicateUserIdentities GROUP BY user_id, provider);'
|
||||
execute 'DROP TABLE IF EXISTS tt_migration_DeduplicateUserIdentities;'
|
||||
end
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddConsumedTimestepToUsers < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :users, :consumed_timestep, :integer
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class AddLineCodeToSentNotification < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :sent_notifications, :line_code, :string
|
||||
end
|
||||
end
|
||||
+3
-1
@@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20150918084513) do
|
||||
ActiveRecord::Schema.define(version: 20150920161119) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
@@ -623,6 +623,7 @@ ActiveRecord::Schema.define(version: 20150918084513) do
|
||||
t.integer "recipient_id"
|
||||
t.string "commit_id"
|
||||
t.string "reply_key", null: false
|
||||
t.string "line_code"
|
||||
end
|
||||
|
||||
add_index "sent_notifications", ["reply_key"], name: "index_sent_notifications_on_reply_key", unique: true, using: :btree
|
||||
@@ -749,6 +750,7 @@ ActiveRecord::Schema.define(version: 20150918084513) do
|
||||
t.string "public_email", default: "", null: false
|
||||
t.integer "dashboard", default: 0
|
||||
t.integer "project_view", default: 0
|
||||
t.integer "consumed_timestep"
|
||||
end
|
||||
|
||||
add_index "users", ["admin"], name: "index_users_on_admin", using: :btree
|
||||
|
||||
@@ -36,7 +36,7 @@ We do not recommend using MySQL due to various issues. For example, case [(in)se
|
||||
mysql> CREATE DATABASE IF NOT EXISTS `gitlabhq_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`;
|
||||
|
||||
# Grant the GitLab user necessary permissions on the database
|
||||
mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, LOCK TABLES ON `gitlabhq_production`.* TO 'git'@'localhost';
|
||||
mysql> GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, CREATE TEMPORARY TABLES, DROP, INDEX, ALTER, LOCK TABLES ON `gitlabhq_production`.* TO 'git'@'localhost';
|
||||
|
||||
# Quit the database session
|
||||
mysql> \q
|
||||
|
||||
@@ -10,7 +10,7 @@ See the documentation below for details on how to configure these services.
|
||||
- [SAML](saml.md) Configure GitLab as a SAML 2.0 Service Provider
|
||||
- [Slack](slack.md) Integrate with the Slack chat service
|
||||
- [OAuth2 provider](oauth_provider.md) OAuth2 application creation
|
||||
- [Gmail](gitlab_buttons_in_gmail.md) Adds GitLab actions to messages
|
||||
- [Gmail actions buttons](gmail_action_buttons_for_gitlab.md) Adds GitLab actions to messages
|
||||
|
||||
GitLab Enterprise Edition contains [advanced JIRA support](http://doc.gitlab.com/ee/integration/jira.html) and [advanced Jenkins support](http://doc.gitlab.com/ee/integration/jenkins.html).
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# Gmail actions buttons for GitLab
|
||||
|
||||
GitLab supports [Google actions in email](https://developers.google.com/gmail/markup/actions/actions-overview).
|
||||
|
||||
If correctly setup, emails that require an action will be marked in Gmail.
|
||||
|
||||

|
||||
|
||||
To get this functioning, you need to be registered with Google.
|
||||
[See how to register with Google in this document.](https://developers.google.com/gmail/markup/registering-with-google)
|
||||
|
||||
*This process has a lot of steps so make sure that you fulfill all requirements set by Google.*
|
||||
*Your application will be rejected by Google if you fail to do so.*
|
||||
|
||||
Pay close attention to:
|
||||
|
||||
* Email account used by GitLab to send notification emails needs to have "Consistent history of sending a high volume of mail from your domain (order of hundred emails a day minimum to Gmail) for a few weeks at least".
|
||||
* "A very very low rate of spam complaints from users."
|
||||
* Emails must be authenticated via DKIM or SPF
|
||||
* Before sending the final form("Gmail Schema Whitelist Request"), you must send a real email from your production server. This means that you will have to find a way to send this email from the email address you are registering. You can do this by, for example, forwarding the real email from the email address you are registering or going into the rails console on the GitLab server and triggering the email sending from there.
|
||||
|
||||
You can check how it looks going through all the steps laid out in the "Registering with Google" doc in [this GitLab.com issue](https://gitlab.com/gitlab-org/gitlab-ce/issues/1517).
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
@@ -98,7 +98,8 @@ module Gitlab
|
||||
note: reply,
|
||||
noteable_type: sent_notification.noteable_type,
|
||||
noteable_id: sent_notification.noteable_id,
|
||||
commit_id: sent_notification.commit_id
|
||||
commit_id: sent_notification.commit_id,
|
||||
line_code: sent_notification.line_code
|
||||
).execute
|
||||
end
|
||||
end
|
||||
|
||||
@@ -37,7 +37,7 @@ describe Profiles::TwoFactorAuthsController do
|
||||
|
||||
context 'with valid pin' do
|
||||
before do
|
||||
expect(user).to receive(:valid_otp?).with(pin).and_return(true)
|
||||
expect(user).to receive(:validate_and_consume_otp!).with(pin).and_return(true)
|
||||
end
|
||||
|
||||
it 'sets two_factor_enabled' do
|
||||
@@ -63,7 +63,7 @@ describe Profiles::TwoFactorAuthsController do
|
||||
|
||||
context 'with invalid pin' do
|
||||
before do
|
||||
expect(user).to receive(:valid_otp?).with(pin).and_return(false)
|
||||
expect(user).to receive(:validate_and_consume_otp!).with(pin).and_return(false)
|
||||
end
|
||||
|
||||
it 'assigns error' do
|
||||
|
||||
@@ -712,7 +712,7 @@ describe Notify do
|
||||
|
||||
before do
|
||||
user.update_attribute(:email, "user@company.com")
|
||||
user.confirm!
|
||||
user.confirm
|
||||
end
|
||||
|
||||
it "is sent from the committer email" do
|
||||
@@ -730,7 +730,7 @@ describe Notify do
|
||||
|
||||
before do
|
||||
user.update_attribute(:email, "user@something.company.com")
|
||||
user.confirm!
|
||||
user.confirm
|
||||
end
|
||||
|
||||
it "is sent from the default email" do
|
||||
@@ -748,7 +748,7 @@ describe Notify do
|
||||
|
||||
before do
|
||||
user.update_attribute(:email, "user@mpany.com")
|
||||
user.confirm!
|
||||
user.confirm
|
||||
end
|
||||
|
||||
it "is sent from the default email" do
|
||||
|
||||
@@ -34,8 +34,6 @@ describe DroneCiService do
|
||||
it { is_expected.to validate_presence_of(:drone_url) }
|
||||
it { is_expected.to allow_value('ewf9843kdnfdfs89234n').for(:token) }
|
||||
it { is_expected.to allow_value('http://ci.example.com').for(:drone_url) }
|
||||
it { is_expected.not_to allow_value('token with spaces').for(:token) }
|
||||
it { is_expected.not_to allow_value('token/with%spaces').for(:token) }
|
||||
it { is_expected.not_to allow_value('this is not url').for(:drone_url) }
|
||||
it { is_expected.not_to allow_value('http//noturl').for(:drone_url) }
|
||||
it { is_expected.not_to allow_value('ftp://ci.example.com').for(:drone_url) }
|
||||
@@ -48,7 +46,6 @@ describe DroneCiService do
|
||||
it { is_expected.not_to validate_presence_of(:drone_url) }
|
||||
it { is_expected.to allow_value('ewf9843kdnfdfs89234n').for(:token) }
|
||||
it { is_expected.to allow_value('http://drone.example.com').for(:drone_url) }
|
||||
it { is_expected.to allow_value('token with spaces').for(:token) }
|
||||
it { is_expected.to allow_value('ftp://drone.example.com').for(:drone_url) }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -188,7 +188,7 @@ describe User do
|
||||
end
|
||||
|
||||
it 'confirms a user' do
|
||||
user.confirm!
|
||||
user.confirm
|
||||
expect(user.confirmed?).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user