Commit 9e9ce95d authored by Vinnie Okada's avatar Vinnie Okada

Merge branch 'master' into rails-4.1.9

Conflicts:
	app/views/dashboard/_project.html.haml
	app/views/events/event/_common.html.haml
	app/views/explore/projects/_project.html.haml
	app/views/groups/_projects.html.haml
	app/views/projects/_home_panel.html.haml
	app/views/projects/_issues_nav.html.haml
	app/views/projects/issues/_discussion.html.haml
	app/views/projects/issues/_issues.html.haml
	app/views/projects/issues/show.html.haml
	app/views/projects/merge_requests/_discussion.html.haml
	app/views/projects/merge_requests/_show.html.haml
	app/views/projects/milestones/index.html.haml
	app/views/projects/notes/_edit_form.html.haml
	app/views/shared/_issuable_filter.html.haml
parents 76aad9b7 de040ffa
v 7.9.0 (unreleased)
- Fix broken access control for note attachments (Hannes Rosenögger)
v 7.8.0 (unreleased) v 7.8.0 (unreleased)
- Replace highlight.js with rouge-fork rugments (Stefan Tatschner) - Replace highlight.js with rouge-fork rugments (Stefan Tatschner)
- Make project search case insensitive (Hannes Rosenögger) - Make project search case insensitive (Hannes Rosenögger)
...@@ -10,7 +13,7 @@ v 7.8.0 (unreleased) ...@@ -10,7 +13,7 @@ v 7.8.0 (unreleased)
- View note image attachments in new tab when clicked instead of downloading them - View note image attachments in new tab when clicked instead of downloading them
- Improve sorting logic in UI and API. Explicitly define what sorting method is used by default - Improve sorting logic in UI and API. Explicitly define what sorting method is used by default
- Allow more variations for commit messages closing issues (Julien Bianchi and Hannes Rosenögger) - Allow more variations for commit messages closing issues (Julien Bianchi and Hannes Rosenögger)
- Fix overflow at sidebar when have several itens - Fix overflow at sidebar when have several items
- Add notes for label changes in issue and merge requests - Add notes for label changes in issue and merge requests
- Show tags in commit view (Hannes Rosenögger) - Show tags in commit view (Hannes Rosenögger)
- Only count a user's vote once on a merge request or issue (Michael Clarke) - Only count a user's vote once on a merge request or issue (Michael Clarke)
...@@ -54,6 +57,13 @@ v 7.8.0 (unreleased) ...@@ -54,6 +57,13 @@ v 7.8.0 (unreleased)
- Link head panel titles to relevant root page. - Link head panel titles to relevant root page.
- Allow users that signed up via OAuth to set their password in order to use Git over HTTP(S). - Allow users that signed up via OAuth to set their password in order to use Git over HTTP(S).
- Upgrade Rails gem to version 4.1.9. - Upgrade Rails gem to version 4.1.9.
- Show users button to share their newly created public or internal projects on twitter
- Add quick help links to the GitLab pricing and feature comparison pages.
- Fix duplicate authorized applications in user profile and incorrect application client count in admin area.
- Make sure Markdown previews always use the same styling as the eventual destination.
- Remove deprecated Group#owner_id from API
- Show projects user contributed to on user page. Show stars near project on user page.
- Improve database performance for GitLab
v 7.7.2 v 7.7.2
- Update GitLab Shell to version 2.4.2 that fixes a bug when developers can push to protected branch - Update GitLab Shell to version 2.4.2 that fixes a bug when developers can push to protected branch
......
...@@ -47,6 +47,9 @@ GEM ...@@ -47,6 +47,9 @@ GEM
astrolabe (1.3.0) astrolabe (1.3.0)
parser (>= 2.2.0.pre.3, < 3.0) parser (>= 2.2.0.pre.3, < 3.0)
attr_required (1.0.0) attr_required (1.0.0)
autoprefixer-rails (5.1.6)
execjs
json
awesome_print (1.2.0) awesome_print (1.2.0)
axiom-types (0.0.5) axiom-types (0.0.5)
descendants_tracker (~> 0.0.1) descendants_tracker (~> 0.0.1)
...@@ -57,8 +60,9 @@ GEM ...@@ -57,8 +60,9 @@ GEM
erubis (>= 2.6.6) erubis (>= 2.6.6)
binding_of_caller (0.7.2) binding_of_caller (0.7.2)
debug_inspector (>= 0.0.1) debug_inspector (>= 0.0.1)
bootstrap-sass (3.0.3.0) bootstrap-sass (3.3.3)
sass (~> 3.2) autoprefixer-rails (>= 5.0.0.1)
sass (>= 3.2.19)
browser (0.7.2) browser (0.7.2)
builder (3.2.2) builder (3.2.2)
cal-heatmap-rails (0.0.1) cal-heatmap-rails (0.0.1)
......
...@@ -71,7 +71,7 @@ Thanks for the issue report. Please reformat your issue to conform to the issue ...@@ -71,7 +71,7 @@ Thanks for the issue report. Please reformat your issue to conform to the issue
### Feature requests ### Feature requests
Thank you for your interest in improving GitLab. We don't use the issue tracker for feature requests. Things that are wrong but are not a regression compared to older versions of GitLab are considered feature requests and not issues. Please use the [feature request forum](http://feedback.gitlab.com/) for this purpose or create a merge request implementing this feature. Have a look at the \[contribution guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) for more information. Thank you for your interest in improving GitLab. We don't use the issue tracker for feature requests. Things that are wrong but are not a regression compared to older versions of GitLab are considered feature requests and not issues. Please use the \[feature request forum\]\(http://feedback.gitlab.com/) for this purpose or create a merge request implementing this feature. Have a look at the \[contribution guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) for more information.
### Issue report for old version ### Issue report for old version
......
...@@ -60,7 +60,7 @@ Please see the [requirements documentation](doc/install/requirements.md) for sys ...@@ -60,7 +60,7 @@ Please see the [requirements documentation](doc/install/requirements.md) for sys
## Installation ## Installation
The recommended way to install GitLab is using the provided [Omnibus packages](https://about.gitlab.com/downloads/). Compared to a manual installation, this is faster and less error prone. Just select your operating system, download the respective package (Debian or RPM) and install it using the system's package manager. The recommended way to install GitLab is using the provided [Omnibus packages](https://about.gitlab.com/downloads/). Compared to an installation from source, this is faster and less error prone. Just select your operating system, download the respective package (Debian or RPM) and install it using the system's package manager.
There are various other options to install GitLab, please refer to the [installation page on the GitLab website](https://about.gitlab.com/installation/) for more information. There are various other options to install GitLab, please refer to the [installation page on the GitLab website](https://about.gitlab.com/installation/) for more information.
...@@ -76,7 +76,7 @@ Since 2011 a minor or major version of GitLab is released on the 22nd of every m ...@@ -76,7 +76,7 @@ Since 2011 a minor or major version of GitLab is released on the 22nd of every m
## Upgrading ## Upgrading
For updating the Omnibus installation please see the [update documentation](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/update.md). For manual installations there is an [upgrader script](doc/update/upgrader.md) and there are [upgrade guides](doc/update) detailing all necessary commands to migrate to the next version. For updating the Omnibus installation please see the [update documentation](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/update.md). For installations from source there is an [upgrader script](doc/update/upgrader.md) and there are [upgrade guides](doc/update) detailing all necessary commands to migrate to the next version.
## Install a development environment ## Install a development environment
......
7.8.0.pre 7.9.0.pre
...@@ -15,3 +15,9 @@ class @Issue ...@@ -15,3 +15,9 @@ class @Issue
"issue" "issue"
updateTaskState updateTaskState
) )
$('.issuable-affix').affix offset:
top: ->
@top = $('.issue-details').outerHeight(true) + 25
bottom: ->
@bottom = $('.footer').outerHeight(true)
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
$(this).html totalIssues + 1 $(this).html totalIssues + 1
else else
$(this).html totalIssues - 1 $(this).html totalIssues - 1
$("body").on "click", ".issues-filters .dropdown-menu a", -> $("body").on "click", ".issues-other-filters .dropdown-menu a", ->
$('.issues-list').block( $('.issues-list').block(
message: null, message: null,
overlayCSS: overlayCSS:
...@@ -77,9 +77,9 @@ ...@@ -77,9 +77,9 @@
ids.push $(value).attr("data-id") ids.push $(value).attr("data-id")
$("#update_issues_ids").val ids $("#update_issues_ids").val ids
$(".issues-filters").hide() $(".issues-other-filters").hide()
$(".issues_bulk_update").show() $(".issues_bulk_update").show()
else else
$("#update_issues_ids").val [] $("#update_issues_ids").val []
$(".issues_bulk_update").hide() $(".issues_bulk_update").hide()
$(".issues-filters").show() $(".issues-other-filters").show()
...@@ -20,6 +20,12 @@ class @MergeRequest ...@@ -20,6 +20,12 @@ class @MergeRequest
if $("a.btn-close").length if $("a.btn-close").length
$("li.task-list-item input:checkbox").prop("disabled", false) $("li.task-list-item input:checkbox").prop("disabled", false)
$('.issuable-affix').affix offset:
top: ->
@top = $('.merge-request-details').outerHeight(true) + 70
bottom: ->
@bottom = $('.footer').outerHeight(true)
# Local jQuery finder # Local jQuery finder
$: (selector) -> $: (selector) ->
this.$el.find(selector) this.$el.find(selector)
......
...@@ -77,7 +77,7 @@ class @Notes ...@@ -77,7 +77,7 @@ class @Notes
$(document).off "click", ".js-discussion-reply-button" $(document).off "click", ".js-discussion-reply-button"
$(document).off "click", ".js-add-diff-note-button" $(document).off "click", ".js-add-diff-note-button"
$(document).off "visibilitychange" $(document).off "visibilitychange"
$(document).off "keypress", @notes_forms $(document).off "keydown", @notes_forms
$(document).off "keyup", ".js-note-text" $(document).off "keyup", ".js-note-text"
$(document).off "click", ".js-note-target-reopen" $(document).off "click", ".js-note-target-reopen"
$(document).off "click", ".js-note-target-close" $(document).off "click", ".js-note-target-close"
...@@ -272,7 +272,7 @@ class @Notes ...@@ -272,7 +272,7 @@ class @Notes
note_li = $(".note-row-" + note.id) note_li = $(".note-row-" + note.id)
note_li.replaceWith(note.html) note_li.replaceWith(note.html)
note_li.find('.note-edit-form').hide() note_li.find('.note-edit-form').hide()
note_li.find('.note-text').show() note_li.find('.note-body > .note-text').show()
### ###
Called in response to clicking the edit note link Called in response to clicking the edit note link
...@@ -284,7 +284,7 @@ class @Notes ...@@ -284,7 +284,7 @@ class @Notes
showEditForm: (e) -> showEditForm: (e) ->
e.preventDefault() e.preventDefault()
note = $(this).closest(".note") note = $(this).closest(".note")
note.find(".note-text").hide() note.find(".note-body > .note-text").hide()
note.find(".note-header").hide() note.find(".note-header").hide()
base_form = note.find(".note-edit-form") base_form = note.find(".note-edit-form")
form = base_form.clone().insertAfter(base_form) form = base_form.clone().insertAfter(base_form)
...@@ -311,7 +311,7 @@ class @Notes ...@@ -311,7 +311,7 @@ class @Notes
cancelEdit: (e) -> cancelEdit: (e) ->
e.preventDefault() e.preventDefault()
note = $(this).closest(".note") note = $(this).closest(".note")
note.find(".note-text").show() note.find(".note-body > .note-text").show()
note.find(".note-header").show() note.find(".note-header").show()
note.find(".current-note-edit-form").remove() note.find(".current-note-edit-form").remove()
...@@ -345,7 +345,7 @@ class @Notes ...@@ -345,7 +345,7 @@ class @Notes
removeAttachment: -> removeAttachment: ->
note = $(this).closest(".note") note = $(this).closest(".note")
note.find(".note-attachment").remove() note.find(".note-attachment").remove()
note.find(".note-text").show() note.find(".note-body > .note-text").show()
note.find(".js-note-attachment-delete").hide() note.find(".js-note-attachment-delete").hide()
note.find(".note-edit-form").hide() note.find(".note-edit-form").hide()
......
...@@ -17,6 +17,10 @@ h3.page-title { ...@@ -17,6 +17,10 @@ h3.page-title {
font-size: 22px; font-size: 22px;
} }
h4.page-title {
margin-top: 0px;
}
h6 { h6 {
color: #888; color: #888;
text-transform: uppercase; text-transform: uppercase;
...@@ -131,4 +135,4 @@ textarea.js-gfm-input { ...@@ -131,4 +135,4 @@ textarea.js-gfm-input {
.strikethrough { .strikethrough {
text-decoration: line-through; text-decoration: line-through;
} }
\ No newline at end of file
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
border-left: 1px solid #666; border-left: 1px solid #666;
} }
// highlight line via anchor
pre.hll { pre.hll {
background-color: #fff !important; background-color: #fff !important;
} }
......
...@@ -12,6 +12,11 @@ ...@@ -12,6 +12,11 @@
border-left: 1px solid #555; border-left: 1px solid #555;
} }
// highlight line via anchor
pre.hll {
background-color: #49483e !important;
}
.hll { background-color: #49483e } .hll { background-color: #49483e }
.c { color: #75715e } /* Comment */ .c { color: #75715e } /* Comment */
.err { color: #960050; background-color: #1e0010 } /* Error */ .err { color: #960050; background-color: #1e0010 } /* Error */
......
...@@ -12,6 +12,11 @@ ...@@ -12,6 +12,11 @@
border-left: 1px solid #113b46; border-left: 1px solid #113b46;
} }
// highlight line via anchor
pre.hll {
background-color: #073642 !important;
}
/* Solarized Dark /* Solarized Dark
For use with Jekyll and Pygments For use with Jekyll and Pygments
......
...@@ -12,6 +12,11 @@ ...@@ -12,6 +12,11 @@
border-left: 1px solid #c5d0d4; border-left: 1px solid #c5d0d4;
} }
// highlight line via anchor
pre.hll {
background-color: #eee8d5 !important;
}
/* Solarized Light /* Solarized Light
For use with Jekyll and Pygments For use with Jekyll and Pygments
......
...@@ -12,6 +12,11 @@ ...@@ -12,6 +12,11 @@
border-left: 1px solid #bbb; border-left: 1px solid #bbb;
} }
// highlight line via anchor
pre.hll {
background-color: #f8eec7 !important;
}
.hll { background-color: #f8f8f8 } .hll { background-color: #f8f8f8 }
.c { color: #999988; font-style: italic; } .c { color: #999988; font-style: italic; }
.err { color: #a61717; background-color: #e3d2d2; } .err { color: #a61717; background-color: #e3d2d2; }
......
...@@ -120,6 +120,15 @@ ...@@ -120,6 +120,15 @@
} }
} }
.dash-new-group {
background: $bg_success;
border: 1px solid $border_success;
a {
color: #FFF;
}
}
.dash-list .str-truncated { .dash-list .str-truncated {
max-width: 72%; max-width: 72%;
} }
...@@ -64,6 +64,10 @@ ...@@ -64,6 +64,10 @@
.md { .md {
font-size: 13px; font-size: 13px;
iframe.twitter-share-button {
vertical-align: bottom;
}
} }
pre { pre {
......
@media (max-width: $screen-sm-max) {
.issuable-affix {
margin-top: 20px;
}
}
@media (max-width: $screen-md-max) {
.issuable-affix {
position: static;
}
}
@media (min-width: $screen-md-max) {
.issuable-affix {
&.affix-top {
position: static;
}
&.affix {
position: fixed;
top: 70px;
width: 220px;
}
}
}
...@@ -94,8 +94,15 @@ ...@@ -94,8 +94,15 @@
} }
} }
.issue-show-labels .color-label { .issue-show-labels {
padding: 6px 10px; a {
margin-right: 5px;
margin-bottom: 5px;
display: inline-block;
.color-label {
padding: 6px 10px;
}
}
} }
form.edit-issue { form.edit-issue {
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
.accept-control { .accept-control {
display: inline-block; display: inline-block;
margin: 0;
margin-left: 20px; margin-left: 20px;
padding: 10px 0; padding: 10px 0;
line-height: 20px; line-height: 20px;
...@@ -31,6 +32,7 @@ ...@@ -31,6 +32,7 @@
.remove_source_checkbox { .remove_source_checkbox {
margin: 0; margin: 0;
font-weight: bold;
} }
} }
} }
...@@ -185,6 +187,13 @@ ...@@ -185,6 +187,13 @@
} }
} }
.merge-request-show-labels .label { .merge-request-show-labels {
padding: 6px 10px; a {
margin-right: 5px;
margin-bottom: 5px;
display: inline-block;
.color-label {
padding: 6px 10px;
}
}
} }
...@@ -40,12 +40,16 @@ ...@@ -40,12 +40,16 @@
.nav-sidebar li { .nav-sidebar li {
&.active a { &.active a {
color: #111; color: #333;
background: #EEE; background: #FFF;
font-weight: bold; font-weight: bold;
border: 1px solid #EEE;
border-right: 1px solid transparent;
border-left: 3px solid $style_color;
&.no-highlight { &.no-highlight {
background: none; background: none;
border: none;
} }
i { i {
...@@ -65,7 +69,7 @@ ...@@ -65,7 +69,7 @@
color: #555; color: #555;
display: block; display: block;
text-decoration: none; text-decoration: none;
padding: 6px 15px; padding: 8px 15px;
font-size: 13px; font-size: 13px;
line-height: 20px; line-height: 20px;
text-shadow: 0 1px 2px #FFF; text-shadow: 0 1px 2px #FFF;
...@@ -133,7 +137,7 @@ ...@@ -133,7 +137,7 @@
li a { li a {
padding-left: 18px; padding-left: 18px;
font-size: 14px; font-size: 14px;
padding: 10px 15px; padding: 8px 15px;
text-align: center; text-align: center;
& > span { & > span {
......
...@@ -26,6 +26,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController ...@@ -26,6 +26,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:signup_enabled, :signup_enabled,
:signin_enabled, :signin_enabled,
:gravatar_enabled, :gravatar_enabled,
:twitter_sharing_enabled,
:sign_in_text, :sign_in_text,
:home_page_url :home_page_url
) )
......
...@@ -12,11 +12,7 @@ class DashboardController < ApplicationController ...@@ -12,11 +12,7 @@ class DashboardController < ApplicationController
@groups = current_user.authorized_groups.order_name_asc @groups = current_user.authorized_groups.order_name_asc
@has_authorized_projects = @projects.count > 0 @has_authorized_projects = @projects.count > 0
@projects_count = @projects.count @projects_count = @projects.count
@projects = @projects.limit(@projects_limit) @projects = @projects.includes(:namespace).limit(@projects_limit)
@events = Event.in_projects(current_user.authorized_projects.pluck(:id))
@events = @event_filter.apply_filter(@events)
@events = @events.limit(20).offset(params[:offset] || 0)
@last_push = current_user.recent_push @last_push = current_user.recent_push
...@@ -24,8 +20,16 @@ class DashboardController < ApplicationController ...@@ -24,8 +20,16 @@ class DashboardController < ApplicationController
respond_to do |format| respond_to do |format|
format.html format.html
format.json { pager_json("events/_events", @events.count) }
format.atom { render layout: false } format.json do
load_events
pager_json("events/_events", @events.count)
end
format.atom do
load_events
render layout: false
end
end end
end end
...@@ -74,4 +78,10 @@ class DashboardController < ApplicationController ...@@ -74,4 +78,10 @@ class DashboardController < ApplicationController
def load_projects def load_projects
@projects = current_user.authorized_projects.sorted_by_activity.non_archived @projects = current_user.authorized_projects.sorted_by_activity.non_archived
end end
def load_events
@events = Event.in_projects(current_user.authorized_projects.pluck(:id))
@events = @event_filter.apply_filter(@events).with_associations
@events = @events.limit(20).offset(params[:offset] || 0)
end
end end
...@@ -18,7 +18,7 @@ class Explore::ProjectsController < ApplicationController ...@@ -18,7 +18,7 @@ class Explore::ProjectsController < ApplicationController
def starred def starred
@starred_projects = ProjectsFinder.new.execute(current_user) @starred_projects = ProjectsFinder.new.execute(current_user)
@starred_projects = @starred_projects.order('star_count DESC') @starred_projects = @starred_projects.reorder('star_count DESC')
@starred_projects = @starred_projects.page(params[:page]).per(10) @starred_projects = @starred_projects.page(params[:page]).per(10)
end end
end end
...@@ -10,11 +10,11 @@ class GroupsController < ApplicationController ...@@ -10,11 +10,11 @@ class GroupsController < ApplicationController
# Load group projects # Load group projects
before_filter :load_projects, except: [:new, :create, :projects, :edit, :update] before_filter :load_projects, except: [:new, :create, :projects, :edit, :update]
before_filter :event_filter, only: :show
before_filter :set_title, only: [:new, :create]
layout :determine_layout layout :determine_layout
before_filter :set_title, only: [:new, :create]
def new def new
@group = Group.new @group = Group.new
end end
...@@ -32,15 +32,21 @@ class GroupsController < ApplicationController ...@@ -32,15 +32,21 @@ class GroupsController < ApplicationController
end end
def show def show
@events = Event.in_projects(project_ids)
@events = event_filter.apply_filter(@events)
@events = @events.limit(20).offset(params[:offset] || 0)
@last_push = current_user.recent_push if current_user @last_push = current_user.recent_push if current_user
@projects = @projects.includes(:namespace)
respond_to do |format| respond_to do |format|
format.html format.html
format.json { pager_json("events/_events", @events.count) }
format.atom { render layout: false } format.json do
load_events
pager_json("events/_events", @events.count)
end
format.atom do
load_events
render layout: false
end
end end
end end
...@@ -149,4 +155,10 @@ class GroupsController < ApplicationController ...@@ -149,4 +155,10 @@ class GroupsController < ApplicationController
def group_params def group_params
params.require(:group).permit(:name, :description, :path, :avatar) params.require(:group).permit(:name, :description, :path, :avatar)
end end
def load_events
@events = Event.in_projects(project_ids)
@events = event_filter.apply_filter(@events).with_associations
@events = @events.limit(20).offset(params[:offset] || 0)
end
end end
...@@ -16,6 +16,7 @@ class ProfilesController < ApplicationController ...@@ -16,6 +16,7 @@ class ProfilesController < ApplicationController
def applications def applications
@applications = current_user.oauth_applications @applications = current_user.oauth_applications
@authorized_tokens = current_user.oauth_authorized_tokens @authorized_tokens = current_user.oauth_authorized_tokens
@authorized_apps = @authorized_tokens.map(&:application).uniq
end end
def update def update
......
...@@ -27,7 +27,7 @@ class Projects::TagsController < Projects::ApplicationController ...@@ -27,7 +27,7 @@ class Projects::TagsController < Projects::ApplicationController
tag = @repository.find_tag(params[:id]) tag = @repository.find_tag(params[:id])
if tag && @repository.rm_tag(tag.name) if tag && @repository.rm_tag(tag.name)
Event.create_ref_event(@project, current_user, tag, 'rm', 'refs/tags') EventCreateService.new.push_ref(@project, current_user, tag, 'rm', 'refs/tags')
end end
respond_to do |format| respond_to do |format|
......
...@@ -5,9 +5,10 @@ class ProjectsController < ApplicationController ...@@ -5,9 +5,10 @@ class ProjectsController < ApplicationController
# Authorize # Authorize
before_filter :authorize_admin_project!, only: [:edit, :update, :destroy, :transfer, :archive, :unarchive] before_filter :authorize_admin_project!, only: [:edit, :update, :destroy, :transfer, :archive, :unarchive]
before_filter :set_title, only: [:new, :create]
before_filter :event_filter, only: :show
layout 'navless', only: [:new, :create, :fork] layout 'navless', only: [:new, :create, :fork]
before_filter :set_title, only: [:new, :create]
def new def new
@project = Project.new @project = Project.new
...@@ -65,9 +66,6 @@ class ProjectsController < ApplicationController ...@@ -65,9 +66,6 @@ class ProjectsController < ApplicationController
end end
limit = (params[:limit] || 20).to_i limit = (params[:limit] || 20).to_i
@events = @project.events.recent
@events = event_filter.apply_filter(@events)
@events = @events.limit(limit).offset(params[:offset] || 0)
@show_star = !(current_user && current_user.starred?(@project)) @show_star = !(current_user && current_user.starred?(@project))
...@@ -85,7 +83,12 @@ class ProjectsController < ApplicationController ...@@ -85,7 +83,12 @@ class ProjectsController < ApplicationController
end end
end end
format.json { pager_json('events/_events', @events.count) } format.json do
@events = @project.events.recent
@events = event_filter.apply_filter(@events).with_associations
@events = @events.limit(limit).offset(params[:offset] || 0)
pager_json('events/_events', @events.count)
end
end end
end end
......
...@@ -4,19 +4,20 @@ class UsersController < ApplicationController ...@@ -4,19 +4,20 @@ class UsersController < ApplicationController
layout :determine_layout layout :determine_layout
def show def show
# Projects user can view @contributed_projects = Project.
visible_projects = ProjectsFinder.new.execute(current_user) where(id: authorized_projects_ids & @user.contributed_projects_ids).
authorized_projects_ids = visible_projects.pluck(:id) in_group_namespace.includes(:namespace)
@projects = @user.personal_projects. @projects = @user.personal_projects.
where(id: authorized_projects_ids) where(id: authorized_projects_ids).includes(:namespace)
# Collect only groups common for both users # Collect only groups common for both users
@groups = @user.groups & GroupsFinder.new.execute(current_user) @groups = @user.groups & GroupsFinder.new.execute(current_user)
# Get user activity feed for projects common for both users # Get user activity feed for projects common for both users
@events = @user.recent_events. @events = @user.recent_events.
where(project_id: authorized_projects_ids).limit(30) where(project_id: authorized_projects_ids).
with_associations.limit(30)
@title = @user.name @title = @user.name
@title_url = user_path(@user) @title_url = user_path(@user)
...@@ -28,8 +29,8 @@ class UsersController < ApplicationController ...@@ -28,8 +29,8 @@ class UsersController < ApplicationController
end end
def calendar def calendar
visible_projects = ProjectsFinder.new.execute(current_user) projects = Project.where(id: authorized_projects_ids & @user.contributed_projects_ids)
calendar = Gitlab::CommitsCalendar.new(visible_projects, @user) calendar = Gitlab::CommitsCalendar.new(projects, @user)
@timestamps = calendar.timestamps @timestamps = calendar.timestamps
@starting_year = calendar.starting_year @starting_year = calendar.starting_year
@starting_month = calendar.starting_month @starting_month = calendar.starting_month
...@@ -54,4 +55,10 @@ class UsersController < ApplicationController ...@@ -54,4 +55,10 @@ class UsersController < ApplicationController
return authenticate_user! return authenticate_user!
end end
end end
def authorized_projects_ids
# Projects user can view
@authorized_projects_ids ||=
ProjectsFinder.new.execute(current_user).pluck(:id)
end
end end
...@@ -8,7 +8,7 @@ class TrendingProjectsFinder ...@@ -8,7 +8,7 @@ class TrendingProjectsFinder
# for period of time - ex. month # for period of time - ex. month
projects.joins(:notes).where('notes.created_at > ?', start_date). projects.joins(:notes).where('notes.created_at > ?', start_date).
select("projects.*, count(notes.id) as ncount"). select("projects.*, count(notes.id) as ncount").
group("projects.id").order("ncount DESC") group("projects.id").reorder("ncount DESC")
end end
private private
......
...@@ -51,7 +51,13 @@ module ApplicationHelper ...@@ -51,7 +51,13 @@ module ApplicationHelper
end end
def project_icon(project_id, options = {}) def project_icon(project_id, options = {})
project = Project.find_with_namespace(project_id) project =
if project_id.is_a?(Project)
project = project_id
else
Project.find_with_namespace(project_id)
end
if project.avatar.present? if project.avatar.present?
image_tag project.avatar.url, options image_tag project.avatar.url, options
elsif project.avatar_in_git elsif project.avatar_in_git
......
...@@ -3,6 +3,10 @@ module ApplicationSettingsHelper ...@@ -3,6 +3,10 @@ module ApplicationSettingsHelper
current_application_settings.gravatar_enabled? current_application_settings.gravatar_enabled?
end end
def twitter_sharing_enabled?
current_application_settings.twitter_sharing_enabled?
end
def signup_enabled? def signup_enabled?
current_application_settings.signup_enabled? current_application_settings.signup_enabled?
end end
......
...@@ -17,7 +17,7 @@ module BlobHelper ...@@ -17,7 +17,7 @@ module BlobHelper
end end
def no_highlight_files def no_highlight_files
%w(credits changelog copying copyright license authors) %w(credits changelog news copying copyright license authors)
end end
def edit_blob_link(project, ref, path, options = {}) def edit_blob_link(project, ref, path, options = {})
......
...@@ -10,11 +10,15 @@ module EventsHelper ...@@ -10,11 +10,15 @@ module EventsHelper
end end
def event_action_name(event) def event_action_name(event)
target = if event.target_type target = if event.target_type
event.target_type.titleize.downcase if event.note?
else event.note_target_type
'project' else
end event.target_type.titleize.downcase
end
else
'project'
end
[event.action_name, target].join(" ") [event.action_name, target].join(" ")
end end
...@@ -42,21 +46,30 @@ module EventsHelper ...@@ -42,21 +46,30 @@ module EventsHelper
end end
def event_feed_title(event) def event_feed_title(event)
if event.issue? words = []
"#{event.author_name} #{event.action_name} issue ##{event.target_iid}: #{event.issue_title} at #{event.project_name}" words << event.author_name
elsif event.merge_request? words << event_action_name(event)
"#{event.author_name} #{event.action_name} MR ##{event.target_iid}: #{event.merge_request_title} at #{event.project_name}"
elsif event.push? if event.push?
"#{event.author_name} #{event.push_action_name} #{event.ref_type} #{event.ref_name} at #{event.project_name}" words << event.ref_type
elsif event.membership_changed? words << event.ref_name
"#{event.author_name} #{event.action_name} #{event.project_name}" words << "at"
elsif event.note? && event.note_commit? elsif event.commented?
"#{event.author_name} commented on #{event.note_target_type} #{event.note_short_commit_id} at #{event.project_name}" if event.note_commit?
elsif event.note? words << event.note_short_commit_id
"#{event.author_name} commented on #{event.note_target_type} ##{truncate event.note_target_iid} at #{event.project_name}" else
else words << "##{truncate event.note_target_iid}"
"" end
words << "at"
elsif event.target
words << "##{event.target_iid}:"
words << event.target.title if event.target.respond_to?(:title)
words << "at"
end end
words << event.project_name
words.join(" ")
end end
def event_feed_url(event) def event_feed_url(event)
...@@ -106,8 +119,6 @@ module EventsHelper ...@@ -106,8 +119,6 @@ module EventsHelper
render "events/event_push", event: event render "events/event_push", event: event
elsif event.merge_request? elsif event.merge_request?
render "events/event_merge_request", merge_request: event.merge_request render "events/event_merge_request", merge_request: event.merge_request
elsif event.push?
render "events/event_push", event: event
elsif event.note? elsif event.note?
render "events/event_note", note: event.note render "events/event_note", note: event.note
end end
......
...@@ -110,7 +110,7 @@ module GitlabMarkdownHelper ...@@ -110,7 +110,7 @@ module GitlabMarkdownHelper
end end
def link_to_ignore?(link) def link_to_ignore?(link)
if link =~ /\#\w+/ if link =~ /\A\#\w+/
# ignore anchors like <a href="#my-header"> # ignore anchors like <a href="#my-header">
true true
else else
...@@ -122,10 +122,11 @@ module GitlabMarkdownHelper ...@@ -122,10 +122,11 @@ module GitlabMarkdownHelper
["http://","https://", "ftp://", "mailto:"] ["http://","https://", "ftp://", "mailto:"]
end end
def rebuild_path(path) def rebuild_path(file_path)
path.gsub!(/(#.*)/, "") file_path = file_path.dup
file_path.gsub!(/(#.*)/, "")
id = $1 || "" id = $1 || ""
file_path = relative_file_path(path) file_path = relative_file_path(file_path)
file_path = sanitize_slashes(file_path) file_path = sanitize_slashes(file_path)
[ [
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
# signup_enabled :boolean # signup_enabled :boolean
# signin_enabled :boolean # signin_enabled :boolean
# gravatar_enabled :boolean # gravatar_enabled :boolean
# twitter_sharing_enabled :boolean
# sign_in_text :text # sign_in_text :text
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
...@@ -30,6 +31,7 @@ class ApplicationSetting < ActiveRecord::Base ...@@ -30,6 +31,7 @@ class ApplicationSetting < ActiveRecord::Base
default_branch_protection: Settings.gitlab['default_branch_protection'], default_branch_protection: Settings.gitlab['default_branch_protection'],
signup_enabled: Settings.gitlab['signup_enabled'], signup_enabled: Settings.gitlab['signup_enabled'],
signin_enabled: Settings.gitlab['signin_enabled'], signin_enabled: Settings.gitlab['signin_enabled'],
twitter_sharing_enabled: Settings.gitlab['twitter_sharing_enabled'],
gravatar_enabled: Settings.gravatar['enabled'], gravatar_enabled: Settings.gravatar['enabled'],
sign_in_text: Settings.extra['sign_in_text'], sign_in_text: Settings.extra['sign_in_text'],
) )
......
...@@ -47,31 +47,9 @@ class Event < ActiveRecord::Base ...@@ -47,31 +47,9 @@ class Event < ActiveRecord::Base
scope :recent, -> { order("created_at DESC") } scope :recent, -> { order("created_at DESC") }
scope :code_push, -> { where(action: PUSHED) } scope :code_push, -> { where(action: PUSHED) }
scope :in_projects, ->(project_ids) { where(project_id: project_ids).recent } scope :in_projects, ->(project_ids) { where(project_id: project_ids).recent }
scope :with_associations, -> { includes(project: :namespace) }
class << self class << self
def create_ref_event(project, user, ref, action = 'add', prefix = 'refs/heads')
commit = project.repository.commit(ref.target)
if action.to_s == 'add'
before = '00000000'
after = commit.id
else
before = commit.id
after = '00000000'
end
Event.create(
project: project,
action: Event::PUSHED,
data: {
ref: "#{prefix}/#{ref.name}",
before: before,
after: after
},
author_id: user.id
)
end
def reset_event_cache_for(target) def reset_event_cache_for(target)
Event.where(target_id: target.id, target_type: target.class.to_s). Event.where(target_id: target.id, target_type: target.class.to_s).
order('id DESC').limit(100). order('id DESC').limit(100).
...@@ -84,6 +62,8 @@ class Event < ActiveRecord::Base ...@@ -84,6 +62,8 @@ class Event < ActiveRecord::Base
true true
elsif membership_changed? elsif membership_changed?
true true
elsif created_project?
true
else else
(issue? || merge_request? || note? || milestone?) && target (issue? || merge_request? || note? || milestone?) && target
end end
...@@ -98,25 +78,51 @@ class Event < ActiveRecord::Base ...@@ -98,25 +78,51 @@ class Event < ActiveRecord::Base
end end
def target_title def target_title
if target && target.respond_to?(:title) target.title if target && target.respond_to?(:title)
target.title end
end
def created?
action == CREATED
end end
def push? def push?
action == self.class::PUSHED && valid_push? action == PUSHED && valid_push?
end end
def merged? def merged?
action == self.class::MERGED action == MERGED
end end
def closed? def closed?
action == self.class::CLOSED action == CLOSED
end end
def reopened? def reopened?
action == self.class::REOPENED action == REOPENED
end
def joined?
action == JOINED
end
def left?
action == LEFT
end
def commented?
action == COMMENTED
end
def membership_changed?
joined? || left?
end
def created_project?
created? && !target
end
def created_target?
created? && target
end end
def milestone? def milestone?
...@@ -135,32 +141,32 @@ class Event < ActiveRecord::Base ...@@ -135,32 +141,32 @@ class Event < ActiveRecord::Base
target_type == "MergeRequest" target_type == "MergeRequest"
end end
def joined? def milestone
action == JOINED target if milestone?
end
def left?
action == LEFT
end
def membership_changed?
joined? || left?
end end
def issue def issue
target if target_type == "Issue" target if issue?
end end
def merge_request def merge_request
target if target_type == "MergeRequest" target if merge_request?
end end
def note def note
target if target_type == "Note" target if note?
end end
def action_name def action_name
if closed? if push?
if new_ref?
"pushed new"
elsif rm_ref?
"deleted"
else
"pushed to"
end
elsif closed?
"closed" "closed"
elsif merged? elsif merged?
"accepted" "accepted"
...@@ -168,6 +174,10 @@ class Event < ActiveRecord::Base ...@@ -168,6 +174,10 @@ class Event < ActiveRecord::Base
'joined' 'joined'
elsif left? elsif left?
'left' 'left'
elsif commented?
"commented on"
elsif created_project?
"created"
else else
"opened" "opened"
end end
...@@ -236,16 +246,6 @@ class Event < ActiveRecord::Base ...@@ -236,16 +246,6 @@ class Event < ActiveRecord::Base
tag? ? "tag" : "branch" tag? ? "tag" : "branch"
end end
def push_action_name
if new_ref?
"pushed new"
elsif rm_ref?
"deleted"
else
"pushed to"
end
end
def push_with_commits? def push_with_commits?
md_ref? && commits.any? && commit_from && commit_to md_ref? && commits.any? && commit_from && commit_to
end end
......
...@@ -114,13 +114,11 @@ class ProjectMember < Member ...@@ -114,13 +114,11 @@ class ProjectMember < Member
end end
def post_create_hook def post_create_hook
Event.create( unless owner?
project_id: self.project.id, event_service.join_project(self.project, self.user)
action: Event::JOINED, notification_service.new_team_member(self)
author_id: self.user.id end
)
notification_service.new_team_member(self) unless owner?
system_hook_service.execute_hooks_for(self, :create) system_hook_service.execute_hooks_for(self, :create)
end end
...@@ -129,15 +127,14 @@ class ProjectMember < Member ...@@ -129,15 +127,14 @@ class ProjectMember < Member
end end
def post_destroy_hook def post_destroy_hook
Event.create( event_service.leave_project(self.project, self.user)
project_id: self.project.id,
action: Event::LEFT,
author_id: self.user.id
)
system_hook_service.execute_hooks_for(self, :destroy) system_hook_service.execute_hooks_for(self, :destroy)
end end
def event_service
EventCreateService.new
end
def notification_service def notification_service
NotificationService.new NotificationService.new
end end
......
...@@ -55,14 +55,13 @@ class User < ActiveRecord::Base ...@@ -55,14 +55,13 @@ class User < ActiveRecord::Base
include Gitlab::ConfigHelper include Gitlab::ConfigHelper
include TokenAuthenticatable include TokenAuthenticatable
extend Gitlab::ConfigHelper extend Gitlab::ConfigHelper
extend Gitlab::CurrentSettings include Gitlab::CurrentSettings
default_value_for :admin, false default_value_for :admin, false
default_value_for :can_create_group, gitlab_config.default_can_create_group default_value_for :can_create_group, gitlab_config.default_can_create_group
default_value_for :can_create_team, false default_value_for :can_create_team, false
default_value_for :hide_no_ssh_key, false default_value_for :hide_no_ssh_key, false
default_value_for :hide_no_password, false default_value_for :hide_no_password, false
default_value_for :projects_limit, current_application_settings.default_projects_limit
default_value_for :theme_id, gitlab_config.default_theme default_value_for :theme_id, gitlab_config.default_theme
devise :database_authenticatable, :lockable, :async, devise :database_authenticatable, :lockable, :async,
...@@ -141,6 +140,7 @@ class User < ActiveRecord::Base ...@@ -141,6 +140,7 @@ class User < ActiveRecord::Base
before_save :ensure_authentication_token before_save :ensure_authentication_token
after_save :ensure_namespace_correct after_save :ensure_namespace_correct
after_initialize :set_projects_limit
after_create :post_create_hook after_create :post_create_hook
after_destroy :post_destroy_hook after_destroy :post_destroy_hook
...@@ -255,7 +255,7 @@ class User < ActiveRecord::Base ...@@ -255,7 +255,7 @@ class User < ActiveRecord::Base
counter = 0 counter = 0
base = username base = username
while User.by_login(username).present? || Namespace.by_path(username).present? while User.by_login(username).present? || Namespace.by_path(username).present?
counter += 1 counter += 1
username = "#{base}#{counter}" username = "#{base}#{counter}"
end end
...@@ -459,10 +459,17 @@ class User < ActiveRecord::Base ...@@ -459,10 +459,17 @@ class User < ActiveRecord::Base
def set_notification_email def set_notification_email
if self.notification_email.blank? || !self.all_emails.include?(self.notification_email) if self.notification_email.blank? || !self.all_emails.include?(self.notification_email)
self.notification_email = self.email self.notification_email = self.email
end end
end end
def set_projects_limit
connection_default_value_defined = new_record? && !projects_limit_changed?
return unless self.projects_limit.nil? || connection_default_value_defined
self.projects_limit = current_application_settings.default_projects_limit
end
def requires_ldap_check? def requires_ldap_check?
if !Gitlab.config.ldap.enabled if !Gitlab.config.ldap.enabled
false false
...@@ -559,7 +566,7 @@ class User < ActiveRecord::Base ...@@ -559,7 +566,7 @@ class User < ActiveRecord::Base
def post_create_hook def post_create_hook
log_info("User \"#{self.name}\" (#{self.email}) was created") log_info("User \"#{self.name}\" (#{self.email}) was created")
notification_service.new_user(self, @reset_token) notification_service.new_user(self, @reset_token) if self.created_by_id
system_hook_service.execute_hooks_for(self, :create) system_hook_service.execute_hooks_for(self, :create)
end end
...@@ -607,4 +614,13 @@ class User < ActiveRecord::Base ...@@ -607,4 +614,13 @@ class User < ActiveRecord::Base
def oauth_authorized_tokens def oauth_authorized_tokens
Doorkeeper::AccessToken.where(resource_owner_id: self.id, revoked_at: nil) Doorkeeper::AccessToken.where(resource_owner_id: self.id, revoked_at: nil)
end end
def contributed_projects_ids
Event.where(author_id: self).
where("created_at > ?", Time.now - 1.year).
code_push.
reorder(project_id: :desc).
select('DISTINCT(project_id)').
map(&:project_id)
end
end end
...@@ -17,7 +17,7 @@ class CreateBranchService < BaseService ...@@ -17,7 +17,7 @@ class CreateBranchService < BaseService
new_branch = repository.find_branch(branch_name) new_branch = repository.find_branch(branch_name)
if new_branch if new_branch
Event.create_ref_event(project, current_user, new_branch, 'add') EventCreateService.new.push_ref(project, current_user, new_branch, 'add')
return success(new_branch) return success(new_branch)
else else
return error('Invalid reference name') return error('Invalid reference name')
......
...@@ -26,7 +26,7 @@ class CreateTagService < BaseService ...@@ -26,7 +26,7 @@ class CreateTagService < BaseService
project.gitlab_ci_service.async_execute(push_data) project.gitlab_ci_service.async_execute(push_data)
end end
Event.create_ref_event(project, current_user, new_tag, 'add', 'refs/tags') EventCreateService.new.push_ref(project, current_user, new_tag, 'add', 'refs/tags')
success(new_tag) success(new_tag)
else else
error('Invalid reference name') error('Invalid reference name')
......
...@@ -25,7 +25,7 @@ class DeleteBranchService < BaseService ...@@ -25,7 +25,7 @@ class DeleteBranchService < BaseService
end end
if repository.rm_branch(branch_name) if repository.rm_branch(branch_name)
Event.create_ref_event(project, current_user, branch, 'rm') EventCreateService.new.push_ref(project, current_user, branch, 'rm')
success('Branch was removed') success('Branch was removed')
else else
return error('Failed to remove branch') return error('Failed to remove branch')
......
...@@ -7,58 +7,98 @@ ...@@ -7,58 +7,98 @@
# #
class EventCreateService class EventCreateService
def open_issue(issue, current_user) def open_issue(issue, current_user)
create_event(issue, current_user, Event::CREATED) create_record_event(issue, current_user, Event::CREATED)
end end
def close_issue(issue, current_user) def close_issue(issue, current_user)
create_event(issue, current_user, Event::CLOSED) create_record_event(issue, current_user, Event::CLOSED)
end end
def reopen_issue(issue, current_user) def reopen_issue(issue, current_user)
create_event(issue, current_user, Event::REOPENED) create_record_event(issue, current_user, Event::REOPENED)
end end
def open_mr(merge_request, current_user) def open_mr(merge_request, current_user)
create_event(merge_request, current_user, Event::CREATED) create_record_event(merge_request, current_user, Event::CREATED)
end end
def close_mr(merge_request, current_user) def close_mr(merge_request, current_user)
create_event(merge_request, current_user, Event::CLOSED) create_record_event(merge_request, current_user, Event::CLOSED)
end end
def reopen_mr(merge_request, current_user) def reopen_mr(merge_request, current_user)
create_event(merge_request, current_user, Event::REOPENED) create_record_event(merge_request, current_user, Event::REOPENED)
end end
def merge_mr(merge_request, current_user) def merge_mr(merge_request, current_user)
create_event(merge_request, current_user, Event::MERGED) create_record_event(merge_request, current_user, Event::MERGED)
end end
def open_milestone(milestone, current_user) def open_milestone(milestone, current_user)
create_event(milestone, current_user, Event::CREATED) create_record_event(milestone, current_user, Event::CREATED)
end end
def close_milestone(milestone, current_user) def close_milestone(milestone, current_user)
create_event(milestone, current_user, Event::CLOSED) create_record_event(milestone, current_user, Event::CLOSED)
end end
def reopen_milestone(milestone, current_user) def reopen_milestone(milestone, current_user)
create_event(milestone, current_user, Event::REOPENED) create_record_event(milestone, current_user, Event::REOPENED)
end end
def leave_note(note, current_user) def leave_note(note, current_user)
create_event(note, current_user, Event::COMMENTED) create_record_event(note, current_user, Event::COMMENTED)
end
def join_project(project, current_user)
create_event(project, current_user, Event::JOINED)
end
def leave_project(project, current_user)
create_event(project, current_user, Event::LEFT)
end
def create_project(project, current_user)
create_event(project, current_user, Event::CREATED)
end
def push_ref(project, current_user, ref, action = 'add', prefix = 'refs/heads')
commit = project.repository.commit(ref.target)
if action.to_s == 'add'
before = '00000000'
after = commit.id
else
before = commit.id
after = '00000000'
end
data = {
ref: "#{prefix}/#{ref.name}",
before: before,
after: after
}
push(project, current_user, data)
end
def push(project, current_user, push_data)
create_event(project, current_user, Event::PUSHED, data: push_data)
end end
private private
def create_event(record, current_user, status) def create_record_event(record, current_user, status)
Event.create( create_event(record.project, current_user, status, target_id: record.id, target_type: record.class.name)
project: record.project, end
target_id: record.id,
target_type: record.class.name, def create_event(project, current_user, status, attributes = {})
attributes.reverse_merge!(
project: project,
action: status, action: status,
author_id: current_user.id author_id: current_user.id
) )
Event.create(attributes)
end end
end end
...@@ -52,7 +52,7 @@ class GitPushService ...@@ -52,7 +52,7 @@ class GitPushService
end end
@push_data = post_receive_data(oldrev, newrev, ref) @push_data = post_receive_data(oldrev, newrev, ref)
create_push_event(@push_data) EventCreateService.new.push(project, user, @push_data)
project.execute_hooks(@push_data.dup, :push_hooks) project.execute_hooks(@push_data.dup, :push_hooks)
project.execute_services(@push_data.dup) project.execute_services(@push_data.dup)
end end
...@@ -60,15 +60,6 @@ class GitPushService ...@@ -60,15 +60,6 @@ class GitPushService
protected protected
def create_push_event(push_data)
Event.create!(
project: project,
action: Event::PUSHED,
data: push_data,
author_id: push_data[:user_id]
)
end
# Extract any GFM references from the pushed commit messages. If the configured issue-closing regex is matched, # Extract any GFM references from the pushed commit messages. If the configured issue-closing regex is matched,
# close the referenced Issue. Create cross-reference Notes corresponding to any other referenced Mentionables. # close the referenced Issue. Create cross-reference Notes corresponding to any other referenced Mentionables.
def process_commit_messages(ref) def process_commit_messages(ref)
......
...@@ -5,7 +5,7 @@ class GitTagPushService ...@@ -5,7 +5,7 @@ class GitTagPushService
@project, @user = project, user @project, @user = project, user
@push_data = create_push_data(oldrev, newrev, ref) @push_data = create_push_data(oldrev, newrev, ref)
create_push_event EventCreateService.new.push(project, user, @push_data)
project.repository.expire_cache project.repository.expire_cache
project.execute_hooks(@push_data.dup, :tag_push_hooks) project.execute_hooks(@push_data.dup, :tag_push_hooks)
...@@ -22,13 +22,4 @@ class GitTagPushService ...@@ -22,13 +22,4 @@ class GitTagPushService
Gitlab::PushDataBuilder. Gitlab::PushDataBuilder.
build(project, user, oldrev, newrev, ref, []) build(project, user, oldrev, newrev, ref, [])
end end
def create_push_event
Event.create!(
project: project,
action: Event::PUSHED,
data: push_data,
author_id: push_data[:user_id]
)
end
end end
...@@ -52,13 +52,7 @@ module Projects ...@@ -52,13 +52,7 @@ module Projects
end end
end end
if @project.persisted? after_create_actions if @project.persisted?
if @project.wiki_enabled?
@project.create_wiki
end
after_create_actions
end
@project @project
rescue => ex rescue => ex
...@@ -79,6 +73,10 @@ module Projects ...@@ -79,6 +73,10 @@ module Projects
def after_create_actions def after_create_actions
log_info("#{@project.owner.name} created a new project \"#{@project.name_with_namespace}\"") log_info("#{@project.owner.name} created a new project \"#{@project.name_with_namespace}\"")
@project.create_wiki if @project.wiki_enabled?
event_service.create_project(@project, current_user)
system_hook_service.execute_hooks_for(@project, :create) system_hook_service.execute_hooks_for(@project, :create)
unless @project.group unless @project.group
......
...@@ -19,6 +19,11 @@ ...@@ -19,6 +19,11 @@
= f.label :gravatar_enabled, class: 'control-label' = f.label :gravatar_enabled, class: 'control-label'
.col-sm-10 .col-sm-10
= f.check_box :gravatar_enabled, class: 'checkbox' = f.check_box :gravatar_enabled, class: 'checkbox'
.form-group
= f.label :twitter_sharing_enabled, "Twitter enabled", class: 'control-label'
.col-sm-10
= f.check_box :twitter_sharing_enabled, class: 'checkbox'
%span.help-block Show users button to share their newly created public or internal projects on twitter
%fieldset %fieldset
%legend Misc %legend Misc
.form-group .form-group
......
...@@ -17,6 +17,6 @@ ...@@ -17,6 +17,6 @@
%tr{:id => "application_#{application.id}"} %tr{:id => "application_#{application.id}"}
%td= link_to application.name, admin_application_path(application) %td= link_to application.name, admin_application_path(application)
%td= application.redirect_uri %td= application.redirect_uri
%td= application.access_tokens.count %td= application.access_tokens.map(&:resource_owner_id).uniq.count
%td= link_to 'Edit', edit_admin_application_path(application), class: 'btn btn-link' %td= link_to 'Edit', edit_admin_application_path(application), class: 'btn btn-link'
%td= render 'delete_form', application: application %td= render 'delete_form', application: application
...@@ -13,15 +13,13 @@ ...@@ -13,15 +13,13 @@
.form-group .form-group
%strong Activity %strong Activity
.checkbox .checkbox
= label_tag :with_push, 'Not empty' = label_tag :with_push do
= check_box_tag :with_push, 1, params[:with_push] = check_box_tag :with_push, 1, params[:with_push]
&nbsp; %span Projects with push events
%span.light Projects with push events
.checkbox .checkbox
= label_tag :abandoned, 'Abandoned' = label_tag :abandoned do
= check_box_tag :abandoned, 1, params[:abandoned] = check_box_tag :abandoned, 1, params[:abandoned]
&nbsp; %span No activity over 6 month
%span.light No activity over 6 month
%fieldset %fieldset
%strong Visibility level: %strong Visibility level:
......
= render "events/event_last_push", event: @last_push = render "events/event_last_push", event: @last_push
= render 'shared/event_filter' = render 'shared/event_filter'
.content_list
- if @events.any?
.content_list
- else
.nothing-here-block Projects activity will be displayed here
= spinner = spinner
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
.input-group .input-group
= search_field_tag :filter_group, nil, placeholder: 'Filter by name', class: 'dash-filter form-control' = search_field_tag :filter_group, nil, placeholder: 'Filter by name', class: 'dash-filter form-control'
- if current_user.can_create_group? - if current_user.can_create_group?
.input-group-addon .input-group-addon.dash-new-group
= link_to new_group_path, class: "" do = link_to new_group_path, class: "" do
%strong New group %strong New group
%ul.well-list.dash-list %ul.well-list.dash-list
......
= link_to namespace_project_path(project.namespace, project), class: dom_class(project) do = link_to namespace_project_path(project.namespace, project), class: dom_class(project) do
.dash-project-avatar .dash-project-avatar
= project_icon("#{project.namespace.to_param}/#{project.to_param}", alt: '', class: 'avatar project-avatar s40') = project_icon(project, alt: '', class: 'avatar project-avatar s40')
.dash-project-access-icon .dash-project-access-icon
= visibility_level_icon(project.visibility_level) = visibility_level_icon(project.visibility_level)
%span.str-truncated %span.str-truncated
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
= f.text_field :login, class: "form-control top", placeholder: "Username or Email", autofocus: "autofocus" = f.text_field :login, class: "form-control top", placeholder: "Username or Email", autofocus: "autofocus"
= f.password_field :password, class: "form-control bottom", placeholder: "Password" = f.password_field :password, class: "form-control bottom", placeholder: "Password"
- if devise_mapping.rememberable? - if devise_mapping.rememberable?
.remember-me .remember-me.checkbox
%label.checkbox.remember_me{for: "user_remember_me"} %label{for: "user_remember_me"}
= f.check_box :remember_me = f.check_box :remember_me
%span Remember me %span Remember me
.pull-right .pull-right
= link_to "Forgot your password?", new_password_path(resource_name) = link_to "Forgot your password?", new_password_path(resource_name)
%div %div
= f.submit "Sign in", class: "btn btn-save" = f.submit "Sign in", class: "btn btn-save"
...@@ -3,12 +3,14 @@ ...@@ -3,12 +3,14 @@
.event-item-timestamp .event-item-timestamp
#{time_ago_with_tooltip(event.created_at)} #{time_ago_with_tooltip(event.created_at)}
= cache event do = cache [event, current_user] do
= image_tag avatar_icon(event.author_email, 24), class: "avatar s24", alt:'' = image_tag avatar_icon(event.author_email, 24), class: "avatar s24", alt:''
- if event.push? - if event.push?
= render "events/event/push", event: event = render "events/event/push", event: event
- elsif event.note? - elsif event.commented?
= render "events/event/note", event: event = render "events/event/note", event: event
- elsif event.created_project?
= render "events/event/created_project", event: event
- else - else
= render "events/event/common", event: event = render "events/event/common", event: event
\ No newline at end of file
.event-title .event-title
%span.author_name= link_to_author event %span.author_name= link_to_author event
%span.event_label{class: event.action_name}= event_action_name(event) %span.event_label{class: event.action_name}
= event_action_name(event)
- if event.target - if event.target
%strong= link_to "##{event.target_iid}", [event.project.namespace.becomes(Namespace), event.project, event.target] %strong= link_to "##{event.target_iid}", [event.project.namespace.becomes(Namespace), event.project, event.target]
- else at
%strong= gfm event.target_title
at
- if event.project - if event.project
= link_to_project event.project = link_to_project event.project
- else - else
= event.project_name = event.project_name
- if event.target.respond_to?(:title) - if event.target.respond_to?(:title)
.event-body .event-body
.event-note .event-note
......
.event-title
%span.author_name= link_to_author event
%span.event_label{class: event.action_name}
= event_action_name(event)
- if event.project
= link_to_project event.project
- else
= event.project_name
- if current_user == event.author && !event.project.private? && twitter_sharing_enabled?
.event-body
.event-note
.md
%p
Congratulations! Why not share your accomplishment with the world?
%a.twitter-share-button{ |
href: "https://twitter.com/share", |
"data-url" => event.project.web_url, |
"data-text" => "I just created a new project in GitLab! GitLab is version control on your server.", |
"data-size" => "medium", |
"data-related" => "gitlab", |
"data-hashtags" => "gitlab", |
"data-count" => "none"}
Tweet
%script{src: "//platform.twitter.com/widgets.js"}
\ No newline at end of file
.event-title .event-title
%span.author_name= link_to_author event %span.author_name= link_to_author event
%span.event_label commented on #{event_note_title_html(event)} at %span.event_label
= event.action_name
= event_note_title_html(event)
at
- if event.project - if event.project
= link_to_project event.project = link_to_project event.project
- else - else
......
.event-title .event-title
%span.author_name= link_to_author event %span.author_name= link_to_author event
%span.event_label.pushed #{event.push_action_name} #{event.ref_type} %span.event_label.pushed #{event.action_name} #{event.ref_type}
- if event.rm_ref? - if event.rm_ref?
%strong= event.ref_name %strong= event.ref_name
- else - else
......
...@@ -3,11 +3,9 @@ ...@@ -3,11 +3,9 @@
.project-access-icon .project-access-icon
= visibility_level_icon(project.visibility_level) = visibility_level_icon(project.visibility_level)
= link_to project.name_with_namespace, [project.namespace.becomes(Namespace), project] = link_to project.name_with_namespace, [project.namespace.becomes(Namespace), project]
%span.pull-right
- if current_page?(starred_explore_projects_path) %i.fa.fa-star
%strong.pull-right = project.star_count
%i.fa.fa-star
= pluralize project.star_count, 'star'
.project-info .project-info
- if project.description.present? - if project.description.present?
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
%li.project-row %li.project-row
= link_to namespace_project_path(project.namespace, project), class: dom_class(project) do = link_to namespace_project_path(project.namespace, project), class: dom_class(project) do
.dash-project-avatar .dash-project-avatar
= project_icon("#{project.namespace.to_param}/#{project.to_param}", alt: '', class: 'avatar s40') = project_icon(project, alt: '', class: 'avatar s40')
.dash-project-access-icon .dash-project-access-icon
= visibility_level_icon(project.visibility_level) = visibility_level_icon(project.visibility_level)
%span.str-truncated %span.str-truncated
......
...@@ -13,10 +13,7 @@ ...@@ -13,10 +13,7 @@
- if current_user - if current_user
= render "events/event_last_push", event: @last_push = render "events/event_last_push", event: @last_push
= render 'shared/event_filter' = render 'shared/event_filter'
- if @events.any? .content_list
.content_list
- else
.nothing-here-block Project activity will be displayed here
= spinner = spinner
%aside.side.col-md-4 %aside.side.col-md-4
= render "projects", projects: @projects = render "projects", projects: @projects
...@@ -42,3 +42,9 @@ ...@@ -42,3 +42,9 @@
%li %li
Use Use
= link_to 'shortcuts', '#', onclick: 'Shortcuts.showHelp(event)' = link_to 'shortcuts', '#', onclick: 'Shortcuts.showHelp(event)'
%li
Get a support
= link_to 'subscription', 'https://about.gitlab.com/pricing/'
%li
= link_to 'Compare', 'https://about.gitlab.com/features/#compare'
GitLab editions
...@@ -49,8 +49,14 @@ ...@@ -49,8 +49,14 @@
%span %span
Graphs Graphs
= nav_link(controller: :milestones) do
= link_to project_milestones_path(@project), title: 'Milestones' do
%i.fa.fa-clock-o
%span
Milestones
- if project_nav_tab? :issues - if project_nav_tab? :issues
= nav_link(controller: %w(issues milestones labels)) do = nav_link(controller: :issues) do
= link_to url_for_project_issues, title: 'Issues', class: 'shortcuts-issues' do = link_to url_for_project_issues, title: 'Issues', class: 'shortcuts-issues' do
%i.fa.fa-exclamation-circle %i.fa.fa-exclamation-circle
%span %span
...@@ -66,6 +72,12 @@ ...@@ -66,6 +72,12 @@
Merge Requests Merge Requests
%span.count.merge_counter= @project.merge_requests.opened.count %span.count.merge_counter= @project.merge_requests.opened.count
= nav_link(controller: :labels) do
= link_to project_labels_path(@project), title: 'Labels' do
%i.fa.fa-tags
%span
Labels
- if project_nav_tab? :wiki - if project_nav_tab? :wiki
= nav_link(controller: :wikis) do = nav_link(controller: :wikis) do
= link_to namespace_project_wiki_path(@project.namespace, @project, :home), title: 'Wiki', class: 'shortcuts-wiki' do = link_to namespace_project_wiki_path(@project.namespace, @project, :home), title: 'Wiki', class: 'shortcuts-wiki' do
......
...@@ -36,12 +36,12 @@ ...@@ -36,12 +36,12 @@
%th Scope %th Scope
%th %th
%tbody %tbody
- @authorized_tokens.each do |token| - @authorized_apps.each do |app|
- application = token.application - token = app.authorized_tokens.order('created_at desc').first
%tr{:id => "application_#{application.id}"} %tr{:id => "application_#{app.id}"}
%td= application.name %td= app.name
%td= token.created_at %td= token.created_at
%td= token.scopes %td= token.scopes
%td= render 'doorkeeper/authorized_applications/delete_form', application: application %td= render 'doorkeeper/authorized_applications/delete_form', application: app
- else - else
%p.light You dont have any authorized applications %p.light You dont have any authorized applications
- empty_repo = @project.empty_repo? - empty_repo = @project.empty_repo?
.project-home-panel{:class => ("empty-project" if empty_repo)} .project-home-panel{:class => ("empty-project" if empty_repo)}
.project-identicon-holder .project-identicon-holder
= project_icon("#{@project.namespace.to_param}/#{@project.to_param}", alt: '', class: 'avatar project-avatar') = project_icon(@project, alt: '', class: 'avatar project-avatar')
.project-home-row .project-home-row
.project-home-desc .project-home-desc
- if @project.description.present? - if @project.description.present?
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
= f.label :description, 'Description', class: 'control-label' = f.label :description, 'Description', class: 'control-label'
.col-sm-10 .col-sm-10
= render layout: 'projects/md_preview' do = render layout: 'projects/md_preview', locals: { preview_class: "wiki" } do
= render 'projects/zen', f: f, attr: :description, = render 'projects/zen', f: f, attr: :description,
classes: 'description form-control' classes: 'description form-control'
.col-sm-12.hint .col-sm-12.hint
......
%ul.nav.nav-tabs
- if project_nav_tab? :issues
= nav_link(controller: :issues) do
= link_to namespace_project_issues_path(@project.namespace, @project), class: "tab" do
%i.fa.fa-exclamation-circle
Issues
- if project_nav_tab? :merge_requests
= nav_link(controller: :merge_requests) do
= link_to namespace_project_merge_requests_path(@project.namespace, @project), class: "tab" do
%i.fa.fa-tasks
Merge Requests
= nav_link(controller: :milestones) do
= link_to namespace_project_milestones_path(@project.namespace, @project), class: "tab" do
%i.fa.fa-clock-o
Milestones
= nav_link(controller: :labels) do
= link_to namespace_project_labels_path(@project.namespace, @project), class: "tab" do
%i.fa.fa-tags
Labels
- if current_controller?(:issues)
- if current_user
%li.hidden-xs
= link_to namespace_project_issues_path(@project.namespace, @project, :atom, { private_token: current_user.private_token }) do
%i.fa.fa-rss
%li.pull-right
.pull-right
.pull-left
= form_tag namespace_project_issues_path(@project.namespace, @project), method: :get, id: "issue_search_form", class: 'pull-left issue-search-form' do
.append-right-10.hidden-xs.hidden-sm
= search_field_tag :issue_search, params[:issue_search], { placeholder: 'Filter by title or description', class: 'form-control issue_search search-text-input input-mn-300' }
= hidden_field_tag :state, params['state']
= hidden_field_tag :scope, params['scope']
= hidden_field_tag :assignee_id, params['assignee_id']
= hidden_field_tag :milestone_id, params['milestone_id']
= hidden_field_tag :label_id, params['label_id']
- if can? current_user, :write_issue, @project
= link_to new_namespace_project_issue_path(@project.namespace, @project, issue: { assignee_id: params[:assignee_id], milestone_id: params[:milestone_id]}), class: "btn btn-new pull-left", title: "New Issue", id: "new_issue_link" do
%i.fa.fa-plus
New Issue
- if current_controller?(:merge_requests)
%li.pull-right
.pull-right
- if can? current_user, :write_merge_request, @project
= link_to new_namespace_project_merge_request_path(@project.namespace, @project), class: "btn btn-new pull-left", title: "New Merge Request" do
%i.fa.fa-plus
New Merge Request
...@@ -10,4 +10,4 @@ ...@@ -10,4 +10,4 @@
.md-write-holder .md-write-holder
= yield = yield
.md-preview-holder.hide .md-preview-holder.hide
.js-md-preview .js-md-preview{class: (preview_class if defined?(preview_class))}
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
- Gitlab::VisibilityLevel.values.each do |level| - Gitlab::VisibilityLevel.values.each do |level|
.radio .radio
- restricted = restricted_visibility_levels.include?(level) - restricted = restricted_visibility_levels.include?(level)
= f.radio_button :visibility_level, level, checked: (visibility_level == level), disabled: restricted
= label :project_visibility_level, level do = label :project_visibility_level, level do
= f.radio_button :visibility_level, level, checked: (visibility_level == level), disabled: restricted
= visibility_level_icon(level) = visibility_level_icon(level)
.option-title .option-title
= visibility_level_label(level) = visibility_level_label(level)
......
...@@ -15,5 +15,5 @@ ...@@ -15,5 +15,5 @@
%p %p
To preserve performance only To preserve performance only
%strong #{allowed_diff_size} of #{diffs.size} %strong #{allowed_diff_size} of #{diffs.size}
files displayed. files are displayed.
...@@ -14,24 +14,24 @@ ...@@ -14,24 +14,24 @@
.voting_notes#notes= render "projects/notes/notes_with_form" .voting_notes#notes= render "projects/notes/notes_with_form"
.col-md-3 .col-md-3
%div .issuable-affix
.clearfix .clearfix
%span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'} %span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'}
= cross_project_reference(@project, @issue) = cross_project_reference(@project, @issue)
%hr
.context
%cite.cgray
= render partial: 'issue_context', locals: { issue: @issue }
%hr
.clearfix
.votes-holder
%h6 Votes
#votes= render 'votes/votes_block', votable: @issue
- if @issue.labels.any?
%hr %hr
%h6 Labels .context
.issue-show-labels %cite.cgray
- @issue.labels.each do |label| = render partial: 'issue_context', locals: { issue: @issue }
= link_to namespace_project_issues_path(@project.namespace, @project, label_name: label.name) do %hr
%p= render_colored_label(label) .clearfix
.votes-holder
%h6 Votes
#votes= render 'votes/votes_block', votable: @issue
- if @issue.labels.any?
%hr
%h6 Labels
.issue-show-labels
- @issue.labels.each do |label|
= link_to namespace_project_issues_path(@project.namespace, @project, label_name: label.name) do
= render_colored_label(label)
.append-bottom-10
.check-all-holder
= check_box_tag "check_all_issues", nil, false, class: "check_all_issues left", disabled: !can?(current_user, :modify_issue, @project)
= render 'shared/issuable_filter'
.clearfix
.issues_bulk_update.hide
= form_tag bulk_update_namespace_project_issues_path(@project.namespace, @project), method: :post do
= select_tag('update[status]', options_for_select([['Open', 'open'], ['Closed', 'closed']]), prompt: "Status")
= project_users_select_tag('update[assignee_id]', placeholder: 'Assignee')
= select_tag('update[milestone_id]', bulk_update_milestone_options, prompt: "Milestone")
= hidden_field_tag 'update[issues_ids]', []
= hidden_field_tag :status, params[:status]
= button_tag "Update issues", class: "btn update_selected_issues btn-save"
.panel.panel-default .panel.panel-default
%ul.well-list.issues-list %ul.well-list.issues-list
= render @issues = render @issues
......
= render "projects/issues_nav" .append-bottom-10
.pull-right
.pull-left
- if current_user
.hidden-xs.pull-left
= link_to project_issues_path(@project, :atom, { private_token: current_user.private_token }), class: 'btn append-right-10' do
%i.fa.fa-rss
= form_tag project_issues_path(@project), method: :get, id: "issue_search_form", class: 'pull-left issue-search-form' do
.append-right-10.hidden-xs.hidden-sm
= search_field_tag :issue_search, params[:issue_search], { placeholder: 'Filter by title or description', class: 'form-control issue_search search-text-input input-mn-300' }
= hidden_field_tag :state, params['state']
= hidden_field_tag :scope, params['scope']
= hidden_field_tag :assignee_id, params['assignee_id']
= hidden_field_tag :milestone_id, params['milestone_id']
= hidden_field_tag :label_id, params['label_id']
- if can? current_user, :write_issue, @project
= link_to new_project_issue_path(@project, issue: { assignee_id: params[:assignee_id], milestone_id: params[:milestone_id]}), class: "btn btn-new pull-left", title: "New Issue", id: "new_issue_link" do
%i.fa.fa-plus
New Issue
= render 'shared/issuable_filter'
.clearfix
.issues_bulk_update.hide
= form_tag bulk_update_project_issues_path(@project), method: :post do
= select_tag('update[status]', options_for_select([['Open', 'open'], ['Closed', 'closed']]), prompt: "Status")
= project_users_select_tag('update[assignee_id]', placeholder: 'Assignee')
= select_tag('update[milestone_id]', bulk_update_milestone_options, prompt: "Milestone")
= hidden_field_tag 'update[issues_ids]', []
= hidden_field_tag :status, params[:status]
= button_tag "Update issues", class: "btn update_selected_issues btn-save"
.issues-holder .issues-holder
= render "issues" = render "issues"
%h4.page-title .issue
.issue-box{ class: issue_box_class(@issue) } .issue-details
- if @issue.closed? %h4.page-title
Closed .issue-box{ class: issue_box_class(@issue) }
- else - if @issue.closed?
Open Closed
Issue ##{@issue.iid} - else
%small.creator Open
&middot; created by #{link_to_member(@project, @issue.author)} #{issue_timestamp(@issue)} Issue ##{@issue.iid}
%small.creator
&middot; created by #{link_to_member(@project, @issue.author)} #{issue_timestamp(@issue)}
.pull-right .pull-right
- if can?(current_user, :write_issue, @project) - if can?(current_user, :write_issue, @project)
= link_to new_namespace_project_issue_path(@project.namespace, @project), class: "btn btn-grouped new-issue-link", title: "New Issue", id: "new_issue_link" do = link_to new_namespace_project_issue_path(@project.namespace, @project), class: "btn btn-grouped new-issue-link", title: "New Issue", id: "new_issue_link" do
%i.fa.fa-plus %i.fa.fa-plus
New Issue New Issue
- if can?(current_user, :modify_issue, @issue) - if can?(current_user, :modify_issue, @issue)
- if @issue.closed? - if @issue.closed?
= link_to 'Reopen', namespace_project_issue_path(@project.namespace, @project, @issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn btn-grouped btn-reopen" = link_to 'Reopen', namespace_project_issue_path(@project.namespace, @project, @issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn btn-grouped btn-reopen"
- else - else
= link_to 'Close', namespace_project_issue_path(@project.namespace, @project, @issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn btn-grouped btn-close", title: "Close Issue" = link_to 'Close', namespace_project_issue_path(@project.namespace, @project, @issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn btn-grouped btn-close", title: "Close Issue"
= link_to edit_namespace_project_issue_path(@project.namespace, @project, @issue), class: "btn btn-grouped issuable-edit" do = link_to edit_namespace_project_issue_path(@project.namespace, @project, @issue), class: "btn btn-grouped issuable-edit" do
%i.fa.fa-pencil-square-o %i.fa.fa-pencil-square-o
Edit Edit
%hr %hr
%h3.issue-title %h3.issue-title
= gfm escape_once(@issue.title) = gfm escape_once(@issue.title)
%div %div
- if @issue.description.present? - if @issue.description.present?
.description .description
.wiki .wiki
= preserve do = preserve do
= markdown(@issue.description, parse_tasks: true) = markdown(@issue.description, parse_tasks: true)
%hr %hr
= render "projects/issues/discussion" .issue-discussion
= render "projects/issues/discussion"
= render "projects/issues_nav"
- if can? current_user, :admin_label, @project - if can? current_user, :admin_label, @project
= link_to new_namespace_project_label_path(@project.namespace, @project), class: "pull-right btn btn-new" do = link_to new_namespace_project_label_path(@project.namespace, @project), class: "pull-right btn btn-new" do
New label New label
......
...@@ -10,22 +10,23 @@ ...@@ -10,22 +10,23 @@
= render "projects/merge_requests/show/participants" = render "projects/merge_requests/show/participants"
= render "projects/notes/notes_with_form" = render "projects/notes/notes_with_form"
.col-md-3 .col-md-3
.clearfix .issuable-affix
%span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'} .clearfix
= cross_project_reference(@project, @merge_request) %span.slead.has_tooltip{:"data-original-title" => 'Cross-project reference'}
%hr = cross_project_reference(@project, @merge_request)
.context %hr
%cite.cgray .context
= render partial: 'projects/merge_requests/show/context', locals: { merge_request: @merge_request } %cite.cgray
%hr = render partial: 'projects/merge_requests/show/context', locals: { merge_request: @merge_request }
.votes-holder
%h6 Votes
#votes= render 'votes/votes_block', votable: @merge_request
- if @merge_request.labels.any?
%hr %hr
%h6 Labels .votes-holder
.merge-request-show-labels %h6 Votes
- @merge_request.labels.each do |label| #votes= render 'votes/votes_block', votable: @merge_request
= link_to namespace_project_merge_requests_path(@project.namespace, @project, label_name: label.name) do
%p= render_colored_label(label) - if @merge_request.labels.any?
%hr
%h6 Labels
.merge-request-show-labels
- @merge_request.labels.each do |label|
= link_to namespace_project_merge_requests_path(@project.namespace, @project, label_name: label.name) do
= render_colored_label(label)
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
- if merge_request.assignee - if merge_request.assignee
assigned to #{link_to_member(merge_request.source_project, merge_request.assignee)} assigned to #{link_to_member(merge_request.source_project, merge_request.assignee)}
- else - else
Work In Progress Unassigned
- if merge_request.votes_count > 0 - if merge_request.votes_count > 0
= render 'votes/votes_inline', votable: merge_request = render 'votes/votes_inline', votable: merge_request
- if merge_request.notes.any? - if merge_request.notes.any?
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
.form-group.issuable-description .form-group.issuable-description
= f.label :description, 'Description', class: 'control-label' = f.label :description, 'Description', class: 'control-label'
.col-sm-10 .col-sm-10
= render layout: 'projects/md_preview' do = render layout: 'projects/md_preview', locals: { preview_class: "wiki" } do
= render 'projects/zen', f: f, attr: :description, classes: 'description form-control' = render 'projects/zen', f: f, attr: :description, classes: 'description form-control'
.col-sm-12-hint .col-sm-12-hint
......
.merge-request{'data-url' => namespace_project_merge_request_path(@project.namespace, @project, @merge_request)} .merge-request{'data-url' => namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}
= render "projects/merge_requests/show/mr_title" .merge-request-details
%hr = render "projects/merge_requests/show/mr_title"
= render "projects/merge_requests/show/mr_box" %hr
%hr = render "projects/merge_requests/show/mr_box"
.append-bottom-20 %hr
.slead .append-bottom-20
%span From .slead
- if @merge_request.for_fork? %span From
%strong.label-branch< - if @merge_request.for_fork?
- if @merge_request.source_project %strong.label-branch<
= link_to @merge_request.source_project_namespace, namespace_project_path(@merge_request.source_project.namespace, @merge_request.source_project) - if @merge_request.source_project
- else = link_to @merge_request.source_project_namespace, namespace_project_path(@merge_request.source_project.namespace, @merge_request.source_project)
\ #{@merge_request.source_project_namespace} - else
\:#{@merge_request.source_branch} \ #{@merge_request.source_project_namespace}
%span into \:#{@merge_request.source_branch}
%strong.label-branch #{@merge_request.target_project_namespace}:#{@merge_request.target_branch} %span into
- else %strong.label-branch #{@merge_request.target_project_namespace}:#{@merge_request.target_branch}
%strong.label-branch #{@merge_request.source_branch} - else
%span into %strong.label-branch #{@merge_request.source_branch}
%strong.label-branch #{@merge_request.target_branch} %span into
- if @merge_request.open? %strong.label-branch #{@merge_request.target_branch}
%span.pull-right - if @merge_request.open?
.btn-group %span.pull-right
%a.btn.dropdown-toggle{ data: {toggle: :dropdown} } .btn-group
%i.fa.fa-download %a.btn.dropdown-toggle{ data: {toggle: :dropdown} }
Download as %i.fa.fa-download
%span.caret Download as
%ul.dropdown-menu %span.caret
%li= link_to "Email Patches", namespace_project_merge_request_path(@project.namespace, @project, @merge_request, format: :patch) %ul.dropdown-menu
%li= link_to "Plain Diff", namespace_project_merge_request_path(@project.namespace, @project, @merge_request, format: :diff) %li= link_to "Email Patches", namespace_project_merge_request_path(@project.namespace, @project, @merge_request, format: :patch)
%li= link_to "Plain Diff", namespace_project_merge_request_path(@project.namespace, @project, @merge_request, format: :diff)
= render "projects/merge_requests/show/how_to_merge" = render "projects/merge_requests/show/how_to_merge"
= render "projects/merge_requests/show/state_widget" = render "projects/merge_requests/show/state_widget"
- if @commits.present? - if @commits.present?
%ul.nav.nav-tabs.merge-request-tabs %ul.nav.nav-tabs.merge-request-tabs
......
= render "projects/issues_nav"
.merge-requests-holder .merge-requests-holder
.append-bottom-10 .append-bottom-10
.pull-right
- if can? current_user, :write_merge_request, @project
= link_to new_project_merge_request_path(@project), class: "btn btn-new pull-left", title: "New Merge Request" do
%i.fa.fa-plus
New Merge Request
= render 'shared/issuable_filter' = render 'shared/issuable_filter'
.panel.panel-default .panel.panel-default
%ul.well-list.mr-list %ul.well-list.mr-list
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
.accept-action .accept-action
= f.submit "Accept Merge Request", class: "btn btn-create accept_merge_request" = f.submit "Accept Merge Request", class: "btn btn-create accept_merge_request"
- if can_remove_branch?(@merge_request.source_project, @merge_request.source_branch) && !@merge_request.for_fork? - if can_remove_branch?(@merge_request.source_project, @merge_request.source_branch) && !@merge_request.for_fork?
.accept-control .accept-control.checkbox
= label_tag :should_remove_source_branch, class: "remove_source_checkbox" do = label_tag :should_remove_source_branch, class: "remove_source_checkbox" do
= check_box_tag :should_remove_source_branch = check_box_tag :should_remove_source_branch
Remove source-branch Remove source-branch
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
.form-group.milestone-description .form-group.milestone-description
= f.label :description, "Description", class: "control-label" = f.label :description, "Description", class: "control-label"
.col-sm-10 .col-sm-10
= render layout: 'projects/md_preview' do = render layout: 'projects/md_preview', locals: { preview_class: "wiki" } do
= render 'projects/zen', f: f, attr: :description, classes: 'description form-control' = render 'projects/zen', f: f, attr: :description, classes: 'description form-control'
.hint .hint
.pull-left Milestones are parsed with #{link_to "GitLab Flavored Markdown", help_page_path("markdown", "markdown"), target: '_blank'}. .pull-left Milestones are parsed with #{link_to "GitLab Flavored Markdown", help_page_path("markdown", "markdown"), target: '_blank'}.
......
= render "projects/issues_nav" .pull-right
.milestones_content - if can? current_user, :admin_milestone, @project
%h3.page-title = link_to new_namespace_project_milestone_path(@project.namespace, @project), class: "pull-right btn btn-new", title: "New Milestone" do
Milestones %i.fa.fa-plus
- if can? current_user, :admin_milestone, @project New Milestone
= link_to new_namespace_project_milestone_path(@project.namespace, @project), class: "pull-right btn btn-new", title: "New Milestone" do
%i.fa.fa-plus
New Milestone
= render 'shared/milestones_filter' = render 'shared/milestones_filter'
.milestones .milestones
......
= render "projects/issues_nav"
%h4.page-title %h4.page-title
.issue-box{ class: issue_box_class(@milestone) } .issue-box{ class: issue_box_class(@milestone) }
- if @milestone.closed? - if @milestone.closed?
......
...@@ -52,7 +52,7 @@ ...@@ -52,7 +52,7 @@
%i.fa.fa-github %i.fa.fa-github
Import projects from GitHub Import projects from GitHub
= render 'github_import_modal' = render 'github_import_modal'
.project-import.form-group .project-import.form-group
.col-sm-2 .col-sm-2
.col-sm-10 .col-sm-10
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
= link_to status_import_gitlab_path do = link_to status_import_gitlab_path do
%i.fa.fa-heart %i.fa.fa-heart
Import projects from GitLab.com Import projects from GitLab.com
- else - elsif request.host != 'gitlab.com'
= link_to '#', class: 'how_to_import_link light' do = link_to '#', class: 'how_to_import_link light' do
%i.fa.fa-heart %i.fa.fa-heart
Import projects from GitLab.com Import projects from GitLab.com
...@@ -99,4 +99,4 @@ ...@@ -99,4 +99,4 @@
e.preventDefault() e.preventDefault()
import_modal = $(this).parent().find(".modal").show() import_modal = $(this).parent().find(".modal").show()
$('.modal-header .close').bind 'click', -> $('.modal-header .close').bind 'click', ->
$(".modal").hide() $(".modal").hide()
\ No newline at end of file
.note-edit-form .note-edit-form
= form_for note, url: namespace_project_note_path(@project.namespace, @project, note), method: :put, remote: true, authenticity_token: true do |f| = form_for note, url: namespace_project_note_path(@project.namespace, @project, note), method: :put, remote: true, authenticity_token: true do |f|
= render layout: 'projects/md_preview' do = render layout: 'projects/md_preview', locals: { preview_class: "note-text" } do
= render 'projects/zen', f: f, attr: :note, = render 'projects/zen', f: f, attr: :note,
classes: 'note_text js-note-text' classes: 'note_text js-note-text'
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
= f.hidden_field :noteable_id = f.hidden_field :noteable_id
= f.hidden_field :noteable_type = f.hidden_field :noteable_type
= render layout: 'projects/md_preview' do = render layout: 'projects/md_preview', locals: { preview_class: "note-text" } do
= render 'projects/zen', f: f, attr: :note, = render 'projects/zen', f: f, attr: :note,
classes: 'note_text js-note-text' classes: 'note_text js-note-text'
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
.form-group.wiki-content .form-group.wiki-content
= f.label :content, class: 'control-label' = f.label :content, class: 'control-label'
.col-sm-10 .col-sm-10
= render layout: 'projects/md_preview' do = render layout: 'projects/md_preview', locals: { preview_class: "wiki" } do
= render 'projects/zen', f: f, attr: :content, classes: 'description form-control' = render 'projects/zen', f: f, attr: :content, classes: 'description form-control'
.col-sm-12.hint .col-sm-12.hint
.pull-left Wiki content is parsed with #{link_to "GitLab Flavored Markdown", help_page_path("markdown", "markdown"), target: '_blank'} .pull-left Wiki content is parsed with #{link_to "GitLab Flavored Markdown", help_page_path("markdown", "markdown"), target: '_blank'}
......
...@@ -7,4 +7,5 @@ ...@@ -7,4 +7,5 @@
= link_to "#L#{i}", id: "L#{i}", rel: "#L#{i}" do = link_to "#L#{i}", id: "L#{i}", rel: "#L#{i}" do
%i.fa.fa-link %i.fa.fa-link
= i = i
= highlight(blob.name, blob.data) :preserve
#{highlight(blob.name, blob.data)}
.issues-filters .issues-filters
.pull-left.append-right-20 .issues-state-filters
%ul.nav.nav-pills.nav-compact %ul.nav.nav-tabs
%li{class: ("active" if params[:state] == 'opened')} %li{class: ("active" if params[:state] == 'opened')}
= link_to page_filter_path(state: 'opened') do = link_to page_filter_path(state: 'opened') do
%i.fa.fa-exclamation-circle %i.fa.fa-exclamation-circle
...@@ -14,99 +14,106 @@ ...@@ -14,99 +14,106 @@
%i.fa.fa-compass %i.fa.fa-compass
All All
.dropdown.inline.assignee-filter %div
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} - if controller.controller_name == 'issues'
%i.fa.fa-user .check-all-holder
%span.light assignee: = check_box_tag "check_all_issues", nil, false,
- if @assignee.present? class: "check_all_issues left",
%strong= @assignee.name disabled: !can?(current_user, :modify_issue, @project)
- elsif params[:assignee_id] == "0" .issues-other-filters
Unassigned .dropdown.inline.assignee-filter
- else %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
Any %i.fa.fa-user
%b.caret %span.light assignee:
%ul.dropdown-menu - if @assignee.present?
%li %strong= @assignee.name
= link_to page_filter_path(assignee_id: nil) do - elsif params[:assignee_id] == "0"
Any Unassigned
= link_to page_filter_path(assignee_id: 0) do - else
Unassigned Any
- @assignees.sort_by(&:name).each do |user| %b.caret
%li %ul.dropdown-menu
= link_to page_filter_path(assignee_id: user.id) do %li
= image_tag avatar_icon(user.email), class: "avatar s16", alt: '' = link_to page_filter_path(assignee_id: nil) do
= user.name Any
= link_to page_filter_path(assignee_id: 0) do
.dropdown.inline.prepend-left-10.author-filter Unassigned
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} - @assignees.sort_by(&:name).each do |user|
%i.fa.fa-user %li
%span.light author: = link_to page_filter_path(assignee_id: user.id) do
- if @author.present? = image_tag avatar_icon(user.email), class: "avatar s16", alt: ''
%strong= @author.name = user.name
- elsif params[:author_id] == "0"
Unassigned
- else
Any
%b.caret
%ul.dropdown-menu
%li
= link_to page_filter_path(author_id: nil) do
Any
= link_to page_filter_path(author_id: 0) do
Unassigned
- @authors.sort_by(&:name).each do |user|
%li
= link_to page_filter_path(author_id: user.id) do
= image_tag avatar_icon(user.email), class: "avatar s16", alt: ''
= user.name
.dropdown.inline.prepend-left-10.milestone-filter
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%i.fa.fa-clock-o
%span.light milestone:
- if @milestone.present?
%strong= @milestone.title
- elsif params[:milestone_id] == "0"
None (backlog)
- else
Any
%b.caret
%ul.dropdown-menu
%li
= link_to page_filter_path(milestone_id: nil) do
Any
= link_to page_filter_path(milestone_id: 0) do
None (backlog)
- @milestones.each do |milestone|
%li
= link_to page_filter_path(milestone_id: milestone.id) do
%strong= milestone.title
%small.light= milestone.expires_at
- if @project .dropdown.inline.prepend-left-10.author-filter
.dropdown.inline.prepend-left-10.labels-filter %a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"} %i.fa.fa-user
%i.fa.fa-tags %span.light author:
%span.light label: - if @author.present?
- if params[:label_name].present? %strong= @author.name
%strong= params[:label_name] - elsif params[:author_id] == "0"
- else Unassigned
Any - else
%b.caret
%ul.dropdown-menu
%li
= link_to page_filter_path(label_name: nil) do
Any Any
- if @project.labels.any? %b.caret
- @project.labels.each do |label| %ul.dropdown-menu
%li
= link_to page_filter_path(author_id: nil) do
Any
= link_to page_filter_path(author_id: 0) do
Unassigned
- @authors.sort_by(&:name).each do |user|
%li %li
= link_to page_filter_path(label_name: label.name) do = link_to page_filter_path(author_id: user.id) do
= render_colored_label(label) = image_tag avatar_icon(user.email), class: "avatar s16", alt: ''
- else = user.name
.dropdown.inline.prepend-left-10.milestone-filter
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%i.fa.fa-clock-o
%span.light milestone:
- if @milestone.present?
%strong= @milestone.title
- elsif params[:milestone_id] == "0"
None (backlog)
- else
Any
%b.caret
%ul.dropdown-menu
%li %li
= link_to generate_namespace_project_labels_path(@project.namespace, @project, redirect: request.original_url), method: :post do = link_to page_filter_path(milestone_id: nil) do
%i.fa.fa-plus-circle Any
Create default labels = link_to page_filter_path(milestone_id: 0) do
None (backlog)
- @milestones.each do |milestone|
%li
= link_to page_filter_path(milestone_id: milestone.id) do
%strong= milestone.title
%small.light= milestone.expires_at
- if @project
.dropdown.inline.prepend-left-10.labels-filter
%a.dropdown-toggle.btn{href: '#', "data-toggle" => "dropdown"}
%i.fa.fa-tags
%span.light label:
- if params[:label_name].present?
%strong= params[:label_name]
- else
Any
%b.caret
%ul.dropdown-menu
%li
= link_to page_filter_path(label_name: nil) do
Any
- if @project.labels.any?
- @project.labels.each do |label|
%li
= link_to page_filter_path(label_name: label.name) do
= render_colored_label(label)
- else
%li
= link_to generate_namespace_project_labels_path(@project.namespace, @project, redirect: request.original_url), method: :post do
%i.fa.fa-plus-circle
Create default labels
.pull-right .pull-right
= render 'shared/sort_dropdown' = render 'shared/sort_dropdown'
.milestones-filters.append-bottom-10 .milestones-filters.append-bottom-10
%ul.nav.nav-pills.nav-compact %ul.nav.nav-tabs
%li{class: ("active" if params[:state].blank? || params[:state] == 'opened')} %li{class: ("active" if params[:state].blank? || params[:state] == 'opened')}
= link_to milestones_filter_path(state: 'opened') do = link_to milestones_filter_path(state: 'opened') do
%i.fa.fa-exclamation-circle %i.fa.fa-exclamation-circle
......
.panel.panel-default - if @contributed_projects.present?
.panel-heading Personal projects .panel.panel-default
%ul.well-list .panel-heading Projects contributed to
- projects.each do |project| %ul.well-list
%li - @contributed_projects.sort_by(&:star_count).reverse.each do |project|
= link_to_project project %li
= link_to_project project
%span.pull-right.light
%i.fa.fa-star
= project.star_count
- if @projects.present?
.panel.panel-default
.panel-heading Personal projects
%ul.well-list
- @projects.sort_by(&:star_count).reverse.each do |project|
%li
= link_to_project project
%span.pull-right.light
%i.fa.fa-star
= project.star_count
%h4 Calendar %h4 Commits calendar
#cal-heatmap.calendar #cal-heatmap.calendar
:javascript :javascript
new calendar( new calendar(
......
...@@ -35,9 +35,7 @@ ...@@ -35,9 +35,7 @@
= render @events = render @events
.col-md-4 .col-md-4
= render 'profile', user: @user = render 'profile', user: @user
- if @projects.present? = render 'projects'
= render 'projects', projects: @projects
:coffeescript :coffeescript
$ -> $ ->
......
...@@ -112,6 +112,7 @@ end ...@@ -112,6 +112,7 @@ end
Settings.gitlab['time_zone'] ||= nil Settings.gitlab['time_zone'] ||= nil
Settings.gitlab['signup_enabled'] ||= true if Settings.gitlab['signup_enabled'].nil? Settings.gitlab['signup_enabled'] ||= true if Settings.gitlab['signup_enabled'].nil?
Settings.gitlab['signin_enabled'] ||= true if Settings.gitlab['signin_enabled'].nil? Settings.gitlab['signin_enabled'] ||= true if Settings.gitlab['signin_enabled'].nil?
Settings.gitlab['twitter_sharing_enabled'] ||= true if Settings.gitlab['twitter_sharing_enabled'].nil?
Settings.gitlab['restricted_visibility_levels'] = Settings.send(:verify_constant_array, Gitlab::VisibilityLevel, Settings.gitlab['restricted_visibility_levels'], []) Settings.gitlab['restricted_visibility_levels'] = Settings.send(:verify_constant_array, Gitlab::VisibilityLevel, Settings.gitlab['restricted_visibility_levels'], [])
Settings.gitlab['username_changing_enabled'] = true if Settings.gitlab['username_changing_enabled'].nil? Settings.gitlab['username_changing_enabled'] = true if Settings.gitlab['username_changing_enabled'].nil?
Settings.gitlab['issue_closing_pattern'] = '((?:[Cc]los(?:e[sd]?|ing)|[Ff]ix(?:e[sd]|ing)?|[Rr]esolv(?:e[sd]?|ing)) +(?:(?:issues? +)?#\d+(?:(?:, *| +and +)?))+)' if Settings.gitlab['issue_closing_pattern'].nil? Settings.gitlab['issue_closing_pattern'] = '((?:[Cc]los(?:e[sd]?|ing)|[Ff]ix(?:e[sd]|ing)?|[Rr]esolv(?:e[sd]?|ing)) +(?:(?:issues? +)?#\d+(?:(?:, *| +and +)?))+)' if Settings.gitlab['issue_closing_pattern'].nil?
......
...@@ -3,6 +3,7 @@ Gitlab::Seeder.quiet do ...@@ -3,6 +3,7 @@ Gitlab::Seeder.quiet do
s.id = 1 s.id = 1
s.name = 'Administrator' s.name = 'Administrator'
s.email = 'admin@example.com' s.email = 'admin@example.com'
s.notification_email = 'admin@example.com'
s.username = 'root' s.username = 'root'
s.password = '5iveL!fe' s.password = '5iveL!fe'
s.admin = true s.admin = true
......
class AddTwitterSharingEnabledToApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :twitter_sharing_enabled, :boolean, default: true
end
end
...@@ -10,10 +10,11 @@ ...@@ -10,10 +10,11 @@
- [SSH](ssh/README.md) Setup your ssh keys and deploy keys for secure access to your projects. - [SSH](ssh/README.md) Setup your ssh keys and deploy keys for secure access to your projects.
- [Web hooks](web_hooks/web_hooks.md) Let GitLab notify you when new code has been pushed to your project. - [Web hooks](web_hooks/web_hooks.md) Let GitLab notify you when new code has been pushed to your project.
- [Workflow](workflow/README.md) Using GitLab functionality and importing projects from GitHub and SVN. - [Workflow](workflow/README.md) Using GitLab functionality and importing projects from GitHub and SVN.
- [GitLab as OAuth2 authentication service provider](integration/oauth_provider.md). It allows you to login to other applications from GitLab.
## Administrator documentation ## Administrator documentation
- [Install](install/README.md) Requirements, directory structures and manual installation. - [Install](install/README.md) Requirements, directory structures and installation from source.
- [Integration](integration/README.md) How to integrate with systems such as JIRA, Redmine, LDAP and Twitter. - [Integration](integration/README.md) How to integrate with systems such as JIRA, Redmine, LDAP and Twitter.
- [Raketasks](raketasks/README.md) Backups, maintenance, automatic web hook setup and the importing of projects. - [Raketasks](raketasks/README.md) Backups, maintenance, automatic web hook setup and the importing of projects.
- [Custom git hooks](hooks/custom_hooks.md) Custom git hooks (on the filesystem) for when web hooks aren't enough. - [Custom git hooks](hooks/custom_hooks.md) Custom git hooks (on the filesystem) for when web hooks aren't enough.
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
## Clients ## Clients
Find API Clients for GitLab [on our website](https://about.gitlab.com/applications/#api-clients). Find API Clients for GitLab [on our website](https://about.gitlab.com/applications/#api-clients).
You can use [GitLab as an OAuth2 client](oauth2.md) to make API calls.
## Introduction ## Introduction
...@@ -67,7 +68,7 @@ curl https://localhost:3000/api/v3/user?access_token=OAUTH-TOKEN ...@@ -67,7 +68,7 @@ curl https://localhost:3000/api/v3/user?access_token=OAUTH-TOKEN
curl -H "Authorization: Bearer OAUTH-TOKEN" https://localhost:3000/api/v3/user curl -H "Authorization: Bearer OAUTH-TOKEN" https://localhost:3000/api/v3/user
``` ```
Read more about [OAuth2 in GitLab](oauth2.md). Read more about [GitLab as an OAuth2 client](oauth2.md).
## Status codes ## Status codes
......
...@@ -15,27 +15,20 @@ Parameters: ...@@ -15,27 +15,20 @@ Parameters:
```json ```json
[ [
{ {
"name": "master",
"commit": { "commit": {
"author_email": "john@example.com",
"author_name": "John Smith",
"authored_date": "2012-06-27T05:51:39-07:00",
"committed_date": "2012-06-28T03:44:20-07:00",
"committer_email": "john@example.com",
"committer_name": "John Smith",
"id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c", "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c",
"parents": [
{
"id": "4ad91d3c1144c406e50c7b33bae684bd6837faf8"
}
],
"tree": "46e82de44b1061621357f24c05515327f2795a95",
"message": "add projects API", "message": "add projects API",
"author": { "parent_ids": [
"name": "John Smith", "4ad91d3c1144c406e50c7b33bae684bd6837faf8"
"email": "john@example.com" ]
},
"committer": {
"name": "John Smith",
"email": "john@example.com"
},
"authored_date": "2012-06-27T05:51:39-07:00",
"committed_date": "2012-06-28T03:44:20-07:00"
}, },
"name": "master",
"protected": true "protected": true
} }
] ]
...@@ -56,27 +49,20 @@ Parameters: ...@@ -56,27 +49,20 @@ Parameters:
```json ```json
{ {
"name": "master",
"commit": { "commit": {
"author_email": "john@example.com",
"author_name": "John Smith",
"authored_date": "2012-06-27T05:51:39-07:00",
"committed_date": "2012-06-28T03:44:20-07:00",
"committer_email": "john@example.com",
"committer_name": "John Smith",
"id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c", "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c",
"parents": [
{
"id": "4ad91d3c1144c406e50c7b33bae684bd6837faf8"
}
],
"tree": "46e82de44b1061621357f24c05515327f2795a95",
"message": "add projects API", "message": "add projects API",
"author": { "parent_ids": [
"name": "John Smith", "4ad91d3c1144c406e50c7b33bae684bd6837faf8"
"email": "john@example.com" ]
},
"committer": {
"name": "John Smith",
"email": "john@example.com"
},
"authored_date": "2012-06-27T05:51:39-07:00",
"committed_date": "2012-06-28T03:44:20-07:00"
}, },
"name": "master",
"protected": true "protected": true
} }
``` ```
...@@ -97,27 +83,20 @@ Parameters: ...@@ -97,27 +83,20 @@ Parameters:
```json ```json
{ {
"name": "master",
"commit": { "commit": {
"author_email": "john@example.com",
"author_name": "John Smith",
"authored_date": "2012-06-27T05:51:39-07:00",
"committed_date": "2012-06-28T03:44:20-07:00",
"committer_email": "john@example.com",
"committer_name": "John Smith",
"id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c", "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c",
"parents": [
{
"id": "4ad91d3c1144c406e50c7b33bae684bd6837faf8"
}
],
"tree": "46e82de44b1061621357f24c05515327f2795a95",
"message": "add projects API", "message": "add projects API",
"author": { "parent_ids": [
"name": "John Smith", "4ad91d3c1144c406e50c7b33bae684bd6837faf8"
"email": "john@example.com" ]
},
"committer": {
"name": "John Smith",
"email": "john@example.com"
},
"authored_date": "2012-06-27T05:51:39-07:00",
"committed_date": "2012-06-28T03:44:20-07:00"
}, },
"name": "master",
"protected": true "protected": true
} }
``` ```
...@@ -138,27 +117,20 @@ Parameters: ...@@ -138,27 +117,20 @@ Parameters:
```json ```json
{ {
"name": "master",
"commit": { "commit": {
"author_email": "john@example.com",
"author_name": "John Smith",
"authored_date": "2012-06-27T05:51:39-07:00",
"committed_date": "2012-06-28T03:44:20-07:00",
"committer_email": "john@example.com",
"committer_name": "John Smith",
"id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c", "id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c",
"parents": [
{
"id": "4ad91d3c1144c406e50c7b33bae684bd6837faf8"
}
],
"tree": "46e82de44b1061621357f24c05515327f2795a95",
"message": "add projects API", "message": "add projects API",
"author": { "parent_ids": [
"name": "John Smith", "4ad91d3c1144c406e50c7b33bae684bd6837faf8"
"email": "john@example.com" ]
},
"committer": {
"name": "John Smith",
"email": "john@example.com"
},
"authored_date": "2012-06-27T05:51:39-07:00",
"committed_date": "2012-06-28T03:44:20-07:00"
}, },
"name": "master",
"protected": false "protected": false
} }
``` ```
...@@ -177,21 +149,20 @@ Parameters: ...@@ -177,21 +149,20 @@ Parameters:
```json ```json
{ {
"name": "my-new-branch",
"commit": { "commit": {
"id": "8848c0e90327a0b70f1865b843fb2fbfb9345e57",
"message": "Merge pull request #54 from brightbox/use_fog_brightbox_module\n\nUpdate to use fog-brightbox module",
"parent_ids": [
"fff449e0bf453576f16c91d6544f00a2664009d8",
"f93a93626fec20fd659f4ed3ab2e64019b6169ae"
],
"authored_date": "2014-02-20T19:54:55+02:00",
"author_name": "john smith",
"author_email": "john@example.com", "author_email": "john@example.com",
"committed_date": "2014-02-20T19:54:55+02:00", "author_name": "John Smith",
"committer_name": "john smith", "authored_date": "2012-06-27T05:51:39-07:00",
"committer_email": "john@example.com" "committed_date": "2012-06-28T03:44:20-07:00",
"committer_email": "john@example.com",
"committer_name": "John Smith",
"id": "7b5c3cc8be40ee161ae89a06bba6229da1032a0c",
"message": "add projects API",
"parent_ids": [
"4ad91d3c1144c406e50c7b33bae684bd6837faf8"
]
}, },
"name": "master",
"protected": false "protected": false
} }
``` ```
......
...@@ -14,7 +14,6 @@ GET /groups ...@@ -14,7 +14,6 @@ GET /groups
"id": 1, "id": 1,
"name": "Foobar Group", "name": "Foobar Group",
"path": "foo-bar", "path": "foo-bar",
"owner_id": 18,
"description": "An interesting group" "description": "An interesting group"
} }
] ]
...@@ -87,7 +86,6 @@ GET /groups?search=foobar ...@@ -87,7 +86,6 @@ GET /groups?search=foobar
"id": 1, "id": 1,
"name": "Foobar Group", "name": "Foobar Group",
"path": "foo-bar", "path": "foo-bar",
"owner_id": 18,
"description": "An interesting group" "description": "An interesting group"
} }
] ]
......
# OAuth2 authentication # GitLab as an OAuth2 client
OAuth2 is a protocol that enables us to get access to private details of user's account without getting its password. This document is about using other OAuth authentication service providers to sign into GitLab.
If you want GitLab to be an OAuth authentication service provider to sign into other services please see the [Oauth2 provider documentation](../integration/oauth_provider.md).
Before using the OAuth2 you should create an application in user's account. Each application getting unique App ID and App Secret parameters. You should not share them. OAuth2 is a protocol that enables us to authenticate a user without requiring them to give their password.
Before using the OAuth2 you should create an application in user's account. Each application gets a unique App ID and App Secret parameters. You should not share these.
This functionality is based on [doorkeeper gem](https://github.com/doorkeeper-gem/doorkeeper) This functionality is based on [doorkeeper gem](https://github.com/doorkeeper-gem/doorkeeper)
## Web Application Flow ## Web Application Flow
This flow is using for authentication from third-party web sites and probably is most used. This flow is using for authentication from third-party web sites and is probably used the most.
It basically consists of an exchange of an authorization token for an access token. For more detailed info, check out the [RFC spec here](http://tools.ietf.org/html/rfc6749#section-4.1) It basically consists of an exchange of an authorization token for an access token. For more detailed info, check out the [RFC spec here](http://tools.ietf.org/html/rfc6749#section-4.1)
This flow consists from 3 steps. This flow consists from 3 steps.
......
# What you should know about omnibus packages
Most users install GitLab using our omnibus packages. As a developer it can be
good to know how the omnibus packages differ from what you have on your laptop
when you are coding.
## Files are owned by root by default
All the files in the Rails tree (`app/`, `config/` etc.) are owned by 'root' in
omnibus installations. This makes the installation simpler and it provides
extra security. The omnibus reconfigure script contains commands that give
write access to the 'git' user only where needed.
For example, the 'git' user is allowed to write in the `log/` directory, in
`public/uploads`, and they are allowed to rewrite the `db/schema.rb` file.
In other cases, the reconfigure script tricks GitLab into not trying to write a
file. For instance, GitLab will generate a `.secret` file if it cannot find one
and write it to the Rails root. In the omnibus packages, reconfigure writes the
`.secret` file first, so that GitLab never tries to write it.
## Code, data and logs are in separate directories
The omnibus design separates code (read-only, under `/opt/gitlab`) from data
(read/write, under `/var/opt/gitlab`) and logs (read/write, under
`/var/log/gitlab`). To make this happen the reconfigure script sets custom
paths where it can in GitLab config files, and where there are no path
settings, it uses symlinks.
For example, `config/gitlab.yml` is treated as data so that file is a symlink.
The same goes for `public/uploads`. The `log/` directory is replaced by omnibus
with a symlink to `/var/log/gitlab/gitlab-rails`.
...@@ -24,7 +24,7 @@ set up a custom hook. ...@@ -24,7 +24,7 @@ set up a custom hook.
1. Pick a project that needs a custom git hook. 1. Pick a project that needs a custom git hook.
1. On the GitLab server, navigate to the project's repository directory. 1. On the GitLab server, navigate to the project's repository directory.
For a manual install the path is usually For an installation from source the path is usually
`/home/git/repositories/<group>/<project>.git`. For Omnibus installs the path is `/home/git/repositories/<group>/<project>.git`. For Omnibus installs the path is
usually `/var/opt/gitlab/git-data/repositories/<group>/<project>.git`. usually `/var/opt/gitlab/git-data/repositories/<group>/<project>.git`.
1. Create a new directory in this location called `custom_hooks`. 1. Create a new directory in this location called `custom_hooks`.
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
## Consider the Omnibus package installation ## Consider the Omnibus package installation
Since a manual installation is a lot of work and error prone we strongly recommend the fast and reliable [Omnibus package installation](https://about.gitlab.com/downloads/) (deb/rpm). Since an installation from source is a lot of work and error prone we strongly recommend the fast and reliable [Omnibus package installation](https://about.gitlab.com/downloads/) (deb/rpm).
## Select Version to Install ## Select Version to Install
...@@ -183,9 +183,9 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da ...@@ -183,9 +183,9 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da
### Clone the Source ### Clone the Source
# Clone GitLab repository # Clone GitLab repository
sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 7-6-stable gitlab sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 7-8-stable gitlab
**Note:** You can change `7-6-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server! **Note:** You can change `7-8-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server!
### Configure It ### Configure It
...@@ -280,7 +280,7 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da ...@@ -280,7 +280,7 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da
GitLab Shell is an SSH access and repository management software developed specially for GitLab. GitLab Shell is an SSH access and repository management software developed specially for GitLab.
# Run the installation task for gitlab-shell (replace `REDIS_URL` if needed): # Run the installation task for gitlab-shell (replace `REDIS_URL` if needed):
sudo -u git -H bundle exec rake gitlab:shell:install[v2.4.2] REDIS_URL=unix:/var/run/redis/redis.sock RAILS_ENV=production sudo -u git -H bundle exec rake gitlab:shell:install[v2.4.3] REDIS_URL=unix:/var/run/redis/redis.sock RAILS_ENV=production
# By default, the gitlab-shell config is generated from your main GitLab config. # By default, the gitlab-shell config is generated from your main GitLab config.
# You can review (and modify) the gitlab-shell config as follows: # You can review (and modify) the gitlab-shell config as follows:
......
...@@ -22,7 +22,7 @@ For the installations options please see [the installation page on the GitLab we ...@@ -22,7 +22,7 @@ For the installations options please see [the installation page on the GitLab we
- FreeBSD - FreeBSD
On the above unsupported distributions is still possible to install GitLab yourself. On the above unsupported distributions is still possible to install GitLab yourself.
Please see the [manual installation guide](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/installation.md) and the [unofficial installation guides](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Unofficial-Installation-Guides) on the public wiki for more information. Please see the [installation from source guide](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/installation.md) and the [unofficial installation guides](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Unofficial-Installation-Guides) on the public wiki for more information.
### Non-Unix operating systems such as Windows ### Non-Unix operating systems such as Windows
......
...@@ -8,9 +8,8 @@ See the documentation below for details on how to configure these services. ...@@ -8,9 +8,8 @@ See the documentation below for details on how to configure these services.
- [LDAP](ldap.md) Set up sign in via LDAP - [LDAP](ldap.md) Set up sign in via LDAP
- [OmniAuth](omniauth.md) Sign in via Twitter, GitHub, GitLab, and Google via OAuth. - [OmniAuth](omniauth.md) Sign in via Twitter, GitHub, GitLab, and Google via OAuth.
- [Slack](slack.md) Integrate with the Slack chat service - [Slack](slack.md) Integrate with the Slack chat service
- [OAuth2 provider](oauth_provider.md) OAuth2 application creation
Jenkins support is [available in GitLab EE](http://doc.gitlab.com/ee/integration/jenkins.html). 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).
## Project services ## Project services
......
...@@ -8,6 +8,8 @@ GitLab has a great issue tracker but you can also use an external issue tracker ...@@ -8,6 +8,8 @@ GitLab has a great issue tracker but you can also use an external issue tracker
![Jira screenshot](jira-integration-points.png) ![Jira screenshot](jira-integration-points.png)
GitLab Enterprise Edition contains [advanced JIRA support](http://doc.gitlab.com/ee/integration/jira.html).
## Configuration ## Configuration
### Project Service ### Project Service
...@@ -23,7 +25,6 @@ Fill in the required details on the page: ...@@ -23,7 +25,6 @@ Fill in the required details on the page:
* `issues_url` The URL to the issue in Redmine project that is linked to this GitLab project. Note that the `issues_url` requires `:id` in the url. This id is used by GitLab as a placeholder to replace the issue number. * `issues_url` The URL to the issue in Redmine project that is linked to this GitLab project. Note that the `issues_url` requires `:id` in the url. This id is used by GitLab as a placeholder to replace the issue number.
* `new_issue_url` This is the URL to create a new issue in Redmine for the project linked to this GitLab project. * `new_issue_url` This is the URL to create a new issue in Redmine for the project linked to this GitLab project.
### Service Template ### Service Template
It is necessary to configure the external issue tracker per project, because project specific details are needed for the integration with GitLab. It is necessary to configure the external issue tracker per project, because project specific details are needed for the integration with GitLab.
......
...@@ -35,7 +35,7 @@ To enable the GitHub OmniAuth provider you must register your application with G ...@@ -35,7 +35,7 @@ To enable the GitHub OmniAuth provider you must register your application with G
sudo -u git -H editor config/gitlab.yml sudo -u git -H editor config/gitlab.yml
``` ```
1. See [Initial OmniAuth Configuration](README.md#initial-omniauth-configuration) for inital settings. 1. See [Initial OmniAuth Configuration](omniauth.md#initial-omniauth-configuration) for inital settings.
1. Add the provider configuration: 1. Add the provider configuration:
......
# GitLab OAuth2 OmniAuth Provider # Integrate your server with GitLab.com
To enable the GitLab OmniAuth provider you must register your application with GitLab. GitLab will generate a client ID and secret key for you to use. Import projects from GitLab.com and login to your GitLab instance with your GitLab.com account.
1. Sign in to GitLab. To enable the GitLab.com OmniAuth provider you must register your application with GitLab.com.
GitLab.com will generate a application ID and secret key for you to use.
1. Navigate to your settings. 1. Sign in to GitLab.com
1. Navigate to your profile settings.
1. Select "Applications" in the left menu. 1. Select "Applications" in the left menu.
...@@ -15,17 +18,17 @@ To enable the GitLab OmniAuth provider you must register your application with G ...@@ -15,17 +18,17 @@ To enable the GitLab OmniAuth provider you must register your application with G
- Redirect URI: - Redirect URI:
``` ```
http://gitlab.example.com/import/gitlab/callback http://your-gitlab.example.com/import/gitlab/callback
http://gitlab.example.com/users/auth/gitlab/callback http://your-gitlab.example.com/users/auth/gitlab/callback
``` ```
The first link is required for the importer and second for the authorization. The first link is required for the importer and second for the authorization.
1. Select "Submit". 1. Select "Submit".
1. You should now see a Application ID and Secret. Keep this page open as you continue configuration. 1. You should now see a Client ID and Client Secret near the top right of the page (see screenshot).
Keep this page open as you continue configuration.
1. You should now see a Client ID and Client Secret near the top right of the page (see screenshot). Keep this page open as you continue configuration. ![GitHub app](github_app.png) ![GitLab app](gitlab_app.png)
1. On your GitLab server, open the configuration file. 1. On your GitLab server, open the configuration file.
...@@ -43,7 +46,7 @@ To enable the GitLab OmniAuth provider you must register your application with G ...@@ -43,7 +46,7 @@ To enable the GitLab OmniAuth provider you must register your application with G
sudo -u git -H editor config/gitlab.yml sudo -u git -H editor config/gitlab.yml
``` ```
1. See [Initial OmniAuth Configuration](README.md#initial-omniauth-configuration) for inital settings. 1. See [Initial OmniAuth Configuration](omniauth.md#initial-omniauth-configuration) for inital settings.
1. Add the provider configuration: 1. Add the provider configuration:
...@@ -76,4 +79,6 @@ To enable the GitLab OmniAuth provider you must register your application with G ...@@ -76,4 +79,6 @@ To enable the GitLab OmniAuth provider you must register your application with G
1. Restart GitLab for the changes to take effect. 1. Restart GitLab for the changes to take effect.
On the sign in page there should now be a GitLab icon below the regular sign in form. Click the icon to begin the authentication process. GitLab will ask the user to sign in and authorize the GitLab application. If everything goes well the user will be returned to your GitLab instance and will be signed in. On the sign in page there should now be a GitLab.com icon below the regular sign in form.
Click the icon to begin the authentication process. GitLab.com will ask the user to sign in and authorize the GitLab application.
If everything goes well the user will be returned to your GitLab instance and will be signed in.
...@@ -68,9 +68,9 @@ To enable the Google OAuth2 OmniAuth provider you must register your application ...@@ -68,9 +68,9 @@ To enable the Google OAuth2 OmniAuth provider you must register your application
args: { access_type: 'offline', approval_prompt: '' } } args: { access_type: 'offline', approval_prompt: '' } }
``` ```
1. Change 'YOUR APP ID' to the client ID from the GitHub application page from step 7. 1. Change 'YOUR APP ID' to the client ID from the Google Developer page from step 10.
1. Change 'YOUR APP SECRET' to the client secret from the GitHub application page from step 7. 1. Change 'YOUR APP SECRET' to the client secret from the Google Developer page from step 10.
1. Save the configuration file. 1. Save the configuration file.
......
## GitLab as OAuth2 provider ## GitLab as OAuth2 authentication service provider
This document is about using GitLab as an OAuth authentication service provider to sign into other services.
If you want to use other OAuth authentication service providers to sign into GitLab please see the [OAuth2 client documentation](../api/oauth2.md)
OAuth2 provides client applications a 'secure delegated access' to server resources on behalf of a resource owner. Or you can allow users to sign in to your application with their GitLab.com account. OAuth2 provides client applications a 'secure delegated access' to server resources on behalf of a resource owner. Or you can allow users to sign in to your application with their GitLab.com account.
In fact OAuth allows to issue access token to third-party clients by an authorization server, In fact OAuth allows to issue access token to third-party clients by an authorization server,
with the approval of the resource owner, or end-user. with the approval of the resource owner, or end-user.
......
...@@ -70,7 +70,7 @@ Now we can choose one or more of the Supported Providers below to continue confi ...@@ -70,7 +70,7 @@ Now we can choose one or more of the Supported Providers below to continue confi
## Supported Providers ## Supported Providers
- [GitHub](github.md) - [GitHub](github.md)
- [GitLab](gitlab.md) - [GitLab.com](gitlab.md)
- [Google](google.md) - [Google](google.md)
- [Shibboleth](shibboleth.md) - [Shibboleth](shibboleth.md)
- [Twitter](twitter.md) - [Twitter](twitter.md)
......
...@@ -137,7 +137,7 @@ with the name of your bucket: ...@@ -137,7 +137,7 @@ with the name of your bucket:
Please be informed that a backup does not store your configuration files. Please be informed that a backup does not store your configuration files.
If you use an Omnibus package please see the [instructions in the readme to backup your configuration](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md#backup-and-restore-omnibus-gitlab-configuration). If you use an Omnibus package please see the [instructions in the readme to backup your configuration](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md#backup-and-restore-omnibus-gitlab-configuration).
If you have a cookbook installation there should be a copy of your configuration in Chef. If you have a cookbook installation there should be a copy of your configuration in Chef.
If you have a manual installation please consider backing up your `gitlab.yml` file, any SSL keys and certificates, and your [SSH host keys](https://superuser.com/questions/532040/copy-ssh-keys-from-one-server-to-another-server/532079#532079). If you have an installation from source, please consider backing up your `gitlab.yml` file, any SSL keys and certificates, and your [SSH host keys](https://superuser.com/questions/532040/copy-ssh-keys-from-one-server-to-another-server/532079#532079).
## Restore a previously created backup ## Restore a previously created backup
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
- For omnibus-gitlab, it is located at: `/var/opt/gitlab/git-data/repositories` by default, unless you changed - For omnibus-gitlab, it is located at: `/var/opt/gitlab/git-data/repositories` by default, unless you changed
it in the `/etc/gitlab/gitlab.rb` file. it in the `/etc/gitlab/gitlab.rb` file.
- For manual installations, it is usually located at: `/home/git/repositories` or you can see where - For installations from source, it is usually located at: `/home/git/repositories` or you can see where
your repositories are located by looking at `config/gitlab.yml` under the `gitlab_shell => repos_path` entry. your repositories are located by looking at `config/gitlab.yml` under the `gitlab_shell => repos_path` entry.
New folder needs to have git user ownership and read/write/execute access for git user and its group: New folder needs to have git user ownership and read/write/execute access for git user and its group:
...@@ -47,7 +47,7 @@ with `/home/git`. ...@@ -47,7 +47,7 @@ with `/home/git`.
$ sudo gitlab-rake gitlab:import:repos $ sudo gitlab-rake gitlab:import:repos
``` ```
#### Manual Installation #### Installation from source
Before running this command you need to change the directory to where your GitLab installation is located: Before running this command you need to change the directory to where your GitLab installation is located:
......
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
GitLab 6.0 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489. GitLab 6.0 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489.
**You need to follow this guide first, before updating past 6.0, as it contains critical migration steps that are only present
in the `6-0-stable` branch**
## Deprecations ## Deprecations
### Global projects ### Global projects
......
# From 6.x or 7.x to 7.7 # From 6.x or 7.x to 7.8
*Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/6.x-or-7.x-to-7.4.md) for the most up to date instructions.* *Make sure you view this [upgrade guide from the `master` branch](../../../master/doc/update/6.x-or-7.x-to-7.8.md) for the most up to date instructions.*
This allows you to upgrade any version of GitLab from 6.0 and up (including 7.0 and up) to 7.7. This allows you to upgrade any version of GitLab from 6.0 and up (including 7.0 and up) to 7.8.
## Global issue numbers ## Global issue numbers
...@@ -71,7 +71,7 @@ sudo -u git -H git checkout -- db/schema.rb # local changes will be restored aut ...@@ -71,7 +71,7 @@ sudo -u git -H git checkout -- db/schema.rb # local changes will be restored aut
For GitLab Community Edition: For GitLab Community Edition:
```bash ```bash
sudo -u git -H git checkout 7-7-stable sudo -u git -H git checkout 7-8-stable
``` ```
OR OR
...@@ -79,7 +79,7 @@ OR ...@@ -79,7 +79,7 @@ OR
For GitLab Enterprise Edition: For GitLab Enterprise Edition:
```bash ```bash
sudo -u git -H git checkout 7-7-stable-ee sudo -u git -H git checkout 7-8-stable-ee
``` ```
## 4. Install additional packages ## 4. Install additional packages
...@@ -123,7 +123,7 @@ sudo apt-get install libkrb5-dev ...@@ -123,7 +123,7 @@ sudo apt-get install libkrb5-dev
```bash ```bash
cd /home/git/gitlab-shell cd /home/git/gitlab-shell
sudo -u git -H git fetch sudo -u git -H git fetch
sudo -u git -H git checkout v2.4.1 sudo -u git -H git checkout v2.4.3
``` ```
## 7. Install libs, migrations, etc. ## 7. Install libs, migrations, etc.
...@@ -158,14 +158,14 @@ sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab ...@@ -158,14 +158,14 @@ sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab
TIP: to see what changed in `gitlab.yml.example` in this release use next command: TIP: to see what changed in `gitlab.yml.example` in this release use next command:
``` ```
git diff 6-0-stable:config/gitlab.yml.example 7-7-stable:config/gitlab.yml.example git diff 6-0-stable:config/gitlab.yml.example 7-8-stable:config/gitlab.yml.example
``` ```
* Make `/home/git/gitlab/config/gitlab.yml` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-7-stable/config/gitlab.yml.example but with your settings. * Make `/home/git/gitlab/config/gitlab.yml` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-8-stable/config/gitlab.yml.example but with your settings.
* Make `/home/git/gitlab/config/unicorn.rb` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-7-stable/config/unicorn.rb.example but with your settings. * Make `/home/git/gitlab/config/unicorn.rb` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-8-stable/config/unicorn.rb.example but with your settings.
* Make `/home/git/gitlab-shell/config.yml` the same as https://gitlab.com/gitlab-org/gitlab-shell/blob/v2.4.0/config.yml.example but with your settings. * Make `/home/git/gitlab-shell/config.yml` the same as https://gitlab.com/gitlab-org/gitlab-shell/blob/v2.4.3/config.yml.example but with your settings.
* HTTP setups: Make `/etc/nginx/sites-available/gitlab` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-7-stable/lib/support/nginx/gitlab but with your settings. * HTTP setups: Make `/etc/nginx/sites-available/gitlab` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-8-stable/lib/support/nginx/gitlab but with your settings.
* HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-7-stable/lib/support/nginx/gitlab-ssl but with your settings. * HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-8-stablef/lib/support/nginx/gitlab-ssl but with your settings.
* Copy rack attack middleware config * Copy rack attack middleware config
```bash ```bash
...@@ -235,7 +235,7 @@ SET foreign_key_checks = 1; ...@@ -235,7 +235,7 @@ SET foreign_key_checks = 1;
# Find MySQL users # Find MySQL users
mysql> SELECT user FROM mysql.user WHERE user LIKE '%git%'; mysql> SELECT user FROM mysql.user WHERE user LIKE '%git%';
# If git user exists and gitlab user does not exist # If git user exists and gitlab user does not exist
# you are done with the database cleanup tasks # you are done with the database cleanup tasks
mysql> \q mysql> \q
...@@ -273,11 +273,11 @@ mysql> \q ...@@ -273,11 +273,11 @@ mysql> \q
sudo -u git -H editor /home/git/gitlab/config/database.yml sudo -u git -H editor /home/git/gitlab/config/database.yml
``` ```
## Things went south? Revert to previous version (6.0) ## Things went south? Revert to previous version (7.0)
### 1. Revert the code to the previous version ### 1. Revert the code to the previous version
Follow the [upgrade guide from 5.4 to 6.0](5.4-to-6.0.md), except for the database migration (the backup is already migrated to the previous version). Follow the [upgrade guide from 6.9 to 7.0](6.9-to-7.0.md), except for the database migration (the backup is already migrated to the previous version).
### 2. Restore from the backup: ### 2. Restore from the backup:
......
# From 7.7 to 7.8
### 0. Stop server
sudo service gitlab stop
### 1. Backup
```bash
cd /home/git/gitlab
sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
```
### 2. Get latest code
```bash
sudo -u git -H git fetch --all
sudo -u git -H git checkout -- db/schema.rb # local changes will be restored automatically
```
For GitLab Community Edition:
```bash
sudo -u git -H git checkout 7-8-stable
```
OR
For GitLab Enterprise Edition:
```bash
sudo -u git -H git checkout 7-8-stable-ee
```
### 3. Update gitlab-shell
```bash
cd /home/git/gitlab-shell
sudo -u git -H git fetch
sudo -u git -H git checkout v2.4.3
```
### 4. Install libs, migrations, etc.
```bash
sudo apt-get install libkrb5-dev
cd /home/git/gitlab
# MySQL installations (note: the line below states '--without ... postgres')
sudo -u git -H bundle install --without development test postgres --deployment
# PostgreSQL installations (note: the line below states '--without ... mysql')
sudo -u git -H bundle install --without development test mysql --deployment
# Run database migrations
sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
# Clean up assets and cache
sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production
# Update init.d script
sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab
```
### 5. Update config files
#### New configuration options for `gitlab.yml`
There are new configuration options available for [`gitlab.yml`](config/gitlab.yml.example). View them with the command below and apply them to your current `gitlab.yml`.
```
git diff origin/7-6-stable:config/gitlab.yml.example origin/7-8-stable:config/gitlab.yml.example
```
#### Change Nginx settings
* HTTP setups: Make `/etc/nginx/sites-available/gitlab` the same as [`lib/support/nginx/gitlab`](/lib/support/nginx/gitlab) but with your settings
* HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as [`lib/support/nginx/gitlab-ssl`](/lib/support/nginx/gitlab-ssl) but with your setting
#### Setup time zone (optional)
Consider setting the time zone in `gitlab.yml` otherwise GitLab will default to UTC. If you set a time zone previously in [`application.rb`](config/application.rb) (unlikely), unset it.
### 6. Start application
sudo service gitlab start
sudo service nginx restart
### 7. Check application status
Check if GitLab and its environment are configured correctly:
sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production
To make sure you didn't miss anything run a more thorough check with:
sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
If all items are green, then congratulations upgrade is complete!
### 8. GitHub settings (if applicable)
If you are using GitHub as an OAuth provider for authentication, you should change the callback URL so that it
only contains a root URL (ex. `https://gitlab.example.com/`)
## Things went south? Revert to previous version (7.6)
### 1. Revert the code to the previous version
Follow the [upgrade guide from 7.5 to 7.6](7.5-to-7.6.md), except for the database migration
(The backup is already migrated to the previous version)
### 2. Restore from the backup:
```bash
cd /home/git/gitlab
sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production
```
If you have more than one backup *.tar file(s) please add `BACKUP=timestamp_of_backup` to the command above.
...@@ -4,11 +4,11 @@ Depending on the installation method and your GitLab version, there are multiple ...@@ -4,11 +4,11 @@ Depending on the installation method and your GitLab version, there are multiple
- [Omnibus update guide](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/update.md) contains the steps needed to update a GitLab [package](https://about.gitlab.com/downloads/). - [Omnibus update guide](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/update.md) contains the steps needed to update a GitLab [package](https://about.gitlab.com/downloads/).
## Manual Installation ## Installation from source
- [The individual upgrade guides](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/update) are for those who have installed GitLab manually. - [The individual upgrade guides](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/update) are for those who have installed GitLab from source.
- [The CE to EE update guides](https://gitlab.com/subscribers/gitlab-ee/tree/master/doc/update) are for subscribers of the Enterprise Edition only. The steps are very similar to a version upgrade: stop the server, get the code, update config files for the new functionality, install libs and do migrations, update the init script, start the application and check the application status. - [The CE to EE update guides](https://gitlab.com/subscribers/gitlab-ee/tree/master/doc/update) are for subscribers of the Enterprise Edition only. The steps are very similar to a version upgrade: stop the server, get the code, update config files for the new functionality, install libs and do migrations, update the init script, start the application and check the application status.
- [Upgrader](upgrader.md) is an automatic ruby script that performs the update for manual installations. - [Upgrader](upgrader.md) is an automatic ruby script that performs the update for installations from source.
- [Patch versions](patch_versions.md) guide includes the steps needed for a patch version, eg. 6.2.0 to 6.2.1. - [Patch versions](patch_versions.md) guide includes the steps needed for a patch version, eg. 6.2.0 to 6.2.1.
## Miscellaneous ## Miscellaneous
......
...@@ -27,11 +27,11 @@ Feature: Dashboard ...@@ -27,11 +27,11 @@ Feature: Dashboard
Scenario: I should see User joined Project event Scenario: I should see User joined Project event
Given user with name "John Doe" joined project "Shop" Given user with name "John Doe" joined project "Shop"
When I visit dashboard page When I visit dashboard page
Then I should see "John Doe joined project at Shop" event Then I should see "John Doe joined project Shop" event
@javascript @javascript
Scenario: I should see User left Project event Scenario: I should see User left Project event
Given user with name "John Doe" joined project "Shop" Given user with name "John Doe" joined project "Shop"
And user with name "John Doe" left project "Shop" And user with name "John Doe" left project "Shop"
When I visit dashboard page When I visit dashboard page
Then I should see "John Doe left project at Shop" event Then I should see "John Doe left project Shop" event
...@@ -106,24 +106,19 @@ Feature: Project Active Tab ...@@ -106,24 +106,19 @@ Feature: Project Active Tab
And no other sub tabs should be active And no other sub tabs should be active
And the active main tab should be Commits And the active main tab should be Commits
# Sub Tabs: Issues
Scenario: On Project Issues/Browse Scenario: On Project Issues/Browse
Given I visit my project's issues page Given I visit my project's issues page
Then the active sub tab should be Issues Then the active main tab should be Issues
And no other sub tabs should be active And no other main tabs should be active
And the active main tab should be Issues
Scenario: On Project Issues/Milestones Scenario: On Project Issues/Milestones
Given I visit my project's issues page Given I visit my project's issues page
And I click the "Milestones" tab And I click the "Milestones" tab
Then the active sub tab should be Milestones Then the active main tab should be Milestones
And no other sub tabs should be active And no other main tabs should be active
And the active main tab should be Issues
Scenario: On Project Issues/Labels Scenario: On Project Issues/Labels
Given I visit my project's issues page Given I visit my project's issues page
And I click the "Labels" tab And I click the "Labels" tab
Then the active sub tab should be Labels Then the active main tab should be Labels
And no other sub tabs should be active And no other main tabs should be active
And the active main tab should be Issues
...@@ -37,8 +37,8 @@ class Spinach::Features::Dashboard < Spinach::FeatureSteps ...@@ -37,8 +37,8 @@ class Spinach::Features::Dashboard < Spinach::FeatureSteps
) )
end end
step 'I should see "John Doe joined project at Shop" event' do step 'I should see "John Doe joined project Shop" event' do
page.should have_content "John Doe joined project at #{project.name_with_namespace}" page.should have_content "John Doe joined project #{project.name_with_namespace}"
end end
step 'user with name "John Doe" left project "Shop"' do step 'user with name "John Doe" left project "Shop"' do
...@@ -50,8 +50,8 @@ class Spinach::Features::Dashboard < Spinach::FeatureSteps ...@@ -50,8 +50,8 @@ class Spinach::Features::Dashboard < Spinach::FeatureSteps
) )
end end
step 'I should see "John Doe left project at Shop" event' do step 'I should see "John Doe left project Shop" event' do
page.should have_content "John Doe left project at #{project.name_with_namespace}" page.should have_content "John Doe left project #{project.name_with_namespace}"
end end
step 'I have group with projects' do step 'I have group with projects' do
......
...@@ -93,11 +93,11 @@ class Spinach::Features::ProjectActiveTab < Spinach::FeatureSteps ...@@ -93,11 +93,11 @@ class Spinach::Features::ProjectActiveTab < Spinach::FeatureSteps
ensure_active_sub_tab('Issues') ensure_active_sub_tab('Issues')
end end
step 'the active sub tab should be Milestones' do step 'the active main tab should be Milestones' do
ensure_active_sub_tab('Milestones') ensure_active_main_tab('Milestones')
end end
step 'the active sub tab should be Labels' do step 'the active main tab should be Labels' do
ensure_active_sub_tab('Labels') ensure_active_main_tab('Labels')
end end
end end
...@@ -253,7 +253,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps ...@@ -253,7 +253,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps
end end
step 'I should still see a comment like "Line is correct" in the first file' do step 'I should still see a comment like "Line is correct" in the first file' do
within '.files [id^=diff]:nth-child(1) .note-text' do within '.files [id^=diff]:nth-child(1) .note-body > .note-text' do
page.should have_visible_content "Line is correct" page.should have_visible_content "Line is correct"
end end
end end
...@@ -271,7 +271,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps ...@@ -271,7 +271,7 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps
end end
step 'I should see comments on the side-by-side diff page' do step 'I should see comments on the side-by-side diff page' do
within '.files [id^=diff]:nth-child(1) .parallel .note-text' do within '.files [id^=diff]:nth-child(1) .parallel .note-body > .note-text' do
page.should have_visible_content "Line is correct" page.should have_visible_content "Line is correct"
end end
end end
......
...@@ -116,7 +116,7 @@ module SharedNote ...@@ -116,7 +116,7 @@ module SharedNote
end end
step 'The comment with the header should not have an ID' do step 'The comment with the header should not have an ID' do
within(".note-text") do within(".note-body > .note-text") do
page.should have_content("Comment with a header") page.should have_content("Comment with a header")
page.should_not have_css("#comment-with-a-header") page.should_not have_css("#comment-with-a-header")
end end
......
...@@ -65,7 +65,7 @@ module API ...@@ -65,7 +65,7 @@ module API
end end
class Group < Grape::Entity class Group < Grape::Entity
expose :id, :name, :path, :owner_id, :description expose :id, :name, :path, :description
end end
class GroupDetail < Group class GroupDetail < Group
......
...@@ -33,9 +33,9 @@ module API ...@@ -33,9 +33,9 @@ module API
attrs = attributes_for_keys [:name, :path, :description] attrs = attributes_for_keys [:name, :path, :description]
@group = Group.new(attrs) @group = Group.new(attrs)
@group.owner = current_user
if @group.save if @group.save
@group.add_owner(current_user)
present @group, with: Entities::Group present @group, with: Entities::Group
else else
render_api_error!("Failed to save group #{@group.errors.messages}", 400) render_api_error!("Failed to save group #{@group.errors.messages}", 400)
......
...@@ -83,7 +83,7 @@ module API ...@@ -83,7 +83,7 @@ module API
end end
def authenticate_by_gitlab_shell_token! def authenticate_by_gitlab_shell_token!
unauthorized! unless secret_token == params['secret_token'] unauthorized! unless secret_token == params['secret_token'].try(:chomp)
end end
def authenticated_as_admin! def authenticated_as_admin!
...@@ -236,7 +236,7 @@ module API ...@@ -236,7 +236,7 @@ module API
end end
def secret_token def secret_token
File.read(Rails.root.join('.gitlab_shell_secret')) File.read(Rails.root.join('.gitlab_shell_secret')).chomp
end end
def handle_member_errors(errors) def handle_member_errors(errors)
......
...@@ -74,7 +74,7 @@ module API ...@@ -74,7 +74,7 @@ module API
if message = BroadcastMessage.current if message = BroadcastMessage.current
present message, with: Entities::BroadcastMessage present message, with: Entities::BroadcastMessage
else else
not_found! {}
end end
end end
end end
......
module Gitlab module Gitlab
module CurrentSettings module CurrentSettings
def current_application_settings def current_application_settings
if ActiveRecord::Base.connected? && ActiveRecord::Base.connection.table_exists?('application_settings') key = :current_application_settings
ApplicationSetting.current ||
ApplicationSetting.create_from_defaults RequestStore.store[key] ||= begin
else if ActiveRecord::Base.connected? && ActiveRecord::Base.connection.table_exists?('application_settings')
fake_application_settings RequestStore.store[:current_application_settings] =
(ApplicationSetting.current || ApplicationSetting.create_from_defaults)
else
fake_application_settings
end
end end
end end
......
...@@ -6,6 +6,8 @@ module Gitlab ...@@ -6,6 +6,8 @@ module Gitlab
attr_reader :params, :project, :git_cmd, :user attr_reader :params, :project, :git_cmd, :user
def self.can_push_to_branch?(user, project, ref) def self.can_push_to_branch?(user, project, ref)
return false unless user
if project.protected_branch?(ref) && if project.protected_branch?(ref) &&
!(project.developers_can_push_to_protected_branch?(ref) && project.team.developer?(user)) !(project.developers_can_push_to_protected_branch?(ref) && project.team.developer?(user))
user.can?(:push_code_to_protected_branches, project) user.can?(:push_code_to_protected_branches, project)
......
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnp2mUaLBoHFX127ysonX
OihiGpI4098eFfH1iAxpKHIof0vs0jFF05IUScNXJZ1U3w8G1U/unY/wGGa3NzAb
ZfDd22eOF6X2Gfiey6U4w9dFf0/UT5x1bphlpX357yh4O9oWWuNaWD062DTbOOsJ
U6UW2U/sZAu/QScys0Nw+gJ58t93hb4jFq+nO5IAQc6g4S8ek5YvIXOshFEpF2in
ZLbSYowx92+9GzfjvdQ7fk0Q2ssg0zfScVa6FY8n019osz0SC3wcSd/qicdfecpu
7oycpd9YDqk4lufE1qVMOsgE8OO4KXMrByz2f+T0p/bH9zdBa5HYylf1T7i60hIL
kQIDAQAB
-----END PUBLIC KEY-----
...@@ -81,7 +81,7 @@ describe 'Comments' do ...@@ -81,7 +81,7 @@ describe 'Comments' do
within("#note_#{note.id}") do within("#note_#{note.id}") do
expect(find('.current-note-edit-form', visible: true)).to be_visible expect(find('.current-note-edit-form', visible: true)).to be_visible
expect(find('.note-edit-form', visible: true)).to be_visible expect(find('.note-edit-form', visible: true)).to be_visible
expect(find(:css, '.note-text', visible: false)).not_to be_visible expect(find(:css, '.note-body > .note-text', visible: false)).not_to be_visible
end end
end end
......
...@@ -584,7 +584,7 @@ describe GitlabMarkdownHelper do ...@@ -584,7 +584,7 @@ describe GitlabMarkdownHelper do
it "should leave code blocks untouched" do it "should leave code blocks untouched" do
allow(helper).to receive(:user_color_scheme_class).and_return(:white) allow(helper).to receive(:user_color_scheme_class).and_return(:white)
target_html = "<pre class=\"code highlight white plaintext\"><code>some code from $40\nhere too\n</code></pre>\n" target_html = "<pre class=\"code highlight white plaintext\"><code>some code from $#{snippet.id}\nhere too\n</code></pre>\n"
expect(helper.markdown("\n some code from $#{snippet.id}\n here too\n")). expect(helper.markdown("\n some code from $#{snippet.id}\n here too\n")).
to eq(target_html) to eq(target_html)
...@@ -638,6 +638,18 @@ describe GitlabMarkdownHelper do ...@@ -638,6 +638,18 @@ describe GitlabMarkdownHelper do
expect(markdown(actual)).to match(expected) expect(markdown(actual)).to match(expected)
end end
it "should handle relative urls for a file in master with an anchor" do
actual = "[GitLab API doc](doc/api/README.md#section)\n"
expected = "<p><a href=\"/#{project.path_with_namespace}/blob/#{@ref}/doc/api/README.md#section\">GitLab API doc</a></p>\n"
expect(markdown(actual)).to match(expected)
end
it "should not handle relative urls for the current file with an anchor" do
actual = "[GitLab API doc](#section)\n"
expected = "<p><a href=\"#section\">GitLab API doc</a></p>\n"
expect(markdown(actual)).to match(expected)
end
it "should handle relative urls for a directory in master" do it "should handle relative urls for a directory in master" do
actual = "[GitLab API doc](doc/api)\n" actual = "[GitLab API doc](doc/api)\n"
expected = "<p><a href=\"/#{project.path_with_namespace}/tree/#{@ref}/doc/api\">GitLab API doc</a></p>\n" expected = "<p><a href=\"/#{project.path_with_namespace}/tree/#{@ref}/doc/api\">GitLab API doc</a></p>\n"
......
...@@ -32,7 +32,8 @@ describe API::API, api: true do ...@@ -32,7 +32,8 @@ describe API::API, api: true do
it do it do
get api("/internal/broadcast_message"), secret_token: secret_token get api("/internal/broadcast_message"), secret_token: secret_token
expect(response.status).to eq(404) expect(response.status).to eq(200)
expect(json_response).to be_empty
end end
end end
end end
......
...@@ -347,7 +347,7 @@ describe API::API, api: true do ...@@ -347,7 +347,7 @@ describe API::API, api: true do
end end
describe 'GET /projects/:id/events' do describe 'GET /projects/:id/events' do
before { project_member } before { project_member2 }
it 'should return a project events' do it 'should return a project events' do
get api("/projects/#{project.id}/events", user) get api("/projects/#{project.id}/events", user)
...@@ -356,7 +356,7 @@ describe API::API, api: true do ...@@ -356,7 +356,7 @@ describe API::API, api: true do
expect(json_event['action_name']).to eq('joined') expect(json_event['action_name']).to eq('joined')
expect(json_event['project_id'].to_i).to eq(project.id) expect(json_event['project_id'].to_i).to eq(project.id)
expect(json_event['author_username']).to eq(user.username) expect(json_event['author_username']).to eq(user3.username)
end end
it 'should return a 404 error if not found' do it 'should return a 404 error if not found' do
......
...@@ -22,16 +22,7 @@ module TestEnv ...@@ -22,16 +22,7 @@ module TestEnv
# Disable mailer for spinach tests # Disable mailer for spinach tests
disable_mailer if opts[:mailer] == false disable_mailer if opts[:mailer] == false
# Clean /tmp/tests clean_test_path
tmp_test_path = Rails.root.join('tmp', 'tests')
if File.directory?(tmp_test_path)
Dir.entries(tmp_test_path).each do |entry|
unless ['.', '..', 'gitlab-shell', factory_repo_name].include?(entry)
FileUtils.rm_r(File.join(tmp_test_path, entry))
end
end
end
FileUtils.mkdir_p(repos_path) FileUtils.mkdir_p(repos_path)
...@@ -50,15 +41,30 @@ module TestEnv ...@@ -50,15 +41,30 @@ module TestEnv
allow_any_instance_of(NotificationService).to receive(:mailer).and_call_original allow_any_instance_of(NotificationService).to receive(:mailer).and_call_original
end end
# Clean /tmp/tests
#
# Keeps gitlab-shell and gitlab-test
def clean_test_path
tmp_test_path = Rails.root.join('tmp', 'tests', '**')
Dir[tmp_test_path].each do |entry|
unless File.basename(entry) =~ /\Agitlab-(shell|test)\z/
FileUtils.rm_rf(entry)
end
end
end
def setup_gitlab_shell def setup_gitlab_shell
`rake gitlab:shell:install` unless File.directory?(Rails.root.join(*%w(tmp tests gitlab-shell)))
`rake gitlab:shell:install`
end
end end
def setup_factory_repo def setup_factory_repo
clone_url = "https://gitlab.com/gitlab-org/#{factory_repo_name}.git" clone_url = "https://gitlab.com/gitlab-org/#{factory_repo_name}.git"
unless File.directory?(factory_repo_path) unless File.directory?(factory_repo_path)
system(*%W(git clone #{clone_url} #{factory_repo_path})) system(*%W(git clone -q #{clone_url} #{factory_repo_path}))
end end
Dir.chdir(factory_repo_path) do Dir.chdir(factory_repo_path) do
...@@ -79,7 +85,7 @@ module TestEnv ...@@ -79,7 +85,7 @@ module TestEnv
end end
# We must copy bare repositories because we will push to them. # We must copy bare repositories because we will push to them.
system(*%W(git clone --bare #{factory_repo_path} #{factory_repo_path_bare})) system(*%W(git clone -q --bare #{factory_repo_path} #{factory_repo_path_bare}))
end end
def copy_repo(project) def copy_repo(project)
...@@ -101,7 +107,7 @@ module TestEnv ...@@ -101,7 +107,7 @@ module TestEnv
end end
def factory_repo_path_bare def factory_repo_path_bare
factory_repo_path.to_s + '_bare' "#{factory_repo_path}_bare"
end end
def factory_repo_name def factory_repo_name
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment