Commit a4592434 authored by Alfredo Sumaran's avatar Alfredo Sumaran

Merge remote-tracking branch 'origin/master' into issue_14904

parents b41ddf9c 832cdd3d
...@@ -728,7 +728,7 @@ Metrics/ParameterLists: ...@@ -728,7 +728,7 @@ Metrics/ParameterLists:
# A complexity metric geared towards measuring complexity for a human reader. # A complexity metric geared towards measuring complexity for a human reader.
Metrics/PerceivedComplexity: Metrics/PerceivedComplexity:
Enabled: true Enabled: true
Max: 17 Max: 18
#################### Lint ################################ #################### Lint ################################
......
Please view this file on the master branch, on stable branches it's out of date. Please view this file on the master branch, on stable branches it's out of date.
v 8.8.0 (unreleased)
v 8.7.0 (unreleased) v 8.7.0 (unreleased)
- The number of InfluxDB points stored per UDP packet can now be configured
- Transactions for /internal/allowed now have an "action" tag set - Transactions for /internal/allowed now have an "action" tag set
- Method instrumentation now uses Module#prepend instead of aliasing methods - Method instrumentation now uses Module#prepend instead of aliasing methods
- Repository.clean_old_archives is now instrumented - Repository.clean_old_archives is now instrumented
...@@ -11,6 +14,7 @@ v 8.7.0 (unreleased) ...@@ -11,6 +14,7 @@ v 8.7.0 (unreleased)
- Developers can now add custom tags to transactions - Developers can now add custom tags to transactions
- Loading of an issue's referenced merge requests and related branches is now done asynchronously - Loading of an issue's referenced merge requests and related branches is now done asynchronously
- Enable gzip for assets, makes the page size significantly smaller. !3544 / !3632 (Connor Shea) - Enable gzip for assets, makes the page size significantly smaller. !3544 / !3632 (Connor Shea)
- Add support to cherry-pick any commit into any branch in the web interface (Minqi Pan)
- Project switcher uses new dropdown styling - Project switcher uses new dropdown styling
- Load award emoji images separately unless opening the full picker. Saves several hundred KBs of data for most pages. (Connor Shea) - Load award emoji images separately unless opening the full picker. Saves several hundred KBs of data for most pages. (Connor Shea)
- Do not include award_emojis in issue and merge_request comment_count !3610 (Lucas Charles) - Do not include award_emojis in issue and merge_request comment_count !3610 (Lucas Charles)
...@@ -21,12 +25,14 @@ v 8.7.0 (unreleased) ...@@ -21,12 +25,14 @@ v 8.7.0 (unreleased)
- Allow projects to be transfered to a lower visibility level group - Allow projects to be transfered to a lower visibility level group
- Fix `signed_in_ip` being set to 127.0.0.1 when using a reverse proxy !3524 - Fix `signed_in_ip` being set to 127.0.0.1 when using a reverse proxy !3524
- Improved Markdown rendering performance !3389 - Improved Markdown rendering performance !3389
- Make shared runners text in box configurable
- Don't attempt to look up an avatar in repo if repo directory does not exist (Stan Hu) - Don't attempt to look up an avatar in repo if repo directory does not exist (Stan Hu)
- API: Ability to subscribe and unsubscribe from issues and merge requests (Robert Schilling) - API: Ability to subscribe and unsubscribe from issues and merge requests (Robert Schilling)
- Expose project badges in project settings - Expose project badges in project settings
- Make /profile/keys/new redirect to /profile/keys for back-compat. !3717 - Make /profile/keys/new redirect to /profile/keys for back-compat. !3717
- Preserve time notes/comments have been updated at when moving issue - Preserve time notes/comments have been updated at when moving issue
- Make HTTP(s) label consistent on clone bar (Stan Hu) - Make HTTP(s) label consistent on clone bar (Stan Hu)
- Add support for `after_script`, requires Runner 1.2 (Kamil Trzciński)
- Expose label description in API (Mariusz Jachimowicz) - Expose label description in API (Mariusz Jachimowicz)
- API: Ability to update a group (Robert Schilling) - API: Ability to update a group (Robert Schilling)
- API: Ability to move issues (Robert Schilling) - API: Ability to move issues (Robert Schilling)
...@@ -34,6 +40,8 @@ v 8.7.0 (unreleased) ...@@ -34,6 +40,8 @@ v 8.7.0 (unreleased)
- Fix a bug whith trailing slash in teamcity_url (Charles May) - Fix a bug whith trailing slash in teamcity_url (Charles May)
- Allow back dating on issues when created or updated through the API - Allow back dating on issues when created or updated through the API
- Allow back dating on issue notes when created through the API - Allow back dating on issue notes when created through the API
- Propose license template when creating a new LICENSE file
- API: Expose /licenses and /licenses/:key
- Fix avatar stretching by providing a cropping feature - Fix avatar stretching by providing a cropping feature
- API: Expose `subscribed` for issues and merge requests (Robert Schilling) - API: Expose `subscribed` for issues and merge requests (Robert Schilling)
- Allow SAML to handle external users based on user's information !3530 - Allow SAML to handle external users based on user's information !3530
...@@ -51,6 +59,7 @@ v 8.7.0 (unreleased) ...@@ -51,6 +59,7 @@ v 8.7.0 (unreleased)
- Use rugged to change HEAD in Project#change_head (P.S.V.R) - Use rugged to change HEAD in Project#change_head (P.S.V.R)
- API: Ability to filter milestones by state `active` and `closed` (Robert Schilling) - API: Ability to filter milestones by state `active` and `closed` (Robert Schilling)
- API: Fix milestone filtering by `iid` (Robert Schilling) - API: Fix milestone filtering by `iid` (Robert Schilling)
- Make before_script and after_script overridable on per-job (Kamil Trzciński)
- API: Delete notes of issues, snippets, and merge requests (Robert Schilling) - API: Delete notes of issues, snippets, and merge requests (Robert Schilling)
- Implement 'Groups View' as an option for dashboard preferences !3379 (Elias W.) - Implement 'Groups View' as an option for dashboard preferences !3379 (Elias W.)
- Better errors handling when creating milestones inside groups - Better errors handling when creating milestones inside groups
...@@ -71,21 +80,38 @@ v 8.7.0 (unreleased) ...@@ -71,21 +80,38 @@ v 8.7.0 (unreleased)
- API: Do not leak group existence via return code (Robert Schilling) - API: Do not leak group existence via return code (Robert Schilling)
- ClosingIssueExtractor regex now also works with colons. e.g. "Fixes: #1234" !3591 - ClosingIssueExtractor regex now also works with colons. e.g. "Fixes: #1234" !3591
- Update number of Todos in the sidebar when it's marked as "Done". !3600 - Update number of Todos in the sidebar when it's marked as "Done". !3600
- Sanitize branch names created for confidential issues
- API: Expose 'updated_at' for issue, snippet, and merge request notes (Robert Schilling) - API: Expose 'updated_at' for issue, snippet, and merge request notes (Robert Schilling)
- API: User can leave a project through the API when not master or owner. !3613 - API: User can leave a project through the API when not master or owner. !3613
- Fix repository cache invalidation issue when project is recreated with an empty repo (Stan Hu) - Fix repository cache invalidation issue when project is recreated with an empty repo (Stan Hu)
- Fix: Allow empty recipients list for builds emails service when pushed is added (Frank Groeneveld) - Fix: Allow empty recipients list for builds emails service when pushed is added (Frank Groeneveld)
- Improved markdown forms - Improved markdown forms
- Delete tags using Rugged for performance reasons (Robert Schilling) - Delete tags using Rugged for performance reasons (Robert Schilling)
- Add Slack notifications when Wiki is edited (Sebastian Klier)
- Diffs load at the correct point when linking from from number - Diffs load at the correct point when linking from from number
- Selected diff rows highlight - Selected diff rows highlight
- Fix emoji categories in the emoji picker - Fix emoji categories in the emoji picker
- API: Properly display annotated tags for GET /projects/:id/repository/tags (Robert Schilling)
- Add encrypted credentials for imported projects and migrate old ones - Add encrypted credentials for imported projects and migrate old ones
- Properly format all merge request references with ! rather than # !3740 (Ben Bodenmiller)
- Author and participants are displayed first on users autocompletion - Author and participants are displayed first on users autocompletion
- Show number sign on external issue reference text (Florent Baldino) - Show number sign on external issue reference text (Florent Baldino)
- Updated print style for issues - Updated print style for issues
- Use GitHub Issue/PR number as iid to keep references - Use GitHub Issue/PR number as iid to keep references
- Add 'l' shortcut to open Label dropdown on issuables and 'i' to create new issue on a project - Add 'l' shortcut to open Label dropdown on issuables and 'i' to create new issue on a project
- Import GitHub labels
- Import GitHub milestones
- Fix emoji catgories in the emoji picker
- Execute system web hooks on push to the project
- Allow enable/disable push events for system hooks
- Fix GitHub project's link in the import page when provider has a custom URL
- Add RAW build trace output and button on build page
- Add incremental build trace update into CI API
v 8.6.7 (unreleased)
- Fix persistent XSS vulnerability in `commit_person_link` helper
- Fix persistent XSS vulnerability in Label and Milestone dropdowns
- Fix vulnerability that made it possible to enumerate private projects belonging to group
v 8.6.6 v 8.6.6
- Expire the exists cache before deletion to ensure project dir actually exists (Stan Hu). !3413 - Expire the exists cache before deletion to ensure project dir actually exists (Stan Hu). !3413
......
...@@ -190,6 +190,9 @@ gem 'babosa', '~> 1.0.2' ...@@ -190,6 +190,9 @@ gem 'babosa', '~> 1.0.2'
# Sanitizes SVG input # Sanitizes SVG input
gem "loofah", "~> 2.0.3" gem "loofah", "~> 2.0.3"
# Working with license
gem 'licensee', '~> 8.0.0'
# Protect against bruteforcing # Protect against bruteforcing
gem "rack-attack", '~> 4.3.1' gem "rack-attack", '~> 4.3.1'
...@@ -315,7 +318,7 @@ end ...@@ -315,7 +318,7 @@ end
gem "newrelic_rpm", '~> 3.14' gem "newrelic_rpm", '~> 3.14'
gem 'octokit', '~> 3.8.0' gem 'octokit', '~> 4.3.0'
gem "mail_room", "~> 0.6.1" gem "mail_room", "~> 0.6.1"
......
...@@ -452,6 +452,8 @@ GEM ...@@ -452,6 +452,8 @@ GEM
addressable (~> 2.3) addressable (~> 2.3)
letter_opener (1.1.2) letter_opener (1.1.2)
launchy (~> 2.2) launchy (~> 2.2)
licensee (8.0.0)
rugged (>= 0.24b)
listen (3.0.5) listen (3.0.5)
rb-fsevent (>= 0.9.3) rb-fsevent (>= 0.9.3)
rb-inotify (>= 0.9) rb-inotify (>= 0.9)
...@@ -485,8 +487,8 @@ GEM ...@@ -485,8 +487,8 @@ GEM
multi_json (~> 1.3) multi_json (~> 1.3)
multi_xml (~> 0.5) multi_xml (~> 0.5)
rack (~> 1.2) rack (~> 1.2)
octokit (3.8.0) octokit (4.3.0)
sawyer (~> 0.6.0, >= 0.5.3) sawyer (~> 0.7.0, >= 0.5.3)
omniauth (1.3.1) omniauth (1.3.1)
hashie (>= 1.2, < 4) hashie (>= 1.2, < 4)
rack (>= 1.0, < 3) rack (>= 1.0, < 3)
...@@ -712,8 +714,8 @@ GEM ...@@ -712,8 +714,8 @@ GEM
sprockets (>= 2.8, < 4.0) sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0) sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3) tilt (>= 1.1, < 3)
sawyer (0.6.0) sawyer (0.7.0)
addressable (~> 2.3.5) addressable (>= 2.3.5, < 2.5)
faraday (~> 0.8, < 0.10) faraday (~> 0.8, < 0.10)
scss_lint (0.47.1) scss_lint (0.47.1)
rake (>= 0.9, < 11) rake (>= 0.9, < 11)
...@@ -957,6 +959,7 @@ DEPENDENCIES ...@@ -957,6 +959,7 @@ DEPENDENCIES
jquery-ui-rails (~> 5.0.0) jquery-ui-rails (~> 5.0.0)
kaminari (~> 0.16.3) kaminari (~> 0.16.3)
letter_opener (~> 1.1.2) letter_opener (~> 1.1.2)
licensee (~> 8.0.0)
loofah (~> 2.0.3) loofah (~> 2.0.3)
mail_room (~> 0.6.1) mail_room (~> 0.6.1)
method_source (~> 0.8) method_source (~> 0.8)
...@@ -968,7 +971,7 @@ DEPENDENCIES ...@@ -968,7 +971,7 @@ DEPENDENCIES
newrelic_rpm (~> 3.14) newrelic_rpm (~> 3.14)
nokogiri (~> 1.6.7, >= 1.6.7.2) nokogiri (~> 1.6.7, >= 1.6.7.2)
oauth2 (~> 1.0.0) oauth2 (~> 1.0.0)
octokit (~> 3.8.0) octokit (~> 4.3.0)
omniauth (~> 1.3.1) omniauth (~> 1.3.1)
omniauth-auth0 (~> 1.4.1) omniauth-auth0 (~> 1.4.1)
omniauth-azure-oauth2 (~> 0.0.6) omniauth-azure-oauth2 (~> 0.0.6)
......
8.7.0-pre 8.8.0-pre
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
group_projects_path: "/api/:version/groups/:id/projects.json" group_projects_path: "/api/:version/groups/:id/projects.json"
projects_path: "/api/:version/projects.json" projects_path: "/api/:version/projects.json"
labels_path: "/api/:version/projects/:id/labels" labels_path: "/api/:version/projects/:id/labels"
license_path: "/api/:version/licenses/:key"
group: (group_id, callback) -> group: (group_id, callback) ->
url = Api.buildUrl(Api.group_path) url = Api.buildUrl(Api.group_path)
...@@ -92,6 +93,16 @@ ...@@ -92,6 +93,16 @@
).done (projects) -> ).done (projects) ->
callback(projects) callback(projects)
# Return text for a specific license
licenseText: (key, data, callback) ->
url = Api.buildUrl(Api.license_path).replace(':key', key)
$.ajax(
url: url
data: data
).done (license) ->
callback(license)
buildUrl: (url) -> buildUrl: (url) ->
url = gon.relative_url_root + url if gon.relative_url_root? url = gon.relative_url_root + url if gon.relative_url_root?
return url.replace(':version', gon.api_version) return url.replace(':version', gon.api_version)
class @BlobLicenseSelector
licenseRegex: /^(.+\/)?(licen[sc]e|copying)($|\.)/i
constructor: (editor) ->
@$licenseSelector = $('.js-license-selector')
$fileNameInput = $('#file_name')
initialFileNameValue = if $fileNameInput.length
$fileNameInput.val()
else if $('.editor-file-name').length
$('.editor-file-name').text().trim()
@toggleLicenseSelector(initialFileNameValue)
if $fileNameInput
$fileNameInput.on 'keyup blur', (e) =>
@toggleLicenseSelector($(e.target).val())
$('select.license-select').on 'change', (e) ->
data =
project: $(this).data('project')
fullname: $(this).data('fullname')
Api.licenseText $(this).val(), data, (license) ->
editor.setValue(license.content, -1)
toggleLicenseSelector: (fileName) =>
if @licenseRegex.test(fileName)
@$licenseSelector.show()
else
@$licenseSelector.hide()
class @EditBlob class @EditBlob
constructor: (assets_path, mode)-> constructor: (assets_path, ace_mode = null) ->
ace.config.set "modePath", assets_path + '/ace' ace.config.set "modePath", "#{assets_path}/ace"
ace.config.loadModule "ace/ext/searchbox" ace.config.loadModule "ace/ext/searchbox"
if mode @editor = ace.edit("editor")
ace_mode = mode @editor.focus()
editor = ace.edit("editor") @editor.getSession().setMode "ace/mode/#{ace_mode}" if ace_mode
editor.focus()
@editor = editor
if ace_mode
editor.getSession().setMode "ace/mode/" + ace_mode
# Before a form submission, move the content from the Ace editor into the # Before a form submission, move the content from the Ace editor into the
# submitted textarea # submitted textarea
$('form').submit -> $('form').submit =>
$("#file-content").val(editor.getValue()) $("#file-content").val(@editor.getValue())
@initModePanesAndLinks()
new BlobLicenseSelector(@editor)
editModePanes = $(".js-edit-mode-pane") initModePanesAndLinks: ->
editModeLinks = $(".js-edit-mode a") @$editModePanes = $(".js-edit-mode-pane")
editModeLinks.click (event) -> @$editModeLinks = $(".js-edit-mode a")
@$editModeLinks.click @editModeLinkClickHandler
editModeLinkClickHandler: (event) =>
event.preventDefault() event.preventDefault()
currentLink = $(this) currentLink = $(event.target)
paneId = currentLink.attr("href") paneId = currentLink.attr("href")
currentPane = editModePanes.filter(paneId) currentPane = @$editModePanes.filter(paneId)
editModeLinks.parent().removeClass "active hover" @$editModeLinks.parent().removeClass "active hover"
currentLink.parent().addClass "active hover" currentLink.parent().addClass "active hover"
editModePanes.hide() @$editModePanes.hide()
if paneId is "#preview"
currentPane.fadeIn 200 currentPane.fadeIn 200
if paneId is "#preview"
$.post currentLink.data("preview-url"), $.post currentLink.data("preview-url"),
content: editor.getValue() content: @editor.getValue()
, (response) -> , (response) ->
currentPane.empty().append response currentPane.empty().append response
currentPane.syntaxHighlight() currentPane.syntaxHighlight()
return
else else
currentPane.fadeIn 200 @editor.focus()
editor.focus()
return
editor: ->
return @editor
class @NewBlob
constructor: (assets_path, mode)->
ace.config.set "modePath", assets_path + '/ace'
ace.config.loadModule "ace/ext/searchbox"
if mode
ace_mode = mode
editor = ace.edit("editor")
editor.focus()
@editor = editor
if ace_mode
editor.getSession().setMode "ace/mode/" + ace_mode
# Before a form submission, move the content from the Ace editor into the
# submitted textarea
$('form').submit ->
$("#file-content").val(editor.getValue())
editor: ->
return @editor
...@@ -154,6 +154,9 @@ class GitLabDropdown ...@@ -154,6 +154,9 @@ class GitLabDropdown
@fullData = data @fullData = data
@parseData @fullData @parseData @fullData
if @options.filterable
@filterInput.trigger 'keyup'
} }
# Init filterable # Init filterable
......
...@@ -9,7 +9,16 @@ class @IssuableContext ...@@ -9,7 +9,16 @@ class @IssuableContext
$(".issuable-sidebar .inline-update").on "change", ".js-assignee", -> $(".issuable-sidebar .inline-update").on "change", ".js-assignee", ->
$(this).submit() $(this).submit()
$(document).off("click", ".edit-link").on "click",".edit-link", (e) -> $(document)
.off 'click', '.dropdown-content a'
.on 'click', '.dropdown-content a', (e) ->
e.preventDefault()
$(document)
.off 'click', '.edit-link'
.on 'click', '.edit-link', (e) ->
e.preventDefault()
$block = $(@).parents('.block') $block = $(@).parents('.block')
$selectbox = $block.find('.selectbox') $selectbox = $block.find('.selectbox')
if $selectbox.is(':visible') if $selectbox.is(':visible')
...@@ -20,9 +29,9 @@ class @IssuableContext ...@@ -20,9 +29,9 @@ class @IssuableContext
$block.find('.value').hide() $block.find('.value').hide()
if $selectbox.is(':visible') if $selectbox.is(':visible')
setTimeout (-> setTimeout ->
$block.find('.dropdown-menu-toggle').trigger 'click' $block.find('.dropdown-menu-toggle').trigger 'click'
), 0 , 0
$(".right-sidebar").niceScroll() $(".right-sidebar").niceScroll()
......
...@@ -33,13 +33,13 @@ class @LabelsSelect ...@@ -33,13 +33,13 @@ class @LabelsSelect
if issueUpdateURL if issueUpdateURL
labelHTMLTemplate = _.template( labelHTMLTemplate = _.template(
'<% _.each(labels, function(label){ %> '<% _.each(labels, function(label){ %>
<a href="<%= ["",issueURLSplit[1], issueURLSplit[2],""].join("/") %>issues?label_name=<%= label.title %>"> <a href="<%= ["",issueURLSplit[1], issueURLSplit[2],""].join("/") %>issues?label_name=<%= _.escape(label.title) %>">
<span class="label has-tooltip color-label" title="<%= label.description %>" style="background-color: <%= label.color %>;"> <span class="label has-tooltip color-label" title="<%= _.escape(label.description) %>" style="background-color: <%= label.color %>;">
<%= label.title %> <%= _.escape(label.title) %>
</span> </span>
</a> </a>
<% }); %>' <% }); %>'
); )
labelNoneHTMLTemplate = _.template('<div class="light">None</div>') labelNoneHTMLTemplate = _.template('<div class="light">None</div>')
if newLabelField.length and $dropdown.hasClass 'js-extra-options' if newLabelField.length and $dropdown.hasClass 'js-extra-options'
...@@ -211,7 +211,7 @@ class @LabelsSelect ...@@ -211,7 +211,7 @@ class @LabelsSelect
"<li> "<li>
<a href='#' class='#{selectedClass}'> <a href='#' class='#{selectedClass}'>
#{color} #{color}
#{label.title} #{_.escape(label.title)}
</a> </a>
</li>" </li>"
filterable: true filterable: true
......
...@@ -24,7 +24,7 @@ class @MilestoneSelect ...@@ -24,7 +24,7 @@ class @MilestoneSelect
if issueUpdateURL if issueUpdateURL
milestoneLinkTemplate = _.template( milestoneLinkTemplate = _.template(
'<a href="/<%= namespace %>/<%= path %>/milestones/<%= iid %>"><%= title %></a>' '<a href="/<%= namespace %>/<%= path %>/milestones/<%= iid %>"><%= _.escape(title) %></a>'
) )
milestoneLinkNoneTemplate = '<div class="light">None</div>' milestoneLinkNoneTemplate = '<div class="light">None</div>'
...@@ -71,7 +71,7 @@ class @MilestoneSelect ...@@ -71,7 +71,7 @@ class @MilestoneSelect
defaultLabel defaultLabel
fieldName: $dropdown.data('field-name') fieldName: $dropdown.data('field-name')
text: (milestone) -> text: (milestone) ->
milestone.title _.escape(milestone.title)
id: (milestone) -> id: (milestone) ->
if !useId if !useId
milestone.name milestone.name
......
...@@ -26,6 +26,10 @@ ...@@ -26,6 +26,10 @@
line-height: 42px; line-height: 42px;
padding-top: 7px; padding-top: 7px;
padding-bottom: 7px; padding-bottom: 7px;
.pull-right {
height: 20px;
}
} }
.editor-ref { .editor-ref {
...@@ -53,4 +57,9 @@ ...@@ -53,4 +57,9 @@
.select2 { .select2 {
float: right; float: right;
} }
.encoding-selector,
.license-selector {
display: inline-block;
}
} }
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
.note-textarea { .note-textarea {
display: block; display: block;
padding: 10px 0; padding: 10px 0;
color: $gl-gray;
font-family: $regular_font; font-family: $regular_font;
border: 0; border: 0;
......
...@@ -75,6 +75,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController ...@@ -75,6 +75,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:admin_notification_email, :admin_notification_email,
:user_oauth_applications, :user_oauth_applications,
:shared_runners_enabled, :shared_runners_enabled,
:shared_runners_text,
:max_artifacts_size, :max_artifacts_size,
:metrics_enabled, :metrics_enabled,
:metrics_host, :metrics_host,
...@@ -92,6 +93,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController ...@@ -92,6 +93,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:akismet_api_key, :akismet_api_key,
:email_author_in_body, :email_author_in_body,
:repository_checks_enabled, :repository_checks_enabled,
:metrics_packet_size,
restricted_visibility_levels: [], restricted_visibility_levels: [],
import_sources: [] import_sources: []
) )
......
...@@ -39,6 +39,6 @@ class Admin::HooksController < Admin::ApplicationController ...@@ -39,6 +39,6 @@ class Admin::HooksController < Admin::ApplicationController
end end
def hook_params def hook_params
params.require(:hook).permit(:url, :enable_ssl_verification) params.require(:hook).permit(:url, :enable_ssl_verification, :push_events, :tag_push_events)
end end
end end
class Projects::BuildsController < Projects::ApplicationController class Projects::BuildsController < Projects::ApplicationController
before_action :build, except: [:index, :cancel_all] before_action :build, except: [:index, :cancel_all]
before_action :authorize_read_build!, except: [:cancel, :cancel_all, :retry] before_action :authorize_read_build!, except: [:cancel, :cancel_all, :retry]
before_action :authorize_update_build!, except: [:index, :show, :status] before_action :authorize_update_build!, except: [:index, :show, :status, :raw]
layout 'project' layout 'project'
def index def index
...@@ -62,6 +62,14 @@ class Projects::BuildsController < Projects::ApplicationController ...@@ -62,6 +62,14 @@ class Projects::BuildsController < Projects::ApplicationController
notice: "Build has been sucessfully erased!" notice: "Build has been sucessfully erased!"
end end
def raw
if @build.has_trace?
send_file @build.path_to_trace, type: 'text/plain; charset=utf-8', disposition: 'inline'
else
render_404
end
end
private private
def build def build
......
...@@ -12,7 +12,7 @@ class Projects::CommitController < Projects::ApplicationController ...@@ -12,7 +12,7 @@ class Projects::CommitController < Projects::ApplicationController
before_action :authorize_read_commit_status!, only: [:builds] before_action :authorize_read_commit_status!, only: [:builds]
before_action :commit before_action :commit
before_action :define_show_vars, only: [:show, :builds] before_action :define_show_vars, only: [:show, :builds]
before_action :authorize_edit_tree!, only: [:revert] before_action :authorize_edit_tree!, only: [:revert, :cherry_pick]
def show def show
apply_diff_view_cookie! apply_diff_view_cookie!
...@@ -60,27 +60,32 @@ class Projects::CommitController < Projects::ApplicationController ...@@ -60,27 +60,32 @@ class Projects::CommitController < Projects::ApplicationController
end end
def revert def revert
assign_revert_commit_vars assign_change_commit_vars(@commit.revert_branch_name)
return render_404 if @target_branch.blank? return render_404 if @target_branch.blank?
create_commit(Commits::RevertService, success_notice: "The #{revert_type_title} has been successfully reverted.", create_commit(Commits::RevertService, success_notice: "The #{@commit.change_type_title} has been successfully reverted.",
success_path: successful_revert_path, failure_path: failed_revert_path) success_path: successful_change_path, failure_path: failed_change_path)
end end
private def cherry_pick
assign_change_commit_vars(@commit.cherry_pick_branch_name)
return render_404 if @target_branch.blank?
def revert_type_title create_commit(Commits::CherryPickService, success_notice: "The #{@commit.change_type_title} has been successfully cherry-picked.",
@commit.merged_merge_request ? 'merge request' : 'commit' success_path: successful_change_path, failure_path: failed_change_path)
end end
def successful_revert_path private
def successful_change_path
return referenced_merge_request_url if @commit.merged_merge_request return referenced_merge_request_url if @commit.merged_merge_request
namespace_project_commits_url(@project.namespace, @project, @target_branch) namespace_project_commits_url(@project.namespace, @project, @target_branch)
end end
def failed_revert_path def failed_change_path
return referenced_merge_request_url if @commit.merged_merge_request return referenced_merge_request_url if @commit.merged_merge_request
namespace_project_commit_url(@project.namespace, @project, params[:id]) namespace_project_commit_url(@project.namespace, @project, params[:id])
...@@ -111,14 +116,13 @@ class Projects::CommitController < Projects::ApplicationController ...@@ -111,14 +116,13 @@ class Projects::CommitController < Projects::ApplicationController
@statuses = ci_commit.statuses if ci_commit @statuses = ci_commit.statuses if ci_commit
end end
def assign_revert_commit_vars def assign_change_commit_vars(mr_source_branch)
@commit = project.commit(params[:id]) @commit = project.commit(params[:id])
@target_branch = params[:target_branch] @target_branch = params[:target_branch]
@mr_source_branch = @commit.revert_branch_name @mr_source_branch = mr_source_branch
@mr_target_branch = @target_branch @mr_target_branch = @target_branch
@commit_params = { @commit_params = {
commit: @commit, commit: @commit,
revert_type_title: revert_type_title,
create_merge_request: params[:create_merge_request].present? || different_project? create_merge_request: params[:create_merge_request].present? || different_project?
} }
end end
......
...@@ -7,10 +7,12 @@ class Projects::GroupLinksController < Projects::ApplicationController ...@@ -7,10 +7,12 @@ class Projects::GroupLinksController < Projects::ApplicationController
end end
def create def create
link = project.project_group_links.new group = Group.find(params[:link_group_id])
link.group_id = params[:link_group_id] return render_404 unless can?(current_user, :read_group, group)
link.group_access = params[:link_group_access]
link.save project.project_group_links.create(
group: group, group_access: params[:link_group_access]
)
redirect_to namespace_project_group_links_path(project.namespace, project) redirect_to namespace_project_group_links_path(project.namespace, project)
end end
......
...@@ -128,10 +128,7 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -128,10 +128,7 @@ class Projects::IssuesController < Projects::ApplicationController
end end
def related_branches def related_branches
merge_requests = @issue.referenced_merge_requests(current_user) @related_branches = @issue.related_branches(current_user)
@related_branches = @issue.related_branches -
merge_requests.map(&:source_branch)
respond_to do |format| respond_to do |format|
format.json do format.json do
......
...@@ -6,7 +6,7 @@ class Projects::ServicesController < Projects::ApplicationController ...@@ -6,7 +6,7 @@ class Projects::ServicesController < Projects::ApplicationController
:description, :issues_url, :new_issue_url, :restrict_to_branch, :channel, :description, :issues_url, :new_issue_url, :restrict_to_branch, :channel,
:colorize_messages, :channels, :colorize_messages, :channels,
:push_events, :issues_events, :merge_requests_events, :tag_push_events, :push_events, :issues_events, :merge_requests_events, :tag_push_events,
:note_events, :build_events, :note_events, :build_events, :wiki_page_events,
:notify_only_broken_builds, :add_pusher, :notify_only_broken_builds, :add_pusher,
:send_from_committer_email, :disable_diffs, :external_wiki_url, :send_from_committer_email, :disable_diffs, :external_wiki_url,
:notify, :color, :notify, :color,
......
...@@ -44,7 +44,7 @@ class Projects::WikisController < Projects::ApplicationController ...@@ -44,7 +44,7 @@ class Projects::WikisController < Projects::ApplicationController
return render('empty') unless can?(current_user, :create_wiki, @project) return render('empty') unless can?(current_user, :create_wiki, @project)
if @page.update(content, format, message) if @page = WikiPages::UpdateService.new(@project, current_user, wiki_params).execute(@page)
redirect_to( redirect_to(
namespace_project_wiki_path(@project.namespace, @project, @page), namespace_project_wiki_path(@project.namespace, @project, @page),
notice: 'Wiki was successfully updated.' notice: 'Wiki was successfully updated.'
...@@ -55,9 +55,9 @@ class Projects::WikisController < Projects::ApplicationController ...@@ -55,9 +55,9 @@ class Projects::WikisController < Projects::ApplicationController
end end
def create def create
@page = WikiPage.new(@project_wiki) @page = WikiPages::CreateService.new(@project, current_user, wiki_params).execute
if @page.create(wiki_params) if @page.persisted?
redirect_to( redirect_to(
namespace_project_wiki_path(@project.namespace, @project, @page), namespace_project_wiki_path(@project.namespace, @project, @page),
notice: 'Wiki was successfully updated.' notice: 'Wiki was successfully updated.'
...@@ -122,15 +122,4 @@ class Projects::WikisController < Projects::ApplicationController ...@@ -122,15 +122,4 @@ class Projects::WikisController < Projects::ApplicationController
params[:wiki].slice(:title, :content, :format, :message) params[:wiki].slice(:title, :content, :format, :message)
end end
def content
params[:wiki][:content]
end
def format
params[:wiki][:format]
end
def message
params[:wiki][:message]
end
end end
...@@ -15,6 +15,10 @@ module ApplicationSettingsHelper ...@@ -15,6 +15,10 @@ module ApplicationSettingsHelper
current_application_settings.sign_in_text current_application_settings.sign_in_text
end end
def shared_runners_text
current_application_settings.shared_runners_text
end
def user_oauth_applications? def user_oauth_applications?
current_application_settings.user_oauth_applications current_application_settings.user_oauth_applications
end end
......
...@@ -173,4 +173,15 @@ module BlobHelper ...@@ -173,4 +173,15 @@ module BlobHelper
response.etag = @blob.id response.etag = @blob.id
!stale !stale
end end
def licenses_for_select
return @licenses_for_select if defined?(@licenses_for_select)
licenses = Licensee::License.all
@licenses_for_select = {
Popular: licenses.select(&:featured).map { |license| [license.name, license.key] },
Other: licenses.reject(&:featured).map { |license| [license.name, license.key] }
}
end
end end
...@@ -126,12 +126,10 @@ module CommitsHelper ...@@ -126,12 +126,10 @@ module CommitsHelper
def revert_commit_link(commit, continue_to_path, btn_class: nil) def revert_commit_link(commit, continue_to_path, btn_class: nil)
return unless current_user return unless current_user
tooltip = "Revert this #{revert_commit_type(commit)} in a new merge request" tooltip = "Revert this #{commit.change_type_title} in a new merge request"
if can_collaborate_with_project? if can_collaborate_with_project?
content_tag :span, 'data-toggle' => 'modal', 'data-target' => '#modal-revert-commit' do link_to 'Revert', '#modal-revert-commit', 'data-toggle' => 'modal', 'data-container' => 'body', title: tooltip, class: "btn btn-default btn-grouped btn-#{btn_class} has-tooltip"
link_to 'Revert', '#modal-revert-commit', 'data-toggle' => 'tooltip', 'data-container' => 'body', title: tooltip, class: "btn btn-default btn-grouped btn-#{btn_class}"
end
elsif can?(current_user, :fork_project, @project) elsif can?(current_user, :fork_project, @project)
continue_params = { continue_params = {
to: continue_to_path, to: continue_to_path,
...@@ -146,11 +144,24 @@ module CommitsHelper ...@@ -146,11 +144,24 @@ module CommitsHelper
end end
end end
def revert_commit_type(commit) def cherry_pick_commit_link(commit, continue_to_path, btn_class: nil)
if commit.merged_merge_request return unless current_user
'merge request'
else tooltip = "Cherry-pick this #{commit.change_type_title} in a new merge request"
'commit'
if can_collaborate_with_project?
link_to 'Cherry-pick', '#modal-cherry-pick-commit', 'data-toggle' => 'modal', 'data-container' => 'body', title: tooltip, class: "btn btn-default btn-grouped btn-#{btn_class} has-tooltip"
elsif can?(current_user, :fork_project, @project)
continue_params = {
to: continue_to_path,
notice: edit_in_new_fork_notice + ' Try to cherry-pick this commit again.',
notice_now: edit_in_new_fork_notice_now
}
fork_path = namespace_project_forks_path(@project.namespace, @project,
namespace_key: current_user.namespace.id,
continue: continue_params)
link_to 'Cherry-pick', fork_path, class: 'btn btn-grouped btn-close', method: :post, 'data-toggle' => 'tooltip', 'data-container' => 'body', title: tooltip
end end
end end
...@@ -183,7 +194,7 @@ module CommitsHelper ...@@ -183,7 +194,7 @@ module CommitsHelper
options = { options = {
class: "commit-#{options[:source]}-link has-tooltip", class: "commit-#{options[:source]}-link has-tooltip",
data: { 'original-title'.to_sym => sanitize(source_email) } title: source_email
} }
if user.nil? if user.nil?
......
module ImportHelper
def github_project_link(path_with_namespace)
link_to path_with_namespace, github_project_url(path_with_namespace), target: '_blank'
end
private
def github_project_url(path_with_namespace)
"#{github_root_url}/#{path_with_namespace}"
end
def github_root_url
return @github_url if defined?(@github_url)
provider = Gitlab.config.omniauth.providers.find { |p| p.name == 'github' }
@github_url = provider.fetch('url', 'https://github.com') if provider
end
end
...@@ -52,7 +52,7 @@ module ProjectsHelper ...@@ -52,7 +52,7 @@ module ProjectsHelper
link_to(author_html, user_path(author), class: "author_link #{"#{opts[:mobile_classes]}" if opts[:mobile_classes]}").html_safe link_to(author_html, user_path(author), class: "author_link #{"#{opts[:mobile_classes]}" if opts[:mobile_classes]}").html_safe
else else
title = opts[:title].sub(":name", sanitize(author.name)) title = opts[:title].sub(":name", sanitize(author.name))
link_to(author_html, user_path(author), class: "author_link has-tooltip", data: { 'original-title'.to_sym => title, container: 'body' } ).html_safe link_to(author_html, user_path(author), class: "author_link has-tooltip", title: title, data: { container: 'body' } ).html_safe
end end
end end
...@@ -216,41 +216,15 @@ module ProjectsHelper ...@@ -216,41 +216,15 @@ module ProjectsHelper
end end
end end
def add_contribution_guide_path(project) def add_special_file_path(project, file_name:, commit_message: nil)
if project && !project.repository.contribution_guide
namespace_project_new_blob_path( namespace_project_new_blob_path(
project.namespace, project.namespace,
project, project,
project.default_branch, project.default_branch || 'master',
file_name: "CONTRIBUTING.md", file_name: file_name,
commit_message: "Add contribution guide" commit_message: commit_message || "Add #{file_name.downcase}"
) )
end end
end
def add_changelog_path(project)
if project && !project.repository.changelog
namespace_project_new_blob_path(
project.namespace,
project,
project.default_branch,
file_name: "CHANGELOG",
commit_message: "Add changelog"
)
end
end
def add_license_path(project)
if project && !project.repository.license
namespace_project_new_blob_path(
project.namespace,
project,
project.default_branch,
file_name: "LICENSE",
commit_message: "Add license"
)
end
end
def contribution_guide_path(project) def contribution_guide_path(project)
if project && contribution_guide = project.repository.contribution_guide if project && contribution_guide = project.repository.contribution_guide
...@@ -272,7 +246,7 @@ module ProjectsHelper ...@@ -272,7 +246,7 @@ module ProjectsHelper
end end
def license_path(project) def license_path(project)
filename_path(project, :license) filename_path(project, :license_blob)
end end
def version_path(project) def version_path(project)
...@@ -306,6 +280,13 @@ module ProjectsHelper ...@@ -306,6 +280,13 @@ module ProjectsHelper
namespace_project_new_blob_path(@project.namespace, @project, tree_join(ref), file_name: 'README.md') namespace_project_new_blob_path(@project.namespace, @project, tree_join(ref), file_name: 'README.md')
end end
def new_license_path
ref = @repository.root_ref if @repository
ref ||= 'master'
namespace_project_new_blob_path(@project.namespace, @project, tree_join(ref), file_name: 'LICENSE')
end
def last_push_event def last_push_event
if current_user if current_user
current_user.recent_push(@project.id) current_user.recent_push(@project.id)
...@@ -335,6 +316,12 @@ module ProjectsHelper ...@@ -335,6 +316,12 @@ module ProjectsHelper
@ref || @repository.try(:root_ref) @ref || @repository.try(:root_ref)
end end
def license_short_name(project)
license = Licensee::License.new(project.repository.license_key)
license.nickname || license.name
end
private private
def filename_path(project, filename) def filename_path(project, filename)
......
...@@ -2,32 +2,29 @@ module SelectsHelper ...@@ -2,32 +2,29 @@ module SelectsHelper
def users_select_tag(id, opts = {}) def users_select_tag(id, opts = {})
css_class = "ajax-users-select " css_class = "ajax-users-select "
css_class << "multiselect " if opts[:multiple] css_class << "multiselect " if opts[:multiple]
css_class << "skip_ldap " if opts[:skip_ldap]
css_class << (opts[:class] || '') css_class << (opts[:class] || '')
value = opts[:selected] || '' value = opts[:selected] || ''
placeholder = opts[:placeholder] || 'Search for a user'
null_user = opts[:null_user] || false
any_user = opts[:any_user] || false
email_user = opts[:email_user] || false
first_user = opts[:first_user] && current_user ? current_user.username : false first_user = opts[:first_user] && current_user ? current_user.username : false
current_user = opts[:current_user] || false
author_id = opts[:author_id] || ''
project = opts[:project] || @project
html = { html = {
class: css_class, class: css_class,
data: { data: {
placeholder: placeholder, placeholder: opts[:placeholder] || 'Search for a user',
null_user: null_user, null_user: opts[:null_user] || false,
any_user: any_user, any_user: opts[:any_user] || false,
email_user: email_user, email_user: opts[:email_user] || false,
first_user: first_user, first_user: first_user,
current_user: current_user, current_user: opts[:current_user] || false,
author_id: author_id "push-code-to-protected-branches" => opts[:push_code_to_protected_branches],
author_id: opts[:author_id] || ''
} }
} }
unless opts[:scope] == :all unless opts[:scope] == :all
project = opts[:project] || @project
if project if project
html['data-project-id'] = project.id html['data-project-id'] = project.id
elsif @group elsif @group
......
...@@ -66,7 +66,7 @@ module TreeHelper ...@@ -66,7 +66,7 @@ module TreeHelper
ref ref
else else
project = tree_edit_project(project) project = tree_edit_project(project)
project.repository.next_patch_branch project.repository.next_branch('patch')
end end
end end
......
...@@ -56,7 +56,7 @@ module Emails ...@@ -56,7 +56,7 @@ module Emails
{ {
from: sender(sender_id), from: sender(sender_id),
to: recipient(recipient_id), to: recipient(recipient_id),
subject: subject("#{@merge_request.title} (##{@merge_request.iid})") subject: subject("#{@merge_request.title} (#{@merge_request.to_reference})")
} }
end end
end end
......
...@@ -38,7 +38,7 @@ module Emails ...@@ -38,7 +38,7 @@ module Emails
{ {
from: sender(@note.author_id), from: sender(@note.author_id),
to: recipient(recipient_id), to: recipient(recipient_id),
subject: subject("#{@note.noteable.title} (##{@note.noteable.iid})") subject: subject("#{@note.noteable.title} (#{@note.noteable.to_reference})")
} }
end end
......
...@@ -8,7 +8,7 @@ class RepositoryCheckMailer < BaseMailer ...@@ -8,7 +8,7 @@ class RepositoryCheckMailer < BaseMailer
mail( mail(
to: User.admins.pluck(:email), to: User.admins.pluck(:email),
subject: @message subject: "GitLab Admin | #{@message}"
) )
end end
end end
...@@ -230,12 +230,33 @@ module Ci ...@@ -230,12 +230,33 @@ module Ci
end end
end end
def trace_length
if raw_trace
raw_trace.length
else
0
end
end
def trace=(trace) def trace=(trace)
recreate_trace_dir
File.write(path_to_trace, trace)
end
def recreate_trace_dir
unless Dir.exists?(dir_to_trace) unless Dir.exists?(dir_to_trace)
FileUtils.mkdir_p(dir_to_trace) FileUtils.mkdir_p(dir_to_trace)
end end
end
private :recreate_trace_dir
File.write(path_to_trace, trace) def append_trace(trace_part, offset)
recreate_trace_dir
File.truncate(path_to_trace, offset) if File.exist?(path_to_trace)
File.open(path_to_trace, 'a') do |f|
f.write(trace_part)
end
end end
def dir_to_trace def dir_to_trace
......
...@@ -15,8 +15,8 @@ class Commit ...@@ -15,8 +15,8 @@ class Commit
DIFF_SAFE_LINES = Gitlab::Git::DiffCollection::DEFAULT_LIMITS[:max_lines] DIFF_SAFE_LINES = Gitlab::Git::DiffCollection::DEFAULT_LIMITS[:max_lines]
# Commits above this size will not be rendered in HTML # Commits above this size will not be rendered in HTML
DIFF_HARD_LIMIT_FILES = 1000 unless defined?(DIFF_HARD_LIMIT_FILES) DIFF_HARD_LIMIT_FILES = 1000
DIFF_HARD_LIMIT_LINES = 50000 unless defined?(DIFF_HARD_LIMIT_LINES) DIFF_HARD_LIMIT_LINES = 50000
class << self class << self
def decorate(commits, project) def decorate(commits, project)
...@@ -219,6 +219,10 @@ class Commit ...@@ -219,6 +219,10 @@ class Commit
"revert-#{short_id}" "revert-#{short_id}"
end end
def cherry_pick_branch_name
project.repository.next_branch("cherry-pick-#{short_id}", mild: true)
end
def revert_description def revert_description
if merged_merge_request if merged_merge_request
"This reverts merge request #{merged_merge_request.to_reference}" "This reverts merge request #{merged_merge_request.to_reference}"
...@@ -253,6 +257,10 @@ class Commit ...@@ -253,6 +257,10 @@ class Commit
end.any? { |commit_ref| commit_ref.reverts_commit?(self) } end.any? { |commit_ref| commit_ref.reverts_commit?(self) }
end end
def change_type_title
merged_merge_request ? 'merge request' : 'commit'
end
private private
def repo_changes def repo_changes
......
...@@ -15,7 +15,6 @@ ...@@ -15,7 +15,6 @@
# #
require 'carrierwave/orm/activerecord' require 'carrierwave/orm/activerecord'
require 'file_size_validator'
class Group < Namespace class Group < Namespace
include Gitlab::ConfigHelper include Gitlab::ConfigHelper
......
...@@ -21,10 +21,9 @@ ...@@ -21,10 +21,9 @@
class ProjectHook < WebHook class ProjectHook < WebHook
belongs_to :project belongs_to :project
scope :push_hooks, -> { where(push_events: true) }
scope :tag_push_hooks, -> { where(tag_push_events: true) }
scope :issue_hooks, -> { where(issues_events: true) } scope :issue_hooks, -> { where(issues_events: true) }
scope :note_hooks, -> { where(note_events: true) } scope :note_hooks, -> { where(note_events: true) }
scope :merge_request_hooks, -> { where(merge_requests_events: true) } scope :merge_request_hooks, -> { where(merge_requests_events: true) }
scope :build_hooks, -> { where(build_events: true) } scope :build_hooks, -> { where(build_events: true) }
scope :wiki_page_hooks, -> { where(wiki_page_events: true) }
end end
...@@ -19,4 +19,7 @@ ...@@ -19,4 +19,7 @@
# #
class SystemHook < WebHook class SystemHook < WebHook
def async_execute(data, hook_name)
Sidekiq::Client.enqueue(SystemHookWorker, id, data, hook_name)
end
end end
...@@ -30,6 +30,9 @@ class WebHook < ActiveRecord::Base ...@@ -30,6 +30,9 @@ class WebHook < ActiveRecord::Base
default_value_for :build_events, false default_value_for :build_events, false
default_value_for :enable_ssl_verification, true default_value_for :enable_ssl_verification, true
scope :push_hooks, -> { where(push_events: true) }
scope :tag_push_hooks, -> { where(tag_push_events: true) }
# HTTParty timeout # HTTParty timeout
default_timeout Gitlab.config.gitlab.webhook_timeout default_timeout Gitlab.config.gitlab.webhook_timeout
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
# #
require 'carrierwave/orm/activerecord' require 'carrierwave/orm/activerecord'
require 'file_size_validator'
class Issue < ActiveRecord::Base class Issue < ActiveRecord::Base
include InternalId include InternalId
...@@ -104,10 +103,16 @@ class Issue < ActiveRecord::Base ...@@ -104,10 +103,16 @@ class Issue < ActiveRecord::Base
end end
end end
def related_branches # All branches containing the current issue's ID, except for
project.repository.branch_names.select do |branch| # those with a merge request open referencing the current issue.
def related_branches(current_user)
branches_with_iid = project.repository.branch_names.select do |branch|
branch =~ /\A#{iid}-(?!\d+-stable)/i branch =~ /\A#{iid}-(?!\d+-stable)/i
end end
branches_with_merge_request = self.referenced_merge_requests(current_user).map(&:source_branch)
branches_with_iid - branches_with_merge_request
end end
# Reset issue events cache # Reset issue events cache
...@@ -151,13 +156,17 @@ class Issue < ActiveRecord::Base ...@@ -151,13 +156,17 @@ class Issue < ActiveRecord::Base
end end
def to_branch_name def to_branch_name
if self.confidential?
"#{iid}-confidential-issue"
else
"#{iid}-#{title.parameterize}" "#{iid}-#{title.parameterize}"
end end
end
def can_be_worked_on?(current_user) def can_be_worked_on?(current_user)
!self.closed? && !self.closed? &&
!self.project.forked? && !self.project.forked? &&
self.related_branches.empty? && self.related_branches(current_user).empty? &&
self.closed_by_merge_requests(current_user).empty? self.closed_by_merge_requests(current_user).empty?
end end
end end
...@@ -27,9 +27,6 @@ ...@@ -27,9 +27,6 @@
# merge_commit_sha :string # merge_commit_sha :string
# #
require Rails.root.join("app/models/commit")
require Rails.root.join("lib/static_model")
class MergeRequest < ActiveRecord::Base class MergeRequest < ActiveRecord::Base
include InternalId include InternalId
include Issuable include Issuable
...@@ -605,4 +602,8 @@ class MergeRequest < ActiveRecord::Base ...@@ -605,4 +602,8 @@ class MergeRequest < ActiveRecord::Base
def can_be_reverted?(current_user = nil) def can_be_reverted?(current_user = nil)
merge_commit && !merge_commit.has_been_reverted?(current_user, self) merge_commit && !merge_commit.has_been_reverted?(current_user, self)
end end
def can_be_cherry_picked?
merge_commit
end
end end
...@@ -11,8 +11,6 @@ ...@@ -11,8 +11,6 @@
# updated_at :datetime # updated_at :datetime
# #
require Rails.root.join("app/models/commit")
class MergeRequestDiff < ActiveRecord::Base class MergeRequestDiff < ActiveRecord::Base
include Sortable include Sortable
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
# #
require 'carrierwave/orm/activerecord' require 'carrierwave/orm/activerecord'
require 'file_size_validator'
class Note < ActiveRecord::Base class Note < ActiveRecord::Base
include Gitlab::CurrentSettings include Gitlab::CurrentSettings
......
...@@ -40,7 +40,6 @@ ...@@ -40,7 +40,6 @@
# #
require 'carrierwave/orm/activerecord' require 'carrierwave/orm/activerecord'
require 'file_size_validator'
class Project < ActiveRecord::Base class Project < ActiveRecord::Base
include Gitlab::ConfigHelper include Gitlab::ConfigHelper
...@@ -831,8 +830,8 @@ class Project < ActiveRecord::Base ...@@ -831,8 +830,8 @@ class Project < ActiveRecord::Base
end end
end end
def hook_attrs def hook_attrs(backward: true)
{ attrs = {
name: name, name: name,
description: description, description: description,
web_url: web_url, web_url: web_url,
...@@ -843,12 +842,19 @@ class Project < ActiveRecord::Base ...@@ -843,12 +842,19 @@ class Project < ActiveRecord::Base
visibility_level: visibility_level, visibility_level: visibility_level,
path_with_namespace: path_with_namespace, path_with_namespace: path_with_namespace,
default_branch: default_branch, default_branch: default_branch,
}
# Backward compatibility # Backward compatibility
if backward
attrs.merge!({
homepage: web_url, homepage: web_url,
url: url_to_repo, url: url_to_repo,
ssh_url: ssh_url_to_repo, ssh_url: ssh_url_to_repo,
http_url: http_url_to_repo http_url: http_url_to_repo
} })
end
attrs
end end
# Reset events cache related to this project # Reset events cache related to this project
......
...@@ -8,7 +8,6 @@ ...@@ -8,7 +8,6 @@
# #
require 'carrierwave/orm/activerecord' require 'carrierwave/orm/activerecord'
require 'file_size_validator'
class ProjectImportData < ActiveRecord::Base class ProjectImportData < ActiveRecord::Base
belongs_to :project belongs_to :project
......
...@@ -183,7 +183,7 @@ class HipchatService < Service ...@@ -183,7 +183,7 @@ class HipchatService < Service
title = obj_attr[:title] title = obj_attr[:title]
merge_request_url = "#{project_url}/merge_requests/#{merge_request_id}" merge_request_url = "#{project_url}/merge_requests/#{merge_request_id}"
merge_request_link = "<a href=\"#{merge_request_url}\">merge request ##{merge_request_id}</a>" merge_request_link = "<a href=\"#{merge_request_url}\">merge request !#{merge_request_id}</a>"
message = "#{user_name} #{state} #{merge_request_link} in " \ message = "#{user_name} #{state} #{merge_request_link} in " \
"#{project_link}: <b>#{title}</b>" "#{project_link}: <b>#{title}</b>"
...@@ -224,7 +224,7 @@ class HipchatService < Service ...@@ -224,7 +224,7 @@ class HipchatService < Service
when "MergeRequest" when "MergeRequest"
subj_attr = HashWithIndifferentAccess.new(data[:merge_request]) subj_attr = HashWithIndifferentAccess.new(data[:merge_request])
subject_id = subj_attr[:iid] subject_id = subj_attr[:iid]
subject_desc = "##{subject_id}" subject_desc = "!#{subject_id}"
subject_type = "merge request" subject_type = "merge request"
title = format_title(subj_attr[:title]) title = format_title(subj_attr[:title])
when "Snippet" when "Snippet"
......
...@@ -60,7 +60,7 @@ class SlackService < Service ...@@ -60,7 +60,7 @@ class SlackService < Service
end end
def supported_events def supported_events
%w(push issue merge_request note tag_push build) %w(push issue merge_request note tag_push build wiki_page)
end end
def execute(data) def execute(data)
...@@ -90,6 +90,8 @@ class SlackService < Service ...@@ -90,6 +90,8 @@ class SlackService < Service
NoteMessage.new(data) NoteMessage.new(data)
when "build" when "build"
BuildMessage.new(data) if should_build_be_notified?(data) BuildMessage.new(data) if should_build_be_notified?(data)
when "wiki_page"
WikiPageMessage.new(data)
end end
opt = {} opt = {}
...@@ -133,3 +135,4 @@ require "slack_service/push_message" ...@@ -133,3 +135,4 @@ require "slack_service/push_message"
require "slack_service/merge_message" require "slack_service/merge_message"
require "slack_service/note_message" require "slack_service/note_message"
require "slack_service/build_message" require "slack_service/build_message"
require "slack_service/wiki_page_message"
...@@ -50,7 +50,7 @@ class SlackService ...@@ -50,7 +50,7 @@ class SlackService
end end
def merge_request_link def merge_request_link
"[merge request ##{merge_request_id}](#{merge_request_url})" "[merge request !#{merge_request_id}](#{merge_request_url})"
end end
def merge_request_url def merge_request_url
......
...@@ -58,7 +58,7 @@ class SlackService ...@@ -58,7 +58,7 @@ class SlackService
def create_merge_note(merge_request) def create_merge_note(merge_request)
commented_on_message( commented_on_message(
"[merge request ##{merge_request[:iid]}](#{@note_url})", "[merge request !#{merge_request[:iid]}](#{@note_url})",
format_title(merge_request[:title])) format_title(merge_request[:title]))
end end
......
class SlackService
class WikiPageMessage < BaseMessage
attr_reader :user_name
attr_reader :title
attr_reader :project_name
attr_reader :project_url
attr_reader :wiki_page_url
attr_reader :action
attr_reader :description
def initialize(params)
@user_name = params[:user][:name]
@project_name = params[:project_name]
@project_url = params[:project_url]
obj_attr = params[:object_attributes]
obj_attr = HashWithIndifferentAccess.new(obj_attr)
@title = obj_attr[:title]
@wiki_page_url = obj_attr[:url]
@description = obj_attr[:content]
@action =
case obj_attr[:action]
when "create"
"created"
when "update"
"edited"
end
end
def attachments
description_message
end
private
def message
"#{user_name} #{action} #{wiki_page_link} in #{project_link}: *#{title}*"
end
def description_message
[{ text: format(@description), color: attachment_color }]
end
def project_link
"[#{project_name}](#{project_url})"
end
def wiki_page_link
"[wiki page](#{wiki_page_url})"
end
end
end
...@@ -228,7 +228,8 @@ class Repository ...@@ -228,7 +228,8 @@ class Repository
def cache_keys def cache_keys
%i(size branch_names tag_names commit_count %i(size branch_names tag_names commit_count
readme version contribution_guide changelog license) readme version contribution_guide changelog
license_blob license_key)
end end
def build_cache def build_cache
...@@ -461,27 +462,21 @@ class Repository ...@@ -461,27 +462,21 @@ class Repository
end end
end end
def license def license_blob
cache.fetch(:license) do return nil if !exists? || empty?
licenses = tree(:head).blobs.find_all do |file|
file.name =~ /\A(copying|license|licence)/i
end
preferences = [
/\Alicen[sc]e\z/i, # LICENSE, LICENCE
/\Alicen[sc]e\./i, # LICENSE.md, LICENSE.txt
/\Acopying\z/i, # COPYING
/\Acopying\.(?!lesser)/i, # COPYING.txt
/Acopying.lesser/i # COPYING.LESSER
]
license = nil cache.fetch(:license_blob) do
preferences.each do |r| if licensee_project.license
license = licenses.find { |l| l.name =~ r } blob_at_branch(root_ref, licensee_project.matched_file.filename)
break if license end
end end
end
def license_key
return nil if !exists? || empty?
license cache.fetch(:license_key) do
licensee_project.license.try(:key) || 'no-license'
end end
end end
...@@ -549,15 +544,18 @@ class Repository ...@@ -549,15 +544,18 @@ class Repository
commit(sha) commit(sha)
end end
def next_patch_branch def next_branch(name, opts={})
patch_branch_ids = self.branch_names.map do |n| branch_ids = self.branch_names.map do |n|
result = n.match(/\Apatch-([0-9]+)\z/) next 1 if n == name
result = n.match(/\A#{name}-([0-9]+)\z/)
result[1].to_i if result result[1].to_i if result
end.compact end.compact
highest_patch_branch_id = patch_branch_ids.max || 0 highest_branch_id = branch_ids.max || 0
return name if opts[:mild] && 0 == highest_branch_id
"patch-#{highest_patch_branch_id + 1}" "#{name}-#{highest_branch_id + 1}"
end end
# Remove archives older than 2 hours # Remove archives older than 2 hours
...@@ -760,6 +758,28 @@ class Repository ...@@ -760,6 +758,28 @@ class Repository
end end
end end
def cherry_pick(user, commit, base_branch, cherry_pick_tree_id = nil)
source_sha = find_branch(base_branch).target
cherry_pick_tree_id ||= check_cherry_pick_content(commit, base_branch)
return false unless cherry_pick_tree_id
commit_with_hooks(user, base_branch) do |ref|
committer = user_to_committer(user)
source_sha = Rugged::Commit.create(rugged,
message: commit.message,
author: {
email: commit.author_email,
name: commit.author_name,
time: commit.authored_date
},
committer: committer,
tree: cherry_pick_tree_id,
parents: [rugged.lookup(source_sha)],
update_ref: ref)
end
end
def check_revert_content(commit, base_branch) def check_revert_content(commit, base_branch)
source_sha = find_branch(base_branch).target source_sha = find_branch(base_branch).target
args = [commit.id, source_sha] args = [commit.id, source_sha]
...@@ -774,6 +794,20 @@ class Repository ...@@ -774,6 +794,20 @@ class Repository
tree_id tree_id
end end
def check_cherry_pick_content(commit, base_branch)
source_sha = find_branch(base_branch).target
args = [commit.id, source_sha]
args << 1 if commit.merge_commit?
cherry_pick_index = rugged.cherrypick_commit(*args)
return false if cherry_pick_index.conflicts?
tree_id = cherry_pick_index.write_tree(rugged)
return false unless diff_exists?(source_sha, tree_id)
tree_id
end
def diff_exists?(sha1, sha2) def diff_exists?(sha1, sha2)
rugged.diff(sha1, sha2).size > 0 rugged.diff(sha1, sha2).size > 0
end end
...@@ -925,4 +959,8 @@ class Repository ...@@ -925,4 +959,8 @@ class Repository
def cache def cache
@cache ||= RepositoryCache.new(path_with_namespace) @cache ||= RepositoryCache.new(path_with_namespace)
end end
def licensee_project
@licensee_project ||= Licensee.project(path)
end
end end
...@@ -32,6 +32,7 @@ class Service < ActiveRecord::Base ...@@ -32,6 +32,7 @@ class Service < ActiveRecord::Base
default_value_for :tag_push_events, true default_value_for :tag_push_events, true
default_value_for :note_events, true default_value_for :note_events, true
default_value_for :build_events, true default_value_for :build_events, true
default_value_for :wiki_page_events, true
after_initialize :initialize_properties after_initialize :initialize_properties
...@@ -53,6 +54,7 @@ class Service < ActiveRecord::Base ...@@ -53,6 +54,7 @@ class Service < ActiveRecord::Base
scope :merge_request_hooks, -> { where(merge_requests_events: true, active: true) } scope :merge_request_hooks, -> { where(merge_requests_events: true, active: true) }
scope :note_hooks, -> { where(note_events: true, active: true) } scope :note_hooks, -> { where(note_events: true, active: true) }
scope :build_hooks, -> { where(build_events: true, active: true) } scope :build_hooks, -> { where(build_events: true, active: true) }
scope :wiki_page_hooks, -> { where(wiki_page_events: true, active: true) }
default_value_for :category, 'common' default_value_for :category, 'common'
...@@ -94,7 +96,7 @@ class Service < ActiveRecord::Base ...@@ -94,7 +96,7 @@ class Service < ActiveRecord::Base
end end
def supported_events def supported_events
%w(push tag_push issue merge_request) %w(push tag_push issue merge_request wiki_page)
end end
def execute(data) def execute(data)
......
...@@ -63,7 +63,6 @@ ...@@ -63,7 +63,6 @@
# #
require 'carrierwave/orm/activerecord' require 'carrierwave/orm/activerecord'
require 'file_size_validator'
class User < ActiveRecord::Base class User < ActiveRecord::Base
extend Gitlab::ConfigHelper extend Gitlab::ConfigHelper
......
...@@ -29,6 +29,10 @@ class WikiPage ...@@ -29,6 +29,10 @@ class WikiPage
# new Page values before writing to the Gollum repository. # new Page values before writing to the Gollum repository.
attr_accessor :attributes attr_accessor :attributes
def hook_attrs
attributes
end
def initialize(wiki, page = nil, persisted = false) def initialize(wiki, page = nil, persisted = false)
@wiki = wiki @wiki = wiki
@page = page @page = page
......
module Commits
class ChangeService < ::BaseService
class ValidationError < StandardError; end
class ChangeError < StandardError; end
def execute
@source_project = params[:source_project] || @project
@target_branch = params[:target_branch]
@commit = params[:commit]
@create_merge_request = params[:create_merge_request].present?
check_push_permissions unless @create_merge_request
commit
rescue Repository::CommitError, Gitlab::Git::Repository::InvalidBlobName, GitHooksService::PreReceiveError,
ValidationError, ChangeError => ex
error(ex.message)
end
def commit
raise NotImplementedError
end
private
def check_push_permissions
allowed = ::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(@target_branch)
unless allowed
raise ValidationError.new('You are not allowed to push into this branch')
end
true
end
def create_target_branch(new_branch)
# Temporary branch exists and contains the change commit
return success if repository.find_branch(new_branch)
result = CreateBranchService.new(@project, current_user)
.execute(new_branch, @target_branch, source_project: @source_project)
if result[:status] == :error
raise ChangeError, "There was an error creating the source branch: #{result[:message]}"
end
end
end
end
module Commits
class CherryPickService < ChangeService
def commit
cherry_pick_into = @create_merge_request ? @commit.cherry_pick_branch_name : @target_branch
cherry_pick_tree_id = repository.check_cherry_pick_content(@commit, @target_branch)
if cherry_pick_tree_id
create_target_branch(cherry_pick_into) if @create_merge_request
repository.cherry_pick(current_user, @commit, cherry_pick_into, cherry_pick_tree_id)
success
else
error_msg = "Sorry, we cannot cherry-pick this #{@commit.change_type_title} automatically.
It may have already been cherry-picked, or a more recent commit may have updated some of its content."
raise ChangeError, error_msg
end
end
end
end
module Commits module Commits
class RevertService < ::BaseService class RevertService < ChangeService
class ValidationError < StandardError; end
class ReversionError < StandardError; end
def execute
@source_project = params[:source_project] || @project
@target_branch = params[:target_branch]
@commit = params[:commit]
@create_merge_request = params[:create_merge_request].present?
check_push_permissions unless @create_merge_request
commit
rescue Repository::CommitError, Gitlab::Git::Repository::InvalidBlobName, GitHooksService::PreReceiveError,
ValidationError, ReversionError => ex
error(ex.message)
end
def commit def commit
revert_into = @create_merge_request ? @commit.revert_branch_name : @target_branch revert_into = @create_merge_request ? @commit.revert_branch_name : @target_branch
revert_tree_id = repository.check_revert_content(@commit, @target_branch) revert_tree_id = repository.check_revert_content(@commit, @target_branch)
...@@ -26,34 +10,10 @@ module Commits ...@@ -26,34 +10,10 @@ module Commits
repository.revert(current_user, @commit, revert_into, revert_tree_id) repository.revert(current_user, @commit, revert_into, revert_tree_id)
success success
else else
error_msg = "Sorry, we cannot revert this #{params[:revert_type_title]} automatically. error_msg = "Sorry, we cannot revert this #{@commit.change_type_title} automatically.
It may have already been reverted, or a more recent commit may have updated some of its content." It may have already been reverted, or a more recent commit may have updated some of its content."
raise ReversionError, error_msg raise ChangeError, error_msg
end end
end end
private
def create_target_branch(new_branch)
# Temporary branch exists and contains the revert commit
return success if repository.find_branch(new_branch)
result = CreateBranchService.new(@project, current_user)
.execute(new_branch, @target_branch, source_project: @source_project)
if result[:status] == :error
raise ReversionError, "There was an error creating the source branch: #{result[:message]}"
end
end
def check_push_permissions
allowed = ::Gitlab::GitAccess.new(current_user, project).can_push_to_branch?(@target_branch)
unless allowed
raise ValidationError.new('You are not allowed to push into this branch')
end
true
end
end end
end end
...@@ -73,6 +73,7 @@ class GitPushService < BaseService ...@@ -73,6 +73,7 @@ class GitPushService < BaseService
@project.update_merge_requests(params[:oldrev], params[:newrev], params[:ref], current_user) @project.update_merge_requests(params[:oldrev], params[:newrev], params[:ref], current_user)
EventCreateService.new.push(@project, current_user, build_push_data) EventCreateService.new.push(@project, current_user, build_push_data)
SystemHooksService.new.execute_hooks(build_push_data_system_hook.dup, :push_hooks)
@project.execute_hooks(build_push_data.dup, :push_hooks) @project.execute_hooks(build_push_data.dup, :push_hooks)
@project.execute_services(build_push_data.dup, :push_hooks) @project.execute_services(build_push_data.dup, :push_hooks)
CreateCommitBuildsService.new.execute(@project, current_user, build_push_data) CreateCommitBuildsService.new.execute(@project, current_user, build_push_data)
...@@ -138,6 +139,11 @@ class GitPushService < BaseService ...@@ -138,6 +139,11 @@ class GitPushService < BaseService
build(@project, current_user, params[:oldrev], params[:newrev], params[:ref], push_commits) build(@project, current_user, params[:oldrev], params[:newrev], params[:ref], push_commits)
end end
def build_push_data_system_hook
@push_data_system ||= Gitlab::PushDataBuilder.
build(@project, current_user, params[:oldrev], params[:newrev], params[:ref], [])
end
def push_to_existing_branch? def push_to_existing_branch?
# Return if this is not a push to a branch (e.g. new commits) # Return if this is not a push to a branch (e.g. new commits)
Gitlab::Git.branch_ref?(params[:ref]) && !Gitlab::Git.blank_ref?(params[:oldrev]) Gitlab::Git.branch_ref?(params[:ref]) && !Gitlab::Git.blank_ref?(params[:oldrev])
......
class GitTagPushService class GitTagPushService < BaseService
attr_accessor :project, :user, :push_data attr_accessor :push_data
def execute(project, user, oldrev, newrev, ref) def execute
project.repository.before_push_tag project.repository.before_push_tag
@project, @user = project, user @push_data = build_push_data
@push_data = build_push_data(oldrev, newrev, ref)
EventCreateService.new.push(project, user, @push_data) EventCreateService.new.push(project, current_user, @push_data)
SystemHooksService.new.execute_hooks(build_system_push_data.dup, :tag_push_hooks)
project.execute_hooks(@push_data.dup, :tag_push_hooks) project.execute_hooks(@push_data.dup, :tag_push_hooks)
project.execute_services(@push_data.dup, :tag_push_hooks) project.execute_services(@push_data.dup, :tag_push_hooks)
CreateCommitBuildsService.new.execute(project, @user, @push_data) CreateCommitBuildsService.new.execute(project, current_user, @push_data)
ProjectCacheWorker.perform_async(project.id) ProjectCacheWorker.perform_async(project.id)
true true
...@@ -18,14 +18,14 @@ class GitTagPushService ...@@ -18,14 +18,14 @@ class GitTagPushService
private private
def build_push_data(oldrev, newrev, ref) def build_push_data
commits = [] commits = []
message = nil message = nil
if !Gitlab::Git.blank_ref?(newrev) if !Gitlab::Git.blank_ref?(params[:newrev])
tag_name = Gitlab::Git.ref_name(ref) tag_name = Gitlab::Git.ref_name(params[:ref])
tag = project.repository.find_tag(tag_name) tag = project.repository.find_tag(tag_name)
if tag && tag.target == newrev if tag && tag.target == params[:newrev]
commit = project.commit(tag.target) commit = project.commit(tag.target)
commits = [commit].compact commits = [commit].compact
message = tag.message message = tag.message
...@@ -33,6 +33,11 @@ class GitTagPushService ...@@ -33,6 +33,11 @@ class GitTagPushService
end end
Gitlab::PushDataBuilder. Gitlab::PushDataBuilder.
build(project, user, oldrev, newrev, ref, commits, message) build(project, current_user, params[:oldrev], params[:newrev], params[:ref], commits, message)
end
def build_system_push_data
Gitlab::PushDataBuilder.
build(project, current_user, params[:oldrev], params[:newrev], params[:ref], [], '')
end end
end end
...@@ -3,17 +3,13 @@ class SystemHooksService ...@@ -3,17 +3,13 @@ class SystemHooksService
execute_hooks(build_event_data(model, event)) execute_hooks(build_event_data(model, event))
end end
private def execute_hooks(data, hooks_scope = :all)
SystemHook.send(hooks_scope).each do |hook|
def execute_hooks(data) hook.async_execute(data, 'system_hooks')
SystemHook.all.each do |sh|
async_execute_hook(sh, data, 'system_hooks')
end end
end end
def async_execute_hook(hook, data, hook_name) private
Sidekiq::Client.enqueue(SystemHookWorker, hook.id, data, hook_name)
end
def build_event_data(model, event) def build_event_data(model, event)
data = { data = {
......
module WikiPages
class BaseService < ::BaseService
def hook_data(page, action)
hook_data = {
object_kind: page.class.name.underscore,
user: current_user.hook_attrs,
project: @project.hook_attrs,
object_attributes: page.hook_attrs,
# DEPRECATED
repository: @project.hook_attrs.slice(:name, :url, :description, :homepage)
}
page_url = Gitlab::UrlBuilder.build(page)
hook_data[:object_attributes].merge!(url: page_url, action: action)
hook_data
end
private
def execute_hooks(page, action = 'create')
page_data = hook_data(page, action)
@project.execute_hooks(page_data, :wiki_page_hooks)
@project.execute_services(page_data, :wiki_page_hooks)
end
end
end
module WikiPages
class CreateService < WikiPages::BaseService
def execute
page = WikiPage.new(@project.wiki)
if page.create(@params)
execute_hooks(page, 'create')
end
page
end
end
end
module WikiPages
class UpdateService < WikiPages::BaseService
def execute(page)
if page.update(@params[:content], @params[:format], @params[:message])
execute_hooks(page, 'update')
end
page
end
end
end
...@@ -155,7 +155,11 @@ ...@@ -155,7 +155,11 @@
= f.label :shared_runners_enabled do = f.label :shared_runners_enabled do
= f.check_box :shared_runners_enabled = f.check_box :shared_runners_enabled
Enable shared runners for new projects Enable shared runners for new projects
.form-group
= f.label :shared_runners_text, class: 'control-label col-sm-2'
.col-sm-10
= f.text_area :shared_runners_text, class: 'form-control', rows: 4
.help-block Markdown enabled
.form-group .form-group
= f.label :max_artifacts_size, 'Maximum artifacts size (MB)', class: 'control-label col-sm-2' = f.label :max_artifacts_size, 'Maximum artifacts size (MB)', class: 'control-label col-sm-2'
.col-sm-10 .col-sm-10
...@@ -214,6 +218,13 @@ ...@@ -214,6 +218,13 @@
.help-block .help-block
The sampling interval in seconds. Sampled data includes memory usage, The sampling interval in seconds. Sampled data includes memory usage,
retained Ruby objects, file descriptors and so on. retained Ruby objects, file descriptors and so on.
.form-group
= f.label :metrics_packet_size, 'Metrics per packet', class: 'control-label col-sm-2'
.col-sm-10
= f.number_field :metrics_packet_size, class: 'form-control'
.help-block
The amount of points to store in a single UDP packet. More points
results in fewer but larger UDP packets being sent.
%fieldset %fieldset
%legend Spam and Anti-bot Protection %legend Spam and Anti-bot Protection
......
...@@ -16,6 +16,27 @@ ...@@ -16,6 +16,27 @@
= f.label :url, "URL:", class: 'control-label' = f.label :url, "URL:", class: 'control-label'
.col-sm-10 .col-sm-10
= f.text_field :url, class: "form-control" = f.text_field :url, class: "form-control"
.form-group
= f.label :url, "Trigger", class: 'control-label'
.col-sm-10.prepend-top-10
%div
System hook will be triggered on set of events like creating project
or adding ssh key. But you can also enable extra triggers like Push events.
%div.prepend-top-default
= f.check_box :push_events, class: 'pull-left'
.prepend-left-20
= f.label :push_events, class: 'list-label' do
%strong Push events
%p.light
This url will be triggered by a push to the repository
%div
= f.check_box :tag_push_events, class: 'pull-left'
.prepend-left-20
= f.label :tag_push_events, class: 'list-label' do
%strong Tag push events
%p.light
This url will be triggered when a new tag is pushed to the repository
.form-group .form-group
= f.label :enable_ssl_verification, "SSL verification", class: 'control-label checkbox' = f.label :enable_ssl_verification, "SSL verification", class: 'control-label checkbox'
.col-sm-10 .col-sm-10
...@@ -31,13 +52,16 @@ ...@@ -31,13 +52,16 @@
.panel.panel-default .panel.panel-default
.panel-heading .panel-heading
System hooks (#{@hooks.count}) System hooks (#{@hooks.count})
%ul.well-list %ul.content-list
- @hooks.each do |hook| - @hooks.each do |hook|
%li %li
.list-item-name .controls
%strong= hook.url
%p SSL Verification: #{hook.enable_ssl_verification ? "enabled" : "disabled"}
.pull-right
= link_to 'Test Hook', admin_hook_test_path(hook), class: "btn btn-sm" = link_to 'Test Hook', admin_hook_test_path(hook), class: "btn btn-sm"
= link_to 'Remove', admin_hook_path(hook), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-remove btn-sm" = link_to 'Remove', admin_hook_path(hook), data: { confirm: 'Are you sure?' }, method: :delete, class: "btn btn-remove btn-sm"
.monospace= hook.url
%div
- %w(push_events tag_push_events issues_events note_events merge_requests_events build_events).each do |trigger|
- if hook.send(trigger)
%span.label.label-gray= trigger.titleize
%span.label.label-gray SSL Verification: #{hook.enable_ssl_verification ? "enabled" : "disabled"}
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
- @already_added_projects.each do |project| - @already_added_projects.each do |project|
%tr{id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}"} %tr{id: "project_#{project.id}", class: "#{project_status_css_class(project.import_status)}"}
%td %td
= link_to project.import_source, "https://github.com/#{project.import_source}", target: "_blank" = github_project_link(project.import_source)
%td %td
= link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project] = link_to project.path_with_namespace, [project.namespace.becomes(Namespace), project]
%td.job-status %td.job-status
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
- @repos.each do |repo| - @repos.each do |repo|
%tr{id: "repo_#{repo.id}"} %tr{id: "repo_#{repo.id}"}
%td %td
= link_to repo.full_name, "https://github.com/#{repo.full_name}", target: "_blank" = github_project_link(repo.full_name)
%td.import-target %td.import-target
= repo.full_name = repo.full_name
%td.import-actions.job-status %td.import-actions.job-status
......
%p %p
= "Merge Request ##{@merge_request.iid} was closed by #{@updated_by.name}" = "Merge Request #{@merge_request.to_reference} was closed by #{@updated_by.name}"
= "Merge Request ##{@merge_request.iid} was closed by #{@updated_by.name}" = "Merge Request #{@merge_request.to_reference} was closed by #{@updated_by.name}"
Merge Request url: #{namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request)} Merge Request url: #{namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request)}
......
%p %p
= "Merge Request ##{@merge_request.iid} was #{@mr_status} by #{@updated_by.name}" = "Merge Request #{@merge_request.to_reference} was #{@mr_status} by #{@updated_by.name}"
= "Merge Request ##{@merge_request.iid} was #{@mr_status} by #{@updated_by.name}" = "Merge Request #{@merge_request.to_reference} was #{@mr_status} by #{@updated_by.name}"
Merge Request url: #{namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request)} Merge Request url: #{namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request)}
......
%p %p
= "Merge Request ##{@merge_request.iid} was merged" = "Merge Request #{@merge_request.to_reference} was merged"
= "Merge Request ##{@merge_request.iid} was merged" = "Merge Request #{@merge_request.to_reference} was merged"
Merge Request url: #{namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request)} Merge Request url: #{namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request)}
......
New Merge Request #<%= @merge_request.iid %> New Merge Request <%= @merge_request.to_reference %>
<%= url_for(namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request)) %> <%= url_for(namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request)) %>
......
New comment for Merge Request <%= @merge_request.iid %> New comment for Merge Request <%= @merge_request.to_reference %>
<%= url_for(namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request, anchor: "note_#{@note.id}")) %> <%= url_for(namespace_project_merge_request_url(@merge_request.target_project.namespace, @merge_request.target_project, @merge_request, anchor: "note_#{@note.id}")) %>
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
- else - else
.gray-content-block.second-block.center .gray-content-block.second-block.center
%h3.page-title %h3.page-title
This project does not have README yet This project does not have a README yet
- if can?(current_user, :push_code, @project) - if can?(current_user, :push_code, @project)
%p %p
A A
...@@ -18,5 +18,5 @@ ...@@ -18,5 +18,5 @@
distributed with computer software, forming part of its documentation. distributed with computer software, forming part of its documentation.
%p %p
We recommend you to We recommend you to
= link_to "add README", new_readme_path, class: 'underlined-link' = link_to "add a README", new_readme_path, class: 'underlined-link'
file to the repository and GitLab will render it here instead of this message. file to the repository and GitLab will render it here instead of this message.
...@@ -13,6 +13,10 @@ ...@@ -13,6 +13,10 @@
required: true, class: 'form-control new-file-name' required: true, class: 'form-control new-file-name'
.pull-right .pull-right
.license-selector.js-license-selector.hide
= select_tag :license_type, grouped_options_for_select(licenses_for_select, @project.repository.license_key), include_blank: true, class: 'select2 license-select', data: {placeholder: 'Choose a license template', project: @project.name, fullname: @project.namespace.human_name}
.encoding-selector
= select_tag :encoding, options_for_select([ "base64", "text" ], "text"), class: 'select2' = select_tag :encoding, options_for_select([ "base64", "text" ], "text"), class: 'select2'
.file-content.code .file-content.code
......
...@@ -14,5 +14,5 @@ ...@@ -14,5 +14,5 @@
cancel_path: namespace_project_tree_path(@project.namespace, @project, @id) cancel_path: namespace_project_tree_path(@project.namespace, @project, @id)
:javascript :javascript
blob = new NewBlob(gon.relative_url_root + "#{Gitlab::Application.config.assets.prefix}", null) blob = new EditBlob(gon.relative_url_root + "#{Gitlab::Application.config.assets.prefix}")
new NewCommitForm($('.js-new-blob-form')) new NewCommitForm($('.js-new-blob-form'))
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
- merge_request = @build.merge_request - merge_request = @build.merge_request
- if merge_request - if merge_request
via via
= link_to "merge request ##{merge_request.iid}", merge_request_path(merge_request) = link_to "merge request #{merge_request.to_reference}", merge_request_path(merge_request)
#up-build-trace #up-build-trace
- builds = @build.commit.matrix_builds(@build) - builds = @build.commit.matrix_builds(@build)
...@@ -110,7 +110,7 @@ ...@@ -110,7 +110,7 @@
= icon('folder-open') = icon('folder-open')
Browse Browse
.build-widget .build-widget.build-controls
%h4.title %h4.title
Build ##{@build.id} Build ##{@build.id}
- if can?(current_user, :update_build, @project) - if can?(current_user, :update_build, @project)
...@@ -127,6 +127,9 @@ ...@@ -127,6 +127,9 @@
data: { confirm: 'Are you sure you want to erase this build?' } do data: { confirm: 'Are you sure you want to erase this build?' } do
= icon('eraser') = icon('eraser')
Erase Erase
- if @build.has_trace?
= link_to 'Raw', raw_namespace_project_build_path(@project.namespace, @project, @build),
class: 'btn btn-sm btn-success', target: '_blank'
.clearfix .clearfix
- if @build.duration - if @build.duration
......
#modal-revert-commit.modal - case type.to_s
- when 'revert'
- label = 'Revert'
- target_label = 'Revert in branch'
- when 'cherry-pick'
- label = 'Cherry-pick'
- target_label = 'Pick into branch'
.modal{id: "modal-#{type}-commit"}
.modal-dialog .modal-dialog
.modal-content .modal-content
.modal-header .modal-header
%a.close{href: "#", "data-dismiss" => "modal"} × %a.close{href: "#", "data-dismiss" => "modal"} ×
%h3.page-title== Revert this #{revert_commit_type(commit)} %h3.page-title== #{label} this #{commit.change_type_title}
.modal-body .modal-body
= form_tag revert_namespace_project_commit_path(@project.namespace, @project, commit.id), method: :post, remote: false, class: 'form-horizontal js-create-dir-form js-requires-input' do = form_tag send("#{type.underscore}_namespace_project_commit_path", @project.namespace, @project, commit.id), method: :post, remote: false, class: 'form-horizontal js-#{type}-form js-requires-input' do
.form-group.branch .form-group.branch
= label_tag 'target_branch', 'Revert in branch', class: 'control-label' = label_tag 'target_branch', target_label, class: 'control-label'
.col-sm-10 .col-sm-10
= select_tag "target_branch", grouped_options_refs, class: "select2 select2-sm js-target-branch" = select_tag "target_branch", grouped_options_refs, class: "select2 select2-sm js-target-branch"
- if can?(current_user, :push_code, @project) - if can?(current_user, :push_code, @project)
...@@ -20,7 +28,7 @@ ...@@ -20,7 +28,7 @@
- else - else
= hidden_field_tag 'create_merge_request', 1 = hidden_field_tag 'create_merge_request', 1
.form-actions .form-actions
= submit_tag "Revert", class: 'btn btn-create' = submit_tag label, class: 'btn btn-create'
= link_to "Cancel", '#', class: "btn btn-cancel", "data-dismiss" => "modal" = link_to "Cancel", '#', class: "btn btn-cancel", "data-dismiss" => "modal"
- unless can?(current_user, :push_code, @project) - unless can?(current_user, :push_code, @project)
...@@ -28,4 +36,4 @@ ...@@ -28,4 +36,4 @@
= commit_in_fork_help = commit_in_fork_help
:javascript :javascript
new NewCommitForm($('.js-create-dir-form')) new NewCommitForm($('.js-#{type}-form'))
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
Browse Files Browse Files
- unless @commit.has_been_reverted?(current_user) - unless @commit.has_been_reverted?(current_user)
= revert_commit_link(@commit, namespace_project_commit_path(@project.namespace, @project, @commit.id)) = revert_commit_link(@commit, namespace_project_commit_path(@project.namespace, @project, @commit.id))
= cherry_pick_commit_link(@commit, namespace_project_commit_path(@project.namespace, @project, @commit.id))
%div %div
%p %p
......
...@@ -13,4 +13,5 @@ ...@@ -13,4 +13,5 @@
diff_refs: @diff_refs diff_refs: @diff_refs
= render "projects/notes/notes_with_form" = render "projects/notes/notes_with_form"
- if can_collaborate_with_project? - if can_collaborate_with_project?
= render "projects/commit/revert", commit: @commit, title: @commit.title - %w(revert cherry-pick).each do |type|
= render "projects/commit/change", type: type, commit: @commit, title: @commit.title
...@@ -31,5 +31,5 @@ ...@@ -31,5 +31,5 @@
by by
= commit_author_link(commit, avatar: true, size: 24) = commit_author_link(commit, avatar: true, size: 24)
.committed_ago .committed_ago
#{time_ago_with_tooltip(commit.committed_date, skip_js: true)} &nbsp; #{time_ago_with_tooltip(commit.committed_date)} &nbsp;
= link_to_browse_code(project, commit) = link_to_browse_code(project, commit)
...@@ -14,8 +14,10 @@ ...@@ -14,8 +14,10 @@
%p %p
If you already have files you can push them using command line instructions below. If you already have files you can push them using command line instructions below.
%p %p
Otherwise you can start with Otherwise you can start with adding a
= link_to "adding README", new_readme_path, class: 'underlined-link' = link_to "README", new_readme_path, class: 'underlined-link'
or a
= link_to "LICENSE", add_special_file_path(@project, file_name: 'LICENSE'), class: 'underlined-link'
file to this project. file to this project.
- if can?(current_user, :push_code, @project) - if can?(current_user, :push_code, @project)
......
...@@ -74,16 +74,15 @@ ...@@ -74,16 +74,15 @@
.panel.panel-default .panel.panel-default
.panel-heading .panel-heading
Webhooks (#{@hooks.count}) Webhooks (#{@hooks.count})
%ul.well-list %ul.content-list
- @hooks.each do |hook| - @hooks.each do |hook|
%li %li
.pull-right .controls
= link_to 'Test Hook', test_namespace_project_hook_path(@project.namespace, @project, hook), class: "btn btn-sm btn-grouped" = link_to 'Test Hook', test_namespace_project_hook_path(@project.namespace, @project, hook), class: "btn btn-sm btn-grouped"
= link_to 'Remove', namespace_project_hook_path(@project.namespace, @project, hook), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn btn-remove btn-sm btn-grouped" = link_to 'Remove', namespace_project_hook_path(@project.namespace, @project, hook), data: { confirm: 'Are you sure?'}, method: :delete, class: "btn btn-remove btn-sm btn-grouped"
.clearfix .monospace= hook.url
%span.monospace= hook.url %div
%p
- %w(push_events tag_push_events issues_events note_events merge_requests_events build_events).each do |trigger| - %w(push_events tag_push_events issues_events note_events merge_requests_events build_events).each do |trigger|
- if hook.send(trigger) - if hook.send(trigger)
%span.label.label-gray= trigger.titleize %span.label.label-gray= trigger.titleize
SSL Verification: #{hook.enable_ssl_verification ? "enabled" : "disabled"} %span.label.label-gray SSL Verification: #{hook.enable_ssl_verification ? "enabled" : "disabled"}
...@@ -86,8 +86,10 @@ ...@@ -86,8 +86,10 @@
= spinner = spinner
= render 'shared/issuable/sidebar', issuable: @merge_request = render 'shared/issuable/sidebar', issuable: @merge_request
- if @merge_request.can_be_reverted? - if @merge_request.can_be_reverted?(current_user)
= render "projects/commit/revert", commit: @merge_request.merge_commit, title: @merge_request.title = render "projects/commit/change", type: 'revert', commit: @merge_request.merge_commit, title: @merge_request.title
- if @merge_request.can_be_cherry_picked?
= render "projects/commit/change", type: 'cherry-pick', commit: @merge_request.merge_commit, title: @merge_request.title
:javascript :javascript
var merge_request; var merge_request;
......
- page_title "Edit", "#{@merge_request.title} (##{@merge_request.iid})", "Merge Requests" - page_title "Edit", "#{@merge_request.title} (#{@merge_request.to_reference}", "Merge Requests"
= render "header_title" = render "header_title"
%h3.page-title %h3.page-title
Edit Merge Request ##{@merge_request.iid} Edit Merge Request #{@merge_request.to_reference}
%hr %hr
= render 'form' = render 'form'
- page_title "#{@merge_request.title} (##{@merge_request.iid})", "Merge Requests" - page_title "#{@merge_request.title} (#{merge_request.to_reference}", "Merge Requests"
= render "header_title" = render "header_title"
.merge-request .merge-request
......
...@@ -44,3 +44,8 @@ ...@@ -44,3 +44,8 @@
$('.remove_source_branch_in_progress').hide(); $('.remove_source_branch_in_progress').hide();
$('.remove_source_branch_widget.failed').show(); $('.remove_source_branch_widget.failed').show();
}); });
- else
%p
The changes were merged into
#{link_to @merge_request.target_branch, namespace_project_commits_path(@project.namespace, @project, @merge_request.target_branch), class: "label-branch"}.
= render 'projects/merge_requests/widget/merged_buttons'
- source_branch_exists = local_assigns.fetch(:source_branch_exists, false) - can_remove_source_branch = local_assigns.fetch(:source_branch_exists, false) && @merge_request.can_remove_source_branch?(current_user)
- mr_can_be_reverted = @merge_request.can_be_reverted? - mr_can_be_reverted = @merge_request.can_be_reverted?(current_user)
- mr_can_be_cherry_picked = @merge_request.can_be_cherry_picked?
- if source_branch_exists || mr_can_be_reverted - if can_remove_source_branch || mr_can_be_reverted || mr_can_be_cherry_picked
.btn-group .btn-group
- if source_branch_exists - if can_remove_source_branch
= link_to namespace_project_branch_path(@merge_request.source_project.namespace, @merge_request.source_project, @merge_request.source_branch), remote: true, method: :delete, class: "btn btn-default btn-grouped btn-sm remove_source_branch" do = link_to namespace_project_branch_path(@merge_request.source_project.namespace, @merge_request.source_project, @merge_request.source_branch), remote: true, method: :delete, class: "btn btn-default btn-grouped btn-sm remove_source_branch" do
= icon('trash-o') = icon('trash-o')
Remove Source Branch Remove Source Branch
- if mr_can_be_reverted - if mr_can_be_reverted
= revert_commit_link(@merge_request.merge_commit, namespace_project_merge_request_path(@project.namespace, @project, @merge_request), btn_class: 'sm') = revert_commit_link(@merge_request.merge_commit, namespace_project_merge_request_path(@project.namespace, @project, @merge_request), btn_class: 'sm')
- if mr_can_be_cherry_picked
= cherry_pick_commit_link(@merge_request.merge_commit, namespace_project_merge_request_path(@project.namespace, @project, @merge_request), btn_class: 'sm')
...@@ -8,7 +8,9 @@ ...@@ -8,7 +8,9 @@
.note-header .note-header
= link_to_member(note.project, note.author, avatar: false) = link_to_member(note.project, note.author, avatar: false)
.inline.note-headline-light .inline.note-headline-light
= "#{note.author.to_reference} commented" = "#{note.author.to_reference}"
- if !note.system
commented
%a{ href: "##{dom_id(note)}" } %a{ href: "##{dom_id(note)}" }
= time_ago_with_tooltip(note.created_at, placement: 'bottom', html_class: 'note-created-ago') = time_ago_with_tooltip(note.created_at, placement: 'bottom', html_class: 'note-created-ago')
.note-actions .note-actions
......
%h3 Shared runners %h3 Shared runners
.bs-callout.bs-callout-warning .bs-callout.bs-callout-warning.shared-runners-description
GitLab Runners do not offer secure isolation between projects that they do builds for. You are TRUSTING all GitLab users who can push code to project A, B or C to run shell scripts on the machine hosting runner X. - if shared_runners_text.present?
= markdown(shared_runners_text, pipeline: 'plain_markdown')
- else
Shared runners execute code of different projects on the same Runner unless you configure GitLab Runner Autoscale with MaxBuilds 1 (which it is on GitLab.com).
%hr %hr
- if @project.shared_runners_enabled? - if @project.shared_runners_enabled?
= link_to toggle_shared_runners_namespace_project_runners_path(@project.namespace, @project), class: 'btn btn-warning', method: :post do = link_to toggle_shared_runners_namespace_project_runners_path(@project.namespace, @project), class: 'btn btn-warning', method: :post do
......
...@@ -36,9 +36,9 @@ ...@@ -36,9 +36,9 @@
%li %li
= link_to 'Changelog', changelog_path(@project) = link_to 'Changelog', changelog_path(@project)
- if @repository.license - if @repository.license_blob
%li %li
= link_to 'License', license_path(@project) = link_to license_short_name(@project), license_path(@project)
- if @repository.contribution_guide - if @repository.contribution_guide
%li %li
...@@ -47,15 +47,15 @@ ...@@ -47,15 +47,15 @@
- if current_user && can_push_branch?(@project, @project.default_branch) - if current_user && can_push_branch?(@project, @project.default_branch)
- unless @repository.changelog - unless @repository.changelog
%li.missing %li.missing
= link_to add_changelog_path(@project) do = link_to add_special_file_path(@project, file_name: 'CHANGELOG') do
Add Changelog Add Changelog
- unless @repository.license - unless @repository.license_blob
%li.missing %li.missing
= link_to add_license_path(@project) do = link_to add_special_file_path(@project, file_name: 'LICENSE') do
Add License Add License
- unless @repository.contribution_guide - unless @repository.contribution_guide
%li.missing %li.missing
= link_to add_contribution_guide_path(@project) do = link_to add_special_file_path(@project, file_name: 'CONTRIBUTING.md', commit_message: 'Add contribution guide') do
Add Contribution guide Add Contribution guide
- if @repository.commit - if @repository.commit
......
...@@ -3,3 +3,6 @@ ...@@ -3,3 +3,6 @@
%p %p
= link_to "See the affected projects in the GitLab admin panel", admin_namespaces_projects_url(last_repository_check_failed: 1) = link_to "See the affected projects in the GitLab admin panel", admin_namespaces_projects_url(last_repository_check_failed: 1)
%p
You are receiving this message because you are a GitLab administrator for #{Gitlab.config.gitlab.url}.
#{@message}. #{@message}.
\ \
View details: #{admin_namespaces_projects_url(last_repository_check_failed: 1)} View details: #{admin_namespaces_projects_url(last_repository_check_failed: 1)}
You are receiving this message because you are a GitLab administrator
for #{Gitlab.config.gitlab.url}.
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
%h4 %h4
= link_to [merge_request.target_project.namespace.becomes(Namespace), merge_request.target_project, merge_request] do = link_to [merge_request.target_project.namespace.becomes(Namespace), merge_request.target_project, merge_request] do
%span.term.str-truncated= merge_request.title %span.term.str-truncated= merge_request.title
.pull-right ##{merge_request.iid} .pull-right #{merge_request.to_reference}
- if merge_request.description.present? - if merge_request.description.present?
.description.term .description.term
= preserve do = preserve do
......
...@@ -62,6 +62,14 @@ ...@@ -62,6 +62,14 @@
%strong Build events %strong Build events
%p.light %p.light
This url will be triggered when a build status changes This url will be triggered when a build status changes
- if @service.supported_events.include?("wiki_page")
%div
= form.check_box :wiki_page_events, class: 'pull-left'
.prepend-left-20
= form.label :wiki_page_events, class: 'list-label' do
%strong Wiki Page events
%p.light
This url will be triggered when a wiki page is created/updated
- @service.fields.each do |field| - @service.fields.each do |field|
......
...@@ -75,6 +75,7 @@ ...@@ -75,6 +75,7 @@
= f.label :label_ids, "Labels", class: 'control-label' = f.label :label_ids, "Labels", class: 'control-label'
.col-sm-10{ class: ('issuable-form-padding-top' if !has_labels) } .col-sm-10{ class: ('issuable-form-padding-top' if !has_labels) }
- if has_labels - if has_labels
.issuable-form-select-holder
= f.collection_select :label_ids, issuable.project.labels.all, :id, :name, = f.collection_select :label_ids, issuable.project.labels.all, :id, :name,
{ selected: issuable.label_ids }, multiple: true, class: 'select2', data: { placeholder: "Select labels" } { selected: issuable.label_ids }, multiple: true, class: 'select2', data: { placeholder: "Select labels" }
- else - else
...@@ -88,6 +89,7 @@ ...@@ -88,6 +89,7 @@
.form-group .form-group
= label_tag :move_to_project_id, 'Move', class: 'control-label' = label_tag :move_to_project_id, 'Move', class: 'control-label'
.col-sm-10 .col-sm-10
.issuable-form-select-holder
- projects = project_options(issuable, current_user, ability: :admin_issue) - projects = project_options(issuable, current_user, ability: :admin_issue)
= select_tag(:move_to_project_id, projects, include_blank: true, = select_tag(:move_to_project_id, projects, include_blank: true,
class: 'select2', data: { placeholder: 'Select project' }) class: 'select2', data: { placeholder: 'Select project' })
...@@ -102,13 +104,15 @@ ...@@ -102,13 +104,15 @@
.form-group .form-group
= f.label :source_branch, class: 'control-label' = f.label :source_branch, class: 'control-label'
.col-sm-10 .col-sm-10
.issuable-form-select-holder
= f.select(:source_branch, [@merge_request.source_branch], { }, { class: 'source_branch select2 span2', disabled: true }) = f.select(:source_branch, [@merge_request.source_branch], { }, { class: 'source_branch select2 span2', disabled: true })
.form-group .form-group
= f.label :target_branch, class: 'control-label' = f.label :target_branch, class: 'control-label'
.col-sm-10 .col-sm-10
.issuable-form-select-holder
= f.select(:target_branch, @merge_request.target_branches, { include_blank: true }, { class: 'target_branch select2 span2', disabled: @merge_request.new_record?, data: {placeholder: "Select branch"} }) = f.select(:target_branch, @merge_request.target_branches, { include_blank: true }, { class: 'target_branch select2 span2', disabled: @merge_request.new_record?, data: {placeholder: "Select branch"} })
- if @merge_request.new_record? - if @merge_request.new_record?
%p.help-block &nbsp;
= link_to 'Change branches', mr_change_branches_path(@merge_request) = link_to 'Change branches', mr_change_branches_path(@merge_request)
- is_footer = !(issuable.is_a?(MergeRequest) && issuable.new_record?) - is_footer = !(issuable.is_a?(MergeRequest) && issuable.new_record?)
......
...@@ -118,6 +118,7 @@ ...@@ -118,6 +118,7 @@
Manage labels Manage labels
- else - else
View labels View labels
= dropdown_loading
= render "shared/issuable/participants", participants: issuable.participants(current_user) = render "shared/issuable/participants", participants: issuable.participants(current_user)
- if current_user - if current_user
...@@ -150,6 +151,6 @@ ...@@ -150,6 +151,6 @@
:javascript :javascript
new MilestoneSelect('{"namespace":"#{@project.namespace.path}","path":"#{@project.path}"}'); new MilestoneSelect('{"namespace":"#{@project.namespace.path}","path":"#{@project.path}"}');
new LabelsSelect(); new LabelsSelect();
new IssuableContext('#{current_user.to_json(only: [:username, :id, :name])}'); new IssuableContext('#{escape_javascript(current_user.to_json(only: [:username, :id, :name]))}');
new Subscription('.subscription') new Subscription('.subscription')
new Sidebar(); new Sidebar();
...@@ -23,5 +23,5 @@ ...@@ -23,5 +23,5 @@
- if assignee - if assignee
= link_to polymorphic_path(base_url_args, { milestone_title: @milestone.title, assignee_id: issuable.assignee_id, state: 'all' }), = link_to polymorphic_path(base_url_args, { milestone_title: @milestone.title, assignee_id: issuable.assignee_id, state: 'all' }),
class: 'has-tooltip', data: { 'original-title' => "Assigned to #{sanitize(assignee.name)}", container: 'body' } do class: 'has-tooltip', title: "Assigned to #{assignee.name}", data: { container: 'body' } do
- image_tag(avatar_icon(issuable.assignee, 16), class: "avatar s16", alt: '') - image_tag(avatar_icon(issuable.assignee, 16), class: "avatar s16", alt: '')
...@@ -6,8 +6,6 @@ ...@@ -6,8 +6,6 @@
= content_for :meta_tags do = content_for :meta_tags do
= auto_discovery_link_tag(:atom, user_url(@user, format: :atom), title: "#{@user.name} activity") = auto_discovery_link_tag(:atom, user_url(@user, format: :atom), title: "#{@user.name} activity")
= render 'shared/show_aside'
.user-profile .user-profile
.cover-block .cover-block
.cover-controls .cover-controls
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment