From 691902e23e25a0cc45b5dd1cb0f6092a4c37b4ec Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Wed, 20 Jul 2016 11:25:31 +0200 Subject: [PATCH 1/7] Don't remove the source branch for another MR When a user checked the box to remove the source branch when an mr was merged, it could have happened the branch was removed while it was the source branch for another MR. This commit prevents that from happening. Fixes: https://gitlab.com/gitlab-org/gitlab-ce/issues/14413#note_12019937 --- app/models/merge_request.rb | 4 ++++ app/services/merge_requests/merge_service.rb | 10 +++++++++- spec/services/merge_requests/merge_service_spec.rb | 12 ++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index b1fb3ce5d697..e845cfcf66a7 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -500,6 +500,10 @@ def target_branch_exists? self.target_project.repository.branch_names.include?(self.target_branch) end + def same_source_branch_merge_requests? + target_project.merge_requests.opened.where(source_branch: source_branch).exists? + end + # Reset merge request events cache # # Since we do cache @event we need to reset cache in special cases: diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb index b037780c4316..a308136f236f 100644 --- a/app/services/merge_requests/merge_service.rb +++ b/app/services/merge_requests/merge_service.rb @@ -56,7 +56,7 @@ def commit def after_merge MergeRequests::PostMergeService.new(project, current_user).execute(merge_request) - if params[:should_remove_source_branch].present? || @merge_request.force_remove_source_branch? + if remove_source_branch? DeleteBranchService.new(@merge_request.source_project, branch_deletion_user). execute(merge_request.source_branch) end @@ -65,5 +65,13 @@ def after_merge def branch_deletion_user @merge_request.force_remove_source_branch? ? @merge_request.author : current_user end + + def remove_source_branch? + return false unless @merge_request.remove_source_branch? + + # If another MR in this project has the same source branch, we should not + # remove this branch + !@merge_request.same_source_branch_merge_requests? + end end end diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb index 8ffebcac6986..fdbcdbe7e8de 100644 --- a/spec/services/merge_requests/merge_service_spec.rb +++ b/spec/services/merge_requests/merge_service_spec.rb @@ -49,8 +49,20 @@ expect(DeleteBranchService).to receive(:new). with(merge_request.source_project, merge_request.author). and_call_original + service.execute(merge_request) end + + context 'when another merge request has the same source branch' do + it 'removes the source branch' do + create(:merge_request, source_project: merge_request.source_project, + target_project: merge_request.target_project, target_branch: 'mepmep') + + expect(DeleteBranchService).not_to receive(:new) + + service.execute(merge_request) + end + end end context "error handling" do -- GitLab From f44a32c5c4593ab7e2cb249c740c19a9bab56fce Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Thu, 21 Jul 2016 12:13:50 +0200 Subject: [PATCH 2/7] Create remove_source_branch field on MergeRequest A few releases back a checkbox was introduced to remove the source branch once the MR was merged. With this checkbox the key `force_remove_source_branch` was introduced, while `should_remove_source_branch` was already introduced at the time that merge when build succeeds was implemented. To me this warranted the creation of a field `remove_source_branch`. A migration has been added, and tested on PG only at this time. MySQL should be done still. Also, this commit updates the style for the API docs on MR's. This was done as I wanted to be a good boyscout, hope the MR stays foccussed enough. --- CHANGELOG | 1 + .../projects/merge_requests_controller.rb | 6 +- app/models/merge_request.rb | 18 +-- app/services/merge_requests/create_service.rb | 2 - app/services/merge_requests/merge_service.rb | 2 +- app/services/merge_requests/update_service.rb | 2 - .../projects/merge_requests/merge.js.haml | 2 +- .../widget/open/_accept.html.haml | 6 +- .../open/_merge_when_build_succeeds.html.haml | 2 +- .../widget/open/_not_allowed.html.haml | 2 +- app/views/shared/issuable/_form.html.haml | 4 +- ..._remove_source_branch_to_merge_requests.rb | 28 ++++ db/schema.rb | 1 + doc/api/merge_requests.md | 147 ++++++++++++------ lib/api/entities.rb | 4 +- lib/api/merge_requests.rb | 33 ++-- .../merge_when_build_succeeds_spec.rb | 1 + spec/models/merge_request_spec.rb | 3 +- .../merge_requests/create_service_spec.rb | 4 +- .../merge_requests/merge_service_spec.rb | 2 +- .../merge_requests/update_service_spec.rb | 4 +- 21 files changed, 173 insertions(+), 101 deletions(-) create mode 100644 db/migrate/20160720102606_add_remove_source_branch_to_merge_requests.rb diff --git a/CHANGELOG b/CHANGELOG index aee59b993826..c8b8081d7136 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,7 @@ v 8.11.0 (unreleased) - Improve performance of AutolinkFilter#text_parse by using XPath - Environments have an url to link to - Remove unused images (ClemMakesApps) + - Check remove source branch by default on a new MR - Limit git rev-list output count to one in forced push check - Clean up unused routes (Josef Strzibny) - Add green outline to New Branch button. !5447 (winniehell) diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 2cf6a2dd1b39..ebb527d2e383 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -239,7 +239,7 @@ def merge TodoService.new.merge_merge_request(merge_request, current_user) - @merge_request.update(merge_error: nil) + @merge_request.update(merge_error: nil, remove_source_branch: !!params[:remove_source_branch]) if params[:merge_when_build_succeeds].present? unless @merge_request.pipeline @@ -434,13 +434,13 @@ def merge_request_params params.require(:merge_request).permit( :title, :assignee_id, :source_project_id, :source_branch, :target_project_id, :target_branch, :milestone_id, - :state_event, :description, :task_num, :force_remove_source_branch, + :state_event, :description, :task_num, :remove_source_branch, label_ids: [] ) end def merge_params - params.permit(:should_remove_source_branch, :commit_message) + params.permit(:commit_message, :remove_source_branch) end # Make sure merge requests created before 8.0 diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index e845cfcf66a7..55548e590bcd 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -390,18 +390,6 @@ def can_remove_source_branch?(current_user) diff_head_commit == source_branch_head end - def should_remove_source_branch? - merge_params['should_remove_source_branch'].present? - end - - def force_remove_source_branch? - merge_params['force_remove_source_branch'].present? - end - - def remove_source_branch? - should_remove_source_branch? || force_remove_source_branch? - end - def mr_and_commit_notes # Fetch comments only from last 100 commits commits_for_notes_limit = 100 @@ -532,10 +520,8 @@ def reset_merge_when_build_succeeds self.merge_when_build_succeeds = false self.merge_user = nil - if merge_params - merge_params.delete('should_remove_source_branch') - merge_params.delete('commit_message') - end + + merge_params.delete('commit_message') if merge_params self.save end diff --git a/app/services/merge_requests/create_service.rb b/app/services/merge_requests/create_service.rb index 96a25330af10..22168ae5b2c6 100644 --- a/app/services/merge_requests/create_service.rb +++ b/app/services/merge_requests/create_service.rb @@ -9,13 +9,11 @@ def execute filter_params label_params = params.delete(:label_ids) - force_remove_source_branch = params.delete(:force_remove_source_branch) merge_request = MergeRequest.new(params) merge_request.source_project = source_project merge_request.target_project ||= source_project merge_request.author = current_user - merge_request.merge_params['force_remove_source_branch'] = force_remove_source_branch if merge_request.save merge_request.update_attributes(label_ids: label_params) diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb index a308136f236f..acdbe0fcf994 100644 --- a/app/services/merge_requests/merge_service.rb +++ b/app/services/merge_requests/merge_service.rb @@ -63,7 +63,7 @@ def after_merge end def branch_deletion_user - @merge_request.force_remove_source_branch? ? @merge_request.author : current_user + @merge_request.remove_source_branch? ? @merge_request.author : current_user end def remove_source_branch? diff --git a/app/services/merge_requests/update_service.rb b/app/services/merge_requests/update_service.rb index 026a37997d44..477c64e7377d 100644 --- a/app/services/merge_requests/update_service.rb +++ b/app/services/merge_requests/update_service.rb @@ -11,8 +11,6 @@ def execute(merge_request) params.except!(:target_project_id) params.except!(:source_branch) - merge_request.merge_params['force_remove_source_branch'] = params.delete(:force_remove_source_branch) - update(merge_request) end diff --git a/app/views/projects/merge_requests/merge.js.haml b/app/views/projects/merge_requests/merge.js.haml index 84b6c9ebc5cf..0cf52fef16f8 100644 --- a/app/views/projects/merge_requests/merge.js.haml +++ b/app/views/projects/merge_requests/merge.js.haml @@ -1,7 +1,7 @@ - case @status - when :success :plain - merge_request_widget.mergeInProgress(#{params[:should_remove_source_branch] == '1'}); + merge_request_widget.mergeInProgress(#{params[:remove_source_branch] == '1'}); - when :merge_when_build_succeeds :plain $('.mr-widget-body').html("#{escape_javascript(render('projects/merge_requests/widget/open/merge_when_build_succeeds'))}"); diff --git a/app/views/projects/merge_requests/widget/open/_accept.html.haml b/app/views/projects/merge_requests/widget/open/_accept.html.haml index bf2e76f00838..d9f33059a7d9 100644 --- a/app/views/projects/merge_requests/widget/open/_accept.html.haml +++ b/app/views/projects/merge_requests/widget/open/_accept.html.haml @@ -27,13 +27,13 @@ - else = f.button class: "btn btn-create btn-grouped js-merge-button accept_merge_request #{status_class}" do Accept Merge Request - - if @merge_request.force_remove_source_branch? + - if @merge_request.remove_source_branch? .accept-control The source branch will be removed. - elsif @merge_request.can_remove_source_branch?(current_user) .accept-control.checkbox - = label_tag :should_remove_source_branch, class: "remove_source_checkbox" do - = check_box_tag :should_remove_source_branch + = f.label :remove_source_branch, class: "remove_source_checkbox" do + = f.check_box :remove_source_branch Remove source branch .accept-control.right = link_to "#", class: "modify-merge-commit-link js-toggle-button" do diff --git a/app/views/projects/merge_requests/widget/open/_merge_when_build_succeeds.html.haml b/app/views/projects/merge_requests/widget/open/_merge_when_build_succeeds.html.haml index 2b6b5e05e865..aa88a07a33d1 100644 --- a/app/views/projects/merge_requests/widget/open/_merge_when_build_succeeds.html.haml +++ b/app/views/projects/merge_requests/widget/open/_merge_when_build_succeeds.html.haml @@ -16,7 +16,7 @@ - if remove_source_branch_button || user_can_cancel_automatic_merge .clearfix.prepend-top-10 - if remove_source_branch_button - = link_to merge_namespace_project_merge_request_path(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request, merge_when_build_succeeds: true, should_remove_source_branch: true, sha: @merge_request.diff_head_sha), remote: true, method: :post, class: "btn btn-grouped btn-primary btn-sm remove_source_branch" do + = link_to merge_namespace_project_merge_request_path(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request, merge_when_build_succeeds: true, remove_source_branch: true, sha: @merge_request.diff_head_sha), remote: true, method: :post, class: "btn btn-grouped btn-primary btn-sm remove_source_branch" do = icon('times') Remove Source Branch When Merged diff --git a/app/views/projects/merge_requests/widget/open/_not_allowed.html.haml b/app/views/projects/merge_requests/widget/open/_not_allowed.html.haml index 57ce1959021f..c4cca63a605b 100644 --- a/app/views/projects/merge_requests/widget/open/_not_allowed.html.haml +++ b/app/views/projects/merge_requests/widget/open/_not_allowed.html.haml @@ -2,5 +2,5 @@ Ready to be merged automatically %p Ask someone with write access to this repository to merge this request. - - if @merge_request.force_remove_source_branch? + - if @merge_request.remove_source_branch? The source branch will be removed. diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml index c30bdb0ae913..78f38bbcde51 100644 --- a/app/views/shared/issuable/_form.html.haml +++ b/app/views/shared/issuable/_form.html.haml @@ -124,8 +124,8 @@ .form-group .col-sm-10.col-sm-offset-2 .checkbox - = label_tag 'merge_request[force_remove_source_branch]' do - = check_box_tag 'merge_request[force_remove_source_branch]', '1', @merge_request.force_remove_source_branch? + = f.label :remove_source_branch do + = f.check_box :remove_source_branch Remove source branch when merge request is accepted. - is_footer = !(issuable.is_a?(MergeRequest) && issuable.new_record?) diff --git a/db/migrate/20160720102606_add_remove_source_branch_to_merge_requests.rb b/db/migrate/20160720102606_add_remove_source_branch_to_merge_requests.rb new file mode 100644 index 000000000000..090bf1573b10 --- /dev/null +++ b/db/migrate/20160720102606_add_remove_source_branch_to_merge_requests.rb @@ -0,0 +1,28 @@ +# online without errors +# This migration makes an actual field now there are more usecases for this field +# Migrating the data between the `merge_params` hash and this field will happen as +# part of this migration, but cleaning up the merge_params field will not. So some +# keys will be there but never used. +class AddRemoveSourceBranchToMergeRequests < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + disable_ddl_transaction! + + def up + add_column_with_default(:merge_requests, :remove_source_branch, :boolean, default: true) + + set_to_true = if Gitlab::Database.postgresql? + execute "SELECT id FROM merge_requests WHERE merge_params ~* 'remove_source_branch:.+1';" + else + execute "SELECT id FROM merge_requests WHERE merge_params REGEXP 'remove_source_branch:.+1;'" + end + + set_to_true.each_slice(1000) do |ids| + MergeRequest.where(id: ids).update_all(remove_source_branch: true) + end + end + + def down + # noop - We don't want to serialize and deserialize, also, the keys are still there + end +end diff --git a/db/schema.rb b/db/schema.rb index 5b35a528e71b..ea654289cc5e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -632,6 +632,7 @@ t.string "merge_commit_sha" t.datetime "deleted_at" t.string "in_progress_merge_commit_sha" + t.boolean "remove_source_branch", default: true, null: false end add_index "merge_requests", ["assignee_id"], name: "index_merge_requests_on_assignee_id", using: :btree diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md index e00882e6d5db..04af7cf714e6 100644 --- a/doc/api/merge_requests.md +++ b/doc/api/merge_requests.md @@ -1,5 +1,7 @@ # Merge requests +Merge requests provide a way to contribute your way into the specified branch so your changes can combined with others. + ## List merge requests Get all merge requests for this project. @@ -15,11 +17,17 @@ GET /projects/:id/merge_requests?iid=42 Parameters: -- `id` (required) - The ID of a project -- `iid` (optional) - Return the request having the given `iid` -- `state` (optional) - Return `all` requests or just those that are `merged`, `opened` or `closed` -- `order_by` (optional) - Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` -- `sort` (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc` +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `id` | integer | yes | The ID of a project | +| `iid` | integer | no | Return the request having the given `iid` | +| `state` | string | no | Return `all` requests or just those that are `merged`, `opened` or `closed` | +| `order_by` | string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` | +| `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc` | + +```bash +curl -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" http://gitlab.example.com/api/v3/projects/1/merge_requests/ +``` ```json [ @@ -70,7 +78,7 @@ Parameters: "subscribed" : false, "user_notes_count": 1, "should_remove_source_branch": true, - "force_remove_source_branch": false + "force_remove_source_branch": true } ] ``` @@ -85,8 +93,14 @@ GET /projects/:id/merge_requests/:merge_request_id Parameters: -- `id` (required) - The ID of a project -- `merge_request_id` (required) - The ID of MR +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `id` | integer | yes | The ID of a project | +| `iid` | integer | no | Return the request having the given `iid` | + +```bash +curl -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" http://gitlab.example.com/api/v3/projects/1/merge_requests/1 +``` ```json { @@ -136,7 +150,7 @@ Parameters: "subscribed" : true, "user_notes_count": 1, "should_remove_source_branch": true, - "force_remove_source_branch": false + "force_remove_source_branch": true } ``` @@ -150,9 +164,14 @@ GET /projects/:id/merge_requests/:merge_request_id/commits Parameters: -- `id` (required) - The ID of a project -- `merge_request_id` (required) - The ID of MR +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `id` | integer | yes | The ID of a project | +| `iid` | integer | no | Return the request having the given `iid` | +```bash +curl -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" http://gitlab.example.com/api/v3/projects/1/merge_requests/1/commits +``` ```json [ @@ -187,8 +206,15 @@ GET /projects/:id/merge_requests/:merge_request_id/changes Parameters: -- `id` (required) - The ID of a project -- `merge_request_id` (required) - The ID of MR +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `id` | integer | yes | The ID of a project | +| `iid` | integer | no | Return the request having the given `iid` | + +```bash +curl -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" http://gitlab.example.com/api/v3/projects/21/merge_requests/1/changes +``` + ```json { @@ -238,7 +264,7 @@ Parameters: "subscribed" : true, "user_notes_count": 1, "should_remove_source_branch": true, - "force_remove_source_branch": false, + "force_remove_source_branch": true, "changes": [ { "old_path": "VERSION", @@ -257,21 +283,28 @@ Parameters: ## Create MR Creates a new merge request. + ``` POST /projects/:id/merge_requests ``` Parameters: -- `id` (required) - The ID of a project -- `source_branch` (required) - The source branch -- `target_branch` (required) - The target branch -- `assignee_id` (optional) - Assignee user ID -- `title` (required) - Title of MR -- `description` (optional) - Description of MR -- `target_project_id` (optional) - The target project (numeric id) -- `labels` (optional) - Labels for MR as a comma-separated list -- `milestone_id` (optional) - Milestone ID +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `id` | integer | yes | The ID of a project | +| `source_branch` | string | yes | The source branch | +| `target_branch` | string | yes | The target branch | +| `assignee_id` | integer | no | Assignee user ID | +| `title` | string | yes | Title of the new MR | +| `description` | string | no | Description of MR | +| `target_project_id` | integer | no | The target project | +| `labels` | string | no | Labels for MR as a comma-separated list | +| `milestone_id` | string | no | Milestone ID | + +```bash +curl -X POST -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" http://gitlab.example.com/api/v3/projects/1/merge_requests?source_branch=test1&target_branch=master&title=test1 +``` ```json { @@ -333,20 +366,27 @@ If an error occurs, an error number and a message explaining the reason is retur Updates an existing merge request. You can change the target branch, title, or even close the MR. ``` -PUT /projects/:id/merge_requests/:merge_request_id +PUT /projects/:id/merge_requests/:iid ``` Parameters: -- `id` (required) - The ID of a project -- `merge_request_id` (required) - ID of MR -- `target_branch` - The target branch -- `assignee_id` - Assignee user ID -- `title` - Title of MR -- `description` - Description of MR -- `state_event` - New state (close|reopen|merge) -- `labels` (optional) - Labels for MR as a comma-separated list -- `milestone_id` (optional) - Milestone ID +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `id` | integer | yes | The ID of a project | +| `iid` | integer | yes | ID of MR | +| `target_branch` | string | no | The target branch | +| `assignee_id` | integer | no | Assignee user ID | +| `title` | string | no | Title of the new MR | +| `description` | string | no | Description of MR | +| `target_project_id` | integer | no | The target project | +| `labels` | string | no | Labels for MR as a comma-separated list | +| `milestone_id` | string | no | Milestone ID | + + +```bash +curl -X PUT -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" http://gitlab.example.com/api/v3/projects/1/merge_requests/1&title=test11 +``` ```json { @@ -354,7 +394,7 @@ Parameters: "iid": 1, "target_branch": "master", "project_id": 3, - "title": "test1", + "title": "test11", "state": "opened", "upvotes": 0, "downvotes": 0, @@ -395,7 +435,7 @@ Parameters: "subscribed" : true, "user_notes_count": 1, "should_remove_source_branch": true, - "force_remove_source_branch": false + "force_remove_source_branch": true } ``` @@ -441,12 +481,18 @@ PUT /projects/:id/merge_requests/:merge_request_id/merge Parameters: -- `id` (required) - The ID of a project -- `merge_request_id` (required) - ID of MR -- `merge_commit_message` (optional) - Custom merge commit message -- `should_remove_source_branch` (optional) - if `true` removes the source branch -- `merge_when_build_succeeds` (optional) - if `true` the MR is merged when the build succeeds -- `sha` (optional) - if present, then this SHA must match the HEAD of the source branch, otherwise the merge will fail +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `id` | integer | yes | The ID of a project | +| `merge_request_id` | integer | yes | ID of MR | +| `merge_commit_message` | string | no | Custom merge commit message | +| `remove_source_branch` | boolean | no | if `true` removes the source branch | +| `merge_when_build_succeeds` | boolean | no | if `true` the MR is merged when the build succeeds | +| `sha` | string | no | if present, then this SHA must match the HEAD of the source branch, otherwise the merge will fail | + +```bash +curl -X POST -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" http://gitlab.example.com/api/v3/projects/1/merge_requests/1/merge +``` ```json { @@ -496,7 +542,7 @@ Parameters: "subscribed" : true, "user_notes_count": 1, "should_remove_source_branch": true, - "force_remove_source_branch": false + "force_remove_source_branch": true } ``` @@ -509,13 +555,22 @@ If you don't have permissions to accept this merge request - you'll get a 401 If the merge request is already merged or closed - you get 405 and error message 'Method Not Allowed' In case the merge request is not set to be merged when the build succeeds, you'll also get a 406 error. + ``` PUT /projects/:id/merge_requests/:merge_request_id/cancel_merge_when_build_succeeds ``` + Parameters: -- `id` (required) - The ID of a project -- `merge_request_id` (required) - ID of MR +| Attribute | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `id` | integer | yes | The ID of a project | +| `merge_request_id` | integer | yes | ID of MR | + + +```bash +curl -X PUT -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" http://gitlab.example.com/api/v3/projects/1/merge_requests/1/cancel_merge_when_build_succeeds +``` ```json { @@ -565,7 +620,7 @@ Parameters: "subscribed" : true, "user_notes_count": 1, "should_remove_source_branch": true, - "force_remove_source_branch": false + "force_remove_source_branch": true } ``` @@ -886,7 +941,7 @@ Example response: "subscribed": true, "user_notes_count": 7, "should_remove_source_branch": true, - "force_remove_source_branch": false + "force_remove_source_branch": true }, "target_url": "https://gitlab.example.com/gitlab-org/gitlab-ci/merge_requests/7", "body": "Et voluptas laudantium minus nihil recusandae ut accusamus earum aut non.", diff --git a/lib/api/entities.rb b/lib/api/entities.rb index e5b00dc45a52..f8bb7d215eee 100644 --- a/lib/api/entities.rb +++ b/lib/api/entities.rb @@ -218,8 +218,8 @@ class MergeRequest < ProjectEntity merge_request.subscribed?(options[:current_user]) end expose :user_notes_count - expose :should_remove_source_branch?, as: :should_remove_source_branch - expose :force_remove_source_branch?, as: :force_remove_source_branch + expose(:should_remove_source_branch?) { |mr| mr.remove_source_branch } + expose(:force_remove_source_branch?) { |mr| mr.remove_source_branch } end class MergeRequestChanges < MergeRequest diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 2b685621da9a..1aa2a480353e 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -18,6 +18,12 @@ def handle_merge_request_errors!(errors) render_api_error!(errors, 400) end + + def remove_source_branch? + parse_boolean(params[:should_remove_source_branch]) || + parse_boolean(params[:force_remove_source_branch]) || + parse_boolean(params[:remove_source_branch]) + end end # List merge requests @@ -63,15 +69,16 @@ def handle_merge_request_errors!(errors) # # Parameters: # - # id (required) - The ID of a project - this will be the source of the merge request - # source_branch (required) - The source branch - # target_branch (required) - The target branch - # target_project_id - The target project of the merge request defaults to the :id of the project - # assignee_id - Assignee user ID - # title (required) - Title of MR - # description - Description of MR - # labels (optional) - Labels for MR as a comma-separated list - # milestone_id (optional) - Milestone ID + # id (required) - The ID of a project - this will be the source of the merge request + # source_branch (required) - The source branch + # target_branch (required) - The target branch + # target_project_id - The target project of the merge request defaults to the :id of the project + # assignee_id - Assignee user ID + # title (required) - Title of MR + # description(optional) - Description of MR + # labels (optional) - Labels for MR as a comma-separated list + # milestone_id (optional) - Milestone ID + # remove_source_branch (optional) - Should the source branch be deleted if the MR is merged? # # Example: # POST /projects/:id/merge_requests @@ -79,7 +86,7 @@ def handle_merge_request_errors!(errors) post ":id/merge_requests" do authorize! :create_merge_request, user_project required_attributes! [:source_branch, :target_branch, :title] - attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :target_project_id, :description, :milestone_id] + attrs = attributes_for_keys [:source_branch, :target_branch, :assignee_id, :title, :target_project_id, :description, :milestone_id, :remove_source_branch] # Validate label names in advance if (errors = validate_label_params(params)).any? @@ -237,10 +244,8 @@ def handle_merge_request_errors!(errors) render_api_error!("SHA does not match HEAD of source branch: #{merge_request.diff_head_sha}", 409) end - merge_params = { - commit_message: params[:merge_commit_message], - should_remove_source_branch: params[:should_remove_source_branch] - } + merge_params = { commit_message: params[:merge_commit_message] } + merge_request.remove_source_branch = remove_source_branch? if to_boolean(params[:merge_when_build_succeeds]) && merge_request.pipeline && merge_request.pipeline.active? ::MergeRequests::MergeWhenBuildSucceedsService.new(merge_request.target_project, current_user, merge_params). diff --git a/spec/features/merge_requests/merge_when_build_succeeds_spec.rb b/spec/features/merge_requests/merge_when_build_succeeds_spec.rb index 96f7b8c99323..3179162c7ac2 100644 --- a/spec/features/merge_requests/merge_when_build_succeeds_spec.rb +++ b/spec/features/merge_requests/merge_when_build_succeeds_spec.rb @@ -68,6 +68,7 @@ expect(page).to have_link "Remove Source Branch When Merged" click_link "Remove Source Branch When Merged" + expect(page).to have_content "The source branch will be removed" end end diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index d793cfd0bde8..90663be26432 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -331,7 +331,7 @@ describe "#reset_merge_when_build_succeeds" do let(:merge_if_green) do create :merge_request, merge_when_build_succeeds: true, merge_user: create(:user), - merge_params: { "should_remove_source_branch" => "1", "commit_message" => "msg" } + remove_source_branch: true, merge_params: { "commit_message" => "msg" } end it "sets the item to false" do @@ -339,7 +339,6 @@ merge_if_green.reload expect(merge_if_green.merge_when_build_succeeds).to be_falsey - expect(merge_if_green.merge_params["should_remove_source_branch"]).to be_nil expect(merge_if_green.merge_params["commit_message"]).to be_nil end end diff --git a/spec/services/merge_requests/create_service_spec.rb b/spec/services/merge_requests/create_service_spec.rb index d0b55d2d5094..872732c6e944 100644 --- a/spec/services/merge_requests/create_service_spec.rb +++ b/spec/services/merge_requests/create_service_spec.rb @@ -13,7 +13,7 @@ description: 'please fix', source_branch: 'feature', target_branch: 'master', - force_remove_source_branch: '1' + remove_source_branch: true } end @@ -30,7 +30,7 @@ it { expect(@merge_request).to be_valid } it { expect(@merge_request.title).to eq('Awesome merge_request') } it { expect(@merge_request.assignee).to be_nil } - it { expect(@merge_request.merge_params['force_remove_source_branch']).to eq('1') } + it { expect(@merge_request.remove_source_branch).to be true } it 'should execute hooks with default action' do expect(service).to have_received(:execute_hooks).with(@merge_request) diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb index fdbcdbe7e8de..78f97df09edb 100644 --- a/spec/services/merge_requests/merge_service_spec.rb +++ b/spec/services/merge_requests/merge_service_spec.rb @@ -56,7 +56,7 @@ context 'when another merge request has the same source branch' do it 'removes the source branch' do create(:merge_request, source_project: merge_request.source_project, - target_project: merge_request.target_project, target_branch: 'mepmep') + target_project: merge_request.target_project, target_branch: 'mepmep') expect(DeleteBranchService).not_to receive(:new) diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb index d4ebe28c276a..265425656b73 100644 --- a/spec/services/merge_requests/update_service_spec.rb +++ b/spec/services/merge_requests/update_service_spec.rb @@ -40,7 +40,7 @@ def update_merge_request(opts) state_event: 'close', label_ids: [label.id], target_branch: 'target', - force_remove_source_branch: '1' + remove_source_branch: true } end @@ -62,7 +62,7 @@ def update_merge_request(opts) it { expect(@merge_request.labels.count).to eq(1) } it { expect(@merge_request.labels.first.title).to eq(label.name) } it { expect(@merge_request.target_branch).to eq('target') } - it { expect(@merge_request.merge_params['force_remove_source_branch']).to eq('1') } + it { expect(@merge_request.remove_source_branch).to be_truthy } it 'should execute hooks with update action' do expect(service).to have_received(:execute_hooks). -- GitLab From 64400bdd8e085ac4d48c3af6e39fa5f0c638b544 Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Fri, 22 Jul 2016 08:28:21 +0200 Subject: [PATCH 3/7] Incorporate feedback --- app/models/merge_request.rb | 7 ++-- app/services/merge_requests/merge_service.rb | 10 +----- ..._remove_source_branch_to_merge_requests.rb | 14 ++++---- doc/api/merge_requests.md | 26 +++++++-------- .../project/merge_requests/acceptance.rb | 2 +- lib/api/merge_requests.rb | 23 +++++++++---- .../merge_when_build_succeeds_spec.rb | 13 ++++---- spec/requests/api/merge_requests_spec.rb | 32 +++++++++++++------ 8 files changed, 71 insertions(+), 56 deletions(-) diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 55548e590bcd..90dcfccee5fb 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -387,7 +387,8 @@ def can_remove_source_branch?(current_user) !source_project.protected_branch?(source_branch) && !source_project.root_ref?(source_branch) && Ability.abilities.allowed?(current_user, :push_code, source_project) && - diff_head_commit == source_branch_head + diff_head_commit == source_branch_head && + !same_source_branch_merge_requests? end def mr_and_commit_notes @@ -520,9 +521,7 @@ def reset_merge_when_build_succeeds self.merge_when_build_succeeds = false self.merge_user = nil - - merge_params.delete('commit_message') if merge_params - + self.merge_params = nil self.save end diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb index acdbe0fcf994..4b133f8f4d7f 100644 --- a/app/services/merge_requests/merge_service.rb +++ b/app/services/merge_requests/merge_service.rb @@ -56,7 +56,7 @@ def commit def after_merge MergeRequests::PostMergeService.new(project, current_user).execute(merge_request) - if remove_source_branch? + if merge_request.can_remove_source_branch?(branch_deletion_user) DeleteBranchService.new(@merge_request.source_project, branch_deletion_user). execute(merge_request.source_branch) end @@ -65,13 +65,5 @@ def after_merge def branch_deletion_user @merge_request.remove_source_branch? ? @merge_request.author : current_user end - - def remove_source_branch? - return false unless @merge_request.remove_source_branch? - - # If another MR in this project has the same source branch, we should not - # remove this branch - !@merge_request.same_source_branch_merge_requests? - end end end diff --git a/db/migrate/20160720102606_add_remove_source_branch_to_merge_requests.rb b/db/migrate/20160720102606_add_remove_source_branch_to_merge_requests.rb index 090bf1573b10..8abb7a7c0f13 100644 --- a/db/migrate/20160720102606_add_remove_source_branch_to_merge_requests.rb +++ b/db/migrate/20160720102606_add_remove_source_branch_to_merge_requests.rb @@ -11,14 +11,14 @@ class AddRemoveSourceBranchToMergeRequests < ActiveRecord::Migration def up add_column_with_default(:merge_requests, :remove_source_branch, :boolean, default: true) - set_to_true = if Gitlab::Database.postgresql? - execute "SELECT id FROM merge_requests WHERE merge_params ~* 'remove_source_branch:.+1';" - else - execute "SELECT id FROM merge_requests WHERE merge_params REGEXP 'remove_source_branch:.+1;'" - end + set_to_false = if Gitlab::Database.postgresql? + execute "SELECT id FROM merge_requests WHERE merge_params !~* 'remove_source_branch:.{0,2}1';" + else + execute "SELECT id FROM merge_requests WHERE merge_params NOT REGEXP 'remove_source_branch:.{0,2}1;'" + end - set_to_true.each_slice(1000) do |ids| - MergeRequest.where(id: ids).update_all(remove_source_branch: true) + set_to_false.each_slice(1000) do |ids| + MergeRequest.where(id: ids).update_all(remove_source_branch: false) end end diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md index 04af7cf714e6..8dde754663ec 100644 --- a/doc/api/merge_requests.md +++ b/doc/api/merge_requests.md @@ -1,6 +1,6 @@ # Merge requests -Merge requests provide a way to contribute your way into the specified branch so your changes can combined with others. +Merge requests provide a way to contribute your work into the specified branch so your changes can be combined with others. ## List merge requests @@ -20,10 +20,10 @@ Parameters: | Attribute | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `id` | integer | yes | The ID of a project | -| `iid` | integer | no | Return the request having the given `iid` | -| `state` | string | no | Return `all` requests or just those that are `merged`, `opened` or `closed` | -| `order_by` | string | no | Return requests ordered by `created_at` or `updated_at` fields. Default is `created_at` | -| `sort` | string | no | Return requests sorted in `asc` or `desc` order. Default is `desc` | +| `iid` | integer | no | Return the MRs having the given `iid` | +| `state` | string | no | Return `all` MRs or just those that are `merged`, `opened` or `closed` | +| `order_by` | string | no | Return MRs ordered by `created_at` or `updated_at` fields. Default is `created_at` | +| `sort` | string | no | Return MRs sorted in `asc` or `desc` order. Default is `desc` | ```bash curl -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" http://gitlab.example.com/api/v3/projects/1/merge_requests/ @@ -83,7 +83,7 @@ curl -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" http://gitlab.example.com/api/v3/p ] ``` -## Get single MR +## Get a single Merge Request Shows information about a single merge request. @@ -96,7 +96,7 @@ Parameters: | Attribute | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `id` | integer | yes | The ID of a project | -| `iid` | integer | no | Return the request having the given `iid` | +| `merge_request_id` | integer | no | Return the MR having the given `merge_request_id` | ```bash curl -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" http://gitlab.example.com/api/v3/projects/1/merge_requests/1 @@ -167,7 +167,7 @@ Parameters: | Attribute | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `id` | integer | yes | The ID of a project | -| `iid` | integer | no | Return the request having the given `iid` | +| `merge_request_id` | integer | no | Return the MR having the given `merge_request_id` | ```bash curl -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" http://gitlab.example.com/api/v3/projects/1/merge_requests/1/commits @@ -209,13 +209,12 @@ Parameters: | Attribute | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `id` | integer | yes | The ID of a project | -| `iid` | integer | no | Return the request having the given `iid` | +| `merge_request_id` | integer | no | Return the MR having the given `merge_request_id` | ```bash curl -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" http://gitlab.example.com/api/v3/projects/21/merge_requests/1/changes ``` - ```json { "id": 21, @@ -301,6 +300,7 @@ Parameters: | `target_project_id` | integer | no | The target project | | `labels` | string | no | Labels for MR as a comma-separated list | | `milestone_id` | string | no | Milestone ID | +| `remove_source_branch` | boolean | no | Remove the source branch when the MR is merged | ```bash curl -X POST -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" http://gitlab.example.com/api/v3/projects/1/merge_requests?source_branch=test1&target_branch=master&title=test1 @@ -366,7 +366,7 @@ If an error occurs, an error number and a message explaining the reason is retur Updates an existing merge request. You can change the target branch, title, or even close the MR. ``` -PUT /projects/:id/merge_requests/:iid +PUT /projects/:id/merge_requests/:merge_request_id ``` Parameters: @@ -374,7 +374,7 @@ Parameters: | Attribute | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `id` | integer | yes | The ID of a project | -| `iid` | integer | yes | ID of MR | +| `merge_request_id` | integer | yes | ID of MR | | `target_branch` | string | no | The target branch | | `assignee_id` | integer | no | Assignee user ID | | `title` | string | no | Title of the new MR | @@ -382,7 +382,7 @@ Parameters: | `target_project_id` | integer | no | The target project | | `labels` | string | no | Labels for MR as a comma-separated list | | `milestone_id` | string | no | Milestone ID | - +| `remove_source_branch` | boolean | no | Remove the source branch when the MR is merged | ```bash curl -X PUT -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" http://gitlab.example.com/api/v3/projects/1/merge_requests/1&title=test11 diff --git a/features/steps/project/merge_requests/acceptance.rb b/features/steps/project/merge_requests/acceptance.rb index 4fda0731e2f2..d3f7411f6981 100644 --- a/features/steps/project/merge_requests/acceptance.rb +++ b/features/steps/project/merge_requests/acceptance.rb @@ -30,7 +30,7 @@ class Spinach::Features::ProjectMergeRequestsAcceptance < Spinach::FeatureSteps @user = create(:user) @project = create(:project, :public) @project_member = create(:project_member, :developer, user: @user, project: @project) - @merge_request = create(:merge_request, :with_diffs, :simple, source_project: @project) + @merge_request = create(:merge_request, :with_diffs, :simple, source_project: @project, remove_source_branch: false) end step 'I am signed in as a developer of the project' do diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 1aa2a480353e..02a0bc203548 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -19,10 +19,17 @@ def handle_merge_request_errors!(errors) render_api_error!(errors, 400) end - def remove_source_branch? - parse_boolean(params[:should_remove_source_branch]) || - parse_boolean(params[:force_remove_source_branch]) || - parse_boolean(params[:remove_source_branch]) + def remove_source_branch(merge_request) + # We only need the update the value if it differs from what we've got + # the to_boolean calls could return `nil`, which can't be inserted into + # to the `remove_source_branch` field as the column is restrained + new_value = to_boolean(params[:should_remove_source_branch]) || + to_boolean(params[:force_remove_source_branch]) || + to_boolean(params[:remove_source_branch]) + + if new_value != merge_request.remove_source_branch + merge_request.remove_source_branch = !merge_request.remove_source_branch + end end end @@ -184,11 +191,13 @@ def remove_source_branch? # description - Description of MR # labels (optional) - Labels for a MR as a comma-separated list # milestone_id (optional) - Milestone ID + # remove_source_branch (optional) - Should the source branch be deleted if the MR is merged? + # # Example: # PUT /projects/:id/merge_requests/:merge_request_id # put path do - attrs = attributes_for_keys [:target_branch, :assignee_id, :title, :state_event, :description, :milestone_id] + attrs = attributes_for_keys [:target_branch, :assignee_id, :title, :state_event, :description, :milestone_id, :remove_source_branch] merge_request = user_project.merge_requests.find(params[:merge_request_id]) authorize! :update_merge_request, merge_request @@ -223,7 +232,7 @@ def remove_source_branch? # id (required) - The ID of a project # merge_request_id (required) - ID of MR # merge_commit_message (optional) - Custom merge commit message - # should_remove_source_branch (optional) - When true, the source branch will be deleted if possible + # remove_source_branch (optional) - When true, the source branch will be deleted if possible # merge_when_build_succeeds (optional) - When true, this MR will be merged when the build succeeds # sha (optional) - When present, must have the HEAD SHA of the source branch # Example: @@ -245,7 +254,7 @@ def remove_source_branch? end merge_params = { commit_message: params[:merge_commit_message] } - merge_request.remove_source_branch = remove_source_branch? + remove_source_branch(merge_request) if to_boolean(params[:merge_when_build_succeeds]) && merge_request.pipeline && merge_request.pipeline.active? ::MergeRequests::MergeWhenBuildSucceedsService.new(merge_request.target_project, current_user, merge_params). diff --git a/spec/features/merge_requests/merge_when_build_succeeds_spec.rb b/spec/features/merge_requests/merge_when_build_succeeds_spec.rb index 3179162c7ac2..7a110cf987d6 100644 --- a/spec/features/merge_requests/merge_when_build_succeeds_spec.rb +++ b/spec/features/merge_requests/merge_when_build_succeeds_spec.rb @@ -4,7 +4,7 @@ let(:user) { create(:user) } let(:project) { create(:project, :public) } - let(:merge_request) { create(:merge_request_with_diffs, source_project: project, author: user, title: "Bug NS-04") } + let(:merge_request) { create(:merge_request_with_diffs, source_project: project, author: user) } before do project.team << [user, :master] @@ -42,15 +42,16 @@ end context 'When it is enabled' do - let(:merge_request) do - create(:merge_request_with_diffs, :simple, source_project: project, author: user, - merge_user: user, title: "MepMep", merge_when_build_succeeds: true) - end - let!(:pipeline) { create(:ci_pipeline, project: project, sha: merge_request.diff_head_sha, ref: merge_request.source_branch) } let!(:ci_build) { create(:ci_build, pipeline: pipeline) } before do + # Do not create a new MR here in this scope, this will yield a second MR with the same source branch + merge_request.remove_source_branch = false + merge_request.merge_when_build_succeeds = true + merge_request.merge_user = user + merge_request.save + login_as user visit_merge_request(merge_request) end diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb index 651b91e9f68a..4ea8c7b84d3c 100644 --- a/spec/requests/api/merge_requests_spec.rb +++ b/spec/requests/api/merge_requests_spec.rb @@ -216,11 +216,14 @@ target_branch: 'master', author: user, labels: 'label, label2', - milestone_id: milestone.id + milestone_id: milestone.id, + remove_source_branch: false + expect(response).to have_http_status(201) expect(json_response['title']).to eq('Test merge_request') expect(json_response['labels']).to eq(['label', 'label2']) expect(json_response['milestone']['id']).to eq(milestone.id) + expect(json_response['should_remove_source_branch?']).to be false end it "should return 422 when source_branch equals target_branch" do @@ -384,14 +387,6 @@ end end - describe "PUT /projects/:id/merge_requests/:merge_request_id to close MR" do - it "should return merge_request" do - put api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), state_event: "close" - expect(response).to have_http_status(200) - expect(json_response['state']).to eq('closed') - end - end - describe "PUT /projects/:id/merge_requests/:merge_request_id/merge" do let(:pipeline) { create(:ci_pipeline_without_jobs) } @@ -470,10 +465,25 @@ describe "PUT /projects/:id/merge_requests/:merge_request_id" do it "updates title and returns merge_request" do put api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), title: "New title" + expect(response).to have_http_status(200) expect(json_response['title']).to eq('New title') end + it "updates the state of the merge_request" do + put api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), state_event: "close" + + expect(response).to have_http_status(200) + expect(json_response['state']).to eq('closed') + end + + it 'updates the remove source branch setting' do + put api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), remove_source_branch: false + + expect(response).to have_http_status(200) + expect(json_response['should_remove_source_branch?']).to be false + end + it "updates description and returns merge_request" do put api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), description: "New description" expect(response).to have_http_status(200) @@ -482,18 +492,21 @@ it "updates milestone_id and returns merge_request" do put api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), milestone_id: milestone.id + expect(response).to have_http_status(200) expect(json_response['milestone']['id']).to eq(milestone.id) end it "should return 400 when source_branch is specified" do put api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), + source_branch: "master", target_branch: "master" expect(response).to have_http_status(400) end it "should return merge_request with renamed target_branch" do put api("/projects/#{project.id}/merge_requests/#{merge_request.id}", user), target_branch: "wiki" + expect(response).to have_http_status(200) expect(json_response['target_branch']).to eq('wiki') end @@ -503,6 +516,7 @@ user), title: 'new issue', labels: 'label, label?, label&foo, ?, &' + expect(response.status).to eq(200) expect(json_response['labels']).to include 'label' expect(json_response['labels']).to include 'label?' -- GitLab From d8da0761ae4f16a2f824a45985b67356a042b699 Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Mon, 25 Jul 2016 09:56:25 +0200 Subject: [PATCH 4/7] Remove merge_params from merge_requests The merge_params field had only one key left which was actively used, thus the whole column could be removed --- .../projects/merge_requests_controller.rb | 9 ++---- app/models/merge_request.rb | 6 ++-- .../merge_when_build_succeeds_service.rb | 2 -- ..._remove_source_branch_to_merge_requests.rb | 1 + ..._commit_message_field_to_merge_requests.rb | 12 ++++++++ ...124_migrate_merge_params_commit_message.rb | 29 +++++++++++++++++++ ...20160726093600_drop_merge_params_column.rb | 9 ++++++ db/schema.rb | 10 +++---- spec/models/merge_request_spec.rb | 4 +-- 9 files changed, 63 insertions(+), 19 deletions(-) create mode 100644 db/migrate/20160723112201_add_commit_message_field_to_merge_requests.rb create mode 100644 db/migrate/20160723113124_migrate_merge_params_commit_message.rb create mode 100644 db/migrate/20160726093600_drop_merge_params_column.rb diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index ebb527d2e383..a538954e6411 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -239,7 +239,7 @@ def merge TodoService.new.merge_merge_request(merge_request, current_user) - @merge_request.update(merge_error: nil, remove_source_branch: !!params[:remove_source_branch]) + @merge_request.update(merge_request_params.merge(merge_error: nil)) if params[:merge_when_build_succeeds].present? unless @merge_request.pipeline @@ -435,12 +435,7 @@ def merge_request_params :title, :assignee_id, :source_project_id, :source_branch, :target_project_id, :target_branch, :milestone_id, :state_event, :description, :task_num, :remove_source_branch, - label_ids: [] - ) - end - - def merge_params - params.permit(:commit_message, :remove_source_branch) + label_ids: [], :commit_message) end # Make sure merge requests created before 8.0 diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 90dcfccee5fb..8e51847b736a 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -519,9 +519,9 @@ def merge_commit_message def reset_merge_when_build_succeeds return unless merge_when_build_succeeds? - self.merge_when_build_succeeds = false - self.merge_user = nil - self.merge_params = nil + self.merge_when_build_succeeds = false + self.merge_user = nil + self.commit_message = nil self.save end diff --git a/app/services/merge_requests/merge_when_build_succeeds_service.rb b/app/services/merge_requests/merge_when_build_succeeds_service.rb index 4ad5fb083114..0bbd6af43bc9 100644 --- a/app/services/merge_requests/merge_when_build_succeeds_service.rb +++ b/app/services/merge_requests/merge_when_build_succeeds_service.rb @@ -3,8 +3,6 @@ class MergeWhenBuildSucceedsService < MergeRequests::BaseService # Marks the passed `merge_request` to be merged when the build succeeds or # updates the params for the automatic merge def execute(merge_request) - merge_request.merge_params.merge!(params) - # The service is also called when the merge params are updated. already_approved = merge_request.merge_when_build_succeeds? diff --git a/db/migrate/20160720102606_add_remove_source_branch_to_merge_requests.rb b/db/migrate/20160720102606_add_remove_source_branch_to_merge_requests.rb index 8abb7a7c0f13..eed27fac5968 100644 --- a/db/migrate/20160720102606_add_remove_source_branch_to_merge_requests.rb +++ b/db/migrate/20160720102606_add_remove_source_branch_to_merge_requests.rb @@ -24,5 +24,6 @@ def up def down # noop - We don't want to serialize and deserialize, also, the keys are still there + # These will be removed in the MigrateMergeParamsCommitMessage migration end end diff --git a/db/migrate/20160723112201_add_commit_message_field_to_merge_requests.rb b/db/migrate/20160723112201_add_commit_message_field_to_merge_requests.rb new file mode 100644 index 000000000000..63522f2876fc --- /dev/null +++ b/db/migrate/20160723112201_add_commit_message_field_to_merge_requests.rb @@ -0,0 +1,12 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddCommitMessageFieldToMergeRequests < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def change + add_column(:merge_requests, :commit_message, :text) + end +end diff --git a/db/migrate/20160723113124_migrate_merge_params_commit_message.rb b/db/migrate/20160723113124_migrate_merge_params_commit_message.rb new file mode 100644 index 000000000000..aa6caa72f77b --- /dev/null +++ b/db/migrate/20160723113124_migrate_merge_params_commit_message.rb @@ -0,0 +1,29 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class MigrateMergeParamsCommitMessage < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def up + require 'yaml' + + db.select_all("SELECT id, merge_params FROM merge_requests WHERE merge_params LIKE '%commit_message%'").each do |result| + commit_message = YAML.load(result['merge_params'])['commit_message'] + + db.update("UPDATE merge_requests SET commit_message = #{db.quote(commit_message)} WHERE id = #{db.quote(result['id'])}") + end + end + + def down + # In a migration right after this one, the column will be dropped, so I won't + # implement this here + end + + private + + def db + ActiveRecord::Base.connection + end +end diff --git a/db/migrate/20160726093600_drop_merge_params_column.rb b/db/migrate/20160726093600_drop_merge_params_column.rb new file mode 100644 index 000000000000..010b99672cc9 --- /dev/null +++ b/db/migrate/20160726093600_drop_merge_params_column.rb @@ -0,0 +1,9 @@ +class DropMergeParamsColumn < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + def change + remove_column(:merge_requests, :merge_params, :text) + end +end diff --git a/db/schema.rb b/db/schema.rb index ea654289cc5e..102e4c0fdeba 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -167,8 +167,8 @@ t.text "artifacts_metadata" t.integer "erased_by_id" t.datetime "erased_at" - t.string "environment" t.datetime "artifacts_expire_at" + t.string "environment" t.integer "artifacts_size" t.string "when" t.text "yaml_variables" @@ -626,13 +626,13 @@ t.datetime "locked_at" t.integer "updated_by_id" t.string "merge_error" - t.text "merge_params" t.boolean "merge_when_build_succeeds", default: false, null: false t.integer "merge_user_id" t.string "merge_commit_sha" t.datetime "deleted_at" t.string "in_progress_merge_commit_sha" t.boolean "remove_source_branch", default: true, null: false + t.text "commit_message" end add_index "merge_requests", ["assignee_id"], name: "index_merge_requests_on_assignee_id", using: :btree @@ -783,10 +783,10 @@ t.integer "user_id", null: false t.string "token", null: false t.string "name", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false t.boolean "revoked", default: false t.datetime "expires_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "personal_access_tokens", ["token"], name: "index_personal_access_tokens_on_token", unique: true, using: :btree @@ -848,8 +848,8 @@ t.boolean "only_allow_merge_if_build_succeeds", default: false, null: false t.boolean "has_external_issue_tracker" t.string "repository_storage", default: "default", null: false - t.boolean "has_external_wiki" t.boolean "request_access_enabled", default: true, null: false + t.boolean "has_external_wiki" end add_index "projects", ["builds_enabled", "shared_runners_enabled"], name: "index_projects_on_builds_enabled_and_shared_runners_enabled", using: :btree diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index 90663be26432..f1da2cc785d0 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -54,7 +54,7 @@ it { is_expected.to respond_to(:unchecked?) } it { is_expected.to respond_to(:can_be_merged?) } it { is_expected.to respond_to(:cannot_be_merged?) } - it { is_expected.to respond_to(:merge_params) } + it { is_expected.to respond_to(:commit_message) } it { is_expected.to respond_to(:merge_when_build_succeeds) } end @@ -339,7 +339,7 @@ merge_if_green.reload expect(merge_if_green.merge_when_build_succeeds).to be_falsey - expect(merge_if_green.merge_params["commit_message"]).to be_nil + expect(merge_if_green.commit_message).to be_nil end end -- GitLab From d89f27f44458dff5bf78ef00cd16fed6103bee47 Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Fri, 29 Jul 2016 11:11:12 +0200 Subject: [PATCH 5/7] Remove merge_params hash --- .../projects/merge_requests_controller.rb | 15 ++++---- app/models/merge_request.rb | 3 -- app/services/merge_requests/merge_service.rb | 2 +- .../merge_when_build_succeeds_service.rb | 2 +- .../widget/open/_accept.html.haml | 16 ++++----- app/workers/merge_worker.rb | 5 ++- lib/api/merge_requests.rb | 35 ++++++++++--------- spec/models/merge_request_spec.rb | 5 +-- .../merge_when_build_succeeds_service_spec.rb | 9 ++--- spec/workers/merge_worker_spec.rb | 5 +-- 10 files changed, 46 insertions(+), 51 deletions(-) diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index a538954e6411..55ba3e80b9d7 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -239,7 +239,7 @@ def merge TodoService.new.merge_merge_request(merge_request, current_user) - @merge_request.update(merge_request_params.merge(merge_error: nil)) + @merge_request.update(merge_params.merge(merge_error: nil)) if params[:merge_when_build_succeeds].present? unless @merge_request.pipeline @@ -248,19 +248,19 @@ def merge end if @merge_request.pipeline.active? - MergeRequests::MergeWhenBuildSucceedsService.new(@project, current_user, merge_params) + MergeRequests::MergeWhenBuildSucceedsService.new(@project, current_user) .execute(@merge_request) @status = :merge_when_build_succeeds elsif @merge_request.pipeline.success? # This can be triggered when a user clicks the auto merge button while # the tests finish at about the same time - MergeWorker.perform_async(@merge_request.id, current_user.id, params) + MergeWorker.perform_async(@merge_request.id, current_user.id) @status = :success else @status = :failed end else - MergeWorker.perform_async(@merge_request.id, current_user.id, params) + MergeWorker.perform_async(@merge_request.id, current_user.id) @status = :success end end @@ -434,8 +434,11 @@ def merge_request_params params.require(:merge_request).permit( :title, :assignee_id, :source_project_id, :source_branch, :target_project_id, :target_branch, :milestone_id, - :state_event, :description, :task_num, :remove_source_branch, - label_ids: [], :commit_message) + :state_event, :description, :task_num, label_ids: []) + end + + def merge_params + params.permit(:remove_source_branch, :commit_message) end # Make sure merge requests created before 8.0 diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index 8e51847b736a..6b0d57261997 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -14,8 +14,6 @@ class MergeRequest < ActiveRecord::Base has_many :events, as: :target, dependent: :destroy - serialize :merge_params, Hash - after_create :create_merge_request_diff, unless: :importing? after_update :update_merge_request_diff @@ -521,7 +519,6 @@ def reset_merge_when_build_succeeds self.merge_when_build_succeeds = false self.merge_user = nil - self.commit_message = nil self.save end diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb index 4b133f8f4d7f..345e822bae6f 100644 --- a/app/services/merge_requests/merge_service.rb +++ b/app/services/merge_requests/merge_service.rb @@ -29,7 +29,7 @@ def commit committer = repository.user_to_committer(current_user) options = { - message: params[:commit_message] || merge_request.merge_commit_message, + message: merge_request.commit_message || merge_request.merge_commit_message, author: committer, committer: committer } diff --git a/app/services/merge_requests/merge_when_build_succeeds_service.rb b/app/services/merge_requests/merge_when_build_succeeds_service.rb index 0bbd6af43bc9..eefe6cdb114d 100644 --- a/app/services/merge_requests/merge_when_build_succeeds_service.rb +++ b/app/services/merge_requests/merge_when_build_succeeds_service.rb @@ -23,7 +23,7 @@ def trigger(commit_status) next unless merge_request.mergeable? next unless pipeline.success? - MergeWorker.perform_async(merge_request.id, merge_request.merge_user_id, merge_request.merge_params) + MergeWorker.perform_async(merge_request.id, merge_request.merge_user_id) end end diff --git a/app/views/projects/merge_requests/widget/open/_accept.html.haml b/app/views/projects/merge_requests/widget/open/_accept.html.haml index d9f33059a7d9..9455efc5c692 100644 --- a/app/views/projects/merge_requests/widget/open/_accept.html.haml +++ b/app/views/projects/merge_requests/widget/open/_accept.html.haml @@ -27,21 +27,21 @@ - else = f.button class: "btn btn-create btn-grouped js-merge-button accept_merge_request #{status_class}" do Accept Merge Request - - if @merge_request.remove_source_branch? - .accept-control + .accept-control + - if @merge_request.remove_source_branch? The source branch will be removed. - - elsif @merge_request.can_remove_source_branch?(current_user) - .accept-control.checkbox - = f.label :remove_source_branch, class: "remove_source_checkbox" do - = f.check_box :remove_source_branch - Remove source branch + - elsif @merge_request.can_remove_source_branch?(current_user) + .checkbox + = f.label :remove_source_branch, class: "remove_source_checkbox" do + = f.check_box :remove_source_branch + Remove source branch .accept-control.right = link_to "#", class: "modify-merge-commit-link js-toggle-button" do = icon('edit') Modify commit message .js-toggle-content.hide.prepend-top-default = render 'shared/commit_message_container', params: params, - text: @merge_request.merge_commit_message, + text: @merge_request.commit_message || @merge_request.merge_commit_message, rows: 14, hint: true = hidden_field_tag :merge_when_build_succeeds, "", autocomplete: "off" diff --git a/app/workers/merge_worker.rb b/app/workers/merge_worker.rb index c87c0a252b1f..35316cf12693 100644 --- a/app/workers/merge_worker.rb +++ b/app/workers/merge_worker.rb @@ -3,12 +3,11 @@ class MergeWorker sidekiq_options queue: :default - def perform(merge_request_id, current_user_id, params) - params = params.with_indifferent_access + def perform(merge_request_id, current_user_id) current_user = User.find(current_user_id) merge_request = MergeRequest.find(merge_request_id) - MergeRequests::MergeService.new(merge_request.target_project, current_user, params). + MergeRequests::MergeService.new(merge_request.target_project, current_user). execute(merge_request) end end diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb index 02a0bc203548..b13f848627a5 100644 --- a/lib/api/merge_requests.rb +++ b/lib/api/merge_requests.rb @@ -226,18 +226,15 @@ def remove_source_branch(merge_request) end end - # Merge MR - # - # Parameters: - # id (required) - The ID of a project - # merge_request_id (required) - ID of MR - # merge_commit_message (optional) - Custom merge commit message - # remove_source_branch (optional) - When true, the source branch will be deleted if possible - # merge_when_build_succeeds (optional) - When true, this MR will be merged when the build succeeds - # sha (optional) - When present, must have the HEAD SHA of the source branch - # Example: - # PUT /projects/:id/merge_requests/:merge_request_id/merge - # + desc 'Merge a merge request' do + success Entities::MergeRequest + end + params do + optional :commit_message, type: String, desc: 'The commit message for the merge commit' + optional :remove_source_branch, type: Boolean, desc: 'After the merge, should the branch be removed?' + optional :merge_when_build_succeeds, type: Boolean, desc: 'When true, this MR will be merged when the build succeeds' + optional :sha, type: String, desc: 'When present, must have the HEAD SHA of the source branch' + end put "#{path}/merge" do merge_request = user_project.merge_requests.find(params[:merge_request_id]) @@ -253,15 +250,19 @@ def remove_source_branch(merge_request) render_api_error!("SHA does not match HEAD of source branch: #{merge_request.diff_head_sha}", 409) end - merge_params = { commit_message: params[:merge_commit_message] } + # There used to be a `force_remove_source_branch`, `should_remove_source_branch` which got combined into one. + # To support this untill 9.0 we'll have to update the property like this remove_source_branch(merge_request) - if to_boolean(params[:merge_when_build_succeeds]) && merge_request.pipeline && merge_request.pipeline.active? - ::MergeRequests::MergeWhenBuildSucceedsService.new(merge_request.target_project, current_user, merge_params). + # To still support both `merge_commit_message` and `commit_message` until 9.0 we can't just use `update_attributes` + # Support for `merge_commit_message` should be dropped on 9.0 + merge_request.commit_message = params[:commit_message] || params[:merge_commit_message] || merge_request.commit_message + + if params[:merge_when_build_succeeds] && merge_request.pipeline && merge_request.pipeline.active? + ::MergeRequests::MergeWhenBuildSucceedsService.new(merge_request.target_project, current_user). execute(merge_request) else - ::MergeRequests::MergeService.new(merge_request.target_project, current_user, merge_params). - execute(merge_request) + ::MergeRequests::MergeService.new(merge_request.target_project, current_user).execute(merge_request) end present merge_request, with: Entities::MergeRequest, current_user: current_user diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb index f1da2cc785d0..01c96ff1ab39 100644 --- a/spec/models/merge_request_spec.rb +++ b/spec/models/merge_request_spec.rb @@ -317,6 +317,7 @@ it "can be removed if the last commit is the head of the source branch" do allow(subject.source_project).to receive(:commit).and_return(subject.diff_head_commit) + allow(subject).to receive(:same_source_branch_merge_requests?).and_return(false) expect(subject.can_remove_source_branch?(user)).to be_truthy end @@ -331,7 +332,7 @@ describe "#reset_merge_when_build_succeeds" do let(:merge_if_green) do create :merge_request, merge_when_build_succeeds: true, merge_user: create(:user), - remove_source_branch: true, merge_params: { "commit_message" => "msg" } + remove_source_branch: true, commit_message: 'msg' end it "sets the item to false" do @@ -339,7 +340,7 @@ merge_if_green.reload expect(merge_if_green.merge_when_build_succeeds).to be_falsey - expect(merge_if_green.commit_message).to be_nil + expect(merge_if_green.commit_message).to eq 'msg' end end diff --git a/spec/services/merge_requests/merge_when_build_succeeds_service_spec.rb b/spec/services/merge_requests/merge_when_build_succeeds_service_spec.rb index 4da8146e3d6a..631642466e18 100644 --- a/spec/services/merge_requests/merge_when_build_succeeds_service_spec.rb +++ b/spec/services/merge_requests/merge_when_build_succeeds_service_spec.rb @@ -11,7 +11,7 @@ end let(:pipeline) { create(:ci_pipeline_with_one_job, ref: mr_merge_if_green_enabled.source_branch, project: project) } - let(:service) { MergeRequests::MergeWhenBuildSucceedsService.new(project, user, commit_message: 'Awesome message') } + let(:service) { MergeRequests::MergeWhenBuildSucceedsService.new(project, user) } describe "#execute" do let(:merge_request) do @@ -25,10 +25,9 @@ service.execute(merge_request) end - it 'sets the params, merge_user, and flag' do + it 'sets merge_user and flag' do expect(merge_request).to be_valid expect(merge_request.merge_when_build_succeeds).to be_truthy - expect(merge_request.merge_params).to eq commit_message: 'Awesome message' expect(merge_request.merge_user).to be user end @@ -39,7 +38,7 @@ end context 'already approved' do - let(:service) { MergeRequests::MergeWhenBuildSucceedsService.new(project, user, new_key: true) } + let(:service) { MergeRequests::MergeWhenBuildSucceedsService.new(project, user) } let(:build) { create(:ci_build, ref: mr_merge_if_green_enabled.source_branch) } before do @@ -52,7 +51,6 @@ expect(SystemNoteService).not_to receive(:merge_when_build_succeeds) service.execute(mr_merge_if_green_enabled) - expect(mr_merge_if_green_enabled.merge_params).to have_key(:new_key) end end end @@ -146,7 +144,6 @@ it "resets all the merge_when_build_succeeds params" do expect(mr_merge_if_green_enabled.merge_when_build_succeeds).to be_falsey - expect(mr_merge_if_green_enabled.merge_params).to eq({}) expect(mr_merge_if_green_enabled.merge_user).to be nil end diff --git a/spec/workers/merge_worker_spec.rb b/spec/workers/merge_worker_spec.rb index b5e1fdb8ded4..9213ba63497b 100644 --- a/spec/workers/merge_worker_spec.rb +++ b/spec/workers/merge_worker_spec.rb @@ -15,10 +15,7 @@ it 'clears cache of source repo after removing source branch' do expect(source_project.repository.branch_names).to include('markdown') - MergeWorker.new.perform( - merge_request.id, merge_request.author_id, - commit_message: 'wow such merge', - should_remove_source_branch: true) + MergeWorker.new.perform(merge_request.id, merge_request.author_id) merge_request.reload expect(merge_request).to be_merged -- GitLab From 9fe57578b5da87dd7e8098d071be84e653b2b8f5 Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Tue, 2 Aug 2016 15:43:19 +0200 Subject: [PATCH 6/7] Squash bugs, mark migration as offline --- app/services/merge_requests/merge_service.rb | 2 +- ...20160720102606_add_remove_source_branch_to_merge_requests.rb | 2 ++ .../20160723113124_migrate_merge_params_commit_message.rb | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb index 345e822bae6f..34b23383f158 100644 --- a/app/services/merge_requests/merge_service.rb +++ b/app/services/merge_requests/merge_service.rb @@ -56,7 +56,7 @@ def commit def after_merge MergeRequests::PostMergeService.new(project, current_user).execute(merge_request) - if merge_request.can_remove_source_branch?(branch_deletion_user) + if merge_request.remove_source_branch? && merge_request.can_remove_source_branch?(branch_deletion_user) DeleteBranchService.new(@merge_request.source_project, branch_deletion_user). execute(merge_request.source_branch) end diff --git a/db/migrate/20160720102606_add_remove_source_branch_to_merge_requests.rb b/db/migrate/20160720102606_add_remove_source_branch_to_merge_requests.rb index eed27fac5968..908a35749f58 100644 --- a/db/migrate/20160720102606_add_remove_source_branch_to_merge_requests.rb +++ b/db/migrate/20160720102606_add_remove_source_branch_to_merge_requests.rb @@ -8,6 +8,8 @@ class AddRemoveSourceBranchToMergeRequests < ActiveRecord::Migration disable_ddl_transaction! + DOWNTIME = false + def up add_column_with_default(:merge_requests, :remove_source_branch, :boolean, default: true) diff --git a/db/migrate/20160723113124_migrate_merge_params_commit_message.rb b/db/migrate/20160723113124_migrate_merge_params_commit_message.rb index aa6caa72f77b..e5c411fed82c 100644 --- a/db/migrate/20160723113124_migrate_merge_params_commit_message.rb +++ b/db/migrate/20160723113124_migrate_merge_params_commit_message.rb @@ -4,7 +4,7 @@ class MigrateMergeParamsCommitMessage < ActiveRecord::Migration include Gitlab::Database::MigrationHelpers - DOWNTIME = false + DOWNTIME = true def up require 'yaml' -- GitLab From 7cd29a2c2549eaea51ac7381598afb51c05391d0 Mon Sep 17 00:00:00 2001 From: "Z.J. van de Weg" Date: Fri, 14 Oct 2016 15:54:46 +0200 Subject: [PATCH 7/7] Update schema --- db/schema.rb | 1176 +++++++++++++++++++++++++------------------------- 1 file changed, 588 insertions(+), 588 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 657ffa5216c8..faa71cec1b4f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -18,94 +18,94 @@ enable_extension "pg_trgm" create_table "abuse_reports", force: :cascade do |t| - t.integer "reporter_id" - t.integer "user_id" - t.text "message" + t.integer "reporter_id" + t.integer "user_id" + t.text "message" t.datetime "created_at" t.datetime "updated_at" - t.text "message_html" + t.text "message_html" end create_table "appearances", force: :cascade do |t| - t.string "title" - t.text "description" - t.string "header_logo" - t.string "logo" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.text "description_html" + t.string "title" + t.text "description" + t.string "header_logo" + t.string "logo" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.text "description_html" end create_table "application_settings", force: :cascade do |t| - t.integer "default_projects_limit" - t.boolean "signup_enabled" - t.boolean "signin_enabled" - t.boolean "gravatar_enabled" - t.text "sign_in_text" + t.integer "default_projects_limit" + t.boolean "signup_enabled" + t.boolean "signin_enabled" + t.boolean "gravatar_enabled" + t.text "sign_in_text" t.datetime "created_at" t.datetime "updated_at" - t.string "home_page_url" - t.integer "default_branch_protection", default: 2 - t.text "restricted_visibility_levels" - t.boolean "version_check_enabled", default: true - t.integer "max_attachment_size", default: 10, null: false - t.integer "default_project_visibility" - t.integer "default_snippet_visibility" - t.text "domain_whitelist" - t.boolean "user_oauth_applications", default: true - t.string "after_sign_out_path" - t.integer "session_expire_delay", default: 10080, null: false - t.text "import_sources" - t.text "help_page_text" - t.string "admin_notification_email" - t.boolean "shared_runners_enabled", default: true, null: false - t.integer "max_artifacts_size", default: 100, null: false - t.string "runners_registration_token" - t.boolean "require_two_factor_authentication", default: false - t.integer "two_factor_grace_period", default: 48 - t.boolean "metrics_enabled", default: false - t.string "metrics_host", default: "localhost" - t.integer "metrics_pool_size", default: 16 - t.integer "metrics_timeout", default: 10 - t.integer "metrics_method_call_threshold", default: 10 - t.boolean "recaptcha_enabled", default: false - t.string "recaptcha_site_key" - t.string "recaptcha_private_key" - t.integer "metrics_port", default: 8089 - t.boolean "akismet_enabled", default: false - t.string "akismet_api_key" - t.integer "metrics_sample_interval", default: 15 - t.boolean "sentry_enabled", default: false - t.string "sentry_dsn" - t.boolean "email_author_in_body", default: false - t.integer "default_group_visibility" - t.boolean "repository_checks_enabled", default: false - t.text "shared_runners_text" - t.integer "metrics_packet_size", default: 1 - t.text "disabled_oauth_sign_in_sources" - t.string "health_check_access_token" - t.boolean "send_user_confirmation_email", default: false - t.integer "container_registry_token_expire_delay", default: 5 - t.text "after_sign_up_text" - t.boolean "user_default_external", default: false, null: false - t.string "repository_storage", default: "default" - t.string "enabled_git_access_protocol" - t.boolean "domain_blacklist_enabled", default: false - t.text "domain_blacklist" - t.boolean "koding_enabled" - t.string "koding_url" - t.text "sign_in_text_html" - t.text "help_page_text_html" - t.text "shared_runners_text_html" - t.text "after_sign_up_text_html" + t.string "home_page_url" + t.integer "default_branch_protection", default: 2 + t.text "restricted_visibility_levels" + t.boolean "version_check_enabled", default: true + t.integer "max_attachment_size", default: 10, null: false + t.integer "default_project_visibility" + t.integer "default_snippet_visibility" + t.text "domain_whitelist" + t.boolean "user_oauth_applications", default: true + t.string "after_sign_out_path" + t.integer "session_expire_delay", default: 10080, null: false + t.text "import_sources" + t.text "help_page_text" + t.string "admin_notification_email" + t.boolean "shared_runners_enabled", default: true, null: false + t.integer "max_artifacts_size", default: 100, null: false + t.string "runners_registration_token" + t.boolean "require_two_factor_authentication", default: false + t.integer "two_factor_grace_period", default: 48 + t.boolean "metrics_enabled", default: false + t.string "metrics_host", default: "localhost" + t.integer "metrics_pool_size", default: 16 + t.integer "metrics_timeout", default: 10 + t.integer "metrics_method_call_threshold", default: 10 + t.boolean "recaptcha_enabled", default: false + t.string "recaptcha_site_key" + t.string "recaptcha_private_key" + t.integer "metrics_port", default: 8089 + t.boolean "akismet_enabled", default: false + t.string "akismet_api_key" + t.integer "metrics_sample_interval", default: 15 + t.boolean "sentry_enabled", default: false + t.string "sentry_dsn" + t.boolean "email_author_in_body", default: false + t.integer "default_group_visibility" + t.boolean "repository_checks_enabled", default: false + t.text "shared_runners_text" + t.integer "metrics_packet_size", default: 1 + t.text "disabled_oauth_sign_in_sources" + t.string "health_check_access_token" + t.boolean "send_user_confirmation_email", default: false + t.integer "container_registry_token_expire_delay", default: 5 + t.text "after_sign_up_text" + t.boolean "user_default_external", default: false, null: false + t.string "repository_storage", default: "default" + t.string "enabled_git_access_protocol" + t.boolean "domain_blacklist_enabled", default: false + t.text "domain_blacklist" + t.boolean "koding_enabled" + t.string "koding_url" + t.text "sign_in_text_html" + t.text "help_page_text_html" + t.text "shared_runners_text_html" + t.text "after_sign_up_text_html" end create_table "audit_events", force: :cascade do |t| - t.integer "author_id", null: false - t.string "type", null: false - t.integer "entity_id", null: false - t.string "entity_type", null: false - t.text "details" + t.integer "author_id", null: false + t.string "type", null: false + t.integer "entity_id", null: false + t.string "entity_type", null: false + t.text "details" t.datetime "created_at" t.datetime "updated_at" end @@ -113,10 +113,10 @@ add_index "audit_events", ["entity_id", "entity_type"], name: "index_audit_events_on_entity_id_and_entity_type", using: :btree create_table "award_emoji", force: :cascade do |t| - t.string "name" - t.integer "user_id" - t.integer "awardable_id" - t.string "awardable_type" + t.string "name" + t.integer "user_id" + t.integer "awardable_id" + t.string "awardable_type" t.datetime "created_at" t.datetime "updated_at" end @@ -126,7 +126,7 @@ add_index "award_emoji", ["user_id"], name: "index_award_emoji_on_user_id", using: :btree create_table "boards", force: :cascade do |t| - t.integer "project_id", null: false + t.integer "project_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false end @@ -134,61 +134,61 @@ add_index "boards", ["project_id"], name: "index_boards_on_project_id", using: :btree create_table "broadcast_messages", force: :cascade do |t| - t.text "message", null: false + t.text "message", null: false t.datetime "starts_at" t.datetime "ends_at" t.datetime "created_at" t.datetime "updated_at" - t.string "color" - t.string "font" - t.text "message_html" + t.string "color" + t.string "font" + t.text "message_html" end create_table "ci_application_settings", force: :cascade do |t| - t.boolean "all_broken_builds" - t.boolean "add_pusher" + t.boolean "all_broken_builds" + t.boolean "add_pusher" t.datetime "created_at" t.datetime "updated_at" end create_table "ci_builds", force: :cascade do |t| - t.integer "project_id" - t.string "status" + t.integer "project_id" + t.string "status" t.datetime "finished_at" - t.text "trace" + t.text "trace" t.datetime "created_at" t.datetime "updated_at" t.datetime "started_at" - t.integer "runner_id" - t.float "coverage" - t.integer "commit_id" - t.text "commands" - t.integer "job_id" - t.string "name" - t.boolean "deploy", default: false - t.text "options" - t.boolean "allow_failure", default: false, null: false - t.string "stage" - t.integer "trigger_request_id" - t.integer "stage_idx" - t.boolean "tag" - t.string "ref" - t.integer "user_id" - t.string "type" - t.string "target_url" - t.string "description" - t.text "artifacts_file" - t.integer "gl_project_id" - t.text "artifacts_metadata" - t.integer "erased_by_id" + t.integer "runner_id" + t.float "coverage" + t.integer "commit_id" + t.text "commands" + t.integer "job_id" + t.string "name" + t.boolean "deploy", default: false + t.text "options" + t.boolean "allow_failure", default: false, null: false + t.string "stage" + t.integer "trigger_request_id" + t.integer "stage_idx" + t.boolean "tag" + t.string "ref" + t.integer "user_id" + t.string "type" + t.string "target_url" + t.string "description" + t.text "artifacts_file" + t.integer "gl_project_id" + t.text "artifacts_metadata" + t.integer "erased_by_id" t.datetime "erased_at" t.datetime "artifacts_expire_at" - t.string "environment" - t.integer "artifacts_size", limit: 8 - t.string "when" - t.text "yaml_variables" + t.string "environment" + t.integer "artifacts_size", limit: 8 + t.string "when" + t.text "yaml_variables" t.datetime "queued_at" - t.string "token" + t.string "token" end add_index "ci_builds", ["commit_id", "stage_idx", "created_at"], name: "index_ci_builds_on_commit_id_and_stage_idx_and_created_at", using: :btree @@ -203,22 +203,22 @@ add_index "ci_builds", ["token"], name: "index_ci_builds_on_token", unique: true, using: :btree create_table "ci_commits", force: :cascade do |t| - t.integer "project_id" - t.string "ref" - t.string "sha" - t.string "before_sha" - t.text "push_data" + t.integer "project_id" + t.string "ref" + t.string "sha" + t.string "before_sha" + t.text "push_data" t.datetime "created_at" t.datetime "updated_at" - t.boolean "tag", default: false - t.text "yaml_errors" + t.boolean "tag", default: false + t.text "yaml_errors" t.datetime "committed_at" - t.integer "gl_project_id" - t.string "status" + t.integer "gl_project_id" + t.string "status" t.datetime "started_at" t.datetime "finished_at" - t.integer "duration" - t.integer "user_id" + t.integer "duration" + t.integer "user_id" end add_index "ci_commits", ["gl_project_id", "sha"], name: "index_ci_commits_on_gl_project_id_and_sha", using: :btree @@ -228,140 +228,140 @@ add_index "ci_commits", ["user_id"], name: "index_ci_commits_on_user_id", using: :btree create_table "ci_events", force: :cascade do |t| - t.integer "project_id" - t.integer "user_id" - t.integer "is_admin" - t.text "description" + t.integer "project_id" + t.integer "user_id" + t.integer "is_admin" + t.text "description" t.datetime "created_at" t.datetime "updated_at" end create_table "ci_jobs", force: :cascade do |t| - t.integer "project_id", null: false - t.text "commands" - t.boolean "active", default: true, null: false + t.integer "project_id", null: false + t.text "commands" + t.boolean "active", default: true, null: false t.datetime "created_at" t.datetime "updated_at" - t.string "name" - t.boolean "build_branches", default: true, null: false - t.boolean "build_tags", default: false, null: false - t.string "job_type", default: "parallel" - t.string "refs" + t.string "name" + t.boolean "build_branches", default: true, null: false + t.boolean "build_tags", default: false, null: false + t.string "job_type", default: "parallel" + t.string "refs" t.datetime "deleted_at" end create_table "ci_projects", force: :cascade do |t| - t.string "name" - t.integer "timeout", default: 3600, null: false + t.string "name" + t.integer "timeout", default: 3600, null: false t.datetime "created_at" t.datetime "updated_at" - t.string "token" - t.string "default_ref" - t.string "path" - t.boolean "always_build", default: false, null: false - t.integer "polling_interval" - t.boolean "public", default: false, null: false - t.string "ssh_url_to_repo" - t.integer "gitlab_id" - t.boolean "allow_git_fetch", default: true, null: false - t.string "email_recipients", default: "", null: false - t.boolean "email_add_pusher", default: true, null: false - t.boolean "email_only_broken_builds", default: true, null: false - t.string "skip_refs" - t.string "coverage_regex" - t.boolean "shared_runners_enabled", default: false - t.text "generated_yaml_config" + t.string "token" + t.string "default_ref" + t.string "path" + t.boolean "always_build", default: false, null: false + t.integer "polling_interval" + t.boolean "public", default: false, null: false + t.string "ssh_url_to_repo" + t.integer "gitlab_id" + t.boolean "allow_git_fetch", default: true, null: false + t.string "email_recipients", default: "", null: false + t.boolean "email_add_pusher", default: true, null: false + t.boolean "email_only_broken_builds", default: true, null: false + t.string "skip_refs" + t.string "coverage_regex" + t.boolean "shared_runners_enabled", default: false + t.text "generated_yaml_config" end create_table "ci_runner_projects", force: :cascade do |t| - t.integer "runner_id", null: false - t.integer "project_id" + t.integer "runner_id", null: false + t.integer "project_id" t.datetime "created_at" t.datetime "updated_at" - t.integer "gl_project_id" + t.integer "gl_project_id" end add_index "ci_runner_projects", ["gl_project_id"], name: "index_ci_runner_projects_on_gl_project_id", using: :btree add_index "ci_runner_projects", ["runner_id"], name: "index_ci_runner_projects_on_runner_id", using: :btree create_table "ci_runners", force: :cascade do |t| - t.string "token" + t.string "token" t.datetime "created_at" t.datetime "updated_at" - t.string "description" + t.string "description" t.datetime "contacted_at" - t.boolean "active", default: true, null: false - t.boolean "is_shared", default: false - t.string "name" - t.string "version" - t.string "revision" - t.string "platform" - t.string "architecture" - t.boolean "run_untagged", default: true, null: false - t.boolean "locked", default: false, null: false + t.boolean "active", default: true, null: false + t.boolean "is_shared", default: false + t.string "name" + t.string "version" + t.string "revision" + t.string "platform" + t.string "architecture" + t.boolean "run_untagged", default: true, null: false + t.boolean "locked", default: false, null: false end add_index "ci_runners", ["locked"], name: "index_ci_runners_on_locked", using: :btree add_index "ci_runners", ["token"], name: "index_ci_runners_on_token", using: :btree create_table "ci_sessions", force: :cascade do |t| - t.string "session_id", null: false - t.text "data" + t.string "session_id", null: false + t.text "data" t.datetime "created_at" t.datetime "updated_at" end create_table "ci_taggings", force: :cascade do |t| - t.integer "tag_id" - t.integer "taggable_id" - t.string "taggable_type" - t.integer "tagger_id" - t.string "tagger_type" - t.string "context", limit: 128 + t.integer "tag_id" + t.integer "taggable_id" + t.string "taggable_type" + t.integer "tagger_id" + t.string "tagger_type" + t.string "context", limit: 128 t.datetime "created_at" end add_index "ci_taggings", ["taggable_id", "taggable_type", "context"], name: "index_ci_taggings_on_taggable_id_and_taggable_type_and_context", using: :btree create_table "ci_tags", force: :cascade do |t| - t.string "name" + t.string "name" t.integer "taggings_count", default: 0 end create_table "ci_trigger_requests", force: :cascade do |t| - t.integer "trigger_id", null: false - t.text "variables" + t.integer "trigger_id", null: false + t.text "variables" t.datetime "created_at" t.datetime "updated_at" - t.integer "commit_id" + t.integer "commit_id" end create_table "ci_triggers", force: :cascade do |t| - t.string "token" - t.integer "project_id" + t.string "token" + t.integer "project_id" t.datetime "deleted_at" t.datetime "created_at" t.datetime "updated_at" - t.integer "gl_project_id" + t.integer "gl_project_id" end add_index "ci_triggers", ["gl_project_id"], name: "index_ci_triggers_on_gl_project_id", using: :btree create_table "ci_variables", force: :cascade do |t| t.integer "project_id" - t.string "key" - t.text "value" - t.text "encrypted_value" - t.string "encrypted_value_salt" - t.string "encrypted_value_iv" + t.string "key" + t.text "value" + t.text "encrypted_value" + t.string "encrypted_value_salt" + t.string "encrypted_value_iv" t.integer "gl_project_id" end add_index "ci_variables", ["gl_project_id"], name: "index_ci_variables_on_gl_project_id", using: :btree create_table "deploy_keys_projects", force: :cascade do |t| - t.integer "deploy_key_id", null: false - t.integer "project_id", null: false + t.integer "deploy_key_id", null: false + t.integer "project_id", null: false t.datetime "created_at" t.datetime "updated_at" end @@ -369,15 +369,15 @@ add_index "deploy_keys_projects", ["project_id"], name: "index_deploy_keys_projects_on_project_id", using: :btree create_table "deployments", force: :cascade do |t| - t.integer "iid", null: false - t.integer "project_id", null: false - t.integer "environment_id", null: false - t.string "ref", null: false - t.boolean "tag", null: false - t.string "sha", null: false - t.integer "user_id" - t.integer "deployable_id" - t.string "deployable_type" + t.integer "iid", null: false + t.integer "project_id", null: false + t.integer "environment_id", null: false + t.string "ref", null: false + t.boolean "tag", null: false + t.string "sha", null: false + t.integer "user_id" + t.integer "deployable_id" + t.string "deployable_type" t.datetime "created_at" t.datetime "updated_at" end @@ -388,8 +388,8 @@ add_index "deployments", ["project_id"], name: "index_deployments_on_project_id", using: :btree create_table "emails", force: :cascade do |t| - t.integer "user_id", null: false - t.string "email", null: false + t.integer "user_id", null: false + t.string "email", null: false t.datetime "created_at" t.datetime "updated_at" end @@ -398,26 +398,26 @@ add_index "emails", ["user_id"], name: "index_emails_on_user_id", using: :btree create_table "environments", force: :cascade do |t| - t.integer "project_id" - t.string "name", null: false + t.integer "project_id" + t.string "name", null: false t.datetime "created_at" t.datetime "updated_at" - t.string "external_url" - t.string "environment_type" + t.string "external_url" + t.string "environment_type" end add_index "environments", ["project_id", "name"], name: "index_environments_on_project_id_and_name", using: :btree create_table "events", force: :cascade do |t| - t.string "target_type" - t.integer "target_id" - t.string "title" - t.text "data" - t.integer "project_id" + t.string "target_type" + t.integer "target_id" + t.string "title" + t.text "data" + t.integer "project_id" t.datetime "created_at" t.datetime "updated_at" - t.integer "action" - t.integer "author_id" + t.integer "action" + t.integer "author_id" end add_index "events", ["action"], name: "index_events_on_action", using: :btree @@ -428,8 +428,8 @@ add_index "events", ["target_type"], name: "index_events_on_target_type", using: :btree create_table "forked_project_links", force: :cascade do |t| - t.integer "forked_to_project_id", null: false - t.integer "forked_from_project_id", null: false + t.integer "forked_to_project_id", null: false + t.integer "forked_from_project_id", null: false t.datetime "created_at" t.datetime "updated_at" end @@ -437,9 +437,9 @@ add_index "forked_project_links", ["forked_to_project_id"], name: "index_forked_project_links_on_forked_to_project_id", unique: true, using: :btree create_table "identities", force: :cascade do |t| - t.string "extern_uid" - t.string "provider" - t.integer "user_id" + t.string "extern_uid" + t.string "provider" + t.integer "user_id" t.datetime "created_at" t.datetime "updated_at" end @@ -447,37 +447,37 @@ add_index "identities", ["user_id"], name: "index_identities_on_user_id", using: :btree create_table "issue_metrics", force: :cascade do |t| - t.integer "issue_id", null: false + t.integer "issue_id", null: false t.datetime "first_mentioned_in_commit_at" t.datetime "first_associated_with_milestone_at" t.datetime "first_added_to_board_at" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "issue_metrics", ["issue_id"], name: "index_issue_metrics", using: :btree create_table "issues", force: :cascade do |t| - t.string "title" - t.integer "assignee_id" - t.integer "author_id" - t.integer "project_id" + t.string "title" + t.integer "assignee_id" + t.integer "author_id" + t.integer "project_id" t.datetime "created_at" t.datetime "updated_at" - t.integer "position", default: 0 - t.string "branch_name" - t.text "description" - t.integer "milestone_id" - t.string "state" - t.integer "iid" - t.integer "updated_by_id" - t.boolean "confidential", default: false + t.integer "position", default: 0 + t.string "branch_name" + t.text "description" + t.integer "milestone_id" + t.string "state" + t.integer "iid" + t.integer "updated_by_id" + t.boolean "confidential", default: false t.datetime "deleted_at" - t.date "due_date" - t.integer "moved_to_id" - t.integer "lock_version" - t.text "title_html" - t.text "description_html" + t.date "due_date" + t.integer "moved_to_id" + t.integer "lock_version" + t.text "title_html" + t.text "description_html" end add_index "issues", ["assignee_id"], name: "index_issues_on_assignee_id", using: :btree @@ -493,23 +493,23 @@ add_index "issues", ["title"], name: "index_issues_on_title_trigram", using: :gin, opclasses: {"title"=>"gin_trgm_ops"} create_table "keys", force: :cascade do |t| - t.integer "user_id" + t.integer "user_id" t.datetime "created_at" t.datetime "updated_at" - t.text "key" - t.string "title" - t.string "type" - t.string "fingerprint" - t.boolean "public", default: false, null: false + t.text "key" + t.string "title" + t.string "type" + t.string "fingerprint" + t.boolean "public", default: false, null: false end add_index "keys", ["fingerprint"], name: "index_keys_on_fingerprint", unique: true, using: :btree add_index "keys", ["user_id"], name: "index_keys_on_user_id", using: :btree create_table "label_links", force: :cascade do |t| - t.integer "label_id" - t.integer "target_id" - t.string "target_type" + t.integer "label_id" + t.integer "target_id" + t.string "target_type" t.datetime "created_at" t.datetime "updated_at" end @@ -518,15 +518,15 @@ add_index "label_links", ["target_id", "target_type"], name: "index_label_links_on_target_id_and_target_type", using: :btree create_table "labels", force: :cascade do |t| - t.string "title" - t.string "color" - t.integer "project_id" + t.string "title" + t.string "color" + t.integer "project_id" t.datetime "created_at" t.datetime "updated_at" - t.boolean "template", default: false - t.string "description" - t.integer "priority" - t.text "description_html" + t.boolean "template", default: false + t.string "description" + t.integer "priority" + t.text "description_html" end add_index "labels", ["priority"], name: "index_labels_on_priority", using: :btree @@ -534,18 +534,18 @@ add_index "labels", ["title"], name: "index_labels_on_title", using: :btree create_table "lfs_objects", force: :cascade do |t| - t.string "oid", null: false - t.integer "size", limit: 8, null: false + t.string "oid", null: false + t.integer "size", limit: 8, null: false t.datetime "created_at" t.datetime "updated_at" - t.string "file" + t.string "file" end add_index "lfs_objects", ["oid"], name: "index_lfs_objects_on_oid", unique: true, using: :btree create_table "lfs_objects_projects", force: :cascade do |t| - t.integer "lfs_object_id", null: false - t.integer "project_id", null: false + t.integer "lfs_object_id", null: false + t.integer "project_id", null: false t.datetime "created_at" t.datetime "updated_at" end @@ -553,12 +553,12 @@ add_index "lfs_objects_projects", ["project_id"], name: "index_lfs_objects_projects_on_project_id", using: :btree create_table "lists", force: :cascade do |t| - t.integer "board_id", null: false - t.integer "label_id" - t.integer "list_type", default: 1, null: false - t.integer "position" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.integer "board_id", null: false + t.integer "label_id" + t.integer "list_type", default: 1, null: false + t.integer "position" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "lists", ["board_id", "label_id"], name: "index_lists_on_board_id_and_label_id", unique: true, using: :btree @@ -566,20 +566,20 @@ add_index "lists", ["label_id"], name: "index_lists_on_label_id", using: :btree create_table "members", force: :cascade do |t| - t.integer "access_level", null: false - t.integer "source_id", null: false - t.string "source_type", null: false - t.integer "user_id" - t.integer "notification_level", null: false - t.string "type" + t.integer "access_level", null: false + t.integer "source_id", null: false + t.string "source_type", null: false + t.integer "user_id" + t.integer "notification_level", null: false + t.string "type" t.datetime "created_at" t.datetime "updated_at" - t.integer "created_by_id" - t.string "invite_email" - t.string "invite_token" + t.integer "created_by_id" + t.string "invite_email" + t.string "invite_token" t.datetime "invite_accepted_at" t.datetime "requested_at" - t.date "expires_at" + t.date "expires_at" end add_index "members", ["access_level"], name: "index_members_on_access_level", using: :btree @@ -589,62 +589,62 @@ add_index "members", ["user_id"], name: "index_members_on_user_id", using: :btree create_table "merge_request_diffs", force: :cascade do |t| - t.string "state" - t.text "st_commits" - t.text "st_diffs" - t.integer "merge_request_id", null: false + t.string "state" + t.text "st_commits" + t.text "st_diffs" + t.integer "merge_request_id", null: false t.datetime "created_at" t.datetime "updated_at" - t.string "base_commit_sha" - t.string "real_size" - t.string "head_commit_sha" - t.string "start_commit_sha" + t.string "base_commit_sha" + t.string "real_size" + t.string "head_commit_sha" + t.string "start_commit_sha" end add_index "merge_request_diffs", ["merge_request_id"], name: "index_merge_request_diffs_on_merge_request_id", using: :btree create_table "merge_request_metrics", force: :cascade do |t| - t.integer "merge_request_id", null: false + t.integer "merge_request_id", null: false t.datetime "latest_build_started_at" t.datetime "latest_build_finished_at" t.datetime "first_deployed_to_production_at" t.datetime "merged_at" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "merge_request_metrics", ["first_deployed_to_production_at"], name: "index_merge_request_metrics_on_first_deployed_to_production_at", using: :btree add_index "merge_request_metrics", ["merge_request_id"], name: "index_merge_request_metrics", using: :btree create_table "merge_requests", force: :cascade do |t| - t.string "target_branch", null: false - t.string "source_branch", null: false - t.integer "source_project_id", null: false - t.integer "author_id" - t.integer "assignee_id" - t.string "title" + t.string "target_branch", null: false + t.string "source_branch", null: false + t.integer "source_project_id", null: false + t.integer "author_id" + t.integer "assignee_id" + t.string "title" t.datetime "created_at" t.datetime "updated_at" - t.integer "milestone_id" - t.string "state" - t.string "merge_status" - t.integer "target_project_id", null: false - t.integer "iid" - t.text "description" - t.integer "position", default: 0 + t.integer "milestone_id" + t.string "state" + t.string "merge_status" + t.integer "target_project_id", null: false + t.integer "iid" + t.text "description" + t.integer "position", default: 0 t.datetime "locked_at" - t.integer "updated_by_id" - t.text "merge_error" - t.boolean "merge_when_build_succeeds", default: false, null: false - t.integer "merge_user_id" - t.string "merge_commit_sha" + t.integer "updated_by_id" + t.text "merge_error" + t.boolean "merge_when_build_succeeds", default: false, null: false + t.integer "merge_user_id" + t.string "merge_commit_sha" t.datetime "deleted_at" - t.string "in_progress_merge_commit_sha" - t.integer "lock_version" - t.text "title_html" - t.text "description_html" - t.boolean "remove_source_branch", default: true, null: false - t.text "commit_message" + t.string "in_progress_merge_commit_sha" + t.integer "lock_version" + t.text "title_html" + t.text "description_html" + t.boolean "remove_source_branch", default: true, null: false + t.text "commit_message" end add_index "merge_requests", ["assignee_id"], name: "index_merge_requests_on_assignee_id", using: :btree @@ -661,26 +661,26 @@ add_index "merge_requests", ["title"], name: "index_merge_requests_on_title_trigram", using: :gin, opclasses: {"title"=>"gin_trgm_ops"} create_table "merge_requests_closing_issues", force: :cascade do |t| - t.integer "merge_request_id", null: false - t.integer "issue_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.integer "merge_request_id", null: false + t.integer "issue_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "merge_requests_closing_issues", ["issue_id"], name: "index_merge_requests_closing_issues_on_issue_id", using: :btree add_index "merge_requests_closing_issues", ["merge_request_id"], name: "index_merge_requests_closing_issues_on_merge_request_id", using: :btree create_table "milestones", force: :cascade do |t| - t.string "title", null: false - t.integer "project_id", null: false - t.text "description" - t.date "due_date" + t.string "title", null: false + t.integer "project_id", null: false + t.text "description" + t.date "due_date" t.datetime "created_at" t.datetime "updated_at" - t.string "state" - t.integer "iid" - t.text "title_html" - t.text "description_html" + t.string "state" + t.integer "iid" + t.text "title_html" + t.text "description_html" end add_index "milestones", ["description"], name: "index_milestones_on_description_trigram", using: :gin, opclasses: {"description"=>"gin_trgm_ops"} @@ -691,20 +691,20 @@ add_index "milestones", ["title"], name: "index_milestones_on_title_trigram", using: :gin, opclasses: {"title"=>"gin_trgm_ops"} create_table "namespaces", force: :cascade do |t| - t.string "name", null: false - t.string "path", null: false - t.integer "owner_id" + t.string "name", null: false + t.string "path", null: false + t.integer "owner_id" t.datetime "created_at" t.datetime "updated_at" - t.string "type" - t.string "description", default: "", null: false - t.string "avatar" - t.boolean "share_with_group_lock", default: false - t.integer "visibility_level", default: 20, null: false - t.boolean "request_access_enabled", default: true, null: false + t.string "type" + t.string "description", default: "", null: false + t.string "avatar" + t.boolean "share_with_group_lock", default: false + t.integer "visibility_level", default: 20, null: false + t.boolean "request_access_enabled", default: true, null: false t.datetime "deleted_at" - t.boolean "lfs_enabled" - t.text "description_html" + t.boolean "lfs_enabled" + t.text "description_html" end add_index "namespaces", ["created_at"], name: "index_namespaces_on_created_at", using: :btree @@ -717,27 +717,27 @@ add_index "namespaces", ["type"], name: "index_namespaces_on_type", using: :btree create_table "notes", force: :cascade do |t| - t.text "note" - t.string "noteable_type" - t.integer "author_id" + t.text "note" + t.string "noteable_type" + t.integer "author_id" t.datetime "created_at" t.datetime "updated_at" - t.integer "project_id" - t.string "attachment" - t.string "line_code" - t.string "commit_id" - t.integer "noteable_id" - t.boolean "system", default: false, null: false - t.text "st_diff" - t.integer "updated_by_id" - t.string "type" - t.text "position" - t.text "original_position" + t.integer "project_id" + t.string "attachment" + t.string "line_code" + t.string "commit_id" + t.integer "noteable_id" + t.boolean "system", default: false, null: false + t.text "st_diff" + t.integer "updated_by_id" + t.string "type" + t.text "position" + t.text "original_position" t.datetime "resolved_at" - t.integer "resolved_by_id" - t.string "discussion_id" - t.string "original_discussion_id" - t.text "note_html" + t.integer "resolved_by_id" + t.string "discussion_id" + t.string "original_discussion_id" + t.text "note_html" end add_index "notes", ["author_id"], name: "index_notes_on_author_id", using: :btree @@ -753,13 +753,13 @@ add_index "notes", ["updated_at"], name: "index_notes_on_updated_at", using: :btree create_table "notification_settings", force: :cascade do |t| - t.integer "user_id", null: false - t.integer "source_id" - t.string "source_type" - t.integer "level", default: 0, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.text "events" + t.integer "user_id", null: false + t.integer "source_id" + t.string "source_type" + t.integer "level", default: 0, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.text "events" end add_index "notification_settings", ["source_id", "source_type"], name: "index_notification_settings_on_source_id_and_source_type", using: :btree @@ -767,27 +767,27 @@ add_index "notification_settings", ["user_id"], name: "index_notification_settings_on_user_id", using: :btree create_table "oauth_access_grants", force: :cascade do |t| - t.integer "resource_owner_id", null: false - t.integer "application_id", null: false - t.string "token", null: false - t.integer "expires_in", null: false - t.text "redirect_uri", null: false - t.datetime "created_at", null: false + t.integer "resource_owner_id", null: false + t.integer "application_id", null: false + t.string "token", null: false + t.integer "expires_in", null: false + t.text "redirect_uri", null: false + t.datetime "created_at", null: false t.datetime "revoked_at" - t.string "scopes" + t.string "scopes" end add_index "oauth_access_grants", ["token"], name: "index_oauth_access_grants_on_token", unique: true, using: :btree create_table "oauth_access_tokens", force: :cascade do |t| - t.integer "resource_owner_id" - t.integer "application_id" - t.string "token", null: false - t.string "refresh_token" - t.integer "expires_in" + t.integer "resource_owner_id" + t.integer "application_id" + t.string "token", null: false + t.string "refresh_token" + t.integer "expires_in" t.datetime "revoked_at" - t.datetime "created_at", null: false - t.string "scopes" + t.datetime "created_at", null: false + t.string "scopes" end add_index "oauth_access_tokens", ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true, using: :btree @@ -795,40 +795,40 @@ add_index "oauth_access_tokens", ["token"], name: "index_oauth_access_tokens_on_token", unique: true, using: :btree create_table "oauth_applications", force: :cascade do |t| - t.string "name", null: false - t.string "uid", null: false - t.string "secret", null: false - t.text "redirect_uri", null: false - t.string "scopes", default: "", null: false + t.string "name", null: false + t.string "uid", null: false + t.string "secret", null: false + t.text "redirect_uri", null: false + t.string "scopes", default: "", null: false t.datetime "created_at" t.datetime "updated_at" - t.integer "owner_id" - t.string "owner_type" + t.integer "owner_id" + t.string "owner_type" end add_index "oauth_applications", ["owner_id", "owner_type"], name: "index_oauth_applications_on_owner_id_and_owner_type", using: :btree add_index "oauth_applications", ["uid"], name: "index_oauth_applications_on_uid", unique: true, using: :btree create_table "personal_access_tokens", force: :cascade do |t| - t.integer "user_id", null: false - t.string "token", null: false - t.string "name", null: false - t.boolean "revoked", default: false + t.integer "user_id", null: false + t.string "token", null: false + t.string "name", null: false + t.boolean "revoked", default: false t.datetime "expires_at" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "personal_access_tokens", ["token"], name: "index_personal_access_tokens_on_token", unique: true, using: :btree add_index "personal_access_tokens", ["user_id"], name: "index_personal_access_tokens_on_user_id", using: :btree create_table "project_features", force: :cascade do |t| - t.integer "project_id" - t.integer "merge_requests_access_level" - t.integer "issues_access_level" - t.integer "wiki_access_level" - t.integer "snippets_access_level" - t.integer "builds_access_level" + t.integer "project_id" + t.integer "merge_requests_access_level" + t.integer "issues_access_level" + t.integer "wiki_access_level" + t.integer "snippets_access_level" + t.integer "builds_access_level" t.datetime "created_at" t.datetime "updated_at" end @@ -836,60 +836,60 @@ add_index "project_features", ["project_id"], name: "index_project_features_on_project_id", using: :btree create_table "project_group_links", force: :cascade do |t| - t.integer "project_id", null: false - t.integer "group_id", null: false + t.integer "project_id", null: false + t.integer "group_id", null: false t.datetime "created_at" t.datetime "updated_at" - t.integer "group_access", default: 30, null: false - t.date "expires_at" + t.integer "group_access", default: 30, null: false + t.date "expires_at" end create_table "project_import_data", force: :cascade do |t| t.integer "project_id" - t.text "data" - t.text "encrypted_credentials" - t.string "encrypted_credentials_iv" - t.string "encrypted_credentials_salt" + t.text "data" + t.text "encrypted_credentials" + t.string "encrypted_credentials_iv" + t.string "encrypted_credentials_salt" end create_table "projects", force: :cascade do |t| - t.string "name" - t.string "path" - t.text "description" + t.string "name" + t.string "path" + t.text "description" t.datetime "created_at" t.datetime "updated_at" - t.integer "creator_id" - t.integer "namespace_id" + t.integer "creator_id" + t.integer "namespace_id" t.datetime "last_activity_at" - t.string "import_url" - t.integer "visibility_level", default: 0, null: false - t.boolean "archived", default: false, null: false - t.string "avatar" - t.string "import_status" - t.float "repository_size", default: 0.0 - t.integer "star_count", default: 0, null: false - t.string "import_type" - t.string "import_source" - t.integer "commit_count", default: 0 - t.text "import_error" - t.integer "ci_id" - t.boolean "shared_runners_enabled", default: true, null: false - t.string "runners_token" - t.string "build_coverage_regex" - t.boolean "build_allow_git_fetch", default: true, null: false - t.integer "build_timeout", default: 3600, null: false - t.boolean "pending_delete", default: false - t.boolean "public_builds", default: true, null: false - t.boolean "last_repository_check_failed" + t.string "import_url" + t.integer "visibility_level", default: 0, null: false + t.boolean "archived", default: false, null: false + t.string "avatar" + t.string "import_status" + t.float "repository_size", default: 0.0 + t.integer "star_count", default: 0, null: false + t.string "import_type" + t.string "import_source" + t.integer "commit_count", default: 0 + t.text "import_error" + t.integer "ci_id" + t.boolean "shared_runners_enabled", default: true, null: false + t.string "runners_token" + t.string "build_coverage_regex" + t.boolean "build_allow_git_fetch", default: true, null: false + t.integer "build_timeout", default: 3600, null: false + t.boolean "pending_delete", default: false + t.boolean "public_builds", default: true, null: false + t.boolean "last_repository_check_failed" t.datetime "last_repository_check_at" - t.boolean "container_registry_enabled" - t.boolean "only_allow_merge_if_build_succeeds", default: false, null: false - t.boolean "has_external_issue_tracker" - t.string "repository_storage", default: "default", null: false - t.boolean "request_access_enabled", default: true, null: false - t.boolean "has_external_wiki" - t.boolean "lfs_enabled" - t.text "description_html" + t.boolean "container_registry_enabled" + t.boolean "only_allow_merge_if_build_succeeds", default: false, null: false + t.boolean "has_external_issue_tracker" + t.string "repository_storage", default: "default", null: false + t.boolean "request_access_enabled", default: true, null: false + t.boolean "has_external_wiki" + t.boolean "lfs_enabled" + t.text "description_html" end add_index "projects", ["ci_id"], name: "index_projects_on_ci_id", using: :btree @@ -908,26 +908,26 @@ add_index "projects", ["visibility_level"], name: "index_projects_on_visibility_level", using: :btree create_table "protected_branch_merge_access_levels", force: :cascade do |t| - t.integer "protected_branch_id", null: false - t.integer "access_level", default: 40, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.integer "protected_branch_id", null: false + t.integer "access_level", default: 40, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "protected_branch_merge_access_levels", ["protected_branch_id"], name: "index_protected_branch_merge_access", using: :btree create_table "protected_branch_push_access_levels", force: :cascade do |t| - t.integer "protected_branch_id", null: false - t.integer "access_level", default: 40, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.integer "protected_branch_id", null: false + t.integer "access_level", default: 40, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "protected_branch_push_access_levels", ["protected_branch_id"], name: "index_protected_branch_push_access", using: :btree create_table "protected_branches", force: :cascade do |t| - t.integer "project_id", null: false - t.string "name", null: false + t.integer "project_id", null: false + t.string "name", null: false t.datetime "created_at" t.datetime "updated_at" end @@ -935,12 +935,12 @@ add_index "protected_branches", ["project_id"], name: "index_protected_branches_on_project_id", using: :btree create_table "releases", force: :cascade do |t| - t.string "tag" - t.text "description" - t.integer "project_id" + t.string "tag" + t.text "description" + t.integer "project_id" t.datetime "created_at" t.datetime "updated_at" - t.text "description_html" + t.text "description_html" end add_index "releases", ["project_id", "tag"], name: "index_releases_on_project_id_and_tag", using: :btree @@ -949,54 +949,54 @@ create_table "sent_notifications", force: :cascade do |t| t.integer "project_id" t.integer "noteable_id" - t.string "noteable_type" + t.string "noteable_type" t.integer "recipient_id" - t.string "commit_id" - t.string "reply_key", null: false - t.string "line_code" - t.string "note_type" - t.text "position" + t.string "commit_id" + t.string "reply_key", null: false + t.string "line_code" + t.string "note_type" + t.text "position" end add_index "sent_notifications", ["reply_key"], name: "index_sent_notifications_on_reply_key", unique: true, using: :btree create_table "services", force: :cascade do |t| - t.string "type" - t.string "title" - t.integer "project_id" + t.string "type" + t.string "title" + t.integer "project_id" t.datetime "created_at" t.datetime "updated_at" - t.boolean "active", default: false, null: false - t.text "properties" - t.boolean "template", default: false - t.boolean "push_events", default: true - t.boolean "issues_events", default: true - t.boolean "merge_requests_events", default: true - t.boolean "tag_push_events", default: true - t.boolean "note_events", default: true, null: false - t.boolean "build_events", default: false, null: false - t.string "category", default: "common", null: false - t.boolean "default", default: false - t.boolean "wiki_page_events", default: true - t.boolean "pipeline_events", default: false, null: false - t.boolean "confidential_issues_events", default: true, null: false + t.boolean "active", default: false, null: false + t.text "properties" + t.boolean "template", default: false + t.boolean "push_events", default: true + t.boolean "issues_events", default: true + t.boolean "merge_requests_events", default: true + t.boolean "tag_push_events", default: true + t.boolean "note_events", default: true, null: false + t.boolean "build_events", default: false, null: false + t.string "category", default: "common", null: false + t.boolean "default", default: false + t.boolean "wiki_page_events", default: true + t.boolean "pipeline_events", default: false, null: false + t.boolean "confidential_issues_events", default: true, null: false end add_index "services", ["project_id"], name: "index_services_on_project_id", using: :btree add_index "services", ["template"], name: "index_services_on_template", using: :btree create_table "snippets", force: :cascade do |t| - t.string "title" - t.text "content" - t.integer "author_id", null: false - t.integer "project_id" + t.string "title" + t.text "content" + t.integer "author_id", null: false + t.integer "project_id" t.datetime "created_at" t.datetime "updated_at" - t.string "file_name" - t.string "type" - t.integer "visibility_level", default: 0, null: false - t.text "title_html" - t.text "content_html" + t.string "file_name" + t.string "type" + t.integer "visibility_level", default: 0, null: false + t.text "title_html" + t.text "content_html" end add_index "snippets", ["author_id"], name: "index_snippets_on_author_id", using: :btree @@ -1007,23 +1007,23 @@ add_index "snippets", ["visibility_level"], name: "index_snippets_on_visibility_level", using: :btree create_table "spam_logs", force: :cascade do |t| - t.integer "user_id" - t.string "source_ip" - t.string "user_agent" - t.boolean "via_api" - t.string "noteable_type" - t.string "title" - t.text "description" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.boolean "submitted_as_ham", default: false, null: false + t.integer "user_id" + t.string "source_ip" + t.string "user_agent" + t.boolean "via_api" + t.string "noteable_type" + t.string "title" + t.text "description" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "submitted_as_ham", default: false, null: false end create_table "subscriptions", force: :cascade do |t| - t.integer "user_id" - t.integer "subscribable_id" - t.string "subscribable_type" - t.boolean "subscribed" + t.integer "user_id" + t.integer "subscribable_id" + t.string "subscribable_type" + t.boolean "subscribed" t.datetime "created_at" t.datetime "updated_at" end @@ -1031,12 +1031,12 @@ add_index "subscriptions", ["subscribable_id", "subscribable_type", "user_id"], name: "subscriptions_user_id_and_ref_fields", unique: true, using: :btree create_table "taggings", force: :cascade do |t| - t.integer "tag_id" - t.integer "taggable_id" - t.string "taggable_type" - t.integer "tagger_id" - t.string "tagger_type" - t.string "context" + t.integer "tag_id" + t.integer "taggable_id" + t.string "taggable_type" + t.integer "tagger_id" + t.string "tagger_type" + t.string "context" t.datetime "created_at" end @@ -1044,24 +1044,24 @@ add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context", using: :btree create_table "tags", force: :cascade do |t| - t.string "name" + t.string "name" t.integer "taggings_count", default: 0 end add_index "tags", ["name"], name: "index_tags_on_name", unique: true, using: :btree create_table "todos", force: :cascade do |t| - t.integer "user_id", null: false - t.integer "project_id", null: false - t.integer "target_id" - t.string "target_type", null: false - t.integer "author_id" - t.integer "action", null: false - t.string "state", null: false + t.integer "user_id", null: false + t.integer "project_id", null: false + t.integer "target_id" + t.string "target_type", null: false + t.integer "author_id" + t.integer "action", null: false + t.string "state", null: false t.datetime "created_at" t.datetime "updated_at" - t.integer "note_id" - t.string "commit_id" + t.integer "note_id" + t.string "commit_id" end add_index "todos", ["author_id"], name: "index_todos_on_author_id", using: :btree @@ -1078,88 +1078,88 @@ add_index "trending_projects", ["project_id"], name: "index_trending_projects_on_project_id", using: :btree create_table "u2f_registrations", force: :cascade do |t| - t.text "certificate" - t.string "key_handle" - t.string "public_key" - t.integer "counter" - t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.string "name" + t.text "certificate" + t.string "key_handle" + t.string "public_key" + t.integer "counter" + t.integer "user_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "name" end add_index "u2f_registrations", ["key_handle"], name: "index_u2f_registrations_on_key_handle", using: :btree add_index "u2f_registrations", ["user_id"], name: "index_u2f_registrations_on_user_id", using: :btree create_table "user_agent_details", force: :cascade do |t| - t.string "user_agent", null: false - t.string "ip_address", null: false - t.integer "subject_id", null: false - t.string "subject_type", null: false - t.boolean "submitted", default: false, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.string "user_agent", null: false + t.string "ip_address", null: false + t.integer "subject_id", null: false + t.string "subject_type", null: false + t.boolean "submitted", default: false, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "users", force: :cascade do |t| - t.string "email", default: "", null: false - t.string "encrypted_password", default: "", null: false - t.string "reset_password_token" + t.string "email", default: "", null: false + t.string "encrypted_password", default: "", null: false + t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created_at" - t.integer "sign_in_count", default: 0 + t.integer "sign_in_count", default: 0 t.datetime "current_sign_in_at" t.datetime "last_sign_in_at" - t.string "current_sign_in_ip" - t.string "last_sign_in_ip" + t.string "current_sign_in_ip" + t.string "last_sign_in_ip" t.datetime "created_at" t.datetime "updated_at" - t.string "name" - t.boolean "admin", default: false, null: false - t.integer "projects_limit", default: 10 - t.string "skype", default: "", null: false - t.string "linkedin", default: "", null: false - t.string "twitter", default: "", null: false - t.string "authentication_token" - t.integer "theme_id", default: 1, null: false - t.string "bio" - t.integer "failed_attempts", default: 0 + t.string "name" + t.boolean "admin", default: false, null: false + t.integer "projects_limit", default: 10 + t.string "skype", default: "", null: false + t.string "linkedin", default: "", null: false + t.string "twitter", default: "", null: false + t.string "authentication_token" + t.integer "theme_id", default: 1, null: false + t.string "bio" + t.integer "failed_attempts", default: 0 t.datetime "locked_at" - t.string "username" - t.boolean "can_create_group", default: true, null: false - t.boolean "can_create_team", default: true, null: false - t.string "state" - t.integer "color_scheme_id", default: 1, null: false + t.string "username" + t.boolean "can_create_group", default: true, null: false + t.boolean "can_create_team", default: true, null: false + t.string "state" + t.integer "color_scheme_id", default: 1, null: false t.datetime "password_expires_at" - t.integer "created_by_id" + t.integer "created_by_id" t.datetime "last_credential_check_at" - t.string "avatar" - t.string "confirmation_token" + t.string "avatar" + t.string "confirmation_token" t.datetime "confirmed_at" t.datetime "confirmation_sent_at" - t.string "unconfirmed_email" - t.boolean "hide_no_ssh_key", default: false - t.string "website_url", default: "", null: false - t.string "notification_email" - t.boolean "hide_no_password", default: false - t.boolean "password_automatically_set", default: false - t.string "location" - t.string "encrypted_otp_secret" - t.string "encrypted_otp_secret_iv" - t.string "encrypted_otp_secret_salt" - t.boolean "otp_required_for_login", default: false, null: false - t.text "otp_backup_codes" - t.string "public_email", default: "", null: false - t.integer "dashboard", default: 0 - t.integer "project_view", default: 0 - t.integer "consumed_timestep" - t.integer "layout", default: 0 - t.boolean "hide_project_limit", default: false - t.string "unlock_token" + t.string "unconfirmed_email" + t.boolean "hide_no_ssh_key", default: false + t.string "website_url", default: "", null: false + t.string "notification_email" + t.boolean "hide_no_password", default: false + t.boolean "password_automatically_set", default: false + t.string "location" + t.string "encrypted_otp_secret" + t.string "encrypted_otp_secret_iv" + t.string "encrypted_otp_secret_salt" + t.boolean "otp_required_for_login", default: false, null: false + t.text "otp_backup_codes" + t.string "public_email", default: "", null: false + t.integer "dashboard", default: 0 + t.integer "project_view", default: 0 + t.integer "consumed_timestep" + t.integer "layout", default: 0 + t.boolean "hide_project_limit", default: false + t.string "unlock_token" t.datetime "otp_grace_period_started_at" - t.boolean "ldap_email", default: false, null: false - t.boolean "external", default: false - t.string "organization" + t.boolean "ldap_email", default: false, null: false + t.boolean "external", default: false + t.string "organization" end add_index "users", ["admin"], name: "index_users_on_admin", using: :btree @@ -1177,8 +1177,8 @@ add_index "users", ["username"], name: "index_users_on_username_trigram", using: :gin, opclasses: {"username"=>"gin_trgm_ops"} create_table "users_star_projects", force: :cascade do |t| - t.integer "project_id", null: false - t.integer "user_id", null: false + t.integer "project_id", null: false + t.integer "user_id", null: false t.datetime "created_at" t.datetime "updated_at" end @@ -1188,23 +1188,23 @@ add_index "users_star_projects", ["user_id"], name: "index_users_star_projects_on_user_id", using: :btree create_table "web_hooks", force: :cascade do |t| - t.string "url", limit: 2000 - t.integer "project_id" + t.string "url", limit: 2000 + t.integer "project_id" t.datetime "created_at" t.datetime "updated_at" - t.string "type", default: "ProjectHook" - t.integer "service_id" - t.boolean "push_events", default: true, null: false - t.boolean "issues_events", default: false, null: false - t.boolean "merge_requests_events", default: false, null: false - t.boolean "tag_push_events", default: false - t.boolean "note_events", default: false, null: false - t.boolean "enable_ssl_verification", default: true - t.boolean "build_events", default: false, null: false - t.boolean "wiki_page_events", default: false, null: false - t.string "token" - t.boolean "pipeline_events", default: false, null: false - t.boolean "confidential_issues_events", default: false, null: false + t.string "type", default: "ProjectHook" + t.integer "service_id" + t.boolean "push_events", default: true, null: false + t.boolean "issues_events", default: false, null: false + t.boolean "merge_requests_events", default: false, null: false + t.boolean "tag_push_events", default: false + t.boolean "note_events", default: false, null: false + t.boolean "enable_ssl_verification", default: true + t.boolean "build_events", default: false, null: false + t.boolean "wiki_page_events", default: false, null: false + t.string "token" + t.boolean "pipeline_events", default: false, null: false + t.boolean "confidential_issues_events", default: false, null: false end add_index "web_hooks", ["project_id"], name: "index_web_hooks_on_project_id", using: :btree -- GitLab