Commit e16eb912990770c9e5bddece966d2988ed7fa575

Authored by Marin Jankovski
2 parents e130e2f6 80b11370

Merge branch 'master' into relative

@@ -9,7 +9,6 @@ env: @@ -9,7 +9,6 @@ env:
9 - TASK=jasmine:ci 9 - TASK=jasmine:ci
10 before_install: 10 before_install:
11 - sudo apt-get install libicu-dev -y 11 - sudo apt-get install libicu-dev -y
12 - - gem install charlock_holmes -v="0.6.9"  
13 branches: 12 branches:
14 only: 13 only:
15 - 'master' 14 - 'master'
CONTRIBUTING.md
@@ -9,6 +9,10 @@ This guide details how to use issues and pull requests to improve GitLab. @@ -9,6 +9,10 @@ This guide details how to use issues and pull requests to improve GitLab.
9 9
10 If you want to know how the GitLab team handles contributions have a look at [the GitLab contributing process](PROCESS.md). 10 If you want to know how the GitLab team handles contributions have a look at [the GitLab contributing process](PROCESS.md).
11 11
  12 +## Contributor license agreement
  13 +
  14 +By submitting code as an individual you agree to the [individual contributor license agreement](doc/legal/individual_contributor_license_agreement.md). By submitting code as an entity you agree to the [corporate contributor license agreement](doc/legal/corporate_contributor_license_agreement.md).
  15 +
12 ## Closing policy for issues and pull requests 16 ## Closing policy for issues and pull requests
13 17
14 GitLab is a popular open source project and the capacity to deal with issues and pull requests is limited. Out of respect for our volunteers, issues and pull requests not in line with the guidelines listed in this document may be closed without notice. 18 GitLab is a popular open source project and the capacity to deal with issues and pull requests is limited. Out of respect for our volunteers, issues and pull requests not in line with the guidelines listed in this document may be closed without notice.
@@ -64,9 +64,10 @@ If you want to contribute, please first read our [Contributing Guidelines](https @@ -64,9 +64,10 @@ If you want to contribute, please first read our [Contributing Guidelines](https
64 64
65 * [Installation guides](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Unofficial-Installation-Guides) public wiki with unofficial guides to install GitLab on different operating systems. 65 * [Installation guides](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Unofficial-Installation-Guides) public wiki with unofficial guides to install GitLab on different operating systems.
66 66
67 -* [BitNami one-click installers](http://bitnami.com/stack/gitlab)  
68 67
69 -* [TurnKey Linux virtual appliance](http://www.turnkeylinux.org/gitlab) 68 +* [Digital Ocean 1-Click Application Install](https://www.digitalocean.com/) Have a new server up in 55 seconds. Digital Ocean uses SSD disks which is great for an IO intensive app as GitLab. Look for GitLab under 'Select Image' => 'Applications' when creating a droplet.
  69 +
  70 +* [BitNami one-click installers](http://bitnami.com/stack/gitlab) Get an image with GitLab and GitLab CI preinstalled for Amazon Web Services, Azure, VMware or your local server.
70 71
71 72
72 ### New versions and upgrading 73 ### New versions and upgrading
app/assets/javascripts/notes.js
@@ -233,10 +233,12 @@ var NoteList = { @@ -233,10 +233,12 @@ var NoteList = {
233 form.show(); 233 form.show();
234 234
235 var textarea = form.find("textarea"); 235 var textarea = form.find("textarea");
236 - var p = $("<p></p>").text(textarea.val());  
237 - var hidden_div = $('<div class="note-original-content"></div>').append(p);  
238 - form.append(hidden_div);  
239 - hidden_div.hide(); 236 + if (form.find(".note-original-content").length === 0) {
  237 + var p = $("<p></p>").text(textarea.val());
  238 + var hidden_div = $('<div class="note-original-content"></div>').append(p);
  239 + form.append(hidden_div);
  240 + hidden_div.hide();
  241 + }
240 textarea.focus(); 242 textarea.focus();
241 }, 243 },
242 244
@@ -532,6 +534,8 @@ var NoteList = { @@ -532,6 +534,8 @@ var NoteList = {
532 note_text.html(response.note).show(); 534 note_text.html(response.note).show();
533 535
534 var note_form = note_li.find(".note-edit-form"); 536 var note_form = note_li.find(".note-edit-form");
  537 + var original_content = note_form.find(".note-original-content");
  538 + original_content.remove();
535 note_form.hide(); 539 note_form.hide();
536 note_form.find(".btn-save").enableButton(); 540 note_form.find(".btn-save").enableButton();
537 541
app/assets/javascripts/project.js.coffee
@@ -40,3 +40,8 @@ $ -&gt; @@ -40,3 +40,8 @@ $ -&gt;
40 # Ref switcher 40 # Ref switcher
41 $('.project-refs-select').on 'change', -> 41 $('.project-refs-select').on 'change', ->
42 $(@).parents('form').submit() 42 $(@).parents('form').submit()
  43 +
  44 + $('.hide-no-ssh-message').on 'click', (e) ->
  45 + $.cookie('hide_no_ssh_message', 'false')
  46 + $(@).parents('.no-ssh-key-message').hide()
  47 + e.preventDefault()
app/assets/stylesheets/common.scss
@@ -220,7 +220,6 @@ li.note { @@ -220,7 +220,6 @@ li.note {
220 .error-message { 220 .error-message {
221 padding: 10px; 221 padding: 10px;
222 background: #C67; 222 background: #C67;
223 - padding-left: 20px;  
224 margin: 0; 223 margin: 0;
225 color: #FFF; 224 color: #FFF;
226 225
@@ -228,8 +227,18 @@ li.note { @@ -228,8 +227,18 @@ li.note {
228 color: #fff; 227 color: #fff;
229 text-decoration: underline; 228 text-decoration: underline;
230 } 229 }
231 - &.centered {  
232 - text-align: center; 230 +}
  231 +
  232 +.no-ssh-key-message {
  233 + padding: 10px 0;
  234 + background: #C67;
  235 + margin: 0;
  236 + color: #FFF;
  237 + text-align: center;
  238 +
  239 + a {
  240 + color: #fff;
  241 + text-decoration: underline;
233 } 242 }
234 } 243 }
235 244
app/contexts/files/create_context.rb
@@ -33,11 +33,10 @@ module Files @@ -33,11 +33,10 @@ module Files
33 return error("Your changes could not be commited, because file with such name exists") 33 return error("Your changes could not be commited, because file with such name exists")
34 end 34 end
35 35
36 - new_file_action = Gitlab::Satellite::NewFileAction.new(current_user, project, ref, path) 36 + new_file_action = Gitlab::Satellite::NewFileAction.new(current_user, project, ref, file_path)
37 created_successfully = new_file_action.commit!( 37 created_successfully = new_file_action.commit!(
38 params[:content], 38 params[:content],
39 - params[:commit_message],  
40 - file_name, 39 + params[:commit_message]
41 ) 40 )
42 41
43 if created_successfully 42 if created_successfully
app/contexts/files/update_context.rb
@@ -24,8 +24,7 @@ module Files @@ -24,8 +24,7 @@ module Files
24 new_file_action = Gitlab::Satellite::EditFileAction.new(current_user, project, ref, path) 24 new_file_action = Gitlab::Satellite::EditFileAction.new(current_user, project, ref, path)
25 created_successfully = new_file_action.commit!( 25 created_successfully = new_file_action.commit!(
26 params[:content], 26 params[:content],
27 - params[:commit_message],  
28 - params[:last_commit] 27 + params[:commit_message]
29 ) 28 )
30 29
31 if created_successfully 30 if created_successfully
app/mailers/emails/groups.rb
@@ -5,7 +5,7 @@ module Emails @@ -5,7 +5,7 @@ module Emails
5 @group = @membership.group 5 @group = @membership.group
6 6
7 mail(to: @membership.user.email, 7 mail(to: @membership.user.email,
8 - subject: subject("access to group was granted")) 8 + subject: subject("Access to group was granted"))
9 end 9 end
10 end 10 end
11 end 11 end
app/mailers/emails/issues.rb
@@ -3,14 +3,14 @@ module Emails @@ -3,14 +3,14 @@ module Emails
3 def new_issue_email(recipient_id, issue_id) 3 def new_issue_email(recipient_id, issue_id)
4 @issue = Issue.find(issue_id) 4 @issue = Issue.find(issue_id)
5 @project = @issue.project 5 @project = @issue.project
6 - mail(to: recipient(recipient_id), subject: subject("new issue ##{@issue.iid}", @issue.title)) 6 + mail(to: recipient(recipient_id), subject: subject("New issue ##{@issue.iid}", @issue.title))
7 end 7 end
8 8
9 def reassigned_issue_email(recipient_id, issue_id, previous_assignee_id) 9 def reassigned_issue_email(recipient_id, issue_id, previous_assignee_id)
10 @issue = Issue.find(issue_id) 10 @issue = Issue.find(issue_id)
11 @previous_assignee = User.find_by_id(previous_assignee_id) if previous_assignee_id 11 @previous_assignee = User.find_by_id(previous_assignee_id) if previous_assignee_id
12 @project = @issue.project 12 @project = @issue.project
13 - mail(to: recipient(recipient_id), subject: subject("changed issue ##{@issue.iid}", @issue.title)) 13 + mail(to: recipient(recipient_id), subject: subject("Changed issue ##{@issue.iid}", @issue.title))
14 end 14 end
15 15
16 def closed_issue_email(recipient_id, issue_id, updated_by_user_id) 16 def closed_issue_email(recipient_id, issue_id, updated_by_user_id)
@@ -27,7 +27,7 @@ module Emails @@ -27,7 +27,7 @@ module Emails
27 @project = @issue.project 27 @project = @issue.project
28 @updated_by = User.find updated_by_user_id 28 @updated_by = User.find updated_by_user_id
29 mail(to: recipient(recipient_id), 29 mail(to: recipient(recipient_id),
30 - subject: subject("changed issue ##{@issue.iid}", @issue.title)) 30 + subject: subject("Changed issue ##{@issue.iid}", @issue.title))
31 end 31 end
32 end 32 end
33 end 33 end
app/mailers/emails/merge_requests.rb
@@ -2,24 +2,24 @@ module Emails @@ -2,24 +2,24 @@ module Emails
2 module MergeRequests 2 module MergeRequests
3 def new_merge_request_email(recipient_id, merge_request_id) 3 def new_merge_request_email(recipient_id, merge_request_id)
4 @merge_request = MergeRequest.find(merge_request_id) 4 @merge_request = MergeRequest.find(merge_request_id)
5 - mail(to: recipient(recipient_id), subject: subject("new merge request !#{@merge_request.iid}", @merge_request.title)) 5 + mail(to: recipient(recipient_id), subject: subject("New merge request ##{@merge_request.iid}", @merge_request.title))
6 end 6 end
7 7
8 def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id) 8 def reassigned_merge_request_email(recipient_id, merge_request_id, previous_assignee_id)
9 @merge_request = MergeRequest.find(merge_request_id) 9 @merge_request = MergeRequest.find(merge_request_id)
10 @previous_assignee = User.find_by_id(previous_assignee_id) if previous_assignee_id 10 @previous_assignee = User.find_by_id(previous_assignee_id) if previous_assignee_id
11 - mail(to: recipient(recipient_id), subject: subject("changed merge request !#{@merge_request.iid}", @merge_request.title)) 11 + mail(to: recipient(recipient_id), subject: subject("Changed merge request ##{@merge_request.iid}", @merge_request.title))
12 end 12 end
13 13
14 def closed_merge_request_email(recipient_id, merge_request_id, updated_by_user_id) 14 def closed_merge_request_email(recipient_id, merge_request_id, updated_by_user_id)
15 @merge_request = MergeRequest.find(merge_request_id) 15 @merge_request = MergeRequest.find(merge_request_id)
16 @updated_by = User.find updated_by_user_id 16 @updated_by = User.find updated_by_user_id
17 - mail(to: recipient(recipient_id), subject: subject("Closed merge request !#{@merge_request.iid}", @merge_request.title)) 17 + mail(to: recipient(recipient_id), subject: subject("Closed merge request ##{@merge_request.iid}", @merge_request.title))
18 end 18 end
19 19
20 def merged_merge_request_email(recipient_id, merge_request_id) 20 def merged_merge_request_email(recipient_id, merge_request_id)
21 @merge_request = MergeRequest.find(merge_request_id) 21 @merge_request = MergeRequest.find(merge_request_id)
22 - mail(to: recipient(recipient_id), subject: subject("Accepted merge request !#{@merge_request.iid}", @merge_request.title)) 22 + mail(to: recipient(recipient_id), subject: subject("Accepted merge request ##{@merge_request.iid}", @merge_request.title))
23 end 23 end
24 end 24 end
25 25
app/mailers/emails/notes.rb
@@ -4,27 +4,27 @@ module Emails @@ -4,27 +4,27 @@ module Emails
4 @note = Note.find(note_id) 4 @note = Note.find(note_id)
5 @commit = @note.noteable 5 @commit = @note.noteable
6 @project = @note.project 6 @project = @note.project
7 - mail(to: recipient(recipient_id), subject: subject("note for commit #{@commit.short_id}", @commit.title)) 7 + mail(to: recipient(recipient_id), subject: subject("Note for commit #{@commit.short_id}", @commit.title))
8 end 8 end
9 9
10 def note_issue_email(recipient_id, note_id) 10 def note_issue_email(recipient_id, note_id)
11 @note = Note.find(note_id) 11 @note = Note.find(note_id)
12 @issue = @note.noteable 12 @issue = @note.noteable
13 @project = @note.project 13 @project = @note.project
14 - mail(to: recipient(recipient_id), subject: subject("note for issue ##{@issue.iid}")) 14 + mail(to: recipient(recipient_id), subject: subject("Note for issue ##{@issue.iid}"))
15 end 15 end
16 16
17 def note_merge_request_email(recipient_id, note_id) 17 def note_merge_request_email(recipient_id, note_id)
18 @note = Note.find(note_id) 18 @note = Note.find(note_id)
19 @merge_request = @note.noteable 19 @merge_request = @note.noteable
20 @project = @note.project 20 @project = @note.project
21 - mail(to: recipient(recipient_id), subject: subject("note for merge request ##{@merge_request.iid}")) 21 + mail(to: recipient(recipient_id), subject: subject("Note for merge request ##{@merge_request.iid}"))
22 end 22 end
23 23
24 def note_wall_email(recipient_id, note_id) 24 def note_wall_email(recipient_id, note_id)
25 @note = Note.find(note_id) 25 @note = Note.find(note_id)
26 @project = @note.project 26 @project = @note.project
27 - mail(to: recipient(recipient_id), subject: subject("note on wall")) 27 + mail(to: recipient(recipient_id), subject: subject("Note on wall"))
28 end 28 end
29 end 29 end
30 end 30 end
app/mailers/emails/projects.rb
@@ -4,14 +4,14 @@ module Emails @@ -4,14 +4,14 @@ module Emails
4 @users_project = UsersProject.find user_project_id 4 @users_project = UsersProject.find user_project_id
5 @project = @users_project.project 5 @project = @users_project.project
6 mail(to: @users_project.user.email, 6 mail(to: @users_project.user.email,
7 - subject: subject("access to project was granted")) 7 + subject: subject("Access to project was granted"))
8 end 8 end
9 9
10 def project_was_moved_email(project_id, user_id) 10 def project_was_moved_email(project_id, user_id)
11 @user = User.find user_id 11 @user = User.find user_id
12 @project = Project.find project_id 12 @project = Project.find project_id
13 mail(to: @user.email, 13 mail(to: @user.email,
14 - subject: subject("project was moved")) 14 + subject: subject("Project was moved"))
15 end 15 end
16 end 16 end
17 end 17 end
app/models/issue.rb
@@ -21,6 +21,8 @@ class Issue &lt; ActiveRecord::Base @@ -21,6 +21,8 @@ class Issue &lt; ActiveRecord::Base
21 include Issuable 21 include Issuable
22 include InternalId 22 include InternalId
23 23
  24 + ActsAsTaggableOn.strict_case_match = true
  25 +
24 belongs_to :project 26 belongs_to :project
25 validates :project, presence: true 27 validates :project, presence: true
26 28
app/models/project.rb
@@ -27,6 +27,8 @@ @@ -27,6 +27,8 @@
27 class Project < ActiveRecord::Base 27 class Project < ActiveRecord::Base
28 include Gitlab::ShellAdapter 28 include Gitlab::ShellAdapter
29 extend Enumerize 29 extend Enumerize
  30 +
  31 + ActsAsTaggableOn.strict_case_match = true
30 32
31 attr_accessible :name, :path, :description, :issues_tracker, :label_list, 33 attr_accessible :name, :path, :description, :issues_tracker, :label_list,
32 :issues_enabled, :wall_enabled, :merge_requests_enabled, :snippets_enabled, :issues_tracker_id, 34 :issues_enabled, :wall_enabled, :merge_requests_enabled, :snippets_enabled, :issues_tracker_id,
app/views/notify/_note_message.html.haml
1 %p 1 %p
2 %strong #{@note.author_name} 2 %strong #{@note.author_name}
3 - left next message: 3 + wrote:
4 4
5 %cite{style: 'color: #666'} 5 %cite{style: 'color: #666'}
6 = markdown(@note.note) 6 = markdown(@note.note)
app/views/notify/new_merge_request_email.html.haml
1 %p 1 %p
2 - = "New Merge Request !#{@merge_request.iid}" 2 + = "New Merge Request ##{@merge_request.iid}"
3 %p 3 %p
4 = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.target_project, @merge_request) 4 = link_to_gfm truncate(@merge_request.title, length: 40), project_merge_request_url(@merge_request.target_project, @merge_request)
5 %p 5 %p
app/views/notify/new_merge_request_email.text.erb
1 -New Merge Request <%= @merge_request.iid %> 1 +New Merge Request #<%= @merge_request.iid %>
2 2
3 <%= url_for(project_merge_request_url(@merge_request.target_project, @merge_request)) %> 3 <%= url_for(project_merge_request_url(@merge_request.target_project, @merge_request)) %>
4 4
app/views/notify/reassigned_merge_request_email.html.haml
1 %p 1 %p
2 - = "Reassigned Merge Request !#{@merge_request.iid}" 2 + = "Reassigned Merge Request ##{@merge_request.iid}"
3 = link_to_gfm truncate(@merge_request.title, length: 30), project_merge_request_url(@merge_request.target_project, @merge_request) 3 = link_to_gfm truncate(@merge_request.title, length: 30), project_merge_request_url(@merge_request.target_project, @merge_request)
4 %p 4 %p
5 Assignee changed 5 Assignee changed
app/views/notify/reassigned_merge_request_email.text.erb
1 -Reassigned Merge Request <%= @merge_request.iid %> 1 +Reassigned Merge Request #<%= @merge_request.iid %>
2 2
3 <%= url_for(project_merge_request_url(@merge_request.target_project, @merge_request)) %> 3 <%= url_for(project_merge_request_url(@merge_request.target_project, @merge_request)) %>
4 4
app/views/shared/_no_ssh.html.haml
1 -- if current_user.require_ssh_key? && alert.blank? && notice.blank?  
2 - %p.error-message.centered  
3 - You won't be able to pull or push project code via SSH until you #{link_to 'add an SSH key', new_profile_key_path} to your profile 1 +- if cookies[:hide_no_ssh_message].blank? && current_user.require_ssh_key?
  2 + .no-ssh-key-message
  3 + .container
  4 + You won't be able to pull or push project code via SSH until you #{link_to 'add an SSH key', new_profile_key_path} to your profile
  5 + = link_to '#', class: 'pull-right hide-no-ssh-message' do
  6 + %i.icon-remove
config/application.rb
@@ -78,7 +78,6 @@ module Gitlab @@ -78,7 +78,6 @@ module Gitlab
78 # 78 #
79 # config.relative_url_root = "/gitlab" 79 # config.relative_url_root = "/gitlab"
80 80
81 - # Uncomment to enable rack attack middleware  
82 - # config.middleware.use Rack::Attack 81 + config.middleware.use Rack::Attack
83 end 82 end
84 end 83 end
config/gitlab.yml.example
@@ -59,7 +59,7 @@ production: &amp;base @@ -59,7 +59,7 @@ production: &amp;base
59 # If a commit message matches this regular expression, all issues referenced from the matched text will be closed. 59 # If a commit message matches this regular expression, all issues referenced from the matched text will be closed.
60 # This happends when the commit is pushed or merged into the default branch of a project. 60 # This happends when the commit is pushed or merged into the default branch of a project.
61 # When not specified the default issue_closing_pattern as specified below will be used. 61 # When not specified the default issue_closing_pattern as specified below will be used.
62 - # issue_closing_pattern: ([Cc]loses|[Ff]ixes) +#\d+ 62 + # issue_closing_pattern: ([Cc]lose[sd]|[Ff]ixe[sd]) +#\d+
63 63
64 ## Default project features settings 64 ## Default project features settings
65 default_projects_features: 65 default_projects_features:
config/initializers/rack_attack.rb.example
1 -# To enable rack-attack for your GitLab instance do the following:  
2 -# 1. In config/application.rb find and uncomment the following line:  
3 -# config.middleware.use Rack::Attack  
4 -# 2. Rename this file to rack_attack.rb  
5 -# 3. Review the paths_to_be_protected and add any other path you need protecting  
6 -# 4. Restart GitLab instance 1 +# 1. Rename this file to rack_attack.rb
  2 +# 2. Review the paths_to_be_protected and add any other path you need protecting
7 # 3 #
8 4
9 paths_to_be_protected = [ 5 paths_to_be_protected = [
doc/api/repositories.md
@@ -368,4 +368,32 @@ GET /projects/:id/repository/archive @@ -368,4 +368,32 @@ GET /projects/:id/repository/archive
368 368
369 Parameters: 369 Parameters:
370 + `id` (required) - The ID of a project 370 + `id` (required) - The ID of a project
371 -+ `sha` (optional) - The commit sha to download defaults to the tip of the default branch  
372 \ No newline at end of file 371 \ No newline at end of file
  372 ++ `sha` (optional) - The commit sha to download defaults to the tip of the default branch
  373 +
  374 +
  375 +## Create new file in repository
  376 +
  377 +```
  378 +POST /projects/:id/repository/files
  379 +```
  380 +
  381 +Parameters:
  382 +
  383 ++ `file_name` (required) - The name of new file. Ex. class.rb
  384 ++ `file_path` (optional) - The path to new file. Ex. lib/
  385 ++ `branch_name` (required) - The name of branch
  386 ++ `content` (required) - File content
  387 ++ `commit_message` (required) - Commit message
  388 +
  389 +## Update existing file in repository
  390 +
  391 +```
  392 +PUT /projects/:id/repository/files
  393 +```
  394 +
  395 +Parameters:
  396 +
  397 ++ `file_path` (required) - Full path to file. Ex. lib/class.rb
  398 ++ `branch_name` (required) - The name of branch
  399 ++ `content` (required) - New file content
  400 ++ `commit_message` (required) - Commit message
doc/install/installation.md
@@ -227,10 +227,6 @@ You can change `6-2-stable` to `master` if you want the *bleeding edge* version, @@ -227,10 +227,6 @@ You can change `6-2-stable` to `master` if you want the *bleeding edge* version,
227 # Copy the example Rack attack config 227 # Copy the example Rack attack config
228 sudo -u git -H cp config/initializers/rack_attack.rb.example config/initializers/rack_attack.rb 228 sudo -u git -H cp config/initializers/rack_attack.rb.example config/initializers/rack_attack.rb
229 229
230 - # Enable rack attack middleware  
231 - # Find and uncomment the line 'config.middleware.use Rack::Attack'  
232 - sudo -u git -H editor config/application.rb  
233 -  
234 # Configure Git global settings for git user, useful when editing via web 230 # Configure Git global settings for git user, useful when editing via web
235 # Edit user.email according to what is set in gitlab.yml 231 # Edit user.email according to what is set in gitlab.yml
236 sudo -u git -H git config --global user.name "GitLab" 232 sudo -u git -H git config --global user.name "GitLab"
@@ -265,8 +261,6 @@ Make sure to edit both `gitlab.yml` and `unicorn.rb` to match your setup. @@ -265,8 +261,6 @@ Make sure to edit both `gitlab.yml` and `unicorn.rb` to match your setup.
265 261
266 cd /home/git/gitlab 262 cd /home/git/gitlab
267 263
268 - sudo gem install charlock_holmes --version '0.6.9.4'  
269 -  
270 # For MySQL (note, the option says "without ... postgres") 264 # For MySQL (note, the option says "without ... postgres")
271 sudo -u git -H bundle install --deployment --without development test postgres aws 265 sudo -u git -H bundle install --deployment --without development test postgres aws
272 266
doc/legal/corporate_contributor_license_agreement.md 0 → 100644
@@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
  1 +You accept and agree to the following terms and conditions for Your present and future Contributions submitted to GitLab.com. Except for the license granted herein to GitLab.com and recipients of software distributed by GitLab.com, You reserve all right, title, and interest in and to Your Contributions.
  2 +
  3 +1. Definitions.
  4 +
  5 + "You" (or "Your") shall mean the copyright owner or legal entity authorized by the copyright owner that is making this Agreement with GitLab.com. For legal entities, the entity making a Contribution and all other entities that control, are controlled by, or are under common control with that entity are considered to be a single Contributor. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
  6 +
  7 + "Contribution" shall mean the code, documentation or other original works of authorship expressly identified in Schedule B, as well as any original work of authorship, including any modifications or additions to an existing work, that is intentionally submitted by You to GitLab.com for inclusion in, or documentation of, any of the products owned or managed by GitLab.com (the "Work"). For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to GitLab.com or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, GitLab.com for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by You as "Not a Contribution."
  8 +
  9 +2. Grant of Copyright License. Subject to the terms and conditions of this Agreement, You hereby grant to GitLab.com and to recipients of software distributed by GitLab.com a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Your Contributions and such derivative works.
  10 +
  11 +3. Grant of Patent License. Subject to the terms and conditions of this Agreement, You hereby grant to GitLab.com and to recipients of software distributed by GitLab.com a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by You that are necessarily infringed by Your Contribution(s) alone or by combination of Your Contribution(s) with the Work to which such Contribution(s) was submitted. If any entity institutes patent litigation against You or any other entity (including a cross-claim or counterclaim in a lawsuit) alleging that your Contribution, or the Work to which you have contributed, constitutes direct or contributory patent infringement, then any patent licenses granted to that entity under this Agreement for that Contribution or Work shall terminate as of the date such litigation is filed.
  12 +
  13 +4. You represent that You are legally entitled to grant the above license. You represent further that each employee of the Corporation designated on Schedule A below (or in a subsequent written modification to that Schedule) is authorized to submit Contributions on behalf of the Corporation.
  14 +
  15 +5. You represent that each of Your Contributions is Your original creation (see section 7 for submissions on behalf of others).
  16 +
  17 +6. You are not expected to provide support for Your Contributions, except to the extent You desire to provide support. You may provide support for free, for a fee, or not at all. Unless required by applicable law or agreed to in writing, You provide Your Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
  18 +
  19 +7. Should You wish to submit work that is not Your original creation, You may submit it to GitLab.com separately from any Contribution, identifying the complete details of its source and of any license or other restriction (including, but not limited to, related patents, trademarks, and license agreements) of which you are personally aware, and conspicuously marking the work as "Submitted on behalf of a third-party: [named here]".
  20 +
  21 +8. It is your responsibility to notify GitLab.com when any change is required to the list of designated employees authorized to submit Contributions on behalf of the Corporation, or to the Corporation's Point of Contact with GitLab.com.
  22 +
  23 +---------------------------------------
  24 +
  25 +This text is licensed under the [Creative Commons Attribution 3.0 License](http://creativecommons.org/licenses/by/3.0/) and the original source is the Google Open Source Programs Office.
doc/legal/individual_contributor_license_agreement.md 0 → 100644
@@ -0,0 +1,25 @@ @@ -0,0 +1,25 @@
  1 +You accept and agree to the following terms and conditions for Your present and future Contributions submitted to GitLab.com. Except for the license granted herein to GitLab.com and recipients of software distributed by GitLab.com, You reserve all right, title, and interest in and to Your Contributions.
  2 +
  3 +1. Definitions.
  4 +
  5 + "You" (or "Your") shall mean the copyright owner or legal entity authorized by the copyright owner that is making this Agreement with GitLab.com. For legal entities, the entity making a Contribution and all other entities that control, are controlled by, or are under common control with that entity are considered to be a single Contributor. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
  6 +
  7 + "Contribution" shall mean any original work of authorship, including any modifications or additions to an existing work, that is intentionally submitted by You to GitLab.com for inclusion in, or documentation of, any of the products owned or managed by GitLab.com (the "Work"). For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to GitLab.com or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, GitLab.com for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by You as "Not a Contribution."
  8 +
  9 +2. Grant of Copyright License. Subject to the terms and conditions of this Agreement, You hereby grant to GitLab.com and to recipients of software distributed by GitLab.com a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Your Contributions and such derivative works.
  10 +
  11 +3. Grant of Patent License. Subject to the terms and conditions of this Agreement, You hereby grant to GitLab.com and to recipients of software distributed by GitLab.com a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by You that are necessarily infringed by Your Contribution(s) alone or by combination of Your Contribution(s) with the Work to which such Contribution(s) was submitted. If any entity institutes patent litigation against You or any other entity (including a cross-claim or counterclaim in a lawsuit) alleging that your Contribution, or the Work to which you have contributed, constitutes direct or contributory patent infringement, then any patent licenses granted to that entity under this Agreement for that Contribution or Work shall terminate as of the date such litigation is filed.
  12 +
  13 +4. You represent that you are legally entitled to grant the above license. If your employer(s) has rights to intellectual property that you create that includes your Contributions, you represent that you have received permission to make Contributions on behalf of that employer, that your employer has waived such rights for your Contributions to GitLab.com, or that your employer has executed a separate Corporate CLA with GitLab.com.
  14 +
  15 +5. You represent that each of Your Contributions is Your original creation (see section 7 for submissions on behalf of others). You represent that Your Contribution submissions include complete details of any third-party license or other restriction (including, but not limited to, related patents and trademarks) of which you are personally aware and which are associated with any part of Your Contributions.
  16 +
  17 +6. You are not expected to provide support for Your Contributions, except to the extent You desire to provide support. You may provide support for free, for a fee, or not at all. Unless required by applicable law or agreed to in writing, You provide Your Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON- INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
  18 +
  19 +7. Should You wish to submit work that is not Your original creation, You may submit it to GitLab.com separately from any Contribution, identifying the complete details of its source and of any license or other restriction (including, but not limited to, related patents, trademarks, and license agreements) of which you are personally aware, and conspicuously marking the work as "Submitted on behalf of a third-party: [[]named here]".
  20 +
  21 +8. You agree to notify GitLab.com of any facts or circumstances of which you become aware that would make these representations inaccurate in any respect.
  22 +
  23 +---------------------------------------
  24 +
  25 +This text is licensed under the [Creative Commons Attribution 3.0 License](http://creativecommons.org/licenses/by/3.0/) and the original source is the Google Open Source Programs Office.
lib/api/api.rb
@@ -39,5 +39,6 @@ module API @@ -39,5 +39,6 @@ module API
39 mount DeployKeys 39 mount DeployKeys
40 mount ProjectHooks 40 mount ProjectHooks
41 mount Services 41 mount Services
  42 + mount Files
42 end 43 end
43 end 44 end
lib/api/files.rb 0 → 100644
@@ -0,0 +1,73 @@ @@ -0,0 +1,73 @@
  1 +module API
  2 + # Projects API
  3 + class Files < Grape::API
  4 + before { authenticate! }
  5 + before { authorize! :push_code, user_project }
  6 +
  7 + resource :projects do
  8 + # Create new file in repository
  9 + #
  10 + # Parameters:
  11 + # file_name (required) - The name of new file. Ex. class.rb
  12 + # file_path (optional) - The path to new file. Ex. lib/
  13 + # branch_name (required) - The name of branch
  14 + # content (required) - File content
  15 + # commit_message (required) - Commit message
  16 + #
  17 + # Example Request:
  18 + # POST /projects/:id/repository/files
  19 + #
  20 + post ":id/repository/files" do
  21 + required_attributes! [:file_name, :branch_name, :content, :commit_message]
  22 + attrs = attributes_for_keys [:file_name, :file_path, :branch_name, :content, :commit_message]
  23 + branch_name = attrs.delete(:branch_name)
  24 + file_path = attrs.delete(:file_path)
  25 + result = ::Files::CreateContext.new(user_project, current_user, attrs, branch_name, file_path).execute
  26 +
  27 + if result[:status] == :success
  28 + status(201)
  29 +
  30 + {
  31 + file_name: attrs[:file_name],
  32 + file_path: file_path,
  33 + branch_name: branch_name
  34 + }
  35 + else
  36 + render_api_error!(result[:error], 400)
  37 + end
  38 + end
  39 +
  40 + # Update existing file in repository
  41 + #
  42 + # Parameters:
  43 + # file_name (required) - The name of new file. Ex. class.rb
  44 + # file_path (optional) - The path to new file. Ex. lib/
  45 + # branch_name (required) - The name of branch
  46 + # content (required) - File content
  47 + # commit_message (required) - Commit message
  48 + #
  49 + # Example Request:
  50 + # PUT /projects/:id/repository/files
  51 + #
  52 + put ":id/repository/files" do
  53 + required_attributes! [:file_path, :branch_name, :content, :commit_message]
  54 + attrs = attributes_for_keys [:file_path, :branch_name, :content, :commit_message]
  55 + branch_name = attrs.delete(:branch_name)
  56 + file_path = attrs.delete(:file_path)
  57 + result = ::Files::UpdateContext.new(user_project, current_user, attrs, branch_name, file_path).execute
  58 +
  59 + if result[:status] == :success
  60 + status(200)
  61 +
  62 + {
  63 + file_path: file_path,
  64 + branch_name: branch_name
  65 + }
  66 + else
  67 + render_api_error!(result[:error], 400)
  68 + end
  69 + end
  70 + end
  71 + end
  72 +end
  73 +
lib/api/helpers.rb
@@ -6,19 +6,23 @@ module API @@ -6,19 +6,23 @@ module API
6 SUDO_PARAM = :sudo 6 SUDO_PARAM = :sudo
7 7
8 def current_user 8 def current_user
9 - @current_user ||= User.find_by_authentication_token(params[PRIVATE_TOKEN_PARAM] || env[PRIVATE_TOKEN_HEADER]) 9 + private_token = (params[PRIVATE_TOKEN_PARAM] || env[PRIVATE_TOKEN_HEADER]).to_s
  10 + @current_user ||= User.find_by_authentication_token(private_token)
10 identifier = sudo_identifier() 11 identifier = sudo_identifier()
  12 +
11 # If the sudo is the current user do nothing 13 # If the sudo is the current user do nothing
12 if (identifier && !(@current_user.id == identifier || @current_user.username == identifier)) 14 if (identifier && !(@current_user.id == identifier || @current_user.username == identifier))
13 render_api_error!('403 Forbidden: Must be admin to use sudo', 403) unless @current_user.is_admin? 15 render_api_error!('403 Forbidden: Must be admin to use sudo', 403) unless @current_user.is_admin?
14 @current_user = User.by_username_or_id(identifier) 16 @current_user = User.by_username_or_id(identifier)
15 not_found!("No user id or username for: #{identifier}") if @current_user.nil? 17 not_found!("No user id or username for: #{identifier}") if @current_user.nil?
16 end 18 end
  19 +
17 @current_user 20 @current_user
18 end 21 end
19 22
20 def sudo_identifier() 23 def sudo_identifier()
21 identifier ||= params[SUDO_PARAM] ||= env[SUDO_HEADER] 24 identifier ||= params[SUDO_PARAM] ||= env[SUDO_HEADER]
  25 +
22 # Regex for integers 26 # Regex for integers
23 if (!!(identifier =~ /^[0-9]+$/)) 27 if (!!(identifier =~ /^[0-9]+$/))
24 identifier.to_i 28 identifier.to_i
@@ -29,6 +33,7 @@ module API @@ -29,6 +33,7 @@ module API
29 33
30 def set_current_user_for_thread 34 def set_current_user_for_thread
31 Thread.current[:current_user] = current_user 35 Thread.current[:current_user] = current_user
  36 +
32 begin 37 begin
33 yield 38 yield
34 ensure 39 ensure
lib/gitlab/satellite/files/edit_file_action.rb
@@ -10,9 +10,7 @@ module Gitlab @@ -10,9 +10,7 @@ module Gitlab
10 # Returns false if committing the change fails 10 # Returns false if committing the change fails
11 # Returns false if pushing from the satellite to Gitolite failed or was rejected 11 # Returns false if pushing from the satellite to Gitolite failed or was rejected
12 # Returns true otherwise 12 # Returns true otherwise
13 - def commit!(content, commit_message, last_commit)  
14 - return false unless can_edit?(last_commit)  
15 - 13 + def commit!(content, commit_message)
16 in_locked_and_timed_satellite do |repo| 14 in_locked_and_timed_satellite do |repo|
17 prepare_satellite!(repo) 15 prepare_satellite!(repo)
18 16
lib/gitlab/satellite/files/file_action.rb
@@ -8,13 +8,6 @@ module Gitlab @@ -8,13 +8,6 @@ module Gitlab
8 @file_path = file_path 8 @file_path = file_path
9 @ref = ref 9 @ref = ref
10 end 10 end
11 -  
12 - protected  
13 -  
14 - def can_edit?(last_commit)  
15 - current_last_commit = Gitlab::Git::Commit.last_for_path(@project.repository, ref, file_path).sha  
16 - last_commit == current_last_commit  
17 - end  
18 end 11 end
19 end 12 end
20 end 13 end
lib/gitlab/satellite/files/new_file_action.rb
@@ -9,7 +9,7 @@ module Gitlab @@ -9,7 +9,7 @@ module Gitlab
9 # Returns false if committing the change fails 9 # Returns false if committing the change fails
10 # Returns false if pushing from the satellite to Gitolite failed or was rejected 10 # Returns false if pushing from the satellite to Gitolite failed or was rejected
11 # Returns true otherwise 11 # Returns true otherwise
12 - def commit!(content, commit_message, file_name) 12 + def commit!(content, commit_message)
13 in_locked_and_timed_satellite do |repo| 13 in_locked_and_timed_satellite do |repo|
14 prepare_satellite!(repo) 14 prepare_satellite!(repo)
15 15
@@ -17,7 +17,7 @@ module Gitlab @@ -17,7 +17,7 @@ module Gitlab
17 repo.git.checkout({raise: true, timeout: true, b: true}, ref, "origin/#{ref}") 17 repo.git.checkout({raise: true, timeout: true, b: true}, ref, "origin/#{ref}")
18 18
19 # update the file in the satellite's working dir 19 # update the file in the satellite's working dir
20 - file_path_in_satellite = File.join(repo.working_dir, file_path, file_name) 20 + file_path_in_satellite = File.join(repo.working_dir, file_path)
21 File.open(file_path_in_satellite, 'w') { |f| f.write(content) } 21 File.open(file_path_in_satellite, 'w') { |f| f.write(content) }
22 22
23 # add new file 23 # add new file
spec/mailers/notify_spec.rb
@@ -110,7 +110,7 @@ describe Notify do @@ -110,7 +110,7 @@ describe Notify do
110 it_behaves_like 'an assignee email' 110 it_behaves_like 'an assignee email'
111 111
112 it 'has the correct subject' do 112 it 'has the correct subject' do
113 - should have_subject /#{project.name} \| new issue ##{issue.iid} \| #{issue.title}/ 113 + should have_subject /#{project.name} \| New issue ##{issue.iid} \| #{issue.title}/
114 end 114 end
115 115
116 it 'contains a link to the new issue' do 116 it 'contains a link to the new issue' do
@@ -126,7 +126,7 @@ describe Notify do @@ -126,7 +126,7 @@ describe Notify do
126 it_behaves_like 'a multiple recipients email' 126 it_behaves_like 'a multiple recipients email'
127 127
128 it 'has the correct subject' do 128 it 'has the correct subject' do
129 - should have_subject /changed issue ##{issue.iid} \| #{issue.title}/ 129 + should have_subject /Changed issue ##{issue.iid} \| #{issue.title}/
130 end 130 end
131 131
132 it 'contains the name of the previous assignee' do 132 it 'contains the name of the previous assignee' do
@@ -148,7 +148,7 @@ describe Notify do @@ -148,7 +148,7 @@ describe Notify do
148 subject { Notify.issue_status_changed_email(recipient.id, issue.id, status, current_user) } 148 subject { Notify.issue_status_changed_email(recipient.id, issue.id, status, current_user) }
149 149
150 it 'has the correct subject' do 150 it 'has the correct subject' do
151 - should have_subject /changed issue ##{issue.iid} \| #{issue.title}/i 151 + should have_subject /Changed issue ##{issue.iid} \| #{issue.title}/i
152 end 152 end
153 153
154 it 'contains the new status' do 154 it 'contains the new status' do
@@ -175,7 +175,7 @@ describe Notify do @@ -175,7 +175,7 @@ describe Notify do
175 it_behaves_like 'an assignee email' 175 it_behaves_like 'an assignee email'
176 176
177 it 'has the correct subject' do 177 it 'has the correct subject' do
178 - should have_subject /new merge request !#{merge_request.iid}/ 178 + should have_subject /New merge request ##{merge_request.iid}/
179 end 179 end
180 180
181 it 'contains a link to the new merge request' do 181 it 'contains a link to the new merge request' do
@@ -199,7 +199,7 @@ describe Notify do @@ -199,7 +199,7 @@ describe Notify do
199 it_behaves_like 'a multiple recipients email' 199 it_behaves_like 'a multiple recipients email'
200 200
201 it 'has the correct subject' do 201 it 'has the correct subject' do
202 - should have_subject /changed merge request !#{merge_request.iid}/ 202 + should have_subject /Changed merge request ##{merge_request.iid}/
203 end 203 end
204 204
205 it 'contains the name of the previous assignee' do 205 it 'contains the name of the previous assignee' do
@@ -224,7 +224,7 @@ describe Notify do @@ -224,7 +224,7 @@ describe Notify do
224 subject { Notify.project_was_moved_email(project.id, user.id) } 224 subject { Notify.project_was_moved_email(project.id, user.id) }
225 225
226 it 'has the correct subject' do 226 it 'has the correct subject' do
227 - should have_subject /project was moved/ 227 + should have_subject /Project was moved/
228 end 228 end
229 229
230 it 'contains name of project' do 230 it 'contains name of project' do
@@ -244,7 +244,7 @@ describe Notify do @@ -244,7 +244,7 @@ describe Notify do
244 user: user) } 244 user: user) }
245 subject { Notify.project_access_granted_email(users_project.id) } 245 subject { Notify.project_access_granted_email(users_project.id) }
246 it 'has the correct subject' do 246 it 'has the correct subject' do
247 - should have_subject /access to project was granted/ 247 + should have_subject /Access to project was granted/
248 end 248 end
249 it 'contains name of project' do 249 it 'contains name of project' do
250 should have_body_text /#{project.name}/ 250 should have_body_text /#{project.name}/
@@ -302,7 +302,7 @@ describe Notify do @@ -302,7 +302,7 @@ describe Notify do
302 it_behaves_like 'a note email' 302 it_behaves_like 'a note email'
303 303
304 it 'has the correct subject' do 304 it 'has the correct subject' do
305 - should have_subject /note for commit #{commit.short_id}/ 305 + should have_subject /Note for commit #{commit.short_id}/
306 end 306 end
307 307
308 it 'contains a link to the commit' do 308 it 'contains a link to the commit' do
@@ -320,7 +320,7 @@ describe Notify do @@ -320,7 +320,7 @@ describe Notify do
320 it_behaves_like 'a note email' 320 it_behaves_like 'a note email'
321 321
322 it 'has the correct subject' do 322 it 'has the correct subject' do
323 - should have_subject /note for merge request ##{merge_request.iid}/ 323 + should have_subject /Note for merge request ##{merge_request.iid}/
324 end 324 end
325 325
326 it 'contains a link to the merge request note' do 326 it 'contains a link to the merge request note' do
@@ -338,7 +338,7 @@ describe Notify do @@ -338,7 +338,7 @@ describe Notify do
338 it_behaves_like 'a note email' 338 it_behaves_like 'a note email'
339 339
340 it 'has the correct subject' do 340 it 'has the correct subject' do
341 - should have_subject /note for issue ##{issue.iid}/ 341 + should have_subject /Note for issue ##{issue.iid}/
342 end 342 end
343 343
344 it 'contains a link to the issue note' do 344 it 'contains a link to the issue note' do
@@ -356,7 +356,7 @@ describe Notify do @@ -356,7 +356,7 @@ describe Notify do
356 subject { Notify.group_access_granted_email(membership.id) } 356 subject { Notify.group_access_granted_email(membership.id) }
357 357
358 it 'has the correct subject' do 358 it 'has the correct subject' do
359 - should have_subject /access to group was granted/ 359 + should have_subject /Access to group was granted/
360 end 360 end
361 361
362 it 'contains name of project' do 362 it 'contains name of project' do
@@ -367,4 +367,28 @@ describe Notify do @@ -367,4 +367,28 @@ describe Notify do
367 should have_body_text /#{membership.human_access}/ 367 should have_body_text /#{membership.human_access}/
368 end 368 end
369 end 369 end
  370 +
  371 + describe 'confirmation if email changed' do
  372 + let(:example_site_path) { root_path }
  373 + let(:user) { create(:user, email: 'old-email@mail.com') }
  374 +
  375 + before do
  376 + user.email = "new-email@mail.com"
  377 + user.save
  378 + end
  379 +
  380 + subject { ActionMailer::Base.deliveries.last }
  381 +
  382 + it 'is sent to the new user' do
  383 + should deliver_to 'new-email@mail.com'
  384 + end
  385 +
  386 + it 'has the correct subject' do
  387 + should have_subject "Confirmation instructions"
  388 + end
  389 +
  390 + it 'includes a link to the site' do
  391 + should have_body_text /#{example_site_path}/
  392 + end
  393 + end
370 end 394 end
spec/requests/api/files_spec.rb 0 → 100644
@@ -0,0 +1,81 @@ @@ -0,0 +1,81 @@
  1 +require 'spec_helper'
  2 +
  3 +describe API::API do
  4 + include ApiHelpers
  5 + before(:each) { ActiveRecord::Base.observers.enable(:user_observer) }
  6 + after(:each) { ActiveRecord::Base.observers.disable(:user_observer) }
  7 +
  8 + let(:user) { create(:user) }
  9 + let!(:project) { create(:project_with_code, namespace: user.namespace ) }
  10 + before { project.team << [user, :developer] }
  11 +
  12 + describe "POST /projects/:id/repository/files" do
  13 + let(:valid_params) {
  14 + {
  15 + file_name: 'newfile.rb',
  16 + branch_name: 'master',
  17 + content: 'puts 8',
  18 + commit_message: 'Added newfile'
  19 + }
  20 + }
  21 +
  22 + it "should create a new file in project repo" do
  23 + Gitlab::Satellite::NewFileAction.any_instance.stub(
  24 + commit!: true,
  25 + )
  26 +
  27 + post api("/projects/#{project.id}/repository/files", user), valid_params
  28 + response.status.should == 201
  29 + json_response['file_name'].should == 'newfile.rb'
  30 + end
  31 +
  32 + it "should return a 400 bad request if no params given" do
  33 + post api("/projects/#{project.id}/repository/files", user)
  34 + response.status.should == 400
  35 + end
  36 +
  37 + it "should return a 400 if satellite fails to create file" do
  38 + Gitlab::Satellite::NewFileAction.any_instance.stub(
  39 + commit!: false,
  40 + )
  41 +
  42 + post api("/projects/#{project.id}/repository/files", user), valid_params
  43 + response.status.should == 400
  44 + end
  45 + end
  46 +
  47 + describe "PUT /projects/:id/repository/files" do
  48 + let(:valid_params) {
  49 + {
  50 + file_path: 'spec/spec_helper.rb',
  51 + branch_name: 'master',
  52 + content: 'puts 8',
  53 + commit_message: 'Changed file'
  54 + }
  55 + }
  56 +
  57 + it "should update existing file in project repo" do
  58 + Gitlab::Satellite::EditFileAction.any_instance.stub(
  59 + commit!: true,
  60 + )
  61 +
  62 + put api("/projects/#{project.id}/repository/files", user), valid_params
  63 + response.status.should == 200
  64 + json_response['file_path'].should == 'spec/spec_helper.rb'
  65 + end
  66 +
  67 + it "should return a 400 bad request if no params given" do
  68 + put api("/projects/#{project.id}/repository/files", user)
  69 + response.status.should == 400
  70 + end
  71 +
  72 + it "should return a 400 if satellite fails to create file" do
  73 + Gitlab::Satellite::EditFileAction.any_instance.stub(
  74 + commit!: false,
  75 + )
  76 +
  77 + put api("/projects/#{project.id}/repository/files", user), valid_params
  78 + response.status.should == 400
  79 + end
  80 + end
  81 +end
spec/support/test_env.rb
@@ -45,6 +45,7 @@ module TestEnv @@ -45,6 +45,7 @@ module TestEnv
45 def disable_mailer 45 def disable_mailer
46 NotificationService.any_instance.stub(mailer: double.as_null_object) 46 NotificationService.any_instance.stub(mailer: double.as_null_object)
47 end 47 end
  48 +
48 def enable_mailer 49 def enable_mailer
49 NotificationService.any_instance.unstub(:mailer) 50 NotificationService.any_instance.unstub(:mailer)
50 end 51 end