summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG8
-rw-r--r--Gemfile6
-rw-r--r--Gemfile.lock22
-rw-r--r--app/assets/javascripts/issuable_context.js.coffee9
-rw-r--r--app/assets/stylesheets/base/gl_variables.scss12
-rw-r--r--app/assets/stylesheets/ci/projects.scss68
-rw-r--r--app/assets/stylesheets/generic/blocks.scss7
-rw-r--r--app/assets/stylesheets/generic/callout.scss45
-rw-r--r--app/assets/stylesheets/generic/pagination.scss32
-rw-r--r--app/assets/stylesheets/generic/typography.scss4
-rw-r--r--app/controllers/admin/application_settings_controller.rb2
-rw-r--r--app/controllers/admin/users_controller.rb2
-rw-r--r--app/controllers/ci/application_controller.rb13
-rw-r--r--app/controllers/ci/helps_controller.rb16
-rw-r--r--app/controllers/ci/projects_controller.rb38
-rw-r--r--app/controllers/profiles/two_factor_auths_controller.rb2
-rw-r--r--app/controllers/projects/blob_controller.rb11
-rw-r--r--app/controllers/projects/milestones_controller.rb7
-rw-r--r--app/controllers/sessions_controller.rb2
-rw-r--r--app/finders/trending_projects_finder.rb17
-rw-r--r--app/helpers/application_helper.rb4
-rw-r--r--app/helpers/ci/application_helper.rb130
-rw-r--r--app/helpers/ci/builds_helper.rb22
-rw-r--r--app/helpers/ci/commits_helper.rb15
-rw-r--r--app/helpers/events_helper.rb11
-rw-r--r--app/helpers/gitlab_markdown_helper.rb4
-rw-r--r--app/helpers/groups_helper.rb10
-rw-r--r--app/helpers/projects_helper.rb35
-rw-r--r--app/mailers/emails/notes.rb6
-rw-r--r--app/models/application_setting.rb3
-rw-r--r--app/models/ci/commit.rb2
-rw-r--r--app/models/ci/project.rb15
-rw-r--r--app/models/concerns/issuable.rb6
-rw-r--r--app/models/event.rb12
-rw-r--r--app/models/hooks/web_hook.rb2
-rw-r--r--app/models/milestone.rb2
-rw-r--r--app/models/project.rb2
-rw-r--r--app/models/project_services/buildkite_service.rb8
-rw-r--r--app/models/project_services/drone_ci_service.rb16
-rw-r--r--app/models/project_services/gitlab_ci_service.rb86
-rw-r--r--app/models/sent_notification.rb14
-rw-r--r--app/services/ci/create_project_service.rb9
-rw-r--r--app/services/event_create_service.rb4
-rw-r--r--app/services/milestones/destroy_service.rb22
-rw-r--r--app/services/projects/fork_service.rb2
-rw-r--r--app/views/admin/application_settings/_form.html.haml14
-rw-r--r--app/views/ci/admin/builds/_build.html.haml4
-rw-r--r--app/views/ci/admin/projects/_project.html.haml5
-rw-r--r--app/views/ci/admin/runners/show.html.haml4
-rw-r--r--app/views/ci/builds/_build.html.haml4
-rw-r--r--app/views/ci/builds/show.html.haml69
-rw-r--r--app/views/ci/commits/_commit.html.haml4
-rw-r--r--app/views/ci/commits/show.html.haml55
-rw-r--r--app/views/ci/helps/oauth2.html.haml20
-rw-r--r--app/views/ci/helps/show.html.haml40
-rw-r--r--app/views/ci/projects/_form.html.haml1
-rw-r--r--app/views/ci/projects/_gl_projects.html.haml15
-rw-r--r--app/views/ci/projects/_project.html.haml59
-rw-r--r--app/views/ci/projects/_public.html.haml5
-rw-r--r--app/views/ci/projects/_search.html.haml8
-rw-r--r--app/views/ci/projects/disabled.html.haml1
-rw-r--r--app/views/ci/projects/edit.html.haml2
-rw-r--r--app/views/ci/projects/gitlab.html.haml27
-rw-r--r--app/views/ci/projects/index.html.haml33
-rw-r--r--app/views/events/event/_common.html.haml5
-rw-r--r--app/views/groups/milestones/_header_title.html.haml1
-rw-r--r--app/views/groups/milestones/show.html.haml2
-rw-r--r--app/views/help/index.html.haml3
-rw-r--r--app/views/kaminari/gitlab/_paginator.html.haml2
-rw-r--r--app/views/layouts/ci/_nav_admin.html.haml4
-rw-r--r--app/views/layouts/ci/_nav_dashboard.html.haml24
-rw-r--r--app/views/layouts/ci/application.html.haml4
-rw-r--r--app/views/layouts/dashboard.html.haml3
-rw-r--r--app/views/layouts/group.html.haml5
-rw-r--r--app/views/layouts/group_settings.html.haml1
-rw-r--r--app/views/layouts/nav/_admin.html.haml7
-rw-r--r--app/views/layouts/nav/_dashboard.html.haml14
-rw-r--r--app/views/layouts/nav/_project.html.haml7
-rw-r--r--app/views/layouts/profile.html.haml3
-rw-r--r--app/views/layouts/project.html.haml4
-rw-r--r--app/views/layouts/project_settings.html.haml1
-rw-r--r--app/views/notify/new_user_email.html.haml2
-rw-r--r--app/views/projects/activity.html.haml2
-rw-r--r--app/views/projects/blame/show.html.haml2
-rw-r--r--app/views/projects/blob/_header_title.html.haml1
-rw-r--r--app/views/projects/blob/_upload.html.haml10
-rw-r--r--app/views/projects/blob/edit.html.haml2
-rw-r--r--app/views/projects/blob/new.html.haml5
-rw-r--r--app/views/projects/blob/show.html.haml7
-rw-r--r--app/views/projects/branches/index.html.haml1
-rw-r--r--app/views/projects/branches/new.html.haml2
-rw-r--r--app/views/projects/commit/show.html.haml1
-rw-r--r--app/views/projects/commits/_header_title.html.haml1
-rw-r--r--app/views/projects/commits/show.html.haml1
-rw-r--r--app/views/projects/compare/index.html.haml1
-rw-r--r--app/views/projects/compare/show.html.haml1
-rw-r--r--app/views/projects/graphs/_header_title.html.haml1
-rw-r--r--app/views/projects/graphs/commits.html.haml3
-rw-r--r--app/views/projects/graphs/show.html.haml3
-rw-r--r--app/views/projects/issues/_header_title.html.haml1
-rw-r--r--app/views/projects/issues/index.html.haml2
-rw-r--r--app/views/projects/issues/new.html.haml2
-rw-r--r--app/views/projects/issues/show.html.haml2
-rw-r--r--app/views/projects/labels/_header_title.html.haml1
-rw-r--r--app/views/projects/labels/edit.html.haml2
-rw-r--r--app/views/projects/labels/index.html.haml1
-rw-r--r--app/views/projects/labels/new.html.haml2
-rw-r--r--app/views/projects/merge_requests/_header_title.html.haml1
-rw-r--r--app/views/projects/merge_requests/_show.html.haml2
-rw-r--r--app/views/projects/merge_requests/edit.html.haml2
-rw-r--r--app/views/projects/merge_requests/index.html.haml2
-rw-r--r--app/views/projects/merge_requests/invalid.html.haml2
-rw-r--r--app/views/projects/merge_requests/new.html.haml2
-rw-r--r--app/views/projects/milestones/_header_title.html.haml1
-rw-r--r--app/views/projects/milestones/edit.html.haml1
-rw-r--r--app/views/projects/milestones/index.html.haml1
-rw-r--r--app/views/projects/milestones/new.html.haml1
-rw-r--r--app/views/projects/milestones/show.html.haml2
-rw-r--r--app/views/projects/network/show.html.haml1
-rw-r--r--app/views/projects/project_members/_header_title.html.haml1
-rw-r--r--app/views/projects/project_members/import.html.haml2
-rw-r--r--app/views/projects/project_members/index.html.haml1
-rw-r--r--app/views/projects/snippets/_header_title.html.haml1
-rw-r--r--app/views/projects/snippets/edit.html.haml2
-rw-r--r--app/views/projects/snippets/index.html.haml2
-rw-r--r--app/views/projects/snippets/new.html.haml2
-rw-r--r--app/views/projects/snippets/show.html.haml2
-rw-r--r--app/views/projects/tags/index.html.haml1
-rw-r--r--app/views/projects/tags/new.html.haml2
-rw-r--r--app/views/projects/tree/show.html.haml1
-rw-r--r--app/views/projects/wikis/_header_title.html.haml1
-rw-r--r--app/views/projects/wikis/edit.html.haml2
-rw-r--r--app/views/projects/wikis/empty.html.haml2
-rw-r--r--app/views/projects/wikis/git_access.html.haml2
-rw-r--r--app/views/projects/wikis/history.html.haml4
-rw-r--r--app/views/projects/wikis/pages.html.haml2
-rw-r--r--app/views/projects/wikis/show.html.haml4
-rw-r--r--app/views/shared/projects/_list.html.haml2
-rw-r--r--app/workers/fork_registration_worker.rb12
-rw-r--r--config/gitlab.yml.example3
-rw-r--r--config/initializers/1_settings.rb2
-rw-r--r--config/routes.rb7
-rw-r--r--db/fixtures/production/001_admin.rb2
-rw-r--r--db/migrate/20150817163600_deduplicate_user_identities.rb2
-rw-r--r--db/migrate/20150915001905_enable_ssl_verification_by_default.rb5
-rw-r--r--db/migrate/20150916000405_enable_ssl_verification_for_web_hooks.rb8
-rw-r--r--db/migrate/20150916114643_add_help_page_text_to_application_settings.rb5
-rw-r--r--db/migrate/20150918084513_add_ci_enabled_to_application_settings.rb5
-rw-r--r--db/migrate/20150920010715_add_consumed_timestep_to_users.rb5
-rw-r--r--db/migrate/20150920161119_add_line_code_to_sent_notification.rb5
-rw-r--r--db/schema.rb8
-rw-r--r--doc/ci/api/README.md1
-rw-r--r--doc/ci/api/forks.md23
-rw-r--r--doc/install/database_mysql.md2
-rw-r--r--doc/integration/README.md2
-rw-r--r--doc/integration/gmail_action_buttons_for_gitlab.md22
-rw-r--r--doc/integration/gmail_actions_button.pngbin0 -> 17321 bytes
-rw-r--r--doc/migrate_ci_to_ce/README.md29
-rw-r--r--doc/reply_by_email/postfix.md4
-rw-r--r--doc/ssh/README.md2
-rw-r--r--doc/web_hooks/web_hooks.md6
-rw-r--r--features/project/issues/milestones.feature8
-rw-r--r--features/steps/admin/settings.rb1
-rw-r--r--features/steps/project/issues/milestones.rb7
-rw-r--r--features/steps/project/services.rb4
-rw-r--r--features/steps/shared/project.rb5
-rw-r--r--lib/api/users.rb2
-rw-r--r--lib/backup/database.rb8
-rw-r--r--lib/ci/api/api.rb5
-rw-r--r--lib/ci/api/forks.rb37
-rw-r--r--lib/ci/api/helpers.rb6
-rw-r--r--lib/ci/migrate/builds.rb29
-rw-r--r--lib/ci/migrate/database.rb42
-rw-r--r--lib/ci/migrate/manager.rb70
-rw-r--r--lib/ci/migrate/tags.rb55
-rw-r--r--lib/ci/project_list_builder.rb21
-rw-r--r--lib/gitlab/email/receiver.rb3
-rw-r--r--lib/tasks/ci/migrate.rake62
-rw-r--r--spec/controllers/ci/projects_controller_spec.rb45
-rw-r--r--spec/controllers/profiles/two_factor_auths_controller_spec.rb4
-rw-r--r--spec/controllers/projects/milestones_controller_spec.rb4
-rw-r--r--spec/helpers/gitlab_markdown_helper_spec.rb11
-rw-r--r--spec/lib/gitlab/backend/grack_auth_spec.rb1
-rw-r--r--spec/mailers/notify_spec.rb6
-rw-r--r--spec/models/concerns/issuable_spec.rb16
-rw-r--r--spec/models/project_services/buildkite_service_spec.rb14
-rw-r--r--spec/models/project_services/drone_ci_service_spec.rb3
-rw-r--r--spec/models/project_services/gitlab_ci_service_spec.rb50
-rw-r--r--spec/models/user_spec.rb2
-rw-r--r--spec/requests/api/projects_spec.rb2
-rw-r--r--spec/requests/api/services_spec.rb4
-rw-r--r--spec/requests/api/users_spec.rb56
-rw-r--r--spec/requests/ci/api/forks_spec.rb59
-rw-r--r--spec/services/ci/create_commit_service_spec.rb13
-rw-r--r--spec/services/ci/create_project_service_spec.rb4
-rw-r--r--spec/services/event_create_service_spec.rb10
-rw-r--r--spec/services/projects/fork_service_spec.rb3
-rw-r--r--spec/workers/fork_registration_worker_spec.rb10
198 files changed, 1092 insertions, 1088 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 884e4258db0..31b2a759d40 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,8 @@
Please view this file on the master branch, on stable branches it's out of date.
v 8.0.0 (unreleased)
+ - Fix Markdown links not showing up in dashboard activity feed (Stan Hu)
+ - Fix HTML link that was improperly escaped in new user e-mail (Stan Hu)
- Fix broken sort in merge request API (Stan Hu)
- Bump rouge to 1.10.1 to remove warning noise and fix other syntax highlighting bugs (Stan Hu)
- Gracefully handle errors in syntax highlighting by leaving the block unformatted (Stan Hu)
@@ -17,6 +19,7 @@ v 8.0.0 (unreleased)
- Improve dropdown positioning on the project home page (Hannes Rosenögger)
- Upgrade browser gem to 1.0.0 to avoid warning in IE11 compatibilty mode (Stan Hu)
- Remove user OAuth tokens from the database and request new tokens each session (Stan Hu)
+ - Restrict users API endpoints to use integer IDs (Stan Hu)
- Only show recent push event if the branch still exists or a recent merge request has not been created (Stan Hu)
- Remove satellites
- Better performance for web editor (switched from satellites to rugged)
@@ -40,6 +43,7 @@ v 8.0.0 (unreleased)
- Retrieving oauth token with LDAP credentials
- Load Application settings from running database unless env var USE_DB=false
- Added Drone CI integration (Kirill Zaitsev)
+ - Fail builds if no .gitlab-ci.yml is found
- Refactored service API and added automatically service docs generator (Kirill Zaitsev)
- Added web_url key project hook_attrs (Kirill Zaitsev)
- Add ability to get user information by ID of an SSH key via the API
@@ -51,6 +55,10 @@ v 8.0.0 (unreleased)
- Added service API endpoint to retrieve service parameters (Petheő Bence)
- Add FogBugz project import (Jared Szechy)
- Sort users autocomplete lists by user (Allister Antosik)
+ - Webhook for issue now contains repository field (Jungkook Park)
+ - Add ability to add custom text to the help page (Jeroen van Baarsen)
+ - Add pg_schema to backup config
+ - Removed API calls from CE to CI
v 7.14.3
- No changes
diff --git a/Gemfile b/Gemfile
index 62968c57200..924ee382f4d 100644
--- a/Gemfile
+++ b/Gemfile
@@ -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'
@@ -286,7 +286,7 @@ gem "newrelic_rpm", '~> 3.9.4.245'
gem 'octokit', '~> 3.7.0'
-gem "mail_room", "~> 0.4.2"
+gem "mail_room", "~> 0.5.1"
gem 'email_reply_parser', '~> 0.5.8'
diff --git a/Gemfile.lock b/Gemfile.lock
index a4a0762bdd8..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)
@@ -384,7 +384,7 @@ GEM
systemu (~> 2.6.2)
mail (2.6.3)
mime-types (>= 1.16, < 3)
- mail_room (0.4.2)
+ mail_room (0.5.1)
method_source (0.8.2)
mime-types (1.25.1)
mimemagic (0.3.0)
@@ -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)
@@ -846,7 +848,7 @@ DEPENDENCIES
jquery-ui-rails (~> 4.2.1)
kaminari (~> 0.15.1)
letter_opener (~> 1.1.2)
- mail_room (~> 0.4.2)
+ mail_room (~> 0.5.1)
minitest (~> 5.7.0)
mousetrap-rails (~> 1.4.6)
mysql2 (~> 0.3.16)
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/assets/stylesheets/generic/typography.scss b/app/assets/stylesheets/generic/typography.scss
index 73034c84f9a..41189432bf6 100644
--- a/app/assets/stylesheets/generic/typography.scss
+++ b/app/assets/stylesheets/generic/typography.scss
@@ -89,6 +89,10 @@ a > code {
}
}
+.md-area {
+ @include md-typography;
+}
+
.md {
@include md-typography;
}
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index f38e07af84b..5f70582cbb7 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -46,6 +46,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:gravatar_enabled,
:twitter_sharing_enabled,
:sign_in_text,
+ :help_page_text,
:home_page_url,
:after_sign_out_path,
:max_attachment_size,
@@ -55,6 +56,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:restricted_signup_domains_raw,
:version_check_enabled,
:user_oauth_applications,
+ :ci_enabled,
restricted_visibility_levels: [],
import_sources: []
)
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/ci/application_controller.rb b/app/controllers/ci/application_controller.rb
index a5868da377f..8d8ff75ff72 100644
--- a/app/controllers/ci/application_controller.rb
+++ b/app/controllers/ci/application_controller.rb
@@ -1,5 +1,7 @@
module Ci
class ApplicationController < ::ApplicationController
+ before_action :check_enable_flag!
+
def self.railtie_helpers_paths
"app/helpers/ci"
end
@@ -8,11 +10,16 @@ module Ci
private
+ def check_enable_flag!
+ unless current_application_settings.ci_enabled
+ redirect_to(disabled_ci_projects_path)
+ return
+ end
+ end
+
def authenticate_public_page!
unless project.public
- unless current_user
- redirect_to(new_user_sessions_path) and return
- end
+ authenticate_user!
return access_denied! unless can?(current_user, :read_project, gl_project)
end
diff --git a/app/controllers/ci/helps_controller.rb b/app/controllers/ci/helps_controller.rb
deleted file mode 100644
index a1ee4111614..00000000000
--- a/app/controllers/ci/helps_controller.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-module Ci
- class HelpsController < Ci::ApplicationController
- skip_filter :check_config
-
- def show
- end
-
- def oauth2
- if valid_config?
- redirect_to ci_root_path
- else
- render layout: 'ci/empty'
- end
- end
- end
-end
diff --git a/app/controllers/ci/projects_controller.rb b/app/controllers/ci/projects_controller.rb
index 6483a84ee91..40b61edb0a9 100644
--- a/app/controllers/ci/projects_controller.rb
+++ b/app/controllers/ci/projects_controller.rb
@@ -5,38 +5,36 @@ module Ci
before_action :authenticate_user!, except: [:build, :badge, :index, :show]
before_action :authenticate_public_page!, only: :show
before_action :project, only: [:build, :integration, :show, :badge, :edit, :update, :destroy, :toggle_shared_runners, :dumped_yaml]
- before_action :authorize_access_project!, except: [:build, :gitlab, :badge, :index, :show, :new, :create]
+ before_action :authorize_access_project!, except: [:build, :badge, :index, :show, :new, :create, :disabled]
before_action :authorize_manage_project!, only: [:edit, :integration, :update, :destroy, :toggle_shared_runners, :dumped_yaml]
before_action :authenticate_token!, only: [:build]
before_action :no_cache, only: [:badge]
+ skip_before_action :check_enable_flag!, only: [:disabled]
protect_from_forgery except: :build
- layout 'ci/project', except: [:index, :gitlab]
+ layout 'ci/project', except: [:index, :disabled]
- def index
- @projects = Ci::Project.ordered_by_last_commit_date.public_only.page(params[:page]) unless current_user
+ def disabled
end
- def gitlab
+ def index
@limit, @offset = (params[:limit] || PROJECTS_BATCH).to_i, (params[:offset] || 0).to_i
@page = @offset == 0 ? 1 : (@offset / @limit + 1)
- @gl_projects = current_user.authorized_projects
- @gl_projects = @gl_projects.where("name LIKE ?", "%#{params[:search]}%") if params[:search]
- @gl_projects = @gl_projects.page(@page).per(@limit)
+ if current_user
+ @projects = ProjectListBuilder.new.execute(current_user, params[:search])
- @projects = Ci::Project.where(gitlab_id: @gl_projects.map(&:id)).ordered_by_last_commit_date
- @total_count = @gl_projects.size
+ @projects = @projects.page(@page).per(@limit)
- @gl_projects = @gl_projects.where.not(id: @projects.map(&:gitlab_id))
+ @total_count = @projects.size
+ end
respond_to do |format|
format.json do
- pager_json("ci/projects/gitlab", @total_count)
+ pager_json("ci/projects/index", @total_count)
end
+ format.html
end
- rescue
- @error = 'Failed to fetch GitLab projects'
end
def show
@@ -57,7 +55,7 @@ module Ci
return redirect_to ci_root_path, alert: 'You have to have at least master role to enable CI for this project'
end
- @project = Ci::CreateProjectService.new.execute(current_user, project_data, ci_project_url(":project_id"))
+ @project = Ci::CreateProjectService.new.execute(current_user, project_data)
if @project.persisted?
redirect_to ci_project_path(@project, show_guide: true), notice: 'Project was successfully created.'
@@ -88,16 +86,6 @@ module Ci
redirect_to ci_projects_url
end
- def build
- @commit = Ci::CreateCommitService.new.execute(@project, params.dup)
-
- if @commit && @commit.valid?
- head 201
- else
- head 400
- end
- end
-
# Project status badge
# Image with build status for sha or ref
def badge
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/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index d7be212c33a..8776721d243 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -18,12 +18,6 @@ class Projects::BlobController < Projects::ApplicationController
before_action :after_edit_path, only: [:edit, :update]
def new
- @title = 'Upload'
- @placeholder = 'Upload new file'
- @button_title = 'Upload file'
- @form_path = namespace_project_create_blob_path(@project.namespace, @project, @id)
- @method = :post
-
commit unless @repository.empty?
end
@@ -46,11 +40,6 @@ class Projects::BlobController < Projects::ApplicationController
end
def show
- @title = "Replace #{@blob.name}"
- @placeholder = @title
- @button_title = 'Replace file'
- @form_path = namespace_project_update_blob_path(@project.namespace, @project, @id)
- @method = :put
end
def edit
diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb
index 9efe9704d1e..86f4a02a6e9 100644
--- a/app/controllers/projects/milestones_controller.rb
+++ b/app/controllers/projects/milestones_controller.rb
@@ -66,12 +66,7 @@ class Projects::MilestonesController < Projects::ApplicationController
def destroy
return access_denied! unless can?(current_user, :admin_milestone, @project)
- update_params = { milestone: nil }
- @milestone.issues.each do |issue|
- Issues::UpdateService.new(@project, current_user, update_params).execute(issue)
- end
-
- @milestone.destroy
+ Milestones::DestroyService.new(project, current_user).execute(milestone)
respond_to do |format|
format.html { redirect_to namespace_project_milestones_path }
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/finders/trending_projects_finder.rb b/app/finders/trending_projects_finder.rb
index f3f4d461efa..9ea342cb26d 100644
--- a/app/finders/trending_projects_finder.rb
+++ b/app/finders/trending_projects_finder.rb
@@ -2,21 +2,12 @@ class TrendingProjectsFinder
def execute(current_user, start_date = nil)
start_date ||= Date.today - 1.month
+ projects = projects_for(current_user)
+
# Determine trending projects based on comments count
# for period of time - ex. month
- trending_project_ids = Note.
- select("notes.project_id, count(notes.project_id) as pcount").
- where('notes.created_at > ?', start_date).
- group("project_id").
- reorder("pcount DESC").
- map(&:project_id)
-
- sql_order_ids = trending_project_ids.reverse.
- map { |project_id| "id = #{project_id}" }.join(", ")
-
- # Get list of projects that user allowed to see
- projects = projects_for(current_user)
- projects.where(id: trending_project_ids).reorder(sql_order_ids)
+ projects.joins(:notes).where('notes.created_at > ?', start_date).
+ group("projects.id").reorder("count(notes.id) DESC")
end
private
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index b049bd9fcc2..39ab83ccf12 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -13,7 +13,9 @@ module ApplicationHelper
# current_controller?(:commits) # => false
# current_controller?(:commits, :tree) # => true
def current_controller?(*args)
- args.any? { |v| v.to_s.downcase == controller.controller_name }
+ args.any? do |v|
+ v.to_s.downcase == controller.controller_name || v.to_s.downcase == controller.controller_path
+ end
end
# Check if a particular action is the current one
diff --git a/app/helpers/ci/application_helper.rb b/app/helpers/ci/application_helper.rb
index 3198fe55f91..9fe6282bb81 100644
--- a/app/helpers/ci/application_helper.rb
+++ b/app/helpers/ci/application_helper.rb
@@ -4,118 +4,10 @@ module Ci
image_tag 'ci/loader.gif', alt: 'Loading'
end
- # Navigation link helper
- #
- # Returns an `li` element with an 'active' class if the supplied
- # controller(s) and/or action(s) are currently active. The content of the
- # element is the value passed to the block.
- #
- # options - The options hash used to determine if the element is "active" (default: {})
- # :controller - One or more controller names to check (optional).
- # :action - One or more action names to check (optional).
- # :path - A shorthand path, such as 'dashboard#index', to check (optional).
- # :html_options - Extra options to be passed to the list element (optional).
- # block - An optional block that will become the contents of the returned
- # `li` element.
- #
- # When both :controller and :action are specified, BOTH must match in order
- # to be marked as active. When only one is given, either can match.
- #
- # Examples
- #
- # # Assuming we're on TreeController#show
- #
- # # Controller matches, but action doesn't
- # nav_link(controller: [:tree, :refs], action: :edit) { "Hello" }
- # # => '<li>Hello</li>'
- #
- # # Controller matches
- # nav_link(controller: [:tree, :refs]) { "Hello" }
- # # => '<li class="active">Hello</li>'
- #
- # # Shorthand path
- # nav_link(path: 'tree#show') { "Hello" }
- # # => '<li class="active">Hello</li>'
- #
- # # Supplying custom options for the list element
- # nav_link(controller: :tree, html_options: {class: 'home'}) { "Hello" }
- # # => '<li class="home active">Hello</li>'
- #
- # Returns a list item element String
- def nav_link(options = {}, &block)
- if path = options.delete(:path)
- if path.respond_to?(:each)
- c = path.map { |p| p.split('#').first }
- a = path.map { |p| p.split('#').last }
- else
- c, a, _ = path.split('#')
- end
- else
- c = options.delete(:controller)
- a = options.delete(:action)
- end
-
- if c && a
- # When given both options, make sure BOTH are active
- klass = current_controller?(*c) && current_action?(*a) ? 'active' : ''
- else
- # Otherwise check EITHER option
- klass = current_controller?(*c) || current_action?(*a) ? 'active' : ''
- end
-
- # Add our custom class into the html_options, which may or may not exist
- # and which may or may not already have a :class key
- o = options.delete(:html_options) || {}
- o[:class] ||= ''
- o[:class] += ' ' + klass
- o[:class].strip!
-
- if block_given?
- content_tag(:li, capture(&block), o)
- else
- content_tag(:li, nil, o)
- end
- end
-
- # Check if a particular controller is the current one
- #
- # args - One or more controller names to check
- #
- # Examples
- #
- # # On TreeController
- # current_controller?(:tree) # => true
- # current_controller?(:commits) # => false
- # current_controller?(:commits, :tree) # => true
- def current_controller?(*args)
- args.any? { |v| v.to_s.downcase == controller.controller_name }
- end
-
- # Check if a particular action is the current one
- #
- # args - One or more action names to check
- #
- # Examples
- #
- # # On Projects#new
- # current_action?(:new) # => true
- # current_action?(:create) # => false
- # current_action?(:new, :create) # => true
- def current_action?(*args)
- args.any? { |v| v.to_s.downcase == action_name }
- end
-
def date_from_to(from, to)
"#{from.to_s(:short)} - #{to.to_s(:short)}"
end
- def body_data_page
- path = controller.controller_path.split('/')
- namespace = path.first if path.second
-
- [namespace, controller.controller_name, controller.action_name].compact.join(":")
- end
-
def duration_in_words(finished_at, started_at)
if finished_at && started_at
interval_in_seconds = finished_at.to_i - started_at.to_i
@@ -136,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) + '&nbsp;'.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/helpers/events_helper.rb b/app/helpers/events_helper.rb
index 76602614bcd..6f69c2a9f32 100644
--- a/app/helpers/events_helper.rb
+++ b/app/helpers/events_helper.rb
@@ -46,6 +46,14 @@ module EventsHelper
}
end
+ def event_preposition(event)
+ if event.push? || event.commented? || event.target
+ "at"
+ elsif event.milestone?
+ "in"
+ end
+ end
+
def event_feed_title(event)
words = []
words << event.author_name
@@ -62,6 +70,9 @@ module EventsHelper
words << "##{truncate event.note_target_iid}"
end
words << "at"
+ elsif event.milestone?
+ words << "##{event.target_iid}" if event.target_iid
+ words << "in"
elsif event.target
words << "##{event.target_iid}:"
words << event.target.title if event.target.respond_to?(:title)
diff --git a/app/helpers/gitlab_markdown_helper.rb b/app/helpers/gitlab_markdown_helper.rb
index 1ebfd92f119..78bf25f55e7 100644
--- a/app/helpers/gitlab_markdown_helper.rb
+++ b/app/helpers/gitlab_markdown_helper.rb
@@ -45,7 +45,7 @@ module GitlabMarkdownHelper
end
def markdown(text, context = {})
- context.merge!(
+ context.reverse_merge!(
current_user: current_user,
path: @path,
project: @project,
@@ -59,7 +59,7 @@ module GitlabMarkdownHelper
# TODO (rspeicher): Remove all usages of this helper and just call `markdown`
# with a custom pipeline depending on the content being rendered
def gfm(text, options = {})
- options.merge!(
+ options.reverse_merge!(
current_user: current_user,
path: @path,
project: @project,
diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb
index 5e70de23f29..1d36969cd62 100644
--- a/app/helpers/groups_helper.rb
+++ b/app/helpers/groups_helper.rb
@@ -31,12 +31,12 @@ module GroupsHelper
end
end
- def group_title(group, name, url)
+ def group_title(group, name = nil, url = nil)
+ full_title = link_to(simple_sanitize(group.name), group_path(group))
+ full_title += ' &middot; '.html_safe + link_to(simple_sanitize(name), url) if name
+
content_tag :span do
- link_to(
- simple_sanitize(group.name), group_path(group)
- ) + ' &middot; '.html_safe +
- link_to(simple_sanitize(name), url)
+ full_title
end
end
end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 6a2de0de77c..a2b83c50c2e 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -317,41 +317,6 @@ module ProjectsHelper
@ref || @repository.try(:root_ref)
end
- def detect_project_title(project)
- name, url =
- if current_controller? 'wikis'
- ['Wiki', get_project_wiki_path(project)]
- elsif current_controller? 'project_members'
- ['Members', namespace_project_project_members_path(project.namespace, project)]
- elsif current_controller? 'labels'
- ['Labels', namespace_project_labels_path(project.namespace, project)]
- elsif current_controller? 'members'
- ['Members', project_files_path(project)]
- elsif current_controller? 'commits'
- ['Commits', project_commits_path(project)]
- elsif current_controller? 'graphs'
- ['Graphs', namespace_project_graph_path(project.namespace, project, current_ref)]
- elsif current_controller? 'network'
- ['Network', namespace_project_network_path(project.namespace, project, current_ref)]
- elsif current_controller? 'milestones'
- ['Milestones', namespace_project_milestones_path(project.namespace, project)]
- elsif current_controller? 'snippets'
- ['Snippets', namespace_project_snippets_path(project.namespace, project)]
- elsif current_controller? 'issues'
- ['Issues', namespace_project_issues_path(project.namespace, project)]
- elsif current_controller? 'merge_requests'
- ['Merge Requests', namespace_project_merge_requests_path(project.namespace, project)]
- elsif current_controller? 'tree', 'blob'
- ['Files', project_files_path(project)]
- elsif current_path? 'projects#activity'
- ['Activity', activity_project_path(project)]
- else
- [nil, nil]
- end
-
- project_title(project, name, url)
- end
-
private
def filename_path(project, filename)
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/application_setting.rb b/app/models/application_setting.rb
index c8841178e93..784f5c96a0a 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -83,7 +83,8 @@ class ApplicationSetting < ActiveRecord::Base
default_project_visibility: Settings.gitlab.default_projects_features['visibility_level'],
default_snippet_visibility: Settings.gitlab.default_projects_features['visibility_level'],
restricted_signup_domains: Settings.gitlab['restricted_signup_domains'],
- import_sources: ['github','bitbucket','gitlab','gitorious','google_code','fogbugz','git']
+ import_sources: ['github','bitbucket','gitlab','gitorious','google_code','fogbugz','git'],
+ ci_enabled: Settings.gitlab_ci['enabled']
)
end
diff --git a/app/models/ci/commit.rb b/app/models/ci/commit.rb
index 23cd47dfe37..f102d0a7679 100644
--- a/app/models/ci/commit.rb
+++ b/app/models/ci/commit.rb
@@ -236,7 +236,7 @@ module Ci
end
def config_processor
- @config_processor ||= Ci::GitlabCiYamlProcessor.new(push_data[:ci_yaml_file] || project.generated_yaml_config)
+ @config_processor ||= Ci::GitlabCiYamlProcessor.new(push_data[:ci_yaml_file])
rescue Ci::GitlabCiYamlProcessor::ValidationError => e
save_yaml_error(e.message)
nil
diff --git a/app/models/ci/project.rb b/app/models/ci/project.rb
index ae901d4ccd0..37fbcc287bb 100644
--- a/app/models/ci/project.rb
+++ b/app/models/ci/project.rb
@@ -92,21 +92,6 @@ module Ci
project
end
- # TODO: remove
- def from_gitlab(user, scope = :owned, options)
- opts = user.authenticate_options
- opts.merge! options
-
- raise 'Implement me of fix'
- #projects = Ci::Network.new.projects(opts.compact, scope)
-
- if projects
- projects.map { |pr| OpenStruct.new(pr) }
- else
- []
- end
- end
-
def already_added?(project)
where(gitlab_id: project.id).any?
end
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index 40642dc63ba..4db4ffb2e79 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -140,6 +140,12 @@ module Issuable
{
object_kind: self.class.name.underscore,
user: user.hook_attrs,
+ repository: {
+ name: project.name,
+ url: project.url_to_repo,
+ description: project.description,
+ homepage: project.web_url
+ },
object_attributes: hook_attrs
}
end
diff --git a/app/models/event.rb b/app/models/event.rb
index 78f16c6304e..47600c57e35 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -27,6 +27,7 @@ class Event < ActiveRecord::Base
MERGED = 7
JOINED = 8 # User joined project
LEFT = 9 # User left project
+ DESTROYED = 10
delegate :name, :email, to: :author, prefix: true, allow_nil: true
delegate :title, to: :issue, prefix: true, allow_nil: true
@@ -48,6 +49,7 @@ class Event < ActiveRecord::Base
scope :code_push, -> { where(action: PUSHED) }
scope :in_projects, ->(project_ids) { where(project_id: project_ids).recent }
scope :with_associations, -> { includes(project: :namespace) }
+ scope :for_milestone_id, ->(milestone_id) { where(target_type: "Milestone", target_id: milestone_id) }
class << self
def reset_event_cache_for(target)
@@ -71,7 +73,7 @@ class Event < ActiveRecord::Base
elsif created_project?
true
else
- (issue? || merge_request? || note? || milestone?) && target
+ ((issue? || merge_request? || note?) && target) || milestone?
end
end
@@ -115,6 +117,10 @@ class Event < ActiveRecord::Base
action == LEFT
end
+ def destroyed?
+ action == DESTROYED
+ end
+
def commented?
action == COMMENTED
end
@@ -124,7 +130,7 @@ class Event < ActiveRecord::Base
end
def created_project?
- created? && !target
+ created? && !target && target_type.nil?
end
def created_target?
@@ -180,6 +186,8 @@ class Event < ActiveRecord::Base
'joined'
elsif left?
'left'
+ elsif destroyed?
+ 'destroyed'
elsif commented?
"commented on"
elsif created_project?
diff --git a/app/models/hooks/web_hook.rb b/app/models/hooks/web_hook.rb
index 9a8251bdad5..a078accbdbd 100644
--- a/app/models/hooks/web_hook.rb
+++ b/app/models/hooks/web_hook.rb
@@ -25,7 +25,7 @@ class WebHook < ActiveRecord::Base
default_value_for :note_events, false
default_value_for :merge_requests_events, false
default_value_for :tag_push_events, false
- default_value_for :enable_ssl_verification, false
+ default_value_for :enable_ssl_verification, true
# HTTParty timeout
default_timeout Gitlab.config.gitlab.webhook_timeout
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index c6aff6f709f..d979a35084b 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -61,7 +61,7 @@ class Milestone < ActiveRecord::Base
false
end
end
-
+
def open_items_count
self.issues.opened.count + self.merge_requests.opened.count
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/buildkite_service.rb b/app/models/project_services/buildkite_service.rb
index 9e5da6f45d2..40058b53df5 100644
--- a/app/models/project_services/buildkite_service.rb
+++ b/app/models/project_services/buildkite_service.rb
@@ -69,14 +69,6 @@ class BuildkiteService < CiService
"#{project_url}/builds?commit=#{sha}"
end
- def builds_path
- "#{project_url}/builds?branch=#{project.default_branch}"
- end
-
- def status_img_path
- "#{buildkite_endpoint('badge')}/#{status_token}.svg"
- end
-
def title
'Buildkite'
end
diff --git a/app/models/project_services/drone_ci_service.rb b/app/models/project_services/drone_ci_service.rb
index 3e2b7faecdb..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?
@@ -135,20 +135,6 @@ class DroneCiService < CiService
commit_page(sha, ref)
end
- def builds_path
- url = [drone_url, "#{project.namespace.path}/#{project.path}"]
-
- URI.join(*url).to_s
- end
-
- def status_img_path
- url = [drone_url,
- "api/badges/#{project.namespace.path}/#{project.path}/status.svg",
- "?branch=#{URI::encode(project.default_branch)}"]
-
- URI.join(*url).to_s
- end
-
def title
'Drone CI'
end
diff --git a/app/models/project_services/gitlab_ci_service.rb b/app/models/project_services/gitlab_ci_service.rb
index acbbc9935b6..820dd3f567c 100644
--- a/app/models/project_services/gitlab_ci_service.rb
+++ b/app/models/project_services/gitlab_ci_service.rb
@@ -19,22 +19,12 @@
#
class GitlabCiService < CiService
- API_PREFIX = "api/v1"
-
- prop_accessor :project_url, :token, :enable_ssl_verification
- validates :project_url,
- presence: true,
- 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?
+ prop_accessor :token
after_save :compose_service_hook, if: :activated?
def compose_service_hook
hook = service_hook || build_service_hook
- hook.url = [project_url, "/build", "?token=#{token}"].join("")
- hook.enable_ssl_verification = enable_ssl_verification
hook.save
end
@@ -55,71 +45,47 @@ class GitlabCiService < CiService
end
end
- service_hook.execute(data)
- end
-
- def commit_status_path(sha, ref)
- URI::encode(project_url + "/refs/#{ref}/commits/#{sha}/status.json?token=#{token}")
+ ci_project = Ci::Project.find_by(gitlab_id: project.id)
+ Ci::CreateCommitService.new.execute(ci_project, data)
end
- def get_ci_build(sha, ref)
- @ci_builds ||= {}
- @ci_builds[sha] ||= HTTParty.get(commit_status_path(sha, ref), verify: false)
+ def get_ci_commit(sha, ref)
+ Ci::Project.find(project.gitlab_ci_project).commits.find_by_sha_and_ref!(sha, ref)
end
def commit_status(sha, ref)
- response = get_ci_build(sha, ref)
-
- if response.code == 200 and response["status"]
- response["status"]
- else
- :error
- end
- rescue Errno::ECONNREFUSED
+ get_ci_commit(sha, ref).status
+ rescue ActiveRecord::RecordNotFound
:error
end
- def fork_registration(new_project, private_token)
- params = {
+ def fork_registration(new_project, current_user)
+ params = OpenStruct.new({
id: new_project.id,
name_with_namespace: new_project.name_with_namespace,
path_with_namespace: new_project.path_with_namespace,
web_url: new_project.web_url,
default_branch: new_project.default_branch,
ssh_url_to_repo: new_project.ssh_url_to_repo
- }
-
- HTTParty.post(
- fork_registration_path,
- body: {
- project_id: project.id,
- project_token: token,
- private_token: private_token,
- data: params },
- verify: false
+ })
+
+ ci_project = Ci::Project.find_by!(gitlab_id: project.id)
+
+ Ci::CreateProjectService.new.execute(
+ current_user,
+ params,
+ ci_project
)
end
def commit_coverage(sha, ref)
- response = get_ci_build(sha, ref)
-
- if response.code == 200 and response["coverage"]
- response["coverage"]
- end
- rescue Errno::ECONNREFUSED
- nil
+ get_ci_commit(sha, ref).coverage
+ rescue ActiveRecord::RecordNotFound
+ :error
end
def build_page(sha, ref)
- URI::encode(project_url + "/refs/#{ref}/commits/#{sha}")
- end
-
- def builds_path
- project_url + "?ref=" + project.default_branch
- end
-
- def status_img_path
- project_url + "/status.png?ref=" + project.default_branch
+ Ci::RoutesHelper.ci_project_ref_commits_path(project.gitlab_ci_project, ref, sha)
end
def title
@@ -135,11 +101,7 @@ class GitlabCiService < CiService
end
def fields
- [
- { type: 'text', name: 'token', placeholder: 'GitLab CI project specific token' },
- { type: 'text', name: 'project_url', placeholder: 'http://ci.gitlabhq.com/projects/3' },
- { type: 'checkbox', name: 'enable_ssl_verification', title: "Enable SSL verification" }
- ]
+ []
end
private
@@ -148,10 +110,6 @@ class GitlabCiService < CiService
repository.blob_at(sha, '.gitlab-ci.yml')
end
- def fork_registration_path
- project_url.sub(/projects\/\d*/, "#{API_PREFIX}/forks")
- end
-
def repository
project.repository
end
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/services/ci/create_project_service.rb b/app/services/ci/create_project_service.rb
index 0419612d521..839d3f6b444 100644
--- a/app/services/ci/create_project_service.rb
+++ b/app/services/ci/create_project_service.rb
@@ -2,20 +2,15 @@ module Ci
class CreateProjectService
include Gitlab::Application.routes.url_helpers
- def execute(current_user, params, project_route, forked_project = nil)
+ def execute(current_user, params, forked_project = nil)
@project = Ci::Project.parse(params)
Ci::Project.transaction do
@project.save!
- data = {
- token: @project.token,
- project_url: project_route.gsub(":project_id", @project.id.to_s),
- }
-
gl_project = ::Project.find(@project.gitlab_id)
gl_project.build_missing_services
- gl_project.gitlab_ci_service.update_attributes(data.merge(active: true))
+ gl_project.gitlab_ci_service.update_attributes(active: true, token: @project.token)
end
if forked_project
diff --git a/app/services/event_create_service.rb b/app/services/event_create_service.rb
index 103d6b0a08b..07fc77001a5 100644
--- a/app/services/event_create_service.rb
+++ b/app/services/event_create_service.rb
@@ -46,6 +46,10 @@ class EventCreateService
create_record_event(milestone, current_user, Event::REOPENED)
end
+ def destroy_milestone(milestone, current_user)
+ create_record_event(milestone, current_user, Event::DESTROYED)
+ end
+
def leave_note(note, current_user)
create_record_event(note, current_user, Event::COMMENTED)
end
diff --git a/app/services/milestones/destroy_service.rb b/app/services/milestones/destroy_service.rb
new file mode 100644
index 00000000000..7ce7d259d0b
--- /dev/null
+++ b/app/services/milestones/destroy_service.rb
@@ -0,0 +1,22 @@
+module Milestones
+ class DestroyService < Milestones::BaseService
+ def execute(milestone)
+
+ Milestone.transaction do
+ update_params = { milestone: nil }
+ milestone.issues.each do |issue|
+ Issues::UpdateService.new(project, current_user, update_params).execute(issue)
+ end
+
+ event_service.destroy_milestone(milestone, current_user)
+
+ Event.for_milestone_id(milestone.id).each do |event|
+ event.target_id = nil
+ event.save
+ end
+
+ milestone.destroy
+ end
+ end
+ end
+end
diff --git a/app/services/projects/fork_service.rb b/app/services/projects/fork_service.rb
index 50f208b11d1..2e995d6fd51 100644
--- a/app/services/projects/fork_service.rb
+++ b/app/services/projects/fork_service.rb
@@ -18,7 +18,7 @@ module Projects
if new_project.persisted?
if @project.gitlab_ci?
- ForkRegistrationWorker.perform_async(@project.id, new_project.id, @current_user.private_token)
+ @project.gitlab_ci_service.fork_registration(new_project, @current_user)
end
end
diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml
index 330b8bbf9d2..143cd10c543 100644
--- a/app/views/admin/application_settings/_form.html.haml
+++ b/app/views/admin/application_settings/_form.html.haml
@@ -118,6 +118,20 @@
.col-sm-10
= f.text_area :sign_in_text, class: 'form-control', rows: 4
.help-block Markdown enabled
+ .form-group
+ = f.label :help_page_text, class: 'control-label col-sm-2'
+ .col-sm-10
+ = f.text_area :help_page_text, class: 'form-control', rows: 4
+ .help-block Markdown enabled
+
+ %fieldset
+ %legend Continuous Integration
+ .form-group
+ .col-sm-offset-2.col-sm-10
+ .checkbox
+ = f.label :ci_enabled do
+ = f.check_box :ci_enabled
+ Disable to prevent CI usage until rake ci:migrate is run (8.0 only)
.form-actions
= f.submit 'Save', class: 'btn btn-primary'
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
+ &middot;
= 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
- &middot;
= 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?
&middot;
= 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/helps/oauth2.html.haml b/app/views/ci/helps/oauth2.html.haml
deleted file mode 100644
index 2031b7340d4..00000000000
--- a/app/views/ci/helps/oauth2.html.haml
+++ /dev/null
@@ -1,20 +0,0 @@
-.welcome-block
- %h1
- Welcome to GitLab CI
- %p
- GitLab CI integrates with your GitLab installation and runs tests for your projects.
-
- %h3 You need only 2 steps to set it up
-
- %ol
- %li
- In the GitLab admin area under OAuth applications create a new entry. The redirect url should be
- %code= callback_ci_user_sessions_url
- %li
- Update the GitLab CI config with the application id and the application secret from GitLab.
- %li
- Restart your GitLab CI instance
- %li
- Refresh this page when GitLab CI has started again
-
-
diff --git a/app/views/ci/helps/show.html.haml b/app/views/ci/helps/show.html.haml
deleted file mode 100644
index 9b32d529c60..00000000000
--- a/app/views/ci/helps/show.html.haml
+++ /dev/null
@@ -1,40 +0,0 @@
-.jumbotron
- %h2
- GitLab CI
- %span= GitlabCi::VERSION
- %small= GitlabCi::REVISION
- %p
- GitLab CI integrates with your GitLab installation and run tests for your projects.
- %br
- Login with your GitLab account, add a project with one click and enjoy running your tests.
- %br
- Read more about GitLab CI at #{link_to "about.gitlab.com/gitlab-ci", "https://about.gitlab.com/gitlab-ci/", target: "_blank"}.
-
-
-.bs-callout.bs-callout-success
- %h4
- = link_to 'https://gitlab.com/gitlab-org/gitlab-ci/blob/master/doc/api' do
- %i.fa.fa-cogs
- API
- %p Explore how you can access GitLab CI via the API.
-
-.bs-callout.bs-callout-info
- %h4
- = link_to 'https://gitlab.com/gitlab-org/gitlab-ci/tree/master/doc/examples' do
- %i.fa.fa-info-sign
- Build script examples
- %p This includes the build script we use to test GitLab CE.
-
-.bs-callout.bs-callout-danger
- %h4
- = link_to 'https://gitlab.com/gitlab-org/gitlab-ci/issues' do
- %i.fa.fa-bug
- Issue tracker
- %p Reports about recent bugs and problems..
-
-.bs-callout.bs-callout-warning
- %h4
- = link_to 'http://feedback.gitlab.com/forums/176466-general/category/64310-gitlab-ci' do
- %i.fa.fa-thumbs-up
- Feedback forum
- %p Suggest improvements or new features for GitLab CI.
diff --git a/app/views/ci/projects/_form.html.haml b/app/views/ci/projects/_form.html.haml
index d50e1a83b06..e782fd8a0f7 100644
--- a/app/views/ci/projects/_form.html.haml
+++ b/app/views/ci/projects/_form.html.haml
@@ -96,6 +96,5 @@
.form-actions
= f.submit 'Save changes', class: 'btn btn-save'
- = link_to 'Cancel', projects_path, class: 'btn'
- unless @project.new_record?
= link_to 'Remove Project', ci_project_path(@project), method: :delete, data: { confirm: 'Project will be removed. Are you sure?' }, class: 'btn btn-danger pull-right'
diff --git a/app/views/ci/projects/_gl_projects.html.haml b/app/views/ci/projects/_gl_projects.html.haml
deleted file mode 100644
index 7bd30b37caf..00000000000
--- a/app/views/ci/projects/_gl_projects.html.haml
+++ /dev/null
@@ -1,15 +0,0 @@
-- @gl_projects.sort_by(&:name_with_namespace).each do |project|
- %tr.light
- %td
- = project.name_with_namespace
- %td
- %small Not added to CI
- %td
- %td
- - if Ci::Project.already_added?(project)
- %strong.cgreen
- Added
- - else
- = 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'
diff --git a/app/views/ci/projects/_project.html.haml b/app/views/ci/projects/_project.html.haml
index e4a811119e1..844b6677b3d 100644
--- a/app/views/ci/projects/_project.html.haml
+++ b/app/views/ci/projects/_project.html.haml
@@ -1,22 +1,37 @@
-- last_commit = project.last_commit
-%tr.alert{class: commit_status_alert_class(last_commit) }
- %td
- = link_to [:ci, project] do
- = project.name
- %td
- - if last_commit
- #{last_commit.status} (#{commit_link(last_commit)})
- - if project.last_commit_date
- = time_ago_in_words project.last_commit_date
- ago
- - else
- No builds yet
- %td
- - if project.public
- %i.fa.fa-globe
- Public
- - else
- %i.fa.fa-lock
- Private
- %td
- = project.commits.count
+- if project.gitlab_ci_project
+ - ci_project = project.gitlab_ci_project
+ - last_commit = ci_project.last_commit
+ %tr
+ %td
+ = link_to [:ci, ci_project] do
+ = ci_project.name
+ %td
+ - if last_commit
+ = ci_status_with_icon(last_commit.status)
+ = commit_link(last_commit)
+ &middot;
+ - if ci_project.last_commit_date
+ = time_ago_in_words ci_project.last_commit_date
+ ago
+ - else
+ No builds yet
+ %td
+ - if ci_project.public
+ %i.fa.fa-globe
+ Public
+ - else
+ %i.fa.fa-lock
+ Private
+ %td
+ = ci_project.commits.count
+- else
+ %tr.light
+ %td
+ = project.name_with_namespace
+ %td
+ %small Not added to CI
+ %td
+ %td
+ = 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'
diff --git a/app/views/ci/projects/_public.html.haml b/app/views/ci/projects/_public.html.haml
index c2157ab741a..bcbd60b83f0 100644
--- a/app/views/ci/projects/_public.html.haml
+++ b/app/views/ci/projects/_public.html.haml
@@ -2,11 +2,6 @@
%h3.project-title
Public projects
-.bs-callout
- = link_to new_ci_user_sessions_path(state: generate_oauth_state(request.fullpath)) do
- %strong Login with GitLab
- to see your private projects
-
- if @projects.present?
.projects
%table.table
diff --git a/app/views/ci/projects/_search.html.haml b/app/views/ci/projects/_search.html.haml
index 6d84b25a6af..4ab43a403f7 100644
--- a/app/views/ci/projects/_search.html.haml
+++ b/app/views/ci/projects/_search.html.haml
@@ -5,13 +5,7 @@
.input-group-addon
%i.fa.fa-search
-
:coffeescript
$('.ci-search-form').submit ->
- NProgress.start()
- query = $('.ci-search-form .search-input').val()
- $.get '#{gitlab_ci_projects_path}', { search: query }, (data) ->
- $(".projects").html data.html
- NProgress.done()
- CiPager.init "#{gitlab_ci_projects_path}" + "?search=" + query, #{Ci::ProjectsController::PROJECTS_BATCH}, false
+ CiPager.init "#{ci_projects_path}" + "?search=" + query, #{Ci::ProjectsController::PROJECTS_BATCH}, false
false
diff --git a/app/views/ci/projects/disabled.html.haml b/app/views/ci/projects/disabled.html.haml
new file mode 100644
index 00000000000..83b0d8329e1
--- /dev/null
+++ b/app/views/ci/projects/disabled.html.haml
@@ -0,0 +1 @@
+Continuous Integration has been disabled for time of the migration.
diff --git a/app/views/ci/projects/edit.html.haml b/app/views/ci/projects/edit.html.haml
index 79e8fd3a295..876ae5182d4 100644
--- a/app/views/ci/projects/edit.html.haml
+++ b/app/views/ci/projects/edit.html.haml
@@ -1,6 +1,6 @@
- if @project.generated_yaml_config
%p.alert.alert-danger
- CI Jobs are deprecated now, you can #{link_to "download", dumped_yaml_ci_project(@project)}
+ CI Jobs are deprecated now, you can #{link_to "download", dumped_yaml_ci_project_path(@project)}
or
%a.preview-yml{:href => "#yaml-content", "data-toggle" => "modal"} preview
yaml file which is based on your old jobs.
diff --git a/app/views/ci/projects/gitlab.html.haml b/app/views/ci/projects/gitlab.html.haml
deleted file mode 100644
index 2101aa932a4..00000000000
--- a/app/views/ci/projects/gitlab.html.haml
+++ /dev/null
@@ -1,27 +0,0 @@
-- if @offset == 0
- .gray-content-block.clearfix.light.second-block
- .pull-left.fetch-status
- - if params[:search].present?
- by keyword: "#{params[:search]}",
- #{@total_count} projects, #{@projects.size} of them added to CI
-
- .wide-table-holder
- %table.table.projects-table.content-list
- %thead
- %tr
- %th Project Name
- %th Last commit
- %th Access
- %th Commits
-
- = render @projects
-
- = render "gl_projects"
-
- %p.text-center.hide.loading
- %i.fa.fa-refresh.fa-spin
-
-- else
- = render @projects
-
- = render "gl_projects"
diff --git a/app/views/ci/projects/index.html.haml b/app/views/ci/projects/index.html.haml
index 60ab29a66cf..2b618d61f79 100644
--- a/app/views/ci/projects/index.html.haml
+++ b/app/views/ci/projects/index.html.haml
@@ -1,13 +1,30 @@
- if current_user
- .gray-content-block.top-block
- = render "search"
- .projects
- %p.fetch-status.light
- %i.fa.fa-refresh.fa-spin
+ - if @offset > 0
+ = render @projects
+ - else
+ .gray-content-block.top-block
+ = render "search"
+ .projects
+ .gray-content-block.clearfix.light.second-block
+ .pull-left.fetch-status
+ - if params[:search].present?
+ by keyword: "#{params[:search]}",
+ #{@total_count} projects
+
+ .wide-table-holder
+ %table.table.projects-table.content-list
+ %thead
+ %tr
+ %th Project Name
+ %th Last commit
+ %th Access
+ %th Commits
+
+ = render @projects
+ %p.text-center.hide.loading
+ %i.fa.fa-refresh.fa-spin
:coffeescript
- $.get '#{gitlab_ci_projects_path}', (data) ->
- $(".projects").html data.html
- CiPager.init "#{gitlab_ci_projects_path}", #{Ci::ProjectsController::PROJECTS_BATCH}, false
+ CiPager.init "#{ci_projects_path}", #{Ci::ProjectsController::PROJECTS_BATCH}, false
- else
= render 'public'
diff --git a/app/views/events/event/_common.html.haml b/app/views/events/event/_common.html.haml
index a39e62e9dac..4ecf1c33d2a 100644
--- a/app/views/events/event/_common.html.haml
+++ b/app/views/events/event/_common.html.haml
@@ -5,13 +5,14 @@
- if event.target
%strong= link_to "##{event.target_iid}", [event.project.namespace.becomes(Namespace), event.project, event.target]
- at
+
+ = event_preposition(event)
- if event.project
= link_to_project event.project
- else
= event.project_name
-
+
- if event.target.respond_to?(:title)
.event-body
.event-note
diff --git a/app/views/groups/milestones/_header_title.html.haml b/app/views/groups/milestones/_header_title.html.haml
new file mode 100644
index 00000000000..d7fabf53587
--- /dev/null
+++ b/app/views/groups/milestones/_header_title.html.haml
@@ -0,0 +1 @@
+- header_title group_title(@group, "Milestones", group_milestones_path(@group))
diff --git a/app/views/groups/milestones/show.html.haml b/app/views/groups/milestones/show.html.haml
index 8f2decb851f..0c213f42186 100644
--- a/app/views/groups/milestones/show.html.haml
+++ b/app/views/groups/milestones/show.html.haml
@@ -1,4 +1,6 @@
- page_title @group_milestone.title, "Milestones"
+= render "header_title"
+
%h4.page-title
.issue-box{ class: "issue-box-#{@group_milestone.closed? ? 'closed' : 'open'}" }
- if @group_milestone.closed?
diff --git a/app/views/help/index.html.haml b/app/views/help/index.html.haml
index bf4b7234b21..f492aaf4c0a 100644
--- a/app/views/help/index.html.haml
+++ b/app/views/help/index.html.haml
@@ -17,6 +17,9 @@
Used by more than 100,000 organizations, GitLab is the most popular solution to manage git repositories on-premises.
%br
Read more about GitLab at #{link_to promo_host, promo_url, target: '_blank'}.
+ - if current_application_settings.help_page_text.present?
+ %hr
+ = markdown(current_application_settings.help_page_text)
%hr
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/app/views/layouts/ci/_nav_admin.html.haml b/app/views/layouts/ci/_nav_admin.html.haml
index c987ab876a3..e9974c85733 100644
--- a/app/views/layouts/ci/_nav_admin.html.haml
+++ b/app/views/layouts/ci/_nav_admin.html.haml
@@ -1,9 +1,9 @@
%ul.nav.nav-sidebar
= nav_link do
- = link_to ci_root_path, title: 'Back to dashboard', data: {placement: 'right'}, class: 'back-link' do
+ = link_to admin_root_path, title: 'Back to admin', data: {placement: 'right'}, class: 'back-link' do
= icon('caret-square-o-left fw')
%span
- Back to Dashboard
+ Back to admin
%li.separate-item
= nav_link path: 'projects#index' do
diff --git a/app/views/layouts/ci/_nav_dashboard.html.haml b/app/views/layouts/ci/_nav_dashboard.html.haml
deleted file mode 100644
index fcff405d19d..00000000000
--- a/app/views/layouts/ci/_nav_dashboard.html.haml
+++ /dev/null
@@ -1,24 +0,0 @@
-%ul.nav.nav-sidebar
- = nav_link do
- = link_to root_path, title: 'Back to dashboard', data: {placement: 'right'}, class: 'back-link' do
- = icon('caret-square-o-left fw')
- %span
- Back to GitLab
- %li.separate-item
- = nav_link path: 'projects#index' do
- = link_to ci_root_path do
- %i.fa.fa-home
- %span
- Projects
- - if current_user && current_user.is_admin?
- %li
- = link_to ci_admin_projects_path do
- %i.fa.fa-cogs
- %span
- Admin
- %li
- = link_to ci_help_path do
- %i.fa.fa-info
- %span
- Help
-
diff --git a/app/views/layouts/ci/application.html.haml b/app/views/layouts/ci/application.html.haml
index b9f871d5447..38023468d0b 100644
--- a/app/views/layouts/ci/application.html.haml
+++ b/app/views/layouts/ci/application.html.haml
@@ -2,10 +2,10 @@
%html{ lang: "en"}
= render 'layouts/head'
%body{class: "ci-body #{user_application_theme}", 'data-page' => body_data_page}
- - header_title = "CI Projects"
+ - header_title = "Continuous Integration"
- if current_user
= render "layouts/header/default", title: header_title
- else
= render "layouts/header/public", title: header_title
- = render 'layouts/ci/page', sidebar: 'nav_dashboard'
+ = render 'layouts/ci/page'
diff --git a/app/views/layouts/dashboard.html.haml b/app/views/layouts/dashboard.html.haml
index fad7de69432..cb96bcc2cf4 100644
--- a/app/views/layouts/dashboard.html.haml
+++ b/app/views/layouts/dashboard.html.haml
@@ -1,6 +1,5 @@
- page_title "Dashboard"
-- unless @header_title
- - header_title "Dashboard", root_path
+- header_title "Dashboard", root_path unless header_title
- sidebar "dashboard"
= render template: "layouts/application"
diff --git a/app/views/layouts/group.html.haml b/app/views/layouts/group.html.haml
index 4f00d01d4cd..31888c5580e 100644
--- a/app/views/layouts/group.html.haml
+++ b/app/views/layouts/group.html.haml
@@ -1,6 +1,5 @@
- page_title @group.name
-- unless @header_title
- - header_title @group.name, group_path(@group)
-- sidebar "group" unless sidebar
+- header_title group_title(@group) unless header_title
+- sidebar "group" unless sidebar
= render template: "layouts/application"
diff --git a/app/views/layouts/group_settings.html.haml b/app/views/layouts/group_settings.html.haml
index e303a561628..a1a1fc2f858 100644
--- a/app/views/layouts/group_settings.html.haml
+++ b/app/views/layouts/group_settings.html.haml
@@ -1,4 +1,5 @@
- page_title "Settings"
+- header_title group_title(@group, "Settings", edit_group_path(@group))
- sidebar "group_settings"
= render template: "layouts/group"
diff --git a/app/views/layouts/nav/_admin.html.haml b/app/views/layouts/nav/_admin.html.haml
index 3fe0127041e..2079feeeab6 100644
--- a/app/views/layouts/nav/_admin.html.haml
+++ b/app/views/layouts/nav/_admin.html.haml
@@ -4,7 +4,7 @@
= icon('dashboard fw')
%span
Overview
- = nav_link(controller: :projects) do
+ = nav_link(controller: [:admin, :projects]) do
= link_to admin_namespaces_projects_path, title: 'Projects', data: {placement: 'right'} do
= icon('cube fw')
%span
@@ -24,6 +24,11 @@
= icon('key fw')
%span
Deploy Keys
+ = nav_link do
+ = link_to ci_admin_projects_path, title: 'Continuous Integration', data: {placement: 'right'} do
+ = icon('building fw')
+ %span
+ Continuous Integration
= nav_link(controller: :logs) do
= link_to admin_logs_path, title: 'Logs', data: {placement: 'right'} do
= icon('file-text fw')
diff --git a/app/views/layouts/nav/_dashboard.html.haml b/app/views/layouts/nav/_dashboard.html.haml
index 56283cba6bd..b94165aac39 100644
--- a/app/views/layouts/nav/_dashboard.html.haml
+++ b/app/views/layouts/nav/_dashboard.html.haml
@@ -1,5 +1,5 @@
%ul.nav.nav-sidebar
- = nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'projects#index'], html_options: {class: 'home'}) do
+ = nav_link(path: ['root#index', 'projects#trending', 'projects#starred', 'dashboard/projects#index'], html_options: {class: 'home'}) do
= link_to root_path, title: 'Projects', data: {placement: 'right'} do
= icon('home fw')
%span
@@ -31,6 +31,11 @@
%span
Merge Requests
%span.count= current_user.assigned_merge_requests.opened.count
+ = nav_link(path: ['ci/projects#index', 'ci/projects#disabled']) do
+ = link_to ci_projects_path, title: 'Continuous Integration', data: {placement: 'right'} do
+ = icon('building fw')
+ %span
+ Continuous Integration
= nav_link(controller: :snippets) do
= link_to dashboard_snippets_path, title: 'Your snippets', data: {placement: 'right'} do
= icon('clipboard fw')
@@ -41,13 +46,10 @@
= icon('question-circle fw')
%span
Help
+
+ %li.separate-item
= nav_link(controller: :profile) do
= link_to profile_path, title: 'Profile settings', data: {placement: 'bottom'} do
= icon('user fw')
%span
Profile Settings
- = nav_link(controller: :ci) do
- = link_to ci_root_path, title: 'Continuous Integration', data: {placement: 'right'} do
- = icon('building fw')
- %span
- CI
diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml
index 8ce46d4865b..a218ec7486c 100644
--- a/app/views/layouts/nav/_project.html.haml
+++ b/app/views/layouts/nav/_project.html.haml
@@ -76,6 +76,13 @@
Merge Requests
%span.count.merge_counter= @project.merge_requests.opened.count
+ - if @project.gitlab_ci?
+ = nav_link(controller: [:ci, :project]) do
+ = link_to ci_project_path(@project.gitlab_ci_project), title: 'Continuous Integration', data: {placement: 'right'} do
+ = icon('building fw')
+ %span
+ Continuous Integration
+
- if project_nav_tab? :settings
= nav_link(controller: [:project_members, :teams]) do
= link_to namespace_project_project_members_path(@project.namespace, @project), title: 'Members', class: 'team-tab tab', data: {placement: 'right'} do
diff --git a/app/views/layouts/profile.html.haml b/app/views/layouts/profile.html.haml
index b80ce0dfc75..dfa6cc5702e 100644
--- a/app/views/layouts/profile.html.haml
+++ b/app/views/layouts/profile.html.haml
@@ -1,6 +1,5 @@
- page_title "Profile Settings"
-- unless @header_title
- - header_title "Profile Settings", profile_path
+- header_title "Profile Settings", profile_path unless header_title
- sidebar "profile"
= render template: "layouts/application"
diff --git a/app/views/layouts/project.html.haml b/app/views/layouts/project.html.haml
index 5c4dd67f0ec..78dafcd8bfa 100644
--- a/app/views/layouts/project.html.haml
+++ b/app/views/layouts/project.html.haml
@@ -1,6 +1,6 @@
- page_title @project.name_with_namespace
-- header_title detect_project_title(@project)
-- sidebar "project" unless sidebar
+- header_title project_title(@project) unless header_title
+- sidebar "project" unless sidebar
- content_for :scripts_body_top do
- if current_user
diff --git a/app/views/layouts/project_settings.html.haml b/app/views/layouts/project_settings.html.haml
index 43401668334..59ce38f67bb 100644
--- a/app/views/layouts/project_settings.html.haml
+++ b/app/views/layouts/project_settings.html.haml
@@ -1,4 +1,5 @@
- page_title "Settings"
+- header_title project_title(@project, "Settings", edit_project_path(@project))
- sidebar "project_settings"
= render template: "layouts/project"
diff --git a/app/views/notify/new_user_email.html.haml b/app/views/notify/new_user_email.html.haml
index 4feacdaacff..6b9b42dcf37 100644
--- a/app/views/notify/new_user_email.html.haml
+++ b/app/views/notify/new_user_email.html.haml
@@ -13,4 +13,4 @@
%p
= link_to "Click here to set your password", edit_password_url(@user, reset_password_token: @token)
%p
- = reset_token_expire_message
+ = raw reset_token_expire_message
diff --git a/app/views/projects/activity.html.haml b/app/views/projects/activity.html.haml
index 5f6e5f3b644..555ed76426d 100644
--- a/app/views/projects/activity.html.haml
+++ b/app/views/projects/activity.html.haml
@@ -1,2 +1,4 @@
- page_title "Activity"
+- header_title project_title(@project, "Activity", activity_project_path(@project))
+
= render 'projects/activity'
diff --git a/app/views/projects/blame/show.html.haml b/app/views/projects/blame/show.html.haml
index c1ec42aefca..6518c4173e1 100644
--- a/app/views/projects/blame/show.html.haml
+++ b/app/views/projects/blame/show.html.haml
@@ -1,4 +1,6 @@
- page_title "Blame", @blob.path, @ref
+- header_title project_title(@project, "Files", project_files_path(@project))
+
%h3.page-title Blame view
#tree-holder.tree-holder
diff --git a/app/views/projects/blob/_header_title.html.haml b/app/views/projects/blob/_header_title.html.haml
new file mode 100644
index 00000000000..78c5ef20a5f
--- /dev/null
+++ b/app/views/projects/blob/_header_title.html.haml
@@ -0,0 +1 @@
+- header_title project_title(@project, "Files", project_files_path(@project))
diff --git a/app/views/projects/blob/_upload.html.haml b/app/views/projects/blob/_upload.html.haml
index 2cfb79486dc..1a1df127703 100644
--- a/app/views/projects/blob/_upload.html.haml
+++ b/app/views/projects/blob/_upload.html.haml
@@ -3,12 +3,12 @@
.modal-content
.modal-header
%a.close{href: "#", "data-dismiss" => "modal"} ×
- %h3.page-title #{@title}
+ %h3.page-title #{title}
%p.light
From branch
%strong= @ref
.modal-body
- = form_tag @form_path, method: @method, class: 'blob-file-upload-form-js form-horizontal' do
+ = form_tag form_path, method: method, class: 'blob-file-upload-form-js form-horizontal' do
.dropzone
.dropzone-previews.blob-upload-dropzone-previews
%p.dz-message.light
@@ -17,12 +17,12 @@
%br
.dropzone-alerts{class: "alert alert-danger data", style: "display:none"}
= render 'shared/commit_message_container', params: params,
- placeholder: @placeholder
+ placeholder: placeholder
.form-group
.col-sm-offset-2.col-sm-10
- = button_tag @button_title, class: 'btn btn-small btn-primary btn-upload-file', id: 'submit-all'
+ = button_tag button_title, class: 'btn btn-small btn-primary btn-upload-file', id: 'submit-all'
= link_to "Cancel", '#', class: "btn btn-cancel", "data-dismiss" => "modal"
:coffeescript
disableButtonIfEmptyField $('.blob-file-upload-form-js').find('#commit_message'), '.btn-upload-file'
- new BlobFileDropzone($('.blob-file-upload-form-js'), '#{@method}')
+ new BlobFileDropzone($('.blob-file-upload-form-js'), '#{method}')
diff --git a/app/views/projects/blob/edit.html.haml b/app/views/projects/blob/edit.html.haml
index 648f15418e0..a811adc5094 100644
--- a/app/views/projects/blob/edit.html.haml
+++ b/app/views/projects/blob/edit.html.haml
@@ -1,4 +1,6 @@
- page_title "Edit", @blob.path, @ref
+= render "header_title"
+
.file-editor
%ul.center-top-menu.no-bottom.js-edit-mode
%li.active
diff --git a/app/views/projects/blob/new.html.haml b/app/views/projects/blob/new.html.haml
index 68c9ec7f802..1950586b112 100644
--- a/app/views/projects/blob/new.html.haml
+++ b/app/views/projects/blob/new.html.haml
@@ -1,10 +1,13 @@
+- page_title "New File", @path.presence, @ref
+= render "header_title"
+
.gray-content-block.top-block
Create a new file or
= link_to 'upload', '#modal-upload-blob',
{ class: 'upload-link', 'data-target' => '#modal-upload-blob', 'data-toggle' => 'modal'}
an existing one
-= render 'projects/blob/upload'
+= render 'projects/blob/upload', title: 'Upload', placeholder: 'Upload new file', button_title: 'Upload file', form_path: namespace_project_create_blob_path(@project.namespace, @project, @id), method: :post
.file-editor
= form_tag(namespace_project_create_blob_path(@project.namespace, @project, @id), method: :post, class: 'form-horizontal form-new-file js-requires-input') do
diff --git a/app/views/projects/blob/show.html.haml b/app/views/projects/blob/show.html.haml
index 4e66a43bbd5..fa4be4a1bc4 100644
--- a/app/views/projects/blob/show.html.haml
+++ b/app/views/projects/blob/show.html.haml
@@ -1,4 +1,5 @@
- page_title @blob.path, @ref
+= render "header_title"
= render 'projects/last_push'
@@ -10,4 +11,8 @@
- if allowed_tree_edit?
= render 'projects/blob/remove'
- = render 'projects/blob/upload'
+
+ - title = "Replace #{@blob.name}"
+ = render 'projects/blob/upload', title: title, placeholder: title,
+ button_title: 'Replace file', form_path: namespace_project_update_blob_path(@project.namespace, @project, @id),
+ method: :put
diff --git a/app/views/projects/branches/index.html.haml b/app/views/projects/branches/index.html.haml
index 6e2dc2d2710..03ade02a0c8 100644
--- a/app/views/projects/branches/index.html.haml
+++ b/app/views/projects/branches/index.html.haml
@@ -1,4 +1,5 @@
- page_title "Branches"
+= render "projects/commits/header_title"
= render "projects/commits/head"
.gray-content-block
.pull-right
diff --git a/app/views/projects/branches/new.html.haml b/app/views/projects/branches/new.html.haml
index 29e82b93883..f5577042ca4 100644
--- a/app/views/projects/branches/new.html.haml
+++ b/app/views/projects/branches/new.html.haml
@@ -1,4 +1,6 @@
- page_title "New Branch"
+= render "projects/commits/header_title"
+
- if @error
.alert.alert-danger
%button{ type: "button", class: "close", "data-dismiss" => "alert"} &times;
diff --git a/app/views/projects/commit/show.html.haml b/app/views/projects/commit/show.html.haml
index 60b112e67d4..f8681024d1b 100644
--- a/app/views/projects/commit/show.html.haml
+++ b/app/views/projects/commit/show.html.haml
@@ -1,4 +1,5 @@
- page_title "#{@commit.title} (#{@commit.short_id})", "Commits"
+= render "projects/commits/header_title"
= render "commit_box"
= render "projects/diffs/diffs", diffs: @diffs, project: @project
= render "projects/notes/notes_with_form", view: params[:view]
diff --git a/app/views/projects/commits/_header_title.html.haml b/app/views/projects/commits/_header_title.html.haml
new file mode 100644
index 00000000000..e4385893dd9
--- /dev/null
+++ b/app/views/projects/commits/_header_title.html.haml
@@ -0,0 +1 @@
+- header_title project_title(@project, "Commits", project_commits_path(@project))
diff --git a/app/views/projects/commits/show.html.haml b/app/views/projects/commits/show.html.haml
index a01a99458a0..2dd99cc8215 100644
--- a/app/views/projects/commits/show.html.haml
+++ b/app/views/projects/commits/show.html.haml
@@ -1,4 +1,5 @@
- page_title "Commits", @ref
+= render "header_title"
= content_for :meta_tags do
- if current_user
= auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, format: :atom, private_token: current_user.private_token), title: "#{@project.name}:#{@ref} commits")
diff --git a/app/views/projects/compare/index.html.haml b/app/views/projects/compare/index.html.haml
index 43d00726c48..02be5a2d07f 100644
--- a/app/views/projects/compare/index.html.haml
+++ b/app/views/projects/compare/index.html.haml
@@ -1,4 +1,5 @@
- page_title "Compare"
+= render "projects/commits/header_title"
= render "projects/commits/head"
.gray-content-block
diff --git a/app/views/projects/compare/show.html.haml b/app/views/projects/compare/show.html.haml
index 8800ffdf482..39755efd2fd 100644
--- a/app/views/projects/compare/show.html.haml
+++ b/app/views/projects/compare/show.html.haml
@@ -1,4 +1,5 @@
- page_title "#{params[:from]}...#{params[:to]}"
+= render "projects/commits/header_title"
= render "projects/commits/head"
diff --git a/app/views/projects/graphs/_header_title.html.haml b/app/views/projects/graphs/_header_title.html.haml
new file mode 100644
index 00000000000..1e2f61cd22b
--- /dev/null
+++ b/app/views/projects/graphs/_header_title.html.haml
@@ -0,0 +1 @@
+- header_title project_title(@project, "Graphs", namespace_project_graph_path(@project.namespace, @project, current_ref))
diff --git a/app/views/projects/graphs/commits.html.haml b/app/views/projects/graphs/commits.html.haml
index a357736bf52..bf0cac539b8 100644
--- a/app/views/projects/graphs/commits.html.haml
+++ b/app/views/projects/graphs/commits.html.haml
@@ -1,4 +1,5 @@
-- page_title "Commit statistics"
+- page_title "Commits", "Graphs"
+= render "header_title"
.tree-ref-holder
= render 'shared/ref_switcher', destination: 'graphs_commits'
= render 'head'
diff --git a/app/views/projects/graphs/show.html.haml b/app/views/projects/graphs/show.html.haml
index ecdd0eaf52f..bd342911e49 100644
--- a/app/views/projects/graphs/show.html.haml
+++ b/app/views/projects/graphs/show.html.haml
@@ -1,4 +1,5 @@
-- page_title "Contributor statistics"
+- page_title "Contributors", "Graphs"
+= render "header_title"
.tree-ref-holder
= render 'shared/ref_switcher', destination: 'graphs'
= render 'head'
diff --git a/app/views/projects/issues/_header_title.html.haml b/app/views/projects/issues/_header_title.html.haml
new file mode 100644
index 00000000000..99f03549c44
--- /dev/null
+++ b/app/views/projects/issues/_header_title.html.haml
@@ -0,0 +1 @@
+- header_title project_title(@project, "Issues", namespace_project_issues_path(@project.namespace, @project))
diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml
index 24314d11404..d6260ab2900 100644
--- a/app/views/projects/issues/index.html.haml
+++ b/app/views/projects/issues/index.html.haml
@@ -1,4 +1,6 @@
- page_title "Issues"
+= render "header_title"
+
= content_for :meta_tags do
- if current_user
= auto_discovery_link_tag(:atom, namespace_project_issues_url(@project.namespace, @project, :atom, private_token: current_user.private_token), title: "#{@project.name} issues")
diff --git a/app/views/projects/issues/new.html.haml b/app/views/projects/issues/new.html.haml
index da6edd5c2d2..153447baa1b 100644
--- a/app/views/projects/issues/new.html.haml
+++ b/app/views/projects/issues/new.html.haml
@@ -1,2 +1,4 @@
- page_title "New Issue"
+= render "header_title"
+
= render "form"
diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml
index 09080642293..5cb814c9ea8 100644
--- a/app/views/projects/issues/show.html.haml
+++ b/app/views/projects/issues/show.html.haml
@@ -1,4 +1,6 @@
- page_title "#{@issue.title} (##{@issue.iid})", "Issues"
+= render "header_title"
+
.issue
.issue-details.issuable-details
.page-title
diff --git a/app/views/projects/labels/_header_title.html.haml b/app/views/projects/labels/_header_title.html.haml
new file mode 100644
index 00000000000..abe28da483b
--- /dev/null
+++ b/app/views/projects/labels/_header_title.html.haml
@@ -0,0 +1 @@
+- header_title project_title(@project, "Labels", namespace_project_labels_path(@project.namespace, @project))
diff --git a/app/views/projects/labels/edit.html.haml b/app/views/projects/labels/edit.html.haml
index 645402667fd..bc4ab0ca27c 100644
--- a/app/views/projects/labels/edit.html.haml
+++ b/app/views/projects/labels/edit.html.haml
@@ -1,4 +1,6 @@
- page_title "Edit", @label.name, "Labels"
+= render "header_title"
+
%h3
Edit label
%span.light #{@label.name}
diff --git a/app/views/projects/labels/index.html.haml b/app/views/projects/labels/index.html.haml
index 284adb40e97..97175f8232b 100644
--- a/app/views/projects/labels/index.html.haml
+++ b/app/views/projects/labels/index.html.haml
@@ -1,4 +1,5 @@
- page_title "Labels"
+= render "header_title"
.gray-content-block.top-block
- if can? current_user, :admin_label, @project
diff --git a/app/views/projects/labels/new.html.haml b/app/views/projects/labels/new.html.haml
index b3ef17025c3..342ad4f3f95 100644
--- a/app/views/projects/labels/new.html.haml
+++ b/app/views/projects/labels/new.html.haml
@@ -1,4 +1,6 @@
- page_title "New Label"
+= render "header_title"
+
%h3 New label
.back-link
= link_to namespace_project_labels_path(@project.namespace, @project) do
diff --git a/app/views/projects/merge_requests/_header_title.html.haml b/app/views/projects/merge_requests/_header_title.html.haml
new file mode 100644
index 00000000000..669a9b06bdf
--- /dev/null
+++ b/app/views/projects/merge_requests/_header_title.html.haml
@@ -0,0 +1 @@
+- header_title project_title(@project, "Merge Requests", namespace_project_merge_requests_path(@project.namespace, @project))
diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml
index 61e04dce5ab..0b0f52c653c 100644
--- a/app/views/projects/merge_requests/_show.html.haml
+++ b/app/views/projects/merge_requests/_show.html.haml
@@ -1,4 +1,6 @@
- page_title "#{@merge_request.title} (##{@merge_request.iid})", "Merge Requests"
+= render "header_title"
+
- if params[:view] == 'parallel'
- fluid_layout true
diff --git a/app/views/projects/merge_requests/edit.html.haml b/app/views/projects/merge_requests/edit.html.haml
index 7e5cb07f249..303ca0a880b 100644
--- a/app/views/projects/merge_requests/edit.html.haml
+++ b/app/views/projects/merge_requests/edit.html.haml
@@ -1,4 +1,6 @@
- page_title "Edit", "#{@merge_request.title} (##{@merge_request.iid})", "Merge Requests"
+= render "header_title"
+
%h3.page-title
= "Edit merge request ##{@merge_request.iid}"
%hr
diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml
index d3a576977c2..086298e5af1 100644
--- a/app/views/projects/merge_requests/index.html.haml
+++ b/app/views/projects/merge_requests/index.html.haml
@@ -1,4 +1,6 @@
- page_title "Merge Requests"
+= render "header_title"
+
= render 'projects/last_push'
.project-issuable-filter
.controls
diff --git a/app/views/projects/merge_requests/invalid.html.haml b/app/views/projects/merge_requests/invalid.html.haml
index 15bd4e2fafd..fc03ee73a3d 100644
--- a/app/views/projects/merge_requests/invalid.html.haml
+++ b/app/views/projects/merge_requests/invalid.html.haml
@@ -1,4 +1,6 @@
- page_title "#{@merge_request.title} (##{@merge_request.iid})", "Merge Requests"
+= render "header_title"
+
.merge-request
= render "projects/merge_requests/show/mr_title"
= render "projects/merge_requests/show/mr_box"
diff --git a/app/views/projects/merge_requests/new.html.haml b/app/views/projects/merge_requests/new.html.haml
index b038a640f67..9fdde80c6d9 100644
--- a/app/views/projects/merge_requests/new.html.haml
+++ b/app/views/projects/merge_requests/new.html.haml
@@ -1,4 +1,6 @@
- page_title "New Merge Request"
+= render "header_title"
+
- if @merge_request.can_be_created
= render 'new_submit'
- else
diff --git a/app/views/projects/milestones/_header_title.html.haml b/app/views/projects/milestones/_header_title.html.haml
new file mode 100644
index 00000000000..5f4b6982a6d
--- /dev/null
+++ b/app/views/projects/milestones/_header_title.html.haml
@@ -0,0 +1 @@
+- header_title project_title(@project, "Milestones", namespace_project_milestones_path(@project.namespace, @project))
diff --git a/app/views/projects/milestones/edit.html.haml b/app/views/projects/milestones/edit.html.haml
index c09815a212a..e9dc0b77462 100644
--- a/app/views/projects/milestones/edit.html.haml
+++ b/app/views/projects/milestones/edit.html.haml
@@ -1,2 +1,3 @@
- page_title "Edit", @milestone.title, "Milestones"
+= render "header_title"
= render "form"
diff --git a/app/views/projects/milestones/index.html.haml b/app/views/projects/milestones/index.html.haml
index 2b8fd671587..a207385bd43 100644
--- a/app/views/projects/milestones/index.html.haml
+++ b/app/views/projects/milestones/index.html.haml
@@ -1,4 +1,5 @@
- page_title "Milestones"
+= render "header_title"
= render 'shared/milestones_filter'
.gray-content-block
diff --git a/app/views/projects/milestones/new.html.haml b/app/views/projects/milestones/new.html.haml
index 47149dfea41..9ba9acb6f77 100644
--- a/app/views/projects/milestones/new.html.haml
+++ b/app/views/projects/milestones/new.html.haml
@@ -1,2 +1,3 @@
- page_title "New Milestone"
+= render "header_title"
= render "form"
diff --git a/app/views/projects/milestones/show.html.haml b/app/views/projects/milestones/show.html.haml
index 7b1681df336..4eeb0621e52 100644
--- a/app/views/projects/milestones/show.html.haml
+++ b/app/views/projects/milestones/show.html.haml
@@ -1,4 +1,6 @@
- page_title @milestone.title, "Milestones"
+= render "header_title"
+
%h4.page-title
.issue-box{ class: issue_box_class(@milestone) }
- if @milestone.closed?
diff --git a/app/views/projects/network/show.html.haml b/app/views/projects/network/show.html.haml
index 52b5b8b877e..16005161df6 100644
--- a/app/views/projects/network/show.html.haml
+++ b/app/views/projects/network/show.html.haml
@@ -1,4 +1,5 @@
- page_title "Network", @ref
+= header_title project_title(@project, "Network", namespace_project_network_path(@project.namespace, @project, current_ref))
= render "head"
.project-network
.controls
diff --git a/app/views/projects/project_members/_header_title.html.haml b/app/views/projects/project_members/_header_title.html.haml
new file mode 100644
index 00000000000..a31f0a37fa2
--- /dev/null
+++ b/app/views/projects/project_members/_header_title.html.haml
@@ -0,0 +1 @@
+- header_title project_title(@project, "Members", namespace_project_project_members_path(@project.namespace, @project))
diff --git a/app/views/projects/project_members/import.html.haml b/app/views/projects/project_members/import.html.haml
index 6914543f6da..189906498cb 100644
--- a/app/views/projects/project_members/import.html.haml
+++ b/app/views/projects/project_members/import.html.haml
@@ -1,4 +1,6 @@
- page_title "Import members"
+= render "header_title"
+
%h3.page-title
Import members from another project
%p.light
diff --git a/app/views/projects/project_members/index.html.haml b/app/views/projects/project_members/index.html.haml
index a40d1513671..9a0a824b811 100644
--- a/app/views/projects/project_members/index.html.haml
+++ b/app/views/projects/project_members/index.html.haml
@@ -1,4 +1,5 @@
- page_title "Members"
+= render "header_title"
.gray-content-block.top-block
.clearfix.js-toggle-container
diff --git a/app/views/projects/snippets/_header_title.html.haml b/app/views/projects/snippets/_header_title.html.haml
new file mode 100644
index 00000000000..04f0bbe9853
--- /dev/null
+++ b/app/views/projects/snippets/_header_title.html.haml
@@ -0,0 +1 @@
+- header_title project_title(@project, "Snippets", namespace_project_snippets_path(@project.namespace, @project))
diff --git a/app/views/projects/snippets/edit.html.haml b/app/views/projects/snippets/edit.html.haml
index 945f0084dff..e69f2d99709 100644
--- a/app/views/projects/snippets/edit.html.haml
+++ b/app/views/projects/snippets/edit.html.haml
@@ -1,4 +1,6 @@
- page_title "Edit", @snippet.title, "Snippets"
+= render "header_title"
+
%h3.page-title
Edit snippet
%hr
diff --git a/app/views/projects/snippets/index.html.haml b/app/views/projects/snippets/index.html.haml
index 45d4de6a385..3fed2c9949d 100644
--- a/app/views/projects/snippets/index.html.haml
+++ b/app/views/projects/snippets/index.html.haml
@@ -1,4 +1,6 @@
- page_title "Snippets"
+= render "header_title"
+
%h3.page-title
Snippets
- if can? current_user, :create_project_snippet, @project
diff --git a/app/views/projects/snippets/new.html.haml b/app/views/projects/snippets/new.html.haml
index e38d95c45e7..67cd69fd215 100644
--- a/app/views/projects/snippets/new.html.haml
+++ b/app/views/projects/snippets/new.html.haml
@@ -1,4 +1,6 @@
- page_title "New Snippets"
+= render "header_title"
+
%h3.page-title
New snippet
%hr
diff --git a/app/views/projects/snippets/show.html.haml b/app/views/projects/snippets/show.html.haml
index 8cbb813c758..be7d4d486fa 100644
--- a/app/views/projects/snippets/show.html.haml
+++ b/app/views/projects/snippets/show.html.haml
@@ -1,4 +1,6 @@
- page_title @snippet.title, "Snippets"
+= render "header_title"
+
%h3.page-title
= @snippet.title
diff --git a/app/views/projects/tags/index.html.haml b/app/views/projects/tags/index.html.haml
index 1503a4330f4..85d76eae3b5 100644
--- a/app/views/projects/tags/index.html.haml
+++ b/app/views/projects/tags/index.html.haml
@@ -1,4 +1,5 @@
- page_title "Tags"
+= render "projects/commits/header_title"
= render "projects/commits/head"
.gray-content-block
diff --git a/app/views/projects/tags/new.html.haml b/app/views/projects/tags/new.html.haml
index 172fafdeeff..9f5c1be125c 100644
--- a/app/views/projects/tags/new.html.haml
+++ b/app/views/projects/tags/new.html.haml
@@ -1,4 +1,6 @@
- page_title "New Tag"
+= render "projects/commits/header_title"
+
- if @error
.alert.alert-danger
%button{ type: "button", class: "close", "data-dismiss" => "alert"} &times;
diff --git a/app/views/projects/tree/show.html.haml b/app/views/projects/tree/show.html.haml
index c9e59428e78..dec4677f830 100644
--- a/app/views/projects/tree/show.html.haml
+++ b/app/views/projects/tree/show.html.haml
@@ -1,4 +1,5 @@
- page_title @path.presence || "Files", @ref
+- header_title project_title(@project, "Files", project_files_path(@project))
= content_for :meta_tags do
- if current_user
= auto_discovery_link_tag(:atom, namespace_project_commits_url(@project.namespace, @project, @ref, format: :atom, private_token: current_user.private_token), title: "#{@project.name}:#{@ref} commits")
diff --git a/app/views/projects/wikis/_header_title.html.haml b/app/views/projects/wikis/_header_title.html.haml
new file mode 100644
index 00000000000..408adc36ca6
--- /dev/null
+++ b/app/views/projects/wikis/_header_title.html.haml
@@ -0,0 +1 @@
+- header_title project_title(@project, 'Wiki', get_project_wiki_path(@project))
diff --git a/app/views/projects/wikis/edit.html.haml b/app/views/projects/wikis/edit.html.haml
index 3f1dce1050c..0b709c3695b 100644
--- a/app/views/projects/wikis/edit.html.haml
+++ b/app/views/projects/wikis/edit.html.haml
@@ -1,4 +1,6 @@
- page_title "Edit", @page.title, "Wiki"
+= render "header_title"
+
= render 'nav'
.pull-right
= render 'main_links'
diff --git a/app/views/projects/wikis/empty.html.haml b/app/views/projects/wikis/empty.html.haml
index ead99412406..c7e490c3cd1 100644
--- a/app/views/projects/wikis/empty.html.haml
+++ b/app/views/projects/wikis/empty.html.haml
@@ -1,4 +1,6 @@
- page_title "Wiki"
+= render "header_title"
+
%h3.page-title Empty page
%hr
.error_message
diff --git a/app/views/projects/wikis/git_access.html.haml b/app/views/projects/wikis/git_access.html.haml
index 226fd3b2290..6417ef4a38b 100644
--- a/app/views/projects/wikis/git_access.html.haml
+++ b/app/views/projects/wikis/git_access.html.haml
@@ -1,4 +1,6 @@
- page_title "Git Access", "Wiki"
+= render "header_title"
+
= render 'nav'
.gray-content-block
.row
diff --git a/app/views/projects/wikis/history.html.haml b/app/views/projects/wikis/history.html.haml
index 7c81ad53d32..bfbef823b35 100644
--- a/app/views/projects/wikis/history.html.haml
+++ b/app/views/projects/wikis/history.html.haml
@@ -1,4 +1,6 @@
-- page_title "History", @page.title, "Wiki"
+- page_title "History", @page.title.capitalize, "Wiki"
+= render "header_title"
+
= render 'nav'
.gray-content-block
%h3.page-title
diff --git a/app/views/projects/wikis/pages.html.haml b/app/views/projects/wikis/pages.html.haml
index 7fb91507eb2..03e6a522b25 100644
--- a/app/views/projects/wikis/pages.html.haml
+++ b/app/views/projects/wikis/pages.html.haml
@@ -1,4 +1,6 @@
- page_title "All Pages", "Wiki"
+= render "header_title"
+
= render 'nav'
.gray-content-block
%h3.page-title
diff --git a/app/views/projects/wikis/show.html.haml b/app/views/projects/wikis/show.html.haml
index 126810811ec..55fbf5a8b6e 100644
--- a/app/views/projects/wikis/show.html.haml
+++ b/app/views/projects/wikis/show.html.haml
@@ -1,4 +1,6 @@
-- page_title @page.title, "Wiki"
+- page_title @page.title.capitalize, "Wiki"
+= render "header_title"
+
= render 'nav'
.gray-content-block
diff --git a/app/views/shared/projects/_list.html.haml b/app/views/shared/projects/_list.html.haml
index 021e3b689a1..330b0626d63 100644
--- a/app/views/shared/projects/_list.html.haml
+++ b/app/views/shared/projects/_list.html.haml
@@ -8,7 +8,7 @@
= render "shared/projects/project", project: project,
avatar: avatar, stars: stars, css_class: css_class
- - if projects.count > projects_limit
+ - if projects.size > projects_limit
%li.bottom.center
.light
#{projects_limit} of #{pluralize(projects.count, 'project')} displayed.
diff --git a/app/workers/fork_registration_worker.rb b/app/workers/fork_registration_worker.rb
deleted file mode 100644
index fffa8b3a659..00000000000
--- a/app/workers/fork_registration_worker.rb
+++ /dev/null
@@ -1,12 +0,0 @@
-class ForkRegistrationWorker
- include Sidekiq::Worker
-
- sidekiq_options queue: :default
-
- def perform(from_project_id, to_project_id, private_token)
- from_project = Project.find(from_project_id)
- to_project = Project.find(to_project_id)
-
- from_project.gitlab_ci_service.fork_registration(to_project, private_token)
- end
-end
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index 0005d44e0f2..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"
@@ -306,6 +306,7 @@ production: &base
path: "tmp/backups" # Relative paths are relative to Rails.root (default: tmp/backups/)
# archive_permissions: 0640 # Permissions for the resulting backup.tar file (default: 0600)
# keep_time: 604800 # default: 0 (forever) (in seconds)
+ # pg_schema: public # default: nil, it means that all schemas will be backed up
# upload:
# # Fog storage connection settings, see http://fog.io/storage/ .
# connection:
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index fe81ffd4205..ddc9bbf5dfd 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -178,6 +178,7 @@ Settings.gitlab['import_sources'] ||= ['github','bitbucket','gitlab','gitorious'
# CI
#
Settings['gitlab_ci'] ||= Settingslogic.new({})
+Settings.gitlab_ci['enabled'] = true if Settings.gitlab_ci['enabled'].nil?
Settings.gitlab_ci['all_broken_builds'] = true if Settings.gitlab_ci['all_broken_builds'].nil?
Settings.gitlab_ci['add_pusher'] = false if Settings.gitlab_ci['add_pusher'].nil?
Settings.gitlab_ci['url'] ||= Settings.send(:build_gitlab_ci_url)
@@ -219,6 +220,7 @@ Settings.gitlab_shell['ssh_path_prefix'] ||= Settings.send(:build_gitlab_shell_s
#
Settings['backup'] ||= Settingslogic.new({})
Settings.backup['keep_time'] ||= 0
+Settings.backup['pg_schema'] = nil
Settings.backup['path'] = File.expand_path(Settings.backup['path'] || "tmp/backups/", Rails.root)
Settings.backup['archive_permissions'] ||= 0600
Settings.backup['upload'] ||= Settingslogic.new({ 'remote_directory' => nil, 'connection' => nil })
diff --git a/config/routes.rb b/config/routes.rb
index 41970d2af8a..512dda7b547 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -9,20 +9,15 @@ Gitlab::Application.routes.draw do
resource :lint, only: [:show, :create]
- resource :help do
- get :oauth2
- end
-
resources :projects do
collection do
post :add
- get :gitlab
+ get :disabled
end
member do
get :status, to: 'projects#badge'
get :integration
- post :build
post :toggle_shared_runners
get :dumped_yaml
end
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/20150915001905_enable_ssl_verification_by_default.rb b/db/migrate/20150915001905_enable_ssl_verification_by_default.rb
new file mode 100644
index 00000000000..6e924262a13
--- /dev/null
+++ b/db/migrate/20150915001905_enable_ssl_verification_by_default.rb
@@ -0,0 +1,5 @@
+class EnableSslVerificationByDefault < ActiveRecord::Migration
+ def change
+ change_column :web_hooks, :enable_ssl_verification, :boolean, default: true
+ end
+end
diff --git a/db/migrate/20150916000405_enable_ssl_verification_for_web_hooks.rb b/db/migrate/20150916000405_enable_ssl_verification_for_web_hooks.rb
new file mode 100644
index 00000000000..90ce6c2db3d
--- /dev/null
+++ b/db/migrate/20150916000405_enable_ssl_verification_for_web_hooks.rb
@@ -0,0 +1,8 @@
+class EnableSslVerificationForWebHooks < ActiveRecord::Migration
+ def up
+ execute("UPDATE web_hooks SET enable_ssl_verification = true")
+ end
+
+ def down
+ end
+end
diff --git a/db/migrate/20150916114643_add_help_page_text_to_application_settings.rb b/db/migrate/20150916114643_add_help_page_text_to_application_settings.rb
new file mode 100644
index 00000000000..37a27f11935
--- /dev/null
+++ b/db/migrate/20150916114643_add_help_page_text_to_application_settings.rb
@@ -0,0 +1,5 @@
+class AddHelpPageTextToApplicationSettings < ActiveRecord::Migration
+ def change
+ add_column :application_settings, :help_page_text, :text
+ end
+end
diff --git a/db/migrate/20150918084513_add_ci_enabled_to_application_settings.rb b/db/migrate/20150918084513_add_ci_enabled_to_application_settings.rb
new file mode 100644
index 00000000000..6cf668a170e
--- /dev/null
+++ b/db/migrate/20150918084513_add_ci_enabled_to_application_settings.rb
@@ -0,0 +1,5 @@
+class AddCiEnabledToApplicationSettings < ActiveRecord::Migration
+ def change
+ add_column :application_settings, :ci_enabled, :boolean, null: false, default: true
+ end
+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 48314b8db6a..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: 20150916145038) do
+ActiveRecord::Schema.define(version: 20150920161119) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -45,6 +45,8 @@ ActiveRecord::Schema.define(version: 20150916145038) do
t.string "after_sign_out_path"
t.integer "session_expire_delay", default: 10080, null: false
t.text "import_sources"
+ t.text "help_page_text"
+ t.boolean "ci_enabled", default: true, null: false
end
create_table "audit_events", force: true do |t|
@@ -621,6 +623,7 @@ ActiveRecord::Schema.define(version: 20150916145038) 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
@@ -747,6 +750,7 @@ ActiveRecord::Schema.define(version: 20150916145038) 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
@@ -782,7 +786,7 @@ ActiveRecord::Schema.define(version: 20150916145038) do
t.boolean "merge_requests_events", default: false, null: false
t.boolean "tag_push_events", default: false
t.boolean "note_events", default: false, null: false
- t.boolean "enable_ssl_verification", default: false
+ t.boolean "enable_ssl_verification", default: true
end
add_index "web_hooks", ["created_at", "id"], name: "index_web_hooks_on_created_at_and_id", using: :btree
diff --git a/doc/ci/api/README.md b/doc/ci/api/README.md
index e47e5c46732..33c5b172e98 100644
--- a/doc/ci/api/README.md
+++ b/doc/ci/api/README.md
@@ -6,7 +6,6 @@
- [Runners](runners.md)
- [Commits](commits.md)
- [Builds](builds.md)
-- [Forks](forks.md)
## Authentication
diff --git a/doc/ci/api/forks.md b/doc/ci/api/forks.md
deleted file mode 100644
index 8f32e2d3b40..00000000000
--- a/doc/ci/api/forks.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# Forks API
-
-This API is intended to aid in the setup and configuration of
-forked projects on Gitlab CI.
-
-__Authentication is done by GitLab user token & GitLab project token__
-
-## Forks
-
-### Create fork for project
-
-
-
-```
-POST /ci/forks
-```
-
-Parameters:
-
- project_id (required) - The ID of a project
- project_token (requires) - Project token
- private_token(required) - User private token
- data (required) - GitLab project data (name_with_namespace, web_url, default_branch, ssh_url_to_repo)
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
new file mode 100644
index 00000000000..b08f54d137b
--- /dev/null
+++ b/doc/integration/gmail_actions_button.png
Binary files differ
diff --git a/doc/migrate_ci_to_ce/README.md b/doc/migrate_ci_to_ce/README.md
index 13efc8442d2..1e45f29dbb2 100644
--- a/doc/migrate_ci_to_ce/README.md
+++ b/doc/migrate_ci_to_ce/README.md
@@ -52,7 +52,14 @@ This also breaks your database structure disallowing you to use it anymore.
ALTER TABLE web_hooks RENAME TO ci_web_hooks;
EOF
-### 4. Dump GitLab CI database [CI]
+### 4. Remove CI cronjob
+
+```
+cd /home/gitlab_ci/gitlab-ci
+sudo -u gitlab_ci -H bundle exec whenever --clear-crontab
+```
+
+### 5. Dump GitLab CI database [CI]
First check used database and credentials on GitLab CI and GitLab CE/EE:
@@ -125,18 +132,18 @@ You will need to put these credentials into commands executed below.**
# Filter to only include INSERT statements
grep "^\(START\|SET\|INSERT\|COMMIT\)" gitlab_ci.sql.tmp2 > gitlab_ci.sql
-### 5. Make sure that your GitLab CE/EE is 8.0 [CE]
+### 6. Make sure that your GitLab CE/EE is 8.0 [CE]
Please verify that you use GitLab CE/EE 8.0.
If not, please follow the update guide: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/update/7.14-to-8.0.md
-### 6. Stop GitLab CE/EE [CE]
+### 7. Stop GitLab CE/EE [CE]
Before you can migrate data you need to stop GitLab CE/EE first.
sudo service gitlab stop
-### 7. Backup GitLab CE/EE [CE]
+### 8. Backup GitLab CE/EE [CE]
This migration poses a **significant risk** of breaking your GitLab CE/EE.
**You should create the GitLab CI/EE backup before doing it.**
@@ -144,7 +151,7 @@ This migration poses a **significant risk** of breaking your GitLab CE/EE.
cd /home/git/gitlab
sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
-### 8. Copy secret tokens [CE]
+### 9. Copy secret tokens [CE]
The `secrets.yml` file stores encryption keys for secure variables.
@@ -154,7 +161,7 @@ You need to copy the content of `config/secrets.yml` to the same file in GitLab
sudo chown git:git /home/git/gitlab/config/secrets.yml
sudo chown 0600 /home/git/gitlab/config/secrets.yml
-### 9. New configuration options for `gitlab.yml` [CE]
+### 10. New configuration options for `gitlab.yml` [CE]
There are new configuration options available for [`gitlab.yml`](config/gitlab.yml.example).
View them with the command below and apply them manually to your current `gitlab.yml`:
@@ -165,7 +172,7 @@ git diff origin/7-14-stable:config/gitlab.yml.example origin/8-0-stable:config/g
The new options include configuration of GitLab CI that are now being part of GitLab CE and EE.
-### 10. Copy build logs [CE]
+### 11. Copy build logs [CE]
You need to copy the contents of `builds/` to the same directory in GitLab CE/EE.
@@ -174,7 +181,7 @@ You need to copy the contents of `builds/` to the same directory in GitLab CE/EE
The build traces are usually quite big so it will take a significant amount of time.
-### 11. Import GitLab CI database [CE]
+### 12. Import GitLab CI database [CE]
The one of the last steps is to import existing GitLab CI database.
@@ -189,13 +196,13 @@ The task does:
1. Fix tags assigned to Builds and Runners
1. Fix services used by CI
-### 12. Start GitLab [CE]
+### 13. Start GitLab [CE]
You can start GitLab CI/EE now and see if everything is working.
sudo service gitlab start
-### 13. Update nginx [CI]
+### 14. Update nginx [CI]
Now get back to GitLab CI and update **Nginx** configuration in order to:
1. Have all existing runners able to communicate with a migrated GitLab CI.
@@ -263,7 +270,7 @@ You should also make sure that you can do:
sudo /etc/init.d/nginx restart
-### 14. Done!
+### 15. Done!
If everything went OK you should be able to access all your GitLab CI data by pointing your browser to:
https://gitlab.example.com/ci/.
diff --git a/doc/reply_by_email/postfix.md b/doc/reply_by_email/postfix.md
index b8ab07d9fe1..c0ac59bb922 100644
--- a/doc/reply_by_email/postfix.md
+++ b/doc/reply_by_email/postfix.md
@@ -303,8 +303,8 @@ Courier, which we will install later to add IMAP authentication, requires mailbo
## Done!
-If all the tests were successfull, Postfix is all set up and ready to receive email! Continue with the [Reply by email](./README.md) guide to configure GitLab.
+If all the tests were successful, Postfix is all set up and ready to receive email! Continue with the [Reply by email](./README.md) guide to configure GitLab.
---------
-_This document was adapted from https://help.ubuntu.com/community/PostfixBasicSetupHowto, by contributors to the Ubuntu documentation wiki._
+_This document was adapted from https://help.ubuntu.com/community/PostfixBasicSetupHowto, by contributors to the Ubuntu documentation wiki._ \ No newline at end of file
diff --git a/doc/ssh/README.md b/doc/ssh/README.md
index 7cdcd11c04c..7b294a70fe7 100644
--- a/doc/ssh/README.md
+++ b/doc/ssh/README.md
@@ -72,6 +72,8 @@ access can happen through being a direct member of the project, or through
a group. See `def accessible_deploy_keys` in `app/models/user.rb` for more
information.
+Deploy keys can be shared between projects, you just need to add them to each project.
+
## Applications
### Eclipse
diff --git a/doc/web_hooks/web_hooks.md b/doc/web_hooks/web_hooks.md
index 09400d9b163..f4701bb6db2 100644
--- a/doc/web_hooks/web_hooks.md
+++ b/doc/web_hooks/web_hooks.md
@@ -121,6 +121,12 @@ X-Gitlab-Event: Issue Hook
"username": "root",
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
},
+ "repository": {
+ "name": "Gitlab Test",
+ "url": "http://example.com/gitlabhq/gitlab-test.git",
+ "description": "Aut reprehenderit ut est.",
+ "homepage": "http://example.com/gitlabhq/gitlab-test"
+ },
"object_attributes": {
"id": 301,
"title": "New API: create/update/delete file",
diff --git a/features/project/issues/milestones.feature b/features/project/issues/milestones.feature
index bfbaaec5a35..c1a20e9b488 100644
--- a/features/project/issues/milestones.feature
+++ b/features/project/issues/milestones.feature
@@ -12,13 +12,17 @@ Feature: Project Issues Milestones
Given I click link "v2.2"
Then I should see milestone "v2.2"
- Scenario: I create new milestone
+ @javascript
+ Scenario: I create and delete new milestone
Given I click link "New Milestone"
And I submit new milestone "v2.3"
Then I should see milestone "v2.3"
+ Given I click link to remove milestone
+ When I visit project "Shop" activity page
+ Then I should see deleted milestone activity
Scenario: I delete new milestone
- Given I click link to remove milestone "v2.2"
+ Given I click link to remove milestone
And I should see no milestones
@javascript
diff --git a/features/steps/admin/settings.rb b/features/steps/admin/settings.rb
index 7a6aec23af8..6acbf46eb20 100644
--- a/features/steps/admin/settings.rb
+++ b/features/steps/admin/settings.rb
@@ -7,6 +7,7 @@ class Spinach::Features::AdminSettings < Spinach::FeatureSteps
step 'I modify settings and save form' do
uncheck 'Gravatar enabled'
fill_in 'Home page URL', with: 'https://about.gitlab.com/'
+ fill_in 'Help page text', with: 'Example text'
click_button 'Save'
end
diff --git a/features/steps/project/issues/milestones.rb b/features/steps/project/issues/milestones.rb
index 61e62c2adbd..c8708572ec6 100644
--- a/features/steps/project/issues/milestones.rb
+++ b/features/steps/project/issues/milestones.rb
@@ -49,6 +49,11 @@ class Spinach::Features::ProjectIssuesMilestones < Spinach::FeatureSteps
create(:closed_issue, project: project, milestone: milestone)
end
+ step 'I should see deleted milestone activity' do
+ expect(page).to have_content('opened milestone in')
+ expect(page).to have_content('destroyed milestone in')
+ end
+
When 'I click link "All Issues"' do
click_link 'All Issues'
end
@@ -57,7 +62,7 @@ class Spinach::Features::ProjectIssuesMilestones < Spinach::FeatureSteps
expect(page).to have_selector('#tab-issues li.issue-row', count: 4)
end
- step 'I click link to remove milestone "v2.2"' do
+ step 'I click link to remove milestone' do
click_link 'Remove'
end
diff --git a/features/steps/project/services.rb b/features/steps/project/services.rb
index 0327fd61981..d3b462bfd31 100644
--- a/features/steps/project/services.rb
+++ b/features/steps/project/services.rb
@@ -26,13 +26,11 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps
step 'I fill gitlab-ci settings' do
check 'Active'
- fill_in 'Project url', with: 'http://ci.gitlab.org/projects/3'
- fill_in 'Token', with: 'verySecret'
click_button 'Save'
end
step 'I should see service settings saved' do
- expect(find_field('Project url').value).to eq 'http://ci.gitlab.org/projects/3'
+ expect(find_field('Active').value).to eq '1'
end
step 'I click hipchat service link' do
diff --git a/features/steps/shared/project.rb b/features/steps/shared/project.rb
index ccbe8f96a4c..a9cf426852e 100644
--- a/features/steps/shared/project.rb
+++ b/features/steps/shared/project.rb
@@ -51,6 +51,11 @@ module SharedProject
visit namespace_project_path(project.namespace, project)
end
+ step 'I visit project "Shop" activity page' do
+ project = Project.find_by(name: 'Shop')
+ visit namespace_project_path(project.namespace, project)
+ end
+
step 'project "Shop" has push event' do
@project = Project.find_by(name: "Shop")
diff --git a/lib/api/users.rb b/lib/api/users.rb
index ee29f952246..813cc379e43 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -3,7 +3,7 @@ module API
class Users < Grape::API
before { authenticate! }
- resource :users do
+ resource :users, requirements: { uid: /[0-9]*/, id: /[0-9]*/ } do
# Get a users list
#
# Example Request:
diff --git a/lib/backup/database.rb b/lib/backup/database.rb
index ce75476a09b..959ac4b7868 100644
--- a/lib/backup/database.rb
+++ b/lib/backup/database.rb
@@ -25,8 +25,12 @@ module Backup
when "postgresql" then
$progress.print "Dumping PostgreSQL database #{config['database']} ... "
pg_env
- # Pass '--clean' to include 'DROP TABLE' statements in the DB dump.
- system('pg_dump', '--clean', config['database'], out: db_file_name)
+ pgsql_args = ["--clean"] # Pass '--clean' to include 'DROP TABLE' statements in the DB dump.
+ if Gitlab.config.backup.pg_schema
+ pgsql_args << "-n"
+ pgsql_args << Gitlab.config.backup.pg_schema
+ end
+ system('pg_dump', *pgsql_args, config['database'], out: db_file_name)
end
report_success(success)
abort 'Backup failed' unless success
diff --git a/lib/ci/api/api.rb b/lib/ci/api/api.rb
index 172c6f22164..5109c84e0ea 100644
--- a/lib/ci/api/api.rb
+++ b/lib/ci/api/api.rb
@@ -23,6 +23,10 @@ module Ci
rack_response({ 'message' => '500 Internal Server Error' }, 500)
end
+ before do
+ check_enable_flag!
+ end
+
format :json
helpers Helpers
@@ -32,7 +36,6 @@ module Ci
mount Commits
mount Runners
mount Projects
- mount Forks
mount Triggers
end
end
diff --git a/lib/ci/api/forks.rb b/lib/ci/api/forks.rb
deleted file mode 100644
index 152883a599f..00000000000
--- a/lib/ci/api/forks.rb
+++ /dev/null
@@ -1,37 +0,0 @@
-module Ci
- module API
- class Forks < Grape::API
- resource :forks do
- # Create a fork
- #
- # Parameters:
- # project_id (required) - The ID of a project
- # project_token (requires) - Project token
- # private_token(required) - User private token
- # data (required) - GitLab project data (name_with_namespace, web_url, default_branch, ssh_url_to_repo)
- #
- #
- # Example Request:
- # POST /forks
- post do
- required_attributes! [:project_id, :data, :project_token, :private_token]
- project = Ci::Project.find_by!(gitlab_id: params[:project_id])
- authenticate_project_token!(project)
-
- fork = Ci::CreateProjectService.new.execute(
- current_user,
- params[:data],
- Ci::RoutesHelper.ci_project_url(":project_id"),
- project
- )
-
- if fork
- present fork, with: Entities::Project
- else
- not_found!
- end
- end
- end
- end
- end
-end
diff --git a/lib/ci/api/helpers.rb b/lib/ci/api/helpers.rb
index e602cda81d6..8e893aa5cc6 100644
--- a/lib/ci/api/helpers.rb
+++ b/lib/ci/api/helpers.rb
@@ -3,6 +3,12 @@ module Ci
module Helpers
UPDATE_RUNNER_EVERY = 60
+ def check_enable_flag!
+ unless current_application_settings.ci_enabled
+ render_api_error!('400 (Bad request) CI is disabled', 400)
+ end
+ end
+
def authenticate_runners!
forbidden! unless params[:token] == GitlabCi::REGISTRATION_TOKEN
end
diff --git a/lib/ci/migrate/builds.rb b/lib/ci/migrate/builds.rb
new file mode 100644
index 00000000000..fdc143cfad5
--- /dev/null
+++ b/lib/ci/migrate/builds.rb
@@ -0,0 +1,29 @@
+module Ci
+ module Migrate
+ class Builds
+ attr_reader :app_builds_dir, :backup_builds_tarball, :backup_dir
+
+ def initialize
+ @app_builds_dir = Settings.gitlab_ci.builds_path
+ @backup_dir = Gitlab.config.backup.path
+ @backup_builds_tarball = File.join(backup_dir, 'builds/builds.tar.gz')
+ end
+
+ def restore
+ backup_existing_builds_dir
+
+ FileUtils.mkdir_p(app_builds_dir, mode: 0700)
+ unless system('tar', '-C', app_builds_dir, '-zxvf', backup_builds_tarball)
+ abort 'Restore failed'.red
+ end
+ end
+
+ def backup_existing_builds_dir
+ timestamped_builds_path = File.join(app_builds_dir, '..', "builds.#{Time.now.to_i}")
+ if File.exists?(app_builds_dir)
+ FileUtils.mv(app_builds_dir, File.expand_path(timestamped_builds_path))
+ end
+ end
+ end
+ end
+end
diff --git a/lib/ci/migrate/database.rb b/lib/ci/migrate/database.rb
index 74f592dcaea..bf9b80f1f62 100644
--- a/lib/ci/migrate/database.rb
+++ b/lib/ci/migrate/database.rb
@@ -9,32 +9,32 @@ module Ci
@config = YAML.load_file(File.join(Rails.root, 'config', 'database.yml'))[Rails.env]
end
- def restore(ci_dump)
- puts 'Deleting all CI related data ... '
- truncate_ci_tables
+ def restore
+ decompress_rd, decompress_wr = IO.pipe
+ decompress_pid = spawn(*%W(gzip -cd), out: decompress_wr, in: db_file_name)
+ decompress_wr.close
- puts 'Restoring CI data ... '
- case config["adapter"]
- when /^mysql/ then
- print "Restoring MySQL database #{config['database']} ... "
- # Workaround warnings from MySQL 5.6 about passwords on cmd line
- ENV['MYSQL_PWD'] = config["password"].to_s if config["password"]
- system('mysql', *mysql_args, config['database'], in: ci_dump)
- when "postgresql" then
- puts "Restoring PostgreSQL database #{config['database']} ... "
- pg_env
- system('psql', config['database'], '-f', ci_dump)
- end
+ restore_pid = case config["adapter"]
+ when /^mysql/ then
+ $progress.print "Restoring MySQL database #{config['database']} ... "
+ # Workaround warnings from MySQL 5.6 about passwords on cmd line
+ ENV['MYSQL_PWD'] = config["password"].to_s if config["password"]
+ spawn('mysql', *mysql_args, config['database'], in: decompress_rd)
+ when "postgresql" then
+ $progress.print "Restoring PostgreSQL database #{config['database']} ... "
+ pg_env
+ spawn('psql', config['database'], in: decompress_rd)
+ end
+ decompress_rd.close
+
+ success = [decompress_pid, restore_pid].all? { |pid| Process.waitpid(pid); $?.success? }
+ abort 'Restore failed' unless success
end
protected
- def truncate_ci_tables
- c = ActiveRecord::Base.connection
- c.tables.select { |t| t.start_with?('ci_') }.each do |table|
- puts "Deleting data from #{table}..."
- c.execute("DELETE FROM #{table}")
- end
+ def db_file_name
+ File.join(Gitlab.config.backup.path, 'db', 'database.sql.gz')
end
def mysql_args
diff --git a/lib/ci/migrate/manager.rb b/lib/ci/migrate/manager.rb
new file mode 100644
index 00000000000..4205809368d
--- /dev/null
+++ b/lib/ci/migrate/manager.rb
@@ -0,0 +1,70 @@
+module Ci
+ module Migrate
+ class Manager
+ def cleanup
+ $progress.print "Deleting tmp directories ... "
+
+ backup_contents.each do |dir|
+ next unless File.exist?(File.join(Gitlab.config.backup.path, dir))
+
+ if FileUtils.rm_rf(File.join(Gitlab.config.backup.path, dir))
+ $progress.puts "done".green
+ else
+ puts "deleting tmp directory '#{dir}' failed".red
+ abort 'Backup failed'
+ end
+ end
+ end
+
+ def unpack
+ Dir.chdir(Gitlab.config.backup.path)
+
+ # check for existing backups in the backup dir
+ file_list = Dir.glob("*_gitlab_ci_backup.tar").each.map { |f| f.split(/_/).first.to_i }
+ puts "no backups found" if file_list.count == 0
+
+ if file_list.count > 1 && ENV["BACKUP"].nil?
+ puts "Found more than one backup, please specify which one you want to restore:"
+ puts "rake gitlab:backup:restore BACKUP=timestamp_of_backup"
+ exit 1
+ end
+
+ tar_file = ENV["BACKUP"].nil? ? File.join("#{file_list.first}_gitlab_ci_backup.tar") : File.join(ENV["BACKUP"] + "_gitlab_ci_backup.tar")
+
+ unless File.exists?(tar_file)
+ puts "The specified CI backup doesn't exist!"
+ exit 1
+ end
+
+ $progress.print "Unpacking backup ... "
+
+ unless Kernel.system(*%W(tar -xf #{tar_file}))
+ puts "unpacking backup failed".red
+ exit 1
+ else
+ $progress.puts "done".green
+ end
+
+ ENV["VERSION"] = "#{settings[:db_version]}" if settings[:db_version].to_i > 0
+
+ # restoring mismatching backups can lead to unexpected problems
+ if settings[:gitlab_version] != GitlabCi::VERSION
+ puts "GitLab CI version mismatch:".red
+ puts " Your current GitLab CI version (#{GitlabCi::VERSION}) differs from the GitLab CI (#{settings[:gitlab_version]}) version in the backup!".red
+ exit 1
+ end
+ end
+
+ private
+
+ def backup_contents
+ ["db", "builds", "backup_information.yml"]
+ end
+
+ def settings
+ @settings ||= YAML.load_file("backup_information.yml")
+ end
+ end
+ end
+end
+
diff --git a/lib/ci/migrate/tags.rb b/lib/ci/migrate/tags.rb
index 125a535e9a9..97e043ece27 100644
--- a/lib/ci/migrate/tags.rb
+++ b/lib/ci/migrate/tags.rb
@@ -4,45 +4,38 @@ module Ci
module Migrate
class Tags
def restore
- puts 'Migrating tags for Runners... '
- list_objects('Runner').each do |id|
- putc '.'
- runner = Ci::Runner.find_by_id(id)
- if runner
- tags = list_tags('Runner', id)
- runner.update_attributes(tag_list: tags)
+ puts 'Inserting tags...'
+ connection.select_all('SELECT ci_tags.name FROM ci_tags').each do |tag|
+ begin
+ connection.execute("INSERT INTO tags (name) VALUES(#{ActiveRecord::Base::sanitize(tag['name'])})")
+ rescue ActiveRecord::RecordNotUnique
end
end
- puts ''
- puts 'Migrating tags for Builds... '
- list_objects('Build').each do |id|
- putc '.'
- build = Ci::Build.find_by_id(id)
- if build
- tags = list_tags('Build', id)
- build.update_attributes(tag_list: tags)
- end
+ ActiveRecord::Base.transaction do
+ puts 'Deleting old taggings...'
+ connection.execute "DELETE FROM taggings WHERE context = 'tags' AND taggable_type LIKE 'Ci::%'"
+
+ puts 'Inserting taggings...'
+ connection.execute(
+ 'INSERT INTO taggings (taggable_type, taggable_id, tag_id, context) ' +
+ "SELECT CONCAT('Ci::', ci_taggings.taggable_type), ci_taggings.taggable_id, tags.id, 'tags' FROM ci_taggings " +
+ 'JOIN ci_tags ON ci_tags.id = ci_taggings.tag_id ' +
+ 'JOIN tags ON tags.name = ci_tags.name '
+ )
+
+ puts 'Resetting counters... '
+ connection.execute(
+ 'UPDATE tags SET ' +
+ 'taggings_count = (SELECT COUNT(*) FROM taggings WHERE tags.id = taggings.tag_id)'
+ )
end
- puts ''
end
protected
- def list_objects(type)
- ids = ActiveRecord::Base.connection.select_all(
- "select distinct taggable_id from ci_taggings where taggable_type = #{ActiveRecord::Base::sanitize(type)}"
- )
- ids.map { |id| id['taggable_id'] }
- end
-
- def list_tags(type, id)
- tags = ActiveRecord::Base.connection.select_all(
- 'select ci_tags.name from ci_tags ' +
- 'join ci_taggings on ci_tags.id = ci_taggings.tag_id ' +
- "where taggable_type = #{ActiveRecord::Base::sanitize(type)} and taggable_id = #{ActiveRecord::Base::sanitize(id)} and context = 'tags'"
- )
- tags.map { |tag| tag['name'] }
+ def connection
+ ActiveRecord::Base.connection
end
end
end
diff --git a/lib/ci/project_list_builder.rb b/lib/ci/project_list_builder.rb
new file mode 100644
index 00000000000..da26f9a9f47
--- /dev/null
+++ b/lib/ci/project_list_builder.rb
@@ -0,0 +1,21 @@
+module Ci
+ class ProjectListBuilder
+ def execute(current_user, search = nil)
+ projects = current_user.authorized_projects
+ projects = projects.search(search) if search
+
+ projects.
+ joins("LEFT JOIN ci_projects ON projects.id = ci_projects.gitlab_id
+ LEFT JOIN #{last_commit_subquery} AS last_commit ON #{Ci::Project.table_name}.id = last_commit.project_id").
+ reorder("ci_projects.id is NULL ASC,
+ CASE WHEN last_commit.committed_at IS NULL THEN 1 ELSE 0 END,
+ last_commit.committed_at DESC")
+ end
+
+ private
+
+ def last_commit_subquery
+ "(SELECT project_id, MAX(committed_at) committed_at FROM #{Ci::Commit.table_name} GROUP BY project_id)"
+ end
+ end
+end
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/lib/tasks/ci/migrate.rake b/lib/tasks/ci/migrate.rake
index e7d41874a11..1de664c85e1 100644
--- a/lib/tasks/ci/migrate.rake
+++ b/lib/tasks/ci/migrate.rake
@@ -1,40 +1,56 @@
namespace :ci do
desc 'GitLab | Import and migrate CI database'
task migrate: :environment do
+ warn_user_is_not_gitlab
+ configure_cron_mode
+
unless ENV['force'] == 'yes'
- puts "This will truncate all CI tables and restore it from provided backup."
- puts "You will lose any previous CI data stored in the database."
+ puts 'This will remove all CI related data and restore it from the provided backup.'
ask_to_continue
- puts ""
+ puts ''
end
- Rake::Task["ci:migrate:db"].invoke
- Rake::Task["ci:migrate:autoincrements"].invoke
- Rake::Task["ci:migrate:tags"].invoke
- Rake::Task["ci:migrate:services"].invoke
+ # disable CI for time of migration
+ enable_ci(false)
+
+ # unpack archives
+ migrate = Ci::Migrate::Manager.new
+ migrate.unpack
+
+ Rake::Task['ci:migrate:db'].invoke
+ Rake::Task['ci:migrate:builds'].invoke
+ Rake::Task['ci:migrate:tags'].invoke
+ Rake::Task['ci:migrate:services'].invoke
+
+ # enable CI for time of migration
+ enable_ci(true)
+
+ migrate.cleanup
end
namespace :migrate do
desc 'GitLab | Import CI database'
task db: :environment do
- if ENV["CI_DUMP"].nil?
- puts "No CI SQL dump specified:"
- puts "rake gitlab:backup:restore CI_DUMP=ci_dump.sql"
- exit 1
- end
-
- ci_dump = ENV["CI_DUMP"]
- unless File.exists?(ci_dump)
- puts "The specified sql dump doesn't exist!"
- exit 1
- end
+ configure_cron_mode
+ $progress.puts 'Restoring database ... '.blue
+ Ci::Migrate::Database.new.restore
+ $progress.puts 'done'.green
+ end
- ::Ci::Migrate::Database.new.restore(ci_dump)
+ desc 'GitLab | Import CI builds'
+ task builds: :environment do
+ configure_cron_mode
+ $progress.puts 'Restoring builds ... '.blue
+ Ci::Migrate::Builds.new.restore
+ $progress.puts 'done'.green
end
desc 'GitLab | Migrate CI tags'
task tags: :environment do
+ configure_cron_mode
+ $progress.puts 'Migrating tags ... '.blue
::Ci::Migrate::Tags.new.restore
+ $progress.puts 'done'.green
end
desc 'GitLab | Migrate CI auto-increments'
@@ -56,8 +72,16 @@ namespace :ci do
desc 'GitLab | Migrate CI services'
task services: :environment do
+ $progress.puts 'Migrating services ... '.blue
c = ActiveRecord::Base.connection
c.execute("UPDATE ci_services SET type=CONCAT('Ci::', type) WHERE type NOT LIKE 'Ci::%'")
+ $progress.puts 'done'.green
end
end
+
+ def enable_ci(enabled)
+ settings = ApplicationSetting.current || ApplicationSetting.create_from_defaults
+ settings.ci_enabled = enabled
+ settings.save!
+ end
end
diff --git a/spec/controllers/ci/projects_controller_spec.rb b/spec/controllers/ci/projects_controller_spec.rb
index 015788a05e1..3e579f9a7d6 100644
--- a/spec/controllers/ci/projects_controller_spec.rb
+++ b/spec/controllers/ci/projects_controller_spec.rb
@@ -5,49 +5,6 @@ describe Ci::ProjectsController do
@project = FactoryGirl.create :ci_project
end
- describe "POST #build" do
- it 'should respond 200 if params is ok' do
- post :build, {
- id: @project.id,
- ref: 'master',
- before: '2aa371379db71ac89ae20843fcff3b3477cf1a1d',
- after: '1c8a9df454ef68c22c2a33cca8232bb50849e5c5',
- token: @project.token,
- ci_yaml_file: gitlab_ci_yaml,
- commits: [ { message: "Message" } ]
- }
-
- expect(response).to be_success
- expect(response.code).to eq('201')
- end
-
- it 'should respond 400 if push about removed branch' do
- post :build, {
- id: @project.id,
- ref: 'master',
- before: '2aa371379db71ac89ae20843fcff3b3477cf1a1d',
- after: '0000000000000000000000000000000000000000',
- token: @project.token,
- ci_yaml_file: gitlab_ci_yaml
- }
-
- expect(response).not_to be_success
- expect(response.code).to eq('400')
- end
-
- it 'should respond 400 if some params missed' do
- post :build, id: @project.id, token: @project.token, ci_yaml_file: gitlab_ci_yaml
- expect(response).not_to be_success
- expect(response.code).to eq('400')
- end
-
- it 'should respond 403 if token is wrong' do
- post :build, id: @project.id, token: 'invalid-token'
- expect(response).not_to be_success
- expect(response.code).to eq('403')
- end
- end
-
describe "POST /projects" do
let(:project_dump) { OpenStruct.new({ id: @project.gitlab_id }) }
@@ -84,7 +41,7 @@ describe Ci::ProjectsController do
end
it "searches projects" do
- xhr :get, :gitlab, { search: "str", format: "js" }.with_indifferent_access
+ xhr :get, :index, { search: "str", format: "json" }.with_indifferent_access
expect(response).to be_success
expect(response.code).to eq('200')
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/controllers/projects/milestones_controller_spec.rb b/spec/controllers/projects/milestones_controller_spec.rb
index d3868c13202..35446640929 100644
--- a/spec/controllers/projects/milestones_controller_spec.rb
+++ b/spec/controllers/projects/milestones_controller_spec.rb
@@ -15,8 +15,12 @@ describe Projects::MilestonesController do
describe "#destroy" do
it "should remove milestone" do
expect(issue.milestone_id).to eq(milestone.id)
+
delete :destroy, namespace_id: project.namespace.id, project_id: project.id, id: milestone.id, format: :js
expect(response).to be_success
+
+ expect(Event.first.action).to eq(Event::DESTROYED)
+
expect { Milestone.find(milestone.id) }.to raise_exception(ActiveRecord::RecordNotFound)
issue.reload
expect(issue.milestone_id).to eq(nil)
diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb
index 5639b3db913..b8101ae77ec 100644
--- a/spec/helpers/gitlab_markdown_helper_spec.rb
+++ b/spec/helpers/gitlab_markdown_helper_spec.rb
@@ -38,6 +38,17 @@ describe GitlabMarkdownHelper do
expect(markdown(actual)).to match(expected)
end
end
+
+ describe "override default project" do
+ let(:actual) { issue.to_reference }
+ let(:second_project) { create(:project) }
+ let(:second_issue) { create(:issue, project: second_project) }
+
+ it 'should link to the issue' do
+ expected = namespace_project_issue_path(second_project.namespace, second_project, second_issue)
+ expect(markdown(actual, project: second_project)).to match(expected)
+ end
+ end
end
describe '#link_to_gfm' do
diff --git a/spec/lib/gitlab/backend/grack_auth_spec.rb b/spec/lib/gitlab/backend/grack_auth_spec.rb
index d9676445908..9bed8f8ee5c 100644
--- a/spec/lib/gitlab/backend/grack_auth_spec.rb
+++ b/spec/lib/gitlab/backend/grack_auth_spec.rb
@@ -180,7 +180,6 @@ describe Grack::Auth do
gitlab_ci_service = project.build_gitlab_ci_service
gitlab_ci_service.active = true
gitlab_ci_service.token = token
- gitlab_ci_service.project_url = "http://google.com"
gitlab_ci_service.save
env["HTTP_AUTHORIZATION"] = ActionController::HttpAuthentication::Basic.encode_credentials("gitlab-ci-token", token)
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/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb
index b6d80451d2e..8f706f8934b 100644
--- a/spec/models/concerns/issuable_spec.rb
+++ b/spec/models/concerns/issuable_spec.rb
@@ -2,6 +2,7 @@ require 'spec_helper'
describe Issue, "Issuable" do
let(:issue) { create(:issue) }
+ let(:user) { create(:user) }
describe "Associations" do
it { is_expected.to belong_to(:project) }
@@ -66,4 +67,19 @@ describe Issue, "Issuable" do
expect(issue.new?).to be_falsey
end
end
+
+
+ describe "#to_hook_data" do
+ let(:hook_data) { issue.to_hook_data(user) }
+
+ it "returns correct hook data" do
+ expect(hook_data[:object_kind]).to eq("issue")
+ expect(hook_data[:user]).to eq(user.hook_attrs)
+ expect(hook_data[:repository][:name]).to eq(issue.project.name)
+ expect(hook_data[:repository][:url]).to eq(issue.project.url_to_repo)
+ expect(hook_data[:repository][:description]).to eq(issue.project.description)
+ expect(hook_data[:repository][:homepage]).to eq(issue.project.web_url)
+ expect(hook_data[:object_attributes]).to eq(issue.hook_attrs)
+ end
+ end
end
diff --git a/spec/models/project_services/buildkite_service_spec.rb b/spec/models/project_services/buildkite_service_spec.rb
index 9445d96c337..230807ea672 100644
--- a/spec/models/project_services/buildkite_service_spec.rb
+++ b/spec/models/project_services/buildkite_service_spec.rb
@@ -63,19 +63,5 @@ describe BuildkiteService do
)
end
end
-
- describe :builds_page do
- it 'returns the correct path to the builds page' do
- expect(@service.builds_path).to eq(
- 'https://buildkite.com/account-name/example-project/builds?branch=default-brancho'
- )
- end
- end
-
- describe :status_img_path do
- it 'returns the correct path to the status image' do
- expect(@service.status_img_path).to eq('https://badge.buildkite.com/secret-sauce-status-token.svg')
- end
- end
end
end
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/project_services/gitlab_ci_service_spec.rb b/spec/models/project_services/gitlab_ci_service_spec.rb
index a14384c87b4..e0da04a3f40 100644
--- a/spec/models/project_services/gitlab_ci_service_spec.rb
+++ b/spec/models/project_services/gitlab_ci_service_spec.rb
@@ -26,51 +26,21 @@ describe GitlabCiService do
it { is_expected.to have_one(:service_hook) }
end
- describe 'validations' do
- context 'active' do
- before { allow(subject).to receive(:activated?).and_return(true) }
-
- it { is_expected.to validate_presence_of(:token) }
- it { is_expected.to validate_presence_of(:project_url) }
- it { is_expected.to allow_value('ewf9843kdnfdfs89234n').for(:token) }
- it { is_expected.to allow_value('http://ci.example.com/project/1').for(:project_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(:project_url) }
- it { is_expected.not_to allow_value('http//noturl').for(:project_url) }
- it { is_expected.not_to allow_value('ftp://ci.example.com/projects/3').for(:project_url) }
- end
-
- context 'inactive' do
- before { allow(subject).to receive(:activated?).and_return(false) }
-
- it { is_expected.not_to validate_presence_of(:token) }
- it { is_expected.not_to validate_presence_of(:project_url) }
- it { is_expected.to allow_value('ewf9843kdnfdfs89234n').for(:token) }
- it { is_expected.to allow_value('http://ci.example.com/project/1').for(:project_url) }
- it { is_expected.to allow_value('token with spaces').for(:token) }
- it { is_expected.to allow_value('ftp://ci.example.com/projects/3').for(:project_url) }
- end
- end
-
describe 'commits methods' do
before do
+ @ci_project = create(:ci_project)
@service = GitlabCiService.new
allow(@service).to receive_messages(
service_hook: true,
project_url: 'http://ci.gitlab.org/projects/2',
- token: 'verySecret'
+ token: 'verySecret',
+ project: @ci_project.gl_project
)
end
- describe :commit_status_path do
- it { expect(@service.commit_status_path("2ab7834c", 'master')).to eq("http://ci.gitlab.org/projects/2/refs/master/commits/2ab7834c/status.json?token=verySecret")}
- it { expect(@service.commit_status_path("issue#2", 'master')).to eq("http://ci.gitlab.org/projects/2/refs/master/commits/issue%232/status.json?token=verySecret")}
- end
-
describe :build_page do
- it { expect(@service.build_page("2ab7834c", 'master')).to eq("http://ci.gitlab.org/projects/2/refs/master/commits/2ab7834c")}
- it { expect(@service.build_page("issue#2", 'master')).to eq("http://ci.gitlab.org/projects/2/refs/master/commits/issue%232")}
+ it { expect(@service.build_page("2ab7834c", 'master')).to eq("/ci/projects/#{@ci_project.id}/refs/master/commits/2ab7834c")}
+ it { expect(@service.build_page("issue#2", 'master')).to eq("/ci/projects/#{@ci_project.id}/refs/master/commits/issue%232")}
end
describe "execute" do
@@ -80,8 +50,6 @@ describe GitlabCiService do
it "calls ci_yaml_file" do
service_hook = double
- expect(service_hook).to receive(:execute)
- expect(@service).to receive(:service_hook).and_return(service_hook)
expect(@service).to receive(:ci_yaml_file).with(push_sample_data[:checkout_sha])
@service.execute(push_sample_data)
@@ -91,7 +59,7 @@ describe GitlabCiService do
describe "Fork registration" do
before do
- @old_project = create(:empty_project)
+ @old_project = create(:ci_project).gl_project
@project = create(:empty_project)
@user = create(:user)
@@ -104,9 +72,9 @@ describe GitlabCiService do
)
end
- it "performs http reuquest to ci" do
- stub_request(:post, "http://ci.gitlab.org/api/v1/forks")
- @service.fork_registration(@project, @user.private_token)
+ it "creates fork on CI" do
+ expect_any_instance_of(Ci::CreateProjectService).to receive(:execute)
+ @service.fork_registration(@project, @user)
end
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
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 5bd8206b890..3007a15b0b1 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -89,7 +89,7 @@ describe API::API, api: true do
it 'returns projects in the correct order when ci_enabled_first parameter is passed' do
[project, project2, project3].each{ |project| project.build_missing_services }
- project2.gitlab_ci_service.update(active: true, token: "token", project_url: "http://ci.example.com/projects/1")
+ project2.gitlab_ci_service.update(active: true, token: "token")
get api('/projects', user), { ci_enabled_first: 'true' }
expect(response.status).to eq(200)
expect(json_response).to be_an Array
diff --git a/spec/requests/api/services_spec.rb b/spec/requests/api/services_spec.rb
index fb3b235446f..9aa60826f21 100644
--- a/spec/requests/api/services_spec.rb
+++ b/spec/requests/api/services_spec.rb
@@ -17,9 +17,9 @@ describe API::API, api: true do
it "should return if required fields missing" do
attrs = service_attrs
-
+
required_attributes = service_attrs_list.select do |attr|
- service_klass.validators_on(attr).any? do |v|
+ service_klass.validators_on(attr).any? do |v|
v.class == ActiveRecord::Validations::PresenceValidator
end
end
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index f2aa369985e..f9bc63680ba 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -58,6 +58,11 @@ describe API::API, api: true do
expect(response.status).to eq(404)
expect(json_response['message']).to eq('404 Not found')
end
+
+ it "should return a 404 if invalid ID" do
+ get api("/users/1ASDF", user)
+ expect(response.status).to eq(404)
+ end
end
describe "POST /users" do
@@ -257,6 +262,10 @@ describe API::API, api: true do
expect(json_response['message']).to eq('404 Not found')
end
+ it "should raise error for invalid ID" do
+ expect{put api("/users/ASDF", admin) }.to raise_error(ActionController::RoutingError)
+ end
+
it 'should return 400 error if user does not validate' do
put api("/users/#{user.id}", admin),
password: 'pass',
@@ -319,6 +328,10 @@ describe API::API, api: true do
post api("/users/#{user.id}/keys", admin), key_attrs
end.to change{ user.keys.count }.by(1)
end
+
+ it "should raise error for invalid ID" do
+ expect{post api("/users/ASDF/keys", admin) }.to raise_error(ActionController::RoutingError)
+ end
end
describe 'GET /user/:uid/keys' do
@@ -346,6 +359,11 @@ describe API::API, api: true do
expect(json_response).to be_an Array
expect(json_response.first['title']).to eq(key.title)
end
+
+ it "should return 404 for invalid ID" do
+ get api("/users/ASDF/keys", admin)
+ expect(response.status).to eq(404)
+ end
end
end
@@ -400,6 +418,10 @@ describe API::API, api: true do
post api("/users/#{user.id}/emails", admin), email_attrs
end.to change{ user.emails.count }.by(1)
end
+
+ it "should raise error for invalid ID" do
+ expect{post api("/users/ASDF/emails", admin) }.to raise_error(ActionController::RoutingError)
+ end
end
describe 'GET /user/:uid/emails' do
@@ -427,6 +449,10 @@ describe API::API, api: true do
expect(json_response).to be_an Array
expect(json_response.first['email']).to eq(email.email)
end
+
+ it "should raise error for invalid ID" do
+ expect{put api("/users/ASDF/emails", admin) }.to raise_error(ActionController::RoutingError)
+ end
end
end
@@ -463,6 +489,10 @@ describe API::API, api: true do
expect(response.status).to eq(404)
expect(json_response['message']).to eq('404 Email Not Found')
end
+
+ it "should raise error for invalid ID" do
+ expect{delete api("/users/ASDF/emails/bar", admin) }.to raise_error(ActionController::RoutingError)
+ end
end
end
@@ -491,6 +521,10 @@ describe API::API, api: true do
expect(response.status).to eq(404)
expect(json_response['message']).to eq('404 User Not Found')
end
+
+ it "should raise error for invalid ID" do
+ expect{delete api("/users/ASDF", admin) }.to raise_error(ActionController::RoutingError)
+ end
end
describe "GET /user" do
@@ -553,6 +587,11 @@ describe API::API, api: true do
expect(response.status).to eq(404)
expect(json_response['message']).to eq('404 Not found')
end
+
+ it "should return 404 for invalid ID" do
+ get api("/users/keys/ASDF", admin)
+ expect(response.status).to eq(404)
+ end
end
describe "POST /user/keys" do
@@ -608,6 +647,10 @@ describe API::API, api: true do
delete api("/user/keys/#{key.id}")
expect(response.status).to eq(401)
end
+
+ it "should raise error for invalid ID" do
+ expect{delete api("/users/keys/ASDF", admin) }.to raise_error(ActionController::RoutingError)
+ end
end
describe "GET /user/emails" do
@@ -653,6 +696,11 @@ describe API::API, api: true do
expect(response.status).to eq(404)
expect(json_response['message']).to eq('404 Not found')
end
+
+ it "should return 404 for invalid ID" do
+ get api("/users/emails/ASDF", admin)
+ expect(response.status).to eq(404)
+ end
end
describe "POST /user/emails" do
@@ -697,6 +745,10 @@ describe API::API, api: true do
delete api("/user/emails/#{email.id}")
expect(response.status).to eq(401)
end
+
+ it "should raise error for invalid ID" do
+ expect{delete api("/users/emails/ASDF", admin) }.to raise_error(ActionController::RoutingError)
+ end
end
describe 'PUT /user/:id/block' do
@@ -748,5 +800,9 @@ describe API::API, api: true do
expect(response.status).to eq(404)
expect(json_response['message']).to eq('404 User Not Found')
end
+
+ it "should raise error for invalid ID" do
+ expect{put api("/users/ASDF/block", admin) }.to raise_error(ActionController::RoutingError)
+ end
end
end
diff --git a/spec/requests/ci/api/forks_spec.rb b/spec/requests/ci/api/forks_spec.rb
deleted file mode 100644
index 37fa1e82f25..00000000000
--- a/spec/requests/ci/api/forks_spec.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-require 'spec_helper'
-
-describe Ci::API::API do
- include ApiHelpers
-
- let(:project) { FactoryGirl.create(:ci_project) }
- let(:private_token) { create(:user).private_token }
-
- let(:options) do
- {
- private_token: private_token,
- url: GitlabCi.config.gitlab_ci.url
- }
- end
-
- before do
- stub_gitlab_calls
- end
-
-
- describe "POST /forks" do
- let(:project_info) do
- {
- project_id: project.gitlab_id,
- project_token: project.token,
- data: {
- id: create(:empty_project).id,
- name_with_namespace: "Gitlab.org / Underscore",
- path_with_namespace: "gitlab-org/underscore",
- default_branch: "master",
- ssh_url_to_repo: "git@example.com:gitlab-org/underscore"
- }
- }
- end
-
- context "with valid info" do
- before do
- options.merge!(project_info)
- end
-
- it "should create a project with valid data" do
- post ci_api("/forks"), options
- expect(response.status).to eq(201)
- expect(json_response['name']).to eq("Gitlab.org / Underscore")
- end
- end
-
- context "with invalid project info" do
- before do
- options.merge!({})
- end
-
- it "should error with invalid data" do
- post ci_api("/forks"), options
- expect(response.status).to eq(400)
- end
- end
- end
-end
diff --git a/spec/services/ci/create_commit_service_spec.rb b/spec/services/ci/create_commit_service_spec.rb
index 38d9943765a..84ab0a615dd 100644
--- a/spec/services/ci/create_commit_service_spec.rb
+++ b/spec/services/ci/create_commit_service_spec.rb
@@ -50,6 +50,19 @@ module Ci
end
end
+ it 'fails commits without .gitlab-ci.yml' do
+ result = service.execute(project,
+ ref: 'refs/heads/0_1',
+ before: '00000000',
+ after: '31das312',
+ ci_yaml_file: config,
+ commits: [ { message: 'Message' } ]
+ )
+ expect(result).to be_persisted
+ expect(result.builds.any?).to be_falsey
+ expect(result.status).to eq('failed')
+ end
+
describe :ci_skip? do
it "skips builds creation if there is [ci skip] tag in commit message" do
commits = [{ message: "some message[ci skip]" }]
diff --git a/spec/services/ci/create_project_service_spec.rb b/spec/services/ci/create_project_service_spec.rb
index 64041b8d5a2..c0af515aa8f 100644
--- a/spec/services/ci/create_project_service_spec.rb
+++ b/spec/services/ci/create_project_service_spec.rb
@@ -7,7 +7,7 @@ describe Ci::CreateProjectService do
describe :execute do
context 'valid params' do
- subject { service.execute(current_user, project, 'http://localhost/projects/:project_id') }
+ subject { service.execute(current_user, project) }
it { is_expected.to be_kind_of(Ci::Project) }
it { is_expected.to be_persisted }
@@ -24,7 +24,7 @@ describe Ci::CreateProjectService do
FactoryGirl.create(:ci_project, shared_runners_enabled: true, public: true, allow_git_fetch: true)
end
- subject { service.execute(current_user, project, 'http://localhost/projects/:project_id', ci_origin_project) }
+ subject { service.execute(current_user, project, ci_origin_project) }
it "uses project as a template for settings and jobs" do
expect(subject.shared_runners_enabled).to be_truthy
diff --git a/spec/services/event_create_service_spec.rb b/spec/services/event_create_service_spec.rb
index 007a9eed192..7756b973ecd 100644
--- a/spec/services/event_create_service_spec.rb
+++ b/spec/services/event_create_service_spec.rb
@@ -99,5 +99,15 @@ describe EventCreateService do
expect { service.close_milestone(milestone, user) }.to change { Event.count }
end
end
+
+ describe :destroy_mr do
+ let(:milestone) { create(:milestone) }
+
+ it { expect(service.destroy_milestone(milestone, user)).to be_truthy }
+
+ it "should create new event" do
+ expect { service.destroy_milestone(milestone, user) }.to change { Event.count }
+ end
+ end
end
end
diff --git a/spec/services/projects/fork_service_spec.rb b/spec/services/projects/fork_service_spec.rb
index 7c4bb74b77f..18ab333c1d1 100644
--- a/spec/services/projects/fork_service_spec.rb
+++ b/spec/services/projects/fork_service_spec.rb
@@ -44,10 +44,11 @@ describe Projects::ForkService do
context 'GitLab CI is enabled' do
it "calls fork registrator for CI" do
+ create(:ci_project, gl_project: @from_project)
@from_project.build_missing_services
@from_project.gitlab_ci_service.update_attributes(active: true)
- expect(ForkRegistrationWorker).to receive(:perform_async)
+ expect_any_instance_of(Ci::CreateProjectService).to receive(:execute)
fork_project(@from_project, @to_user)
end
diff --git a/spec/workers/fork_registration_worker_spec.rb b/spec/workers/fork_registration_worker_spec.rb
deleted file mode 100644
index cc6f574b29c..00000000000
--- a/spec/workers/fork_registration_worker_spec.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-
-require 'spec_helper'
-
-describe ForkRegistrationWorker do
- context "as a resque worker" do
- it "reponds to #perform" do
- expect(ForkRegistrationWorker.new).to respond_to(:perform)
- end
- end
-end