diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9084d99db3ac9baa5eb07992a617552367364b3c..a0f9ce2d0da58858a8c3c9cb81604e3120b5159b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -36,7 +36,7 @@ We welcome pull requests with fixes and improvements to GitLab code, tests, and/ ### Pull request guidelines -If you can, please submit a pull request with the fix or improvements including tests. If you don't know how to fix the issue but can write a test that exposes the issue we will accept that as well. The workflow to make a pull request is as follows: +If you can, please submit a pull request with the fix or improvements including tests. If you don't know how to fix the issue but can write a test that exposes the issue we will accept that as well. In general bug fixes that include a regression test are merged quickly while new features without proper tests are least likely to receive timely feedback. The workflow to make a pull request is as follows: 1. Fork the project on GitHub 1. Create a feature branch @@ -51,10 +51,11 @@ We will accept pull requests if: * The code has proper tests and all tests pass (or it is a test exposing a failure in existing code) * It can be merged without problems (if not please use: `git rebase master`) * It doesn't break any existing functionality -* It's quality code that conforms to the [Rails style guide](https://github.com/bbatsov/rails-style-guide) and best practices +* It's quality code that conforms to the [Ruby](https://github.com/bbatsov/ruby-style-guide) and [Rails](https://github.com/bbatsov/rails-style-guide) style guides and best practices * The description includes a motive for your change and the method you used to achieve it * It keeps the GitLab code base clean and well structured * We think other users will benefit from the same functionality * If it makes changes to the UI the pull request should include screenshots +* It is a single commit (please use git rebase -i to squash commits) For examples of feedback on pull requests please look at already [closed pull requests](https://github.com/gitlabhq/gitlabhq/pulls?direction=desc&page=1&sort=created&state=closed). diff --git a/README.md b/README.md index 600fcff6d49afef3783ad9987a7de24ade6fce9f..b5b39648a014b8012c6b0c52ebdf1062662b81be 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ ![logo](https://raw.github.com/gitlabhq/gitlabhq/master/public/gitlab_logo.png) +![animated-screenshots](http://makeagif.com/media/6-23-2013/AN3Mo6.gif) + ### GitLab allows you to * keep your code secure on your own server * manage repositories, users and access permissions @@ -22,7 +24,7 @@ * [![Code Climate](https://codeclimate.com/github/gitlabhq/gitlabhq.png)](https://codeclimate.com/github/gitlabhq/gitlabhq) -* [![Dependency Status](https://gemnasium.com/gitlabhq/gitlabhq.png)](https://gemnasium.com/gitlabhq/gitlabhq) this button can be yellow (small updates are available) but must not be red (a security fix or an important update is available) +* [![Dependency Status](https://gemnasium.com/gitlabhq/gitlabhq.png)](https://gemnasium.com/gitlabhq/gitlabhq) this button can be yellow (small updates are available) but must not be red (a security fix or an important update is available), gems are updated in major releases of GitLab. * [![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.png?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq) diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee index fb149b7f67786072582b64fb663b7cf83f18b911..130db5bfdbb8b054874c4936708715f58d706122 100644 --- a/app/assets/javascripts/dispatcher.js.coffee +++ b/app/assets/javascripts/dispatcher.js.coffee @@ -1,6 +1,6 @@ $ -> new Dispatcher() - + class Dispatcher constructor: () -> @initSearch() @@ -10,8 +10,6 @@ class Dispatcher page = $('body').attr('data-page') project_id = $('body').attr('data-project-id') - console.log(page) - unless page return false diff --git a/app/assets/stylesheets/gitlab_bootstrap/avatar.scss b/app/assets/stylesheets/gitlab_bootstrap/avatar.scss index ed6ec77b89b3fba4d4acaef08abd63ab314435d7..0b147faf59e9940c64fe4337d3222ce976c8e172 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/avatar.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/avatar.scss @@ -15,6 +15,7 @@ &.s16 { width: 16px; height: 16px; margin-right: 6px; } &.s24 { width: 24px; height: 24px; margin-right: 8px; } + &.s26 { width: 26px; height: 26px; margin-right: 8px; } &.s32 { width: 32px; height: 32px; margin-right: 10px; } &.s90 { width: 90px; height: 90px; margin-right: 15px; } } diff --git a/app/assets/stylesheets/sections/issues.scss b/app/assets/stylesheets/sections/issues.scss index 5a1b476fe252be740348906cda22af8fa616a4bb..ed7902fec3a4f6f8d5ad7e355d55fa241a2eb796 100644 --- a/app/assets/stylesheets/sections/issues.scss +++ b/app/assets/stylesheets/sections/issues.scss @@ -106,3 +106,7 @@ input.check_all_issues { #update_status { width: 100px; } + +.participants { + margin-bottom: 10px; +} diff --git a/app/contexts/merge_requests_load_context.rb b/app/contexts/merge_requests_load_context.rb index fde04085f2606673c964c09224f2dbd8a9038307..fd44572c0eb94224064cf49a3865e72fdab6225d 100644 --- a/app/contexts/merge_requests_load_context.rb +++ b/app/contexts/merge_requests_load_context.rb @@ -9,7 +9,7 @@ class MergeRequestsLoadContext < BaseContext merge_requests = case type when 'all' then merge_requests when 'closed' then merge_requests.closed - when 'assigned-to-me' then merge_requests.opened.assigned(current_user) + when 'assigned-to-me' then merge_requests.opened.assigned_to(current_user) else merge_requests.opened end diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb index dc5aa6e1fb66432e49150629d8259e5929b06a59..d7d50db8a2f89b0fde5331b5d21ff35c510f4c20 100644 --- a/app/helpers/issues_helper.rb +++ b/app/helpers/issues_helper.rb @@ -15,7 +15,7 @@ module IssuesHelper # to allow filtering issues by an unassigned User or Milestone def unassigned_filter # Milestone uses :title, Issue uses :name - OpenStruct.new(id: 0, title: 'Unspecified', name: 'Unassigned') + OpenStruct.new(id: 0, title: 'None (backlog)', name: 'Unassigned') end def issues_filter diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 878b0913769c5ae2839e2b1bf643fdd3f838538a..22aec62e2bfb9ddcc59fa3b8af13861fa142aa5a 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -17,7 +17,7 @@ module ProjectsHelper end def link_to_member(project, author, opts = {}) - default_opts = { avatar: true } + default_opts = { avatar: true, name: true, size: 16 } opts = default_opts.merge(opts) return "(deleted)" unless author @@ -25,10 +25,10 @@ module ProjectsHelper author_html = "" # Build avatar image tag - author_html << image_tag(gravatar_icon(author.try(:email)), width: 16, class: "avatar avatar-inline s16") if opts[:avatar] + author_html << image_tag(gravatar_icon(author.try(:email), opts[:size]), width: opts[:size], class: "avatar avatar-inline #{"s#{opts[:size]}" if opts[:size]}", alt:'') if opts[:avatar] # Build name span tag - author_html << content_tag(:span, sanitize(author.name), class: 'author') + author_html << content_tag(:span, sanitize(author.name), class: 'author') if opts[:name] author_html = author_html.html_safe @@ -62,7 +62,7 @@ module ProjectsHelper def get_project_nav_tabs(project, current_user) nav_tabs = [:home] - if project.repo_exists? && can?(current_user, :download_code, project) + if !project.empty_repo? && can?(current_user, :download_code, project) nav_tabs << [:files, :commits, :network, :graphs] end diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb index 11e3d8eed19935e36f2e3686853560f8c5067c73..384408590647198a7c4b8db5448a1d6d9cbfa7e4 100644 --- a/app/models/concerns/issuable.rb +++ b/app/models/concerns/issuable.rb @@ -6,6 +6,7 @@ # module Issuable extend ActiveSupport::Concern + include Mentionable included do belongs_to :project @@ -97,4 +98,18 @@ module Issuable def votes_count upvotes + downvotes end + + # Return all users participating on the discussion + def participants + users = [] + users << author + users << assignee if is_assigned? + mentions = [] + mentions << self.mentioned_users + notes.each do |note| + users << note.author + mentions << note.mentioned_users + end + users.concat(mentions.reduce([], :|)).uniq + end end diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb new file mode 100644 index 0000000000000000000000000000000000000000..f22070f85043f97b6eef5b10c4884eb8698c969e --- /dev/null +++ b/app/models/concerns/mentionable.rb @@ -0,0 +1,37 @@ +# == Mentionable concern +# +# Contains common functionality shared between Issues and Notes +# +# Used by Issue, Note +# +module Mentionable + extend ActiveSupport::Concern + + def mentioned_users + users = [] + return users if mentionable_text.blank? + has_project = self.respond_to? :project + matches = mentionable_text.scan(/@[a-zA-Z][a-zA-Z0-9_\-\.]*/) + matches.each do |match| + identifier = match.delete "@" + if has_project + id = project.users_projects.joins(:user).where(users: { username: identifier }).pluck(:user_id).first + else + id = User.where(username: identifier).pluck(:id).first + end + users << User.find(id) unless id.blank? + end + users.uniq + end + + def mentionable_text + if self.class == Issue + description + elsif self.class == Note + note + else + nil + end + end + +end diff --git a/app/models/note.rb b/app/models/note.rb index 9a3481faaaa4cdee0599fa7a4b8b3df2de563ca7..56a8749e47d639783162da22f11d55c9d355eff1 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -19,6 +19,8 @@ require 'carrierwave/orm/activerecord' require 'file_size_validator' class Note < ActiveRecord::Base + include Mentionable + attr_accessible :note, :noteable, :noteable_id, :noteable_type, :project_id, :attachment, :line_code, :commit_id diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb index 379d2c54629a266008d11a3cd2fafddef1be360d..b0243481b359cc1298084ad90ab9f150ef589c1b 100644 --- a/app/services/notification_service.rb +++ b/app/services/notification_service.rb @@ -110,9 +110,11 @@ class NotificationService else opts.merge!(noteable_id: note.noteable_id) target = note.noteable - recipients = [] - recipients << target.assignee if target.respond_to?(:assignee) - recipients << target.author if target.respond_to?(:author) + if target.respond_to?(:participants) + recipients = target.participants + else + recipients = [] + end end # Get users who left comment in thread @@ -181,7 +183,12 @@ class NotificationService end def new_resource_email(target, method) - recipients = reject_muted_users([target.assignee], target.project) + if target.respond_to?(:participants) + recipients = target.participants + else + recipients = [] + end + recipients = reject_muted_users(recipients, target.project) recipients = recipients.concat(project_watchers(target.project)).uniq recipients.delete(target.author) diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml index 6cf7152e5f75f2d0ad0308119e351ca0c9d6cfd4..3edd76a7c1b3b2ce004ae421256f1152eec30776 100644 --- a/app/views/admin/users/show.html.haml +++ b/app/views/admin/users/show.html.haml @@ -24,7 +24,7 @@ %h5.title Account: .pull-right - = image_tag gravatar_icon(@admin_user.email, 32), class: "avatar s32" + = image_tag gravatar_icon(@admin_user.email, 32), class:"avatar s32", alt:"" %ul.well-list %li %span.light Name: @@ -62,7 +62,6 @@ %span.light Created by: %strong = link_to @admin_user.created_by.name, [:admin, @admin_user.created_by] - %hr %h5 Add User to Projects diff --git a/app/views/events/_commit.html.haml b/app/views/events/_commit.html.haml index 2d80fc103f6ef21ead4966546377156a0759d11e..b50faf5a25cbe3dd46326e3d5904d8263bf90842 100644 --- a/app/views/events/_commit.html.haml +++ b/app/views/events/_commit.html.haml @@ -1,6 +1,6 @@ %li.commit %p - = link_to commit[:id][0..8], project_commit_path(project, commit[:id]), class: "commit_short_id" + = link_to commit[:id][0..8], project_commit_path(project, commit[:id]), class: "commit_short_id", alt: '' %span= commit[:author][:name] – = image_tag gravatar_icon(commit[:author][:email]), class: "avatar", width: 16 diff --git a/app/views/events/_event.html.haml b/app/views/events/_event.html.haml index e2bf54ea5c93900aaa4c25d1cca5dd5ca405cb2d..80d16631fa0bc4a196a8c7fc9e0778db702aaccd 100644 --- a/app/views/events/_event.html.haml +++ b/app/views/events/_event.html.haml @@ -4,7 +4,7 @@ #{time_ago_in_words(event.created_at)} ago. = cache event do - = image_tag gravatar_icon(event.author_email), class: "avatar s24" + = image_tag gravatar_icon(event.author_email), class: "avatar s24", alt:'' - if event.push? = render "events/event/push", event: event diff --git a/app/views/groups/people.html.haml b/app/views/groups/people.html.haml index 3e4eb082f564b37b2992d4d6b03221862f4d62d0..44f623006eb1480e1e53bd86d09514252625fa7d 100644 --- a/app/views/groups/people.html.haml +++ b/app/views/groups/people.html.haml @@ -12,7 +12,7 @@ %ul.well-list - @users.each do |user| %li - = image_tag gravatar_icon(user.email, 16), class: "avatar s16" + = image_tag gravatar_icon(user.email, 16), class: "avatar s16" , alt: '' %strong= user.name %span.cgray= user.email - if @group.owner == user diff --git a/app/views/issues/_issues.html.haml b/app/views/issues/_issues.html.haml index cc8d8d9cae2316d37131592a4bf82487cfe30cc9..fb15effceb8f6de68e102fa701cc76ee6f04f151 100644 --- a/app/views/issues/_issues.html.haml +++ b/app/views/issues/_issues.html.haml @@ -53,7 +53,7 @@ - @project.users.sort_by(&:name).each do |user| %li = link_to project_issues_with_filter_path(@project, assignee_id: user.id) do - = image_tag gravatar_icon(user.email), class: "avatar s16" + = image_tag gravatar_icon(user.email), class: "avatar s16", alt: '' = user.name .dropdown.inline.prepend-left-10 @@ -63,7 +63,7 @@ - if @milestone.present? %strong= @milestone.title - elsif params[:milestone_id] == "0" - Unspecified + None (backlog) - else Any %b.caret @@ -72,7 +72,7 @@ = link_to project_issues_with_filter_path(@project, milestone_id: nil) do Any = link_to project_issues_with_filter_path(@project, milestone_id: 0) do - Unspecified + None (backlog) - issues_active_milestones.each do |milestone| %li = link_to project_issues_with_filter_path(@project, milestone_id: milestone.id) do diff --git a/app/views/issues/show.html.haml b/app/views/issues/show.html.haml index 2e204b8240dc933edb132f4a591aa01b4a145c9f..891a01f14c9d48f110fa06ded693ba2e6292925a 100644 --- a/app/views/issues/show.html.haml +++ b/app/views/issues/show.html.haml @@ -65,4 +65,9 @@ - else = link_to 'Close Issue', project_issue_path(@project, @issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn grouped close_issue", title: "Close Issue" +.participants + %cite.cgray #{@issue.participants.count} participants + - @issue.participants.each do |participant| + = link_to_member(@project, participant, name: false, size: 24) + .voting_notes#notes= render "notes/notes_with_form" diff --git a/app/views/layouts/_head_panel.html.haml b/app/views/layouts/_head_panel.html.haml index f0b001f6efc26d07696168758b237b1777aa35b8..a539d5b74323fe83857706222adf3703f86c1027 100644 --- a/app/views/layouts/_head_panel.html.haml +++ b/app/views/layouts/_head_panel.html.haml @@ -37,5 +37,4 @@ %i.icon-signout %li = link_to current_user, class: "profile-pic" do - = image_tag gravatar_icon(current_user.email, 26) - + = image_tag(gravatar_icon(current_user.email, 26),alt: '',class: "avatar s26") diff --git a/app/views/notes/_discussion.html.haml b/app/views/notes/_discussion.html.haml index 24cb422817445f186124a86743460a5d15c1ec09..e65a4f390e69af28ceafbbc4bed182d383433bb5 100644 --- a/app/views/notes/_discussion.html.haml +++ b/app/views/notes/_discussion.html.haml @@ -8,7 +8,7 @@ = link_to "javascript:;", class: "js-details-target turn-off js-toggler-target" do %i.icon-eye-open Show discussion - = image_tag gravatar_icon(note.author.email), class: "avatar s32" + = image_tag gravatar_icon(note.author.email), class: "avatar s32", alt: '' %div = link_to_member(@project, note.author, avatar: false) - if note.for_merge_request? diff --git a/app/views/notes/_note.html.haml b/app/views/notes/_note.html.haml index b355e2a0bd4ef4f8cdf8c7c29b9befc1c124bff5..88c450d61f936b5e547adb14e1836f029f5633b4 100644 --- a/app/views/notes/_note.html.haml +++ b/app/views/notes/_note.html.haml @@ -8,7 +8,7 @@ - if(note.author_id == current_user.id) || can?(current_user, :admin_note, @project) = link_to project_note_path(@project, note), title: "Remove comment", method: :delete, confirm: 'Are you sure you want to remove comment?', remote: true, class: "danger js-note-delete" do %i.icon-trash.cred - = image_tag gravatar_icon(note.author.email), class: "avatar s32" + = image_tag gravatar_icon(note.author.email), class: "avatar s32", alt: '' = link_to_member(@project, note.author, avatar: false) %span.note-last-update = time_ago_in_words(note.updated_at) diff --git a/app/views/profiles/show.html.haml b/app/views/profiles/show.html.haml index d4793da898722bf1392b4cc6477846507d6287d9..96870924371c6b1e45d9e67e53a4391a0686da17 100644 --- a/app/views/profiles/show.html.haml +++ b/app/views/profiles/show.html.haml @@ -1,5 +1,5 @@ .profile_avatar_holder - = image_tag gravatar_icon(@user.email, 90) + = image_tag gravatar_icon(@user.email, 90), alt: '' %h3.page_title = @user.name %br diff --git a/app/views/repositories/_branch.html.haml b/app/views/repositories/_branch.html.haml index dd91e14b66b78c8609126776dc3aa84bb0b22077..2115f3c427f3b309065493d9f325edb184f013d9 100644 --- a/app/views/repositories/_branch.html.haml +++ b/app/views/repositories/_branch.html.haml @@ -12,7 +12,7 @@ %td = link_to project_commit_path(@project, commit.id), class: 'commit_short_id' do = commit.short_id - = image_tag gravatar_icon(commit.author_email), class: "avatar s16" + = image_tag gravatar_icon(commit.author_email), class: "avatar s16", alt: '' %span.light = gfm escape_once(truncate(commit.title, length: 40)) %span diff --git a/app/views/repositories/_feed.html.haml b/app/views/repositories/_feed.html.haml index 6bb75265ffb2a649a463c1f16cb2523fbfa1189e..faa3ed1746c1cd1f910756a98ee43ffbc5721953 100644 --- a/app/views/repositories/_feed.html.haml +++ b/app/views/repositories/_feed.html.haml @@ -11,7 +11,7 @@ %div = link_to project_commits_path(@project, commit.id) do %code= commit.short_id - = image_tag gravatar_icon(commit.author_email), class: "", width: 16 + = image_tag gravatar_icon(commit.author_email), class: "", width: 16, alt: '' = gfm escape_once(truncate(commit.title, length: 40)) %td %span.pull-right.cgray diff --git a/app/views/repositories/stats.html.haml b/app/views/repositories/stats.html.haml index 6d1fb4686ea917196dac37860218cdced203c987..fc8ccfe458d85ab1519c70c4a065fcad0cd88ad4 100644 --- a/app/views/repositories/stats.html.haml +++ b/app/views/repositories/stats.html.haml @@ -19,7 +19,7 @@ %ol.styled - @stats.authors[0...50].each do |author| %li - = image_tag gravatar_icon(author.email, 16), class: 'avatar s16' + = image_tag gravatar_icon(author.email, 16), class: 'avatar s16', alt: '' = author.name %small.light= author.email .pull-right diff --git a/app/views/snippets/_snippet.html.haml b/app/views/snippets/_snippet.html.haml index 194eb051ee3c8a762f69e5e382326ab704549f83..a013cdfe16aafe0e451d6fc0f9a66b4dc10fc029 100644 --- a/app/views/snippets/_snippet.html.haml +++ b/app/views/snippets/_snippet.html.haml @@ -25,6 +25,6 @@ = "##{snippet.id}" %span.light by - = image_tag gravatar_icon(snippet.author_email), class: "avatar avatar-inline s16" + = image_tag gravatar_icon(snippet.author_email), class: "avatar avatar-inline s16", alt: '' = snippet.author_name diff --git a/app/views/team_members/_team_member.html.haml b/app/views/team_members/_team_member.html.haml index d829a79213c35bcd0ed7d60916fb2236003edc69..d61513fa03a64d8de9c7e45f10628879bd62055b 100644 --- a/app/views/team_members/_team_member.html.haml +++ b/app/views/team_members/_team_member.html.haml @@ -4,7 +4,7 @@ .row .span4 = link_to user, title: user.name, class: "dark" do - = image_tag gravatar_icon(user.email, 32), class: "avatar s32" + = image_tag gravatar_icon(user.email, 32), class: "avatar s32", alt: '' %strong= truncate(user.name, lenght: 40) %br %small.cgray= user.username diff --git a/app/views/teams/members/_member.html.haml b/app/views/teams/members/_member.html.haml index 17096d2f1cd1afbce7bc3884cdd0a3d78cddf449..19591db03e2630035afeea18feb9b66fc71b5d30 100644 --- a/app/views/teams/members/_member.html.haml +++ b/app/views/teams/members/_member.html.haml @@ -4,7 +4,7 @@ .row .span3 = link_to user_path(user.username), title: user.name, class: "dark" do - = image_tag gravatar_icon(user.email, 40), class: "avatar s32" + = image_tag gravatar_icon(user.email, 40), class: "avatar s32", alt: '' = link_to user_path(user.username), title: user.name, class: "dark" do %strong= truncate(user.name, lenght: 40) %br diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index 10bd90b166a6350bae7df3ec23084c97fee82c85..548458e0d3bbccd3676b6ca052f19fb53fd2669e 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -1,7 +1,7 @@ .row .span8 %h3.page_title - = image_tag gravatar_icon(@user.email, 90), class: "avatar s90" + = image_tag gravatar_icon(@user.email, 90), class: "avatar s90", alt: '' = @user.name - if @user == current_user .pull-right diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example index a612102ab1c1780dcf84264a05ba0a257c3442c1..9f50aab3c28add607e54947310ec125fa39a8390 100644 --- a/config/gitlab.yml.example +++ b/config/gitlab.yml.example @@ -1,4 +1,4 @@ -# # # # # # # # # # # # # # # # # # +# # # # # # # # # # # # # # # # # # # GitLab application config file # # # # # # # # # # # # # # # # # # # # @@ -37,7 +37,7 @@ production: &base # default_can_create_group: false # default: true # default_can_create_team: false # default: true # username_changing_enabled: false # default: true - User can change her username/namespace - + ## Users management # signup_enabled: true # default: false - Account passwords are not sent via the email if signup is enabled. @@ -168,12 +168,12 @@ production: &base # 4. Extra customization # ========================== - extra: + extra: ## Google analytics. Uncomment if you want it # google_analytics_id: '_your_tracking_id' ## Text under sign-in page (Markdown enabled) - # sign_in_text: | + # sign_in_text: | # ![Company Logo](http://www.companydomain.com/logo.png) # [Learn more about CompanyName](http://www.companydomain.com/) diff --git a/db/fixtures/development/09_issues.rb b/db/fixtures/development/09_issues.rb index d13d520e3dd7f4ec7481e372503f79d40554efe5..627579721d0fd656883fa17cc4452f795580ec3b 100644 --- a/db/fixtures/development/09_issues.rb +++ b/db/fixtures/development/09_issues.rb @@ -11,7 +11,7 @@ Gitlab::Seeder.quiet do next unless user user_id = user.id - IssueObserver.current_user = user + Thread.current[:current_user] = user Issue.seed(:id, [{ id: i, diff --git a/db/fixtures/development/10_merge_requests.rb b/db/fixtures/development/10_merge_requests.rb index d122d96235e0e6bb89c78569644b2d3d19076e20..0a8d67d446158a023b112b6c7c6543142a21c68b 100644 --- a/db/fixtures/development/10_merge_requests.rb +++ b/db/fixtures/development/10_merge_requests.rb @@ -17,7 +17,8 @@ Gitlab::Seeder.quiet do next if branches.uniq.size < 2 user_id = user.id - MergeRequestObserver.current_user = user + Thread.current[:current_user] = user + MergeRequest.seed(:id, [{ id: i, source_branch: branches.first, diff --git a/db/migrate/20130326142630_add_index_to_users_authentication_token.rb b/db/migrate/20130326142630_add_index_to_users_authentication_token.rb new file mode 100644 index 0000000000000000000000000000000000000000..d42ef113738aad4a3bd4a9b4bf6d572b36199976 --- /dev/null +++ b/db/migrate/20130326142630_add_index_to_users_authentication_token.rb @@ -0,0 +1,5 @@ +class AddIndexToUsersAuthenticationToken < ActiveRecord::Migration + def change + add_index :users, :authentication_token, unique: true + end +end diff --git a/db/schema.rb b/db/schema.rb index c3c751e3a198733ef9107141241d2519903c7ef5..b755d555630997d7e7b684b754c7342e8fcc3ade 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20130614132337) do +ActiveRecord::Schema.define(:version => 20130326142630) do create_table "deploy_keys_projects", :force => true do |t| t.integer "deploy_key_id", :null => false @@ -298,6 +298,7 @@ ActiveRecord::Schema.define(:version => 20130614132337) do end add_index "users", ["admin"], :name => "index_users_on_admin" + add_index "users", ["authentication_token"], :name => "index_users_on_authentication_token", :unique => true add_index "users", ["email"], :name => "index_users_on_email", :unique => true add_index "users", ["extern_uid", "provider"], :name => "index_users_on_extern_uid_and_provider", :unique => true add_index "users", ["name"], :name => "index_users_on_name" diff --git a/doc/install/databases.md b/doc/install/databases.md index 2d94aa9b4a314ae3e67f0a9c7dcb2cc738922144..5ec1d0c6524e41c76ce7f752e7e8fe0cab2068a4 100644 --- a/doc/install/databases.md +++ b/doc/install/databases.md @@ -11,10 +11,17 @@ GitLab supports the following databases: # Install the database packages sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev + # Pick a database root password (can be anything), type it and press enter + # Retype the database root password and press enter + # Login to MySQL mysql -u root -p - # Create a user for GitLab. (change $password to a real password) + # Type the database root password + + # Create a user for GitLab + # do not type the 'mysql>', this is part of the prompt + # change $password in the command below to a real password you pick mysql> CREATE USER 'gitlab'@'localhost' IDENTIFIED BY '$password'; # Create the GitLab production database @@ -29,6 +36,16 @@ GitLab supports the following databases: # Try connecting to the new database with the new user sudo -u git -H mysql -u gitlab -p -D gitlabhq_production + # Type the password you replaced $password with earlier + + # You should now see a 'mysql>' prompt + + # Quit the database session + mysql> \q + + # You are done installing the database and can go back to the rest of the installation. + + ## PostgreSQL # Install the database packages diff --git a/doc/install/installation.md b/doc/install/installation.md index 425feed1a11850a8bc0b5c700eb750d0c93d511e..a16c5acf1b173aee0c409cfef0e9377f688bf493 100644 --- a/doc/install/installation.md +++ b/doc/install/installation.md @@ -36,10 +36,10 @@ The GitLab installation consists of setting up the following components: `sudo` is not installed on Debian by default. Make sure your system is up-to-date and install it. - # run as root - apt-get update - apt-get upgrade - apt-get install sudo + # run as root! + apt-get update -y + apt-get upgrade -y + apt-get install sudo -y **Note:** Vim is an editor that is used here whenever there are files that need to be @@ -55,7 +55,7 @@ Install the required packages: Make sure you have the right version of Python installed. # Install Python - sudo apt-get install python + sudo apt-get install -y python # Make sure that Python is 2.5+ (3.x is not supported at the moment) python --version @@ -73,15 +73,17 @@ Make sure you have the right version of Python installed. mail server. By default, Debian is shipped with exim4 whereas Ubuntu does not ship with one. The recommended mail server is postfix and you can install it with: - sudo apt-get install postfix + sudo apt-get install -y postfix + +Then select 'Internet Site' and press enter to confirm the hostname. # 2. Ruby -Remove old 1.8 ruby if present +Remove the old Ruby 1.8 if present - sudo apt-get remove ruby1.8 + sudo apt-get remove -y ruby1.8 -Download and compile it: +Download Ruby and compile it: mkdir /tmp/ruby && cd /tmp/ruby curl --progress http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p392.tar.gz | tar xz @@ -92,7 +94,7 @@ Download and compile it: Install the Bundler Gem: - sudo gem install bundler + sudo gem install bundler --no-ri --no-rdoc # 3. System Users @@ -106,28 +108,25 @@ Create a `git` user for Gitlab: GitLab Shell is a ssh access and repository management software developed specially for GitLab. - # Login as git - sudo su git - # Go to home directory cd /home/git # Clone gitlab shell - git clone https://github.com/gitlabhq/gitlab-shell.git + sudo -u git -H git clone https://github.com/gitlabhq/gitlab-shell.git cd gitlab-shell # switch to right version - git checkout v1.4.0 + sudo -u git -H git checkout v1.4.0 - cp config.yml.example config.yml + sudo -u git -H cp config.yml.example config.yml # Edit config and replace gitlab_url # with something like 'http://domain.com/' - vim config.yml + sudo -u git -H vim config.yml # Do setup - ./bin/install + sudo -u git -H ./bin/install # 5. Database @@ -152,8 +151,7 @@ To setup the MySQL/PostgreSQL database and dependencies please see [`doc/install sudo -u git -H git checkout 5-3-stable **Note:** -You can change `5-3-stable` to `master` if you want the *bleeding edge* version, but -do so with caution! +You can change `5-3-stable` to `master` if you want the *bleeding edge* version, but do so with caution! ## Configure it @@ -205,10 +203,18 @@ Make sure to edit both `gitlab.yml` and `puma.rb` to match your setup. # Mysql sudo -u git cp config/database.yml.mysql config/database.yml + or + # PostgreSQL sudo -u git cp config/database.yml.postgresql config/database.yml -Make sure to update username/password in config/database.yml. + # Make sure to update username/password in config/database.yml. + # You only need to adapt the production settings (first part). + # If you followed the database guide then please do as follows: + # Change 'root' to 'gitlab' + # Change 'secure password' with the value you have given to $password + # You can keep the double quotes around the password + sudo -u git -H vim config/database.yml ## Install Gems @@ -216,10 +222,10 @@ Make sure to update username/password in config/database.yml. sudo gem install charlock_holmes --version '0.6.9.4' - # For MySQL (note, the option says "without") + # For MySQL (note, the option says "without ... postgres") sudo -u git -H bundle install --deployment --without development test postgres - # Or for PostgreSQL + # Or for PostgreSQL (note, the option says "without ... mysql") sudo -u git -H bundle install --deployment --without development test mysql @@ -227,6 +233,10 @@ Make sure to update username/password in config/database.yml. sudo -u git -H bundle exec rake gitlab:setup RAILS_ENV=production + # Type 'yes' to create the database. + + # When done you see 'Administrator account created:' + ## Install Init Script @@ -269,7 +279,7 @@ If you can't or don't want to use Nginx as your web server, have a look at the [`Advanced Setup Tips`](./installation.md#advanced-setup-tips) section. ## Installation - sudo apt-get install nginx + sudo apt-get install -y nginx ## Site Configuration @@ -280,10 +290,8 @@ Download an example site config: Make sure to edit the config file to match your setup: - # **YOUR_SERVER_FQDN** to the fully-qualified - # domain name of your host serving GitLab. Also, replace - # the 'listen' line with the following: - # listen 80 default_server; # e.g., listen 192.168.1.1:80; + # Change YOUR_SERVER_FQDN to the fully-qualified + # domain name of your host serving GitLab. sudo vim /etc/nginx/sites-available/gitlab ## Restart diff --git a/doc/update/5.0-to-5.1.md b/doc/update/5.0-to-5.1.md index 2042b27f5dd5618c5d8b72623fe54b5ce3a89712..45fc3436ebeb9ea376998b87cd41636e7160141c 100644 --- a/doc/update/5.0-to-5.1.md +++ b/doc/update/5.0-to-5.1.md @@ -41,6 +41,7 @@ sudo -u git -H cp config/puma.rb.example config/puma.rb sudo -u git -H bundle install --without development test postgres --deployment sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production sudo -u git -H bundle exec rake migrate_merge_requests RAILS_ENV=production +sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production ``` ### 5. Update init.d script with a new one diff --git a/doc/update/5.2-to-5.3.md b/doc/update/5.2-to-5.3.md new file mode 100644 index 0000000000000000000000000000000000000000..4d930d84c7df1f2823898a02f6bf48a9670189c2 --- /dev/null +++ b/doc/update/5.2-to-5.3.md @@ -0,0 +1,80 @@ +# From 5.2 to 5.3 + +### 0. Backup + +It's useful to make a backup just in case things go south: +(With MySQL, this may require granting "LOCK TABLES" privileges to the GitLab user on the database version) + +```bash +cd /home/git/gitlab +sudo -u git -H RAILS_ENV=production bundle exec rake gitlab:backup:create +``` + +### 1. Stop server + + sudo service gitlab stop + +### 2. Get latest code + +```bash +cd /home/git/gitlab +sudo -u git -H git fetch +sudo -u git -H git checkout 5-3-stable +``` + +### 3. Install libs, migrations, etc. + +```bash +cd /home/git/gitlab + +# MySQL +sudo -u git -H bundle install --without development test postgres --deployment + +#PostgreSQL +sudo -u git -H bundle install --without development test mysql --deployment + +sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production +``` + +### 4. Update config files + +* Make `/home/git/gitlab/config/gitlab.yml` same as https://github.com/gitlabhq/gitlabhq/blob/5-3-stable/config/gitlab.yml.example but with your settings. +* Make `/home/git/gitlab/config/puma.rb` same as https://github.com/gitlabhq/gitlabhq/blob/5-3-stable/config/puma.rb.example but with your settings. + +### 5. Update Init script + +```bash +sudo rm /etc/init.d/gitlab +sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlabhq/5-3-stable/lib/support/init.d/gitlab +sudo chmod +x /etc/init.d/gitlab +``` + +### 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 complete! + +## Things went south? Revert to previous version (5.2) + +### 1. Revert the code to the previous version +Follow the [`upgrade guide from 5.1 to 5.2`](5.1-to-5.2.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 RAILS_ENV=production bundle exec rake gitlab:backup:restore +``` diff --git a/lib/support/init.d/gitlab b/lib/support/init.d/gitlab index f4ca07b36765700583c9a3a58ebb0ea005adc4c3..bb0151d9335125738744bc2f6711d88530e370be 100644 --- a/lib/support/init.d/gitlab +++ b/lib/support/init.d/gitlab @@ -51,7 +51,7 @@ start() { exit 1 else if [ `whoami` = root ]; then - execute "rm $SOCKET_PATH/gitlab.socket" + execute "rm -f $SOCKET_PATH/gitlab.socket" execute "RAILS_ENV=production bundle exec puma $DAEMON_OPTS" execute "mkdir -p $PID_PATH && $START_SIDEKIQ > /dev/null 2>&1 &" echo "$DESC started" diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab index be7a378b3aafe40897b83de10737cc2b6d9fe431..3e929c52990de1633104b0448a5cee5e189efb3a 100644 --- a/lib/support/nginx/gitlab +++ b/lib/support/nginx/gitlab @@ -7,7 +7,7 @@ upstream gitlab { } server { - listen YOUR_SERVER_IP:80 default_server; # e.g., listen 192.168.1.1:80; In most cases *:80 is a good idea + listen *:80 default_server; # e.g., listen 192.168.1.1:80; In most cases *:80 is a good idea server_name YOUR_SERVER_FQDN; # e.g., server_name source.example.com; server_tokens off; # don't show the version number, a security best practice root /home/git/gitlab/public; diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb index b2b20ef6b5dd7208208e3176a98a4aafaacc49b2..a716f13a4cd69db4ea6d9cd7cf7653b2efbe35bf 100644 --- a/spec/routing/project_routing_spec.rb +++ b/spec/routing/project_routing_spec.rb @@ -262,7 +262,7 @@ end # project_snippet GET /:project_id/snippets/:id(.:format) snippets#show # PUT /:project_id/snippets/:id(.:format) snippets#update # DELETE /:project_id/snippets/:id(.:format) snippets#destroy -describe Project::SnippetsController, "routing" do +describe Projects::SnippetsController, "routing" do it "to #raw" do get("/gitlabhq/snippets/1/raw").should route_to('projects/snippets#raw', project_id: 'gitlabhq', id: '1') end diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb index 21e4202f4ee9f1841f72bc351e742de5cd2b1bc2..765014823038da691da41b3a1ef0f0667ed32ece 100644 --- a/spec/services/notification_service_spec.rb +++ b/spec/services/notification_service_spec.rb @@ -19,7 +19,7 @@ describe NotificationService do describe 'Notes' do context 'issue note' do let(:issue) { create(:issue, assignee: create(:user)) } - let(:note) { create(:note_on_issue, noteable: issue, project_id: issue.project_id) } + let(:note) { create(:note_on_issue, noteable: issue, project_id: issue.project_id, note: '@mention referenced') } before do build_team(note.project) @@ -30,6 +30,7 @@ describe NotificationService do should_email(@u_watcher.id) should_email(note.noteable.author_id) should_email(note.noteable.assignee_id) + should_email(@u_mentioned.id) should_not_email(note.author_id) should_not_email(@u_participating.id) should_not_email(@u_disabled.id) @@ -235,9 +236,11 @@ describe NotificationService do @u_watcher = create(:user, notification_level: Notification::N_WATCH) @u_participating = create(:user, notification_level: Notification::N_PARTICIPATING) @u_disabled = create(:user, notification_level: Notification::N_DISABLED) + @u_mentioned = create(:user, username: 'mention', notification_level: Notification::N_WATCH) project.team << [@u_watcher, :master] project.team << [@u_participating, :master] project.team << [@u_disabled, :master] + project.team << [@u_mentioned, :master] end end