diff options
author | Robert Speicher <rspeicher@gmail.com> | 2015-09-21 05:10:32 +0300 |
---|---|---|
committer | Robert Speicher <rspeicher@gmail.com> | 2015-09-21 05:10:32 +0300 |
commit | 423a39f07d18dbdb6b8fe788fbd6a08919ddb04d (patch) | |
tree | 65f997d9e257e791e8026ee90a9e8a0f99ca49ec | |
parent | 08c8467ffeefaa61c487eb839fdb04e8c00c1b66 (diff) | |
parent | ca45e925dfcf5b67fd494bd2009ca7ed0447dacc (diff) |
Merge branch 'master' into 8-0-stable
42 files changed, 311 insertions, 194 deletions
@@ -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' diff --git a/Gemfile.lock b/Gemfile.lock index f43e885ce48..320f7629fb6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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 diff --git a/app/assets/javascripts/issuable_context.js.coffee b/app/assets/javascripts/issuable_context.js.coffee index 176d9cabefa..c4d3e619f5e 100644 --- a/app/assets/javascripts/issuable_context.js.coffee +++ b/app/assets/javascripts/issuable_context.js.coffee @@ -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('') diff --git a/app/assets/stylesheets/base/gl_variables.scss b/app/assets/stylesheets/base/gl_variables.scss index bfef5f78f83..7378d404008 100644 --- a/app/assets/stylesheets/base/gl_variables.scss +++ b/app/assets/stylesheets/base/gl_variables.scss @@ -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; diff --git a/app/assets/stylesheets/ci/projects.scss b/app/assets/stylesheets/ci/projects.scss index e5d69360c2c..c63a67ab720 100644 --- a/app/assets/stylesheets/ci/projects.scss +++ b/app/assets/stylesheets/ci/projects.scss @@ -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; + } + } } diff --git a/app/assets/stylesheets/generic/blocks.scss b/app/assets/stylesheets/generic/blocks.scss index ce024272a30..6ce34b5c3e8 100644 --- a/app/assets/stylesheets/generic/blocks.scss +++ b/app/assets/stylesheets/generic/blocks.scss @@ -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; } diff --git a/app/assets/stylesheets/generic/callout.scss b/app/assets/stylesheets/generic/callout.scss new file mode 100644 index 00000000000..f1699d21c9b --- /dev/null +++ b/app/assets/stylesheets/generic/callout.scss @@ -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; +} + diff --git a/app/assets/stylesheets/generic/pagination.scss b/app/assets/stylesheets/generic/pagination.scss new file mode 100644 index 00000000000..a937677ebdc --- /dev/null +++ b/app/assets/stylesheets/generic/pagination.scss @@ -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; + } + } +} diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index 6092c79c254..a19b1abee27 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -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" diff --git a/app/controllers/profiles/two_factor_auths_controller.rb b/app/controllers/profiles/two_factor_auths_controller.rb index f9af0871cf1..e6b99be37fb 100644 --- a/app/controllers/profiles/two_factor_auths_controller.rb +++ b/app/controllers/profiles/two_factor_auths_controller.rb @@ -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! diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index cfa565cd03e..1b60d3e27d0 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -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 diff --git a/app/helpers/ci/application_helper.rb b/app/helpers/ci/application_helper.rb index 7e880b00b3a..9fe6282bb81 100644 --- a/app/helpers/ci/application_helper.rb +++ b/app/helpers/ci/application_helper.rb @@ -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 diff --git a/app/helpers/ci/builds_helper.rb b/app/helpers/ci/builds_helper.rb index cdabdad17d2..5d6e785d951 100644 --- a/app/helpers/ci/builds_helper.rb +++ b/app/helpers/ci/builds_helper.rb @@ -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 diff --git a/app/helpers/ci/commits_helper.rb b/app/helpers/ci/commits_helper.rb index 74de30e006e..9069aed5b4d 100644 --- a/app/helpers/ci/commits_helper.rb +++ b/app/helpers/ci/commits_helper.rb @@ -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 diff --git a/app/mailers/emails/notes.rb b/app/mailers/emails/notes.rb index 63d4aca61af..87ba94a583d 100644 --- a/app/mailers/emails/notes.rb +++ b/app/mailers/emails/notes.rb @@ -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 diff --git a/app/models/project.rb b/app/models/project.rb index 6e2f9645661..1a5c1c978c9 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -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 diff --git a/app/models/project_services/drone_ci_service.rb b/app/models/project_services/drone_ci_service.rb index b13fa3e9ecb..c73c4b058a1 100644 --- a/app/models/project_services/drone_ci_service.rb +++ b/app/models/project_services/drone_ci_service.rb @@ -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? diff --git a/app/models/sent_notification.rb b/app/models/sent_notification.rb index 33b113a2a27..03425389dd3 100644 --- a/app/models/sent_notification.rb +++ b/app/models/sent_notification.rb @@ -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 diff --git a/app/views/ci/admin/builds/_build.html.haml b/app/views/ci/admin/builds/_build.html.haml index 47f8df8f98e..778d51d03be 100644 --- a/app/views/ci/admin/builds/_build.html.haml +++ b/app/views/ci/admin/builds/_build.html.haml @@ -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) diff --git a/app/views/ci/admin/projects/_project.html.haml b/app/views/ci/admin/projects/_project.html.haml index 505dd4b3fdc..c461206c72a 100644 --- a/app/views/ci/admin/projects/_project.html.haml +++ b/app/views/ci/admin/projects/_project.html.haml @@ -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 diff --git a/app/views/ci/admin/runners/show.html.haml b/app/views/ci/admin/runners/show.html.haml index 24e0ad3b070..09905e0eb47 100644 --- a/app/views/ci/admin/runners/show.html.haml +++ b/app/views/ci/admin/runners/show.html.haml @@ -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 diff --git a/app/views/ci/builds/_build.html.haml b/app/views/ci/builds/_build.html.haml index da306c9f020..515b862e992 100644 --- a/app/views/ci/builds/_build.html.haml +++ b/app/views/ci/builds/_build.html.haml @@ -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 diff --git a/app/views/ci/builds/show.html.haml b/app/views/ci/builds/show.html.haml index d1e955b5012..839dbf5c554 100644 --- a/app/views/ci/builds/show.html.haml +++ b/app/views/ci/builds/show.html.haml @@ -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 - - = link_to ci_project_path(@build.project, ref: @build.ref) do - %span.label.label-primary= "#{@build.ref}" - - - if @build.duration - .pull-right - %span - %i.fa.fa-time - #{duration_in_words(@build.finished_at, @build.started_at)} +.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 - .clearfix - = @build.status - .pull-right - = @build.updated_at.stamp('19:00 Aug 27') + = 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 + = 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 - = link_to ci_project_build_url(@project, build) do - %span ##{build.id} + = ci_icon_for_status(build.status) %td - - if build.name - = build.name + = link_to ci_project_build_url(@project, build) do + - if build.name + = build.name + - else + %span ##{build.id} + %td.status= build.status diff --git a/app/views/ci/commits/_commit.html.haml b/app/views/ci/commits/_commit.html.haml index c1b1988d147..1eacfca944f 100644 --- a/app/views/ci/commits/_commit.html.haml +++ b/app/views/ci/commits/_commit.html.haml @@ -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 diff --git a/app/views/ci/commits/show.html.haml b/app/views/ci/commits/show.html.haml index 1aeb557314a..8f38aa84676 100644 --- a/app/views/ci/commits/show.html.haml +++ b/app/views/ci/commits/show.html.haml @@ -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 diff --git a/app/views/ci/projects/_project.html.haml b/app/views/ci/projects/_project.html.haml index 869747b6eb1..844b6677b3d 100644 --- a/app/views/ci/projects/_project.html.haml +++ b/app/views/ci/projects/_project.html.haml @@ -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' -
\ No newline at end of file diff --git a/app/views/kaminari/gitlab/_paginator.html.haml b/app/views/kaminari/gitlab/_paginator.html.haml index 4f7996e4996..b8d419b5894 100644 --- a/app/views/kaminari/gitlab/_paginator.html.haml +++ b/app/views/kaminari/gitlab/_paginator.html.haml @@ -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? diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index eada70faebc..69cdf497a84 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -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" diff --git a/db/fixtures/production/001_admin.rb b/db/fixtures/production/001_admin.rb index 1c8740f6ba9..b0c0b6450f6 100644 --- a/db/fixtures/production/001_admin.rb +++ b/db/fixtures/production/001_admin.rb @@ -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[ diff --git a/db/migrate/20150817163600_deduplicate_user_identities.rb b/db/migrate/20150817163600_deduplicate_user_identities.rb index fab669c2905..fceffc48018 100644 --- a/db/migrate/20150817163600_deduplicate_user_identities.rb +++ b/db/migrate/20150817163600_deduplicate_user_identities.rb @@ -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 diff --git a/db/migrate/20150920010715_add_consumed_timestep_to_users.rb b/db/migrate/20150920010715_add_consumed_timestep_to_users.rb new file mode 100644 index 00000000000..c8438b3f6aa --- /dev/null +++ b/db/migrate/20150920010715_add_consumed_timestep_to_users.rb @@ -0,0 +1,5 @@ +class AddConsumedTimestepToUsers < ActiveRecord::Migration + def change + add_column :users, :consumed_timestep, :integer + end +end diff --git a/db/migrate/20150920161119_add_line_code_to_sent_notification.rb b/db/migrate/20150920161119_add_line_code_to_sent_notification.rb new file mode 100644 index 00000000000..d9af4e71751 --- /dev/null +++ b/db/migrate/20150920161119_add_line_code_to_sent_notification.rb @@ -0,0 +1,5 @@ +class AddLineCodeToSentNotification < ActiveRecord::Migration + def change + add_column :sent_notifications, :line_code, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index d70c4b58e93..01ccda7a75e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -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 diff --git a/doc/install/database_mysql.md b/doc/install/database_mysql.md index 362c492d0ac..c565e90da2f 100644 --- a/doc/install/database_mysql.md +++ b/doc/install/database_mysql.md @@ -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 diff --git a/doc/integration/README.md b/doc/integration/README.md index 6d856951d4e..eff39a626ae 100644 --- a/doc/integration/README.md +++ b/doc/integration/README.md @@ -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). diff --git a/doc/integration/gmail_action_buttons_for_gitlab.md b/doc/integration/gmail_action_buttons_for_gitlab.md new file mode 100644 index 00000000000..de45f25ad62 --- /dev/null +++ b/doc/integration/gmail_action_buttons_for_gitlab.md @@ -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. + +![gmail_actions_button.png](gmail_actions_button.png) + +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). diff --git a/doc/integration/gmail_actions_button.png b/doc/integration/gmail_actions_button.png Binary files differnew file mode 100644 index 00000000000..b08f54d137b --- /dev/null +++ b/doc/integration/gmail_actions_button.png diff --git a/lib/gitlab/email/receiver.rb b/lib/gitlab/email/receiver.rb index 355fbd27898..341b557858f 100644 --- a/lib/gitlab/email/receiver.rb +++ b/lib/gitlab/email/receiver.rb @@ -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 diff --git a/spec/controllers/profiles/two_factor_auths_controller_spec.rb b/spec/controllers/profiles/two_factor_auths_controller_spec.rb index f54706e3aa3..4fb1473c2d2 100644 --- a/spec/controllers/profiles/two_factor_auths_controller_spec.rb +++ b/spec/controllers/profiles/two_factor_auths_controller_spec.rb @@ -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 diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb index 97c07ad7d55..2c97a521d96 100644 --- a/spec/mailers/notify_spec.rb +++ b/spec/mailers/notify_spec.rb @@ -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 diff --git a/spec/models/project_services/drone_ci_service_spec.rb b/spec/models/project_services/drone_ci_service_spec.rb index bad9a9e6e1a..e9967f5fe0b 100644 --- a/spec/models/project_services/drone_ci_service_spec.rb +++ b/spec/models/project_services/drone_ci_service_spec.rb @@ -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 diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index eeb9069aa17..480950859a2 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -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 |