Merge branch 'master' into issue_3945
This commit is contained in:
commit
c23ca0b0b5
|
|
@ -8,7 +8,7 @@ before_script:
|
||||||
- touch log/application.log
|
- touch log/application.log
|
||||||
- touch log/test.log
|
- touch log/test.log
|
||||||
- bundle install --without postgres production --jobs $(nproc) "${FLAGS[@]}"
|
- bundle install --without postgres production --jobs $(nproc) "${FLAGS[@]}"
|
||||||
- bundle exec rake db:reset db:create RAILS_ENV=test
|
- RAILS_ENV=test bundle exec rake db:drop db:create db:schema:load db:migrate
|
||||||
|
|
||||||
spec:feature:
|
spec:feature:
|
||||||
script:
|
script:
|
||||||
|
|
@ -118,7 +118,7 @@ flay:
|
||||||
- mysql
|
- mysql
|
||||||
|
|
||||||
bundler:audit:
|
bundler:audit:
|
||||||
script:
|
script:
|
||||||
- "bundle exec bundle-audit update"
|
- "bundle exec bundle-audit update"
|
||||||
- "bundle exec bundle-audit check"
|
- "bundle exec bundle-audit check"
|
||||||
tags:
|
tags:
|
||||||
|
|
|
||||||
26
CHANGELOG
26
CHANGELOG
|
|
@ -1,15 +1,18 @@
|
||||||
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.5.0 (unreleased)
|
v 8.5.0 (unreleased)
|
||||||
- Remove gray background from layout in UI
|
- Add "visibility" flag to GET /projects api endpoint
|
||||||
|
|
||||||
v 8.4.0 (unreleased)
|
v 8.4.0 (unreleased)
|
||||||
|
- Allow LDAP users to change their email if it was not set by the LDAP server
|
||||||
|
- Ensure Gravatar host looks like an actual host
|
||||||
|
- Consider re-assign as a mention from a notification point of view
|
||||||
- Add pagination headers to already paginated API resources
|
- Add pagination headers to already paginated API resources
|
||||||
- Properly generate diff of orphan commits, like the first commit in a repository
|
- Properly generate diff of orphan commits, like the first commit in a repository
|
||||||
- Improve the consistency of commit titles, branch names, tag names, issue/MR titles, on their respective project pages
|
- Improve the consistency of commit titles, branch names, tag names, issue/MR titles, on their respective project pages
|
||||||
- Autocomplete data is now always loaded, instead of when focusing a comment text area (Yorick Peterse)
|
- Autocomplete data is now always loaded, instead of when focusing a comment text area
|
||||||
- Improved performance of finding issues for an entire group (Yorick Peterse)
|
- Improved performance of finding issues for an entire group
|
||||||
- Added custom application performance measuring system powered by InfluxDB (Yorick Peterse)
|
- Added custom application performance measuring system powered by InfluxDB
|
||||||
- Bump fog to 1.36.0 (Stan Hu)
|
- Bump fog to 1.36.0 (Stan Hu)
|
||||||
- Add user's last used IP addresses to admin page (Stan Hu)
|
- Add user's last used IP addresses to admin page (Stan Hu)
|
||||||
- Add housekeeping function to project settings page
|
- Add housekeeping function to project settings page
|
||||||
|
|
@ -19,8 +22,11 @@ v 8.4.0 (unreleased)
|
||||||
- Fix missing date of month in network graph when commits span a month (Stan Hu)
|
- Fix missing date of month in network graph when commits span a month (Stan Hu)
|
||||||
- Expire view caches when application settings change (e.g. Gravatar disabled) (Stan Hu)
|
- Expire view caches when application settings change (e.g. Gravatar disabled) (Stan Hu)
|
||||||
- Don't notify users twice if they are both project watchers and subscribers (Stan Hu)
|
- Don't notify users twice if they are both project watchers and subscribers (Stan Hu)
|
||||||
|
- Remove gray background from layout in UI
|
||||||
|
- Fix signup for OAuth providers that don't provide a name
|
||||||
- Implement new UI for group page
|
- Implement new UI for group page
|
||||||
- Implement search inside emoji picker
|
- Implement search inside emoji picker
|
||||||
|
- Let the CI runner know about builds that this build depends on
|
||||||
- Add API support for looking up a user by username (Stan Hu)
|
- Add API support for looking up a user by username (Stan Hu)
|
||||||
- Add project permissions to all project API endpoints (Stan Hu)
|
- Add project permissions to all project API endpoints (Stan Hu)
|
||||||
- Link to milestone in "Milestone changed" system note
|
- Link to milestone in "Milestone changed" system note
|
||||||
|
|
@ -56,10 +62,18 @@ v 8.4.0 (unreleased)
|
||||||
- Allow broadcast messages to be edited
|
- Allow broadcast messages to be edited
|
||||||
- Autosize Markdown textareas
|
- Autosize Markdown textareas
|
||||||
- Import GitHub wiki into GitLab
|
- Import GitHub wiki into GitLab
|
||||||
|
- Add reporters ability to download and browse build artifacts (Andrew Johnson)
|
||||||
|
- Autofill referring url in message box when reporting user abuse.
|
||||||
|
- Remove leading comma on award emoji when the user is the first to award the emoji (Zeger-Jan van de Weg)
|
||||||
|
- Add build artifacts browser
|
||||||
|
- Improve UX in builds artifacts browser
|
||||||
|
- Increase default size of `data` column in `events` table when using MySQL
|
||||||
|
- Expose button to CI Lint tool on project builds page
|
||||||
|
- Fix: Creator should be added as a master of the project on creation
|
||||||
|
- Added X-GitLab-... headers to emails from CI and Email On Push services (Anton Baklanov)
|
||||||
|
|
||||||
v 8.3.4
|
v 8.3.4
|
||||||
- Use gitlab-workhorse 0.5.4 (fixes API routing bug)
|
- Use gitlab-workhorse 0.5.4 (fixes API routing bug)
|
||||||
- Add build artifacts browser
|
|
||||||
|
|
||||||
v 8.3.3
|
v 8.3.3
|
||||||
- Preserve CE behavior with JIRA integration by only calling API if URL is set
|
- Preserve CE behavior with JIRA integration by only calling API if URL is set
|
||||||
|
|
@ -107,6 +121,7 @@ v 8.3.0
|
||||||
- Fix: Assignee selector is empty when 'Unassigned' is selected (Jose Corcuera)
|
- Fix: Assignee selector is empty when 'Unassigned' is selected (Jose Corcuera)
|
||||||
- Add rake tasks for git repository maintainance (Zeger-Jan van de Weg)
|
- Add rake tasks for git repository maintainance (Zeger-Jan van de Weg)
|
||||||
- Fix 500 error when update group member permission
|
- Fix 500 error when update group member permission
|
||||||
|
- Fix: As an admin, cannot add oneself as a member to a group/project
|
||||||
- Trim leading and trailing whitespace of milestone and issueable titles (Jose Corcuera)
|
- Trim leading and trailing whitespace of milestone and issueable titles (Jose Corcuera)
|
||||||
- Recognize issue/MR/snippet/commit links as references
|
- Recognize issue/MR/snippet/commit links as references
|
||||||
- Backport JIRA features from EE to CE
|
- Backport JIRA features from EE to CE
|
||||||
|
|
@ -168,7 +183,6 @@ v 8.2.2
|
||||||
- Fix Error 500 when viewing user's personal projects from admin page (Stan Hu)
|
- Fix Error 500 when viewing user's personal projects from admin page (Stan Hu)
|
||||||
- Fix: Raw private snippets access workflow
|
- Fix: Raw private snippets access workflow
|
||||||
- Prevent "413 Request entity too large" errors when pushing large files with LFS
|
- Prevent "413 Request entity too large" errors when pushing large files with LFS
|
||||||
- Fix: As an admin, cannot add oneself as a member to a group/project
|
|
||||||
- Fix invalid links within projects dashboard header
|
- Fix invalid links within projects dashboard header
|
||||||
- Make current user the first user in assignee dropdown in issues detail page (Stan Hu)
|
- Make current user the first user in assignee dropdown in issues detail page (Stan Hu)
|
||||||
- Fix: duplicate email notifications on issue comments
|
- Fix: duplicate email notifications on issue comments
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
0.5.4
|
0.6.0
|
||||||
|
|
|
||||||
2
Gemfile
2
Gemfile
|
|
@ -18,7 +18,7 @@ gem "mysql2", '~> 0.3.16', group: :mysql
|
||||||
gem "pg", '~> 0.18.2', group: :postgres
|
gem "pg", '~> 0.18.2', group: :postgres
|
||||||
|
|
||||||
# Authentication libraries
|
# Authentication libraries
|
||||||
gem 'devise', '~> 3.5.3'
|
gem 'devise', '~> 3.5.4'
|
||||||
gem 'devise-async', '~> 0.9.0'
|
gem 'devise-async', '~> 0.9.0'
|
||||||
gem 'doorkeeper', '~> 2.2.0'
|
gem 'doorkeeper', '~> 2.2.0'
|
||||||
gem 'omniauth', '~> 1.2.2'
|
gem 'omniauth', '~> 1.2.2'
|
||||||
|
|
|
||||||
10
Gemfile.lock
10
Gemfile.lock
|
|
@ -157,7 +157,7 @@ GEM
|
||||||
activerecord (>= 3.2.0, < 5.0)
|
activerecord (>= 3.2.0, < 5.0)
|
||||||
descendants_tracker (0.0.4)
|
descendants_tracker (0.0.4)
|
||||||
thread_safe (~> 0.3, >= 0.3.1)
|
thread_safe (~> 0.3, >= 0.3.1)
|
||||||
devise (3.5.3)
|
devise (3.5.4)
|
||||||
bcrypt (~> 3.0)
|
bcrypt (~> 3.0)
|
||||||
orm_adapter (~> 0.1)
|
orm_adapter (~> 0.1)
|
||||||
railties (>= 3.2.6, < 5)
|
railties (>= 3.2.6, < 5)
|
||||||
|
|
@ -614,7 +614,7 @@ GEM
|
||||||
thor (>= 0.18.1, < 2.0)
|
thor (>= 0.18.1, < 2.0)
|
||||||
rainbow (2.0.0)
|
rainbow (2.0.0)
|
||||||
raindrops (0.15.0)
|
raindrops (0.15.0)
|
||||||
rake (10.4.2)
|
rake (10.5.0)
|
||||||
raphael-rails (2.1.2)
|
raphael-rails (2.1.2)
|
||||||
rb-fsevent (0.9.6)
|
rb-fsevent (0.9.6)
|
||||||
rb-inotify (0.9.5)
|
rb-inotify (0.9.5)
|
||||||
|
|
@ -648,8 +648,8 @@ GEM
|
||||||
request_store (1.2.1)
|
request_store (1.2.1)
|
||||||
rerun (0.11.0)
|
rerun (0.11.0)
|
||||||
listen (~> 3.0)
|
listen (~> 3.0)
|
||||||
responders (2.1.0)
|
responders (2.1.1)
|
||||||
railties (>= 4.2.0, < 5)
|
railties (>= 4.2.0, < 5.1)
|
||||||
rest-client (1.8.0)
|
rest-client (1.8.0)
|
||||||
http-cookie (>= 1.0.2, < 2.0)
|
http-cookie (>= 1.0.2, < 2.0)
|
||||||
mime-types (>= 1.16, < 3.0)
|
mime-types (>= 1.16, < 3.0)
|
||||||
|
|
@ -911,7 +911,7 @@ DEPENDENCIES
|
||||||
d3_rails (~> 3.5.0)
|
d3_rails (~> 3.5.0)
|
||||||
database_cleaner (~> 1.4.0)
|
database_cleaner (~> 1.4.0)
|
||||||
default_value_for (~> 3.0.0)
|
default_value_for (~> 3.0.0)
|
||||||
devise (~> 3.5.3)
|
devise (~> 3.5.4)
|
||||||
devise-async (~> 0.9.0)
|
devise-async (~> 0.9.0)
|
||||||
devise-two-factor (~> 2.0.0)
|
devise-two-factor (~> 2.0.0)
|
||||||
diffy (~> 3.0.3)
|
diffy (~> 3.0.3)
|
||||||
|
|
|
||||||
4
Procfile
4
Procfile
|
|
@ -2,6 +2,6 @@
|
||||||
# https://gitlab.com/gitlab-org/omnibus-gitlab or the init scripts in
|
# https://gitlab.com/gitlab-org/omnibus-gitlab or the init scripts in
|
||||||
# lib/support/init.d, which call scripts in bin/ .
|
# lib/support/init.d, which call scripts in bin/ .
|
||||||
#
|
#
|
||||||
web: bundle exec unicorn_rails -p ${PORT:="3000"} -E ${RAILS_ENV:="development"} -c ${UNICORN_CONFIG:="config/unicorn.rb"}
|
web: RAILS_ENV=development bin/web start_foreground
|
||||||
worker: bundle exec sidekiq -q post_receive -q mailers -q archive_repo -q system_hook -q project_web_hook -q gitlab_shell -q incoming_email -q runner -q common -q default
|
worker: RAILS_ENV=development bin/background_jobs start_foreground
|
||||||
# mail_room: bundle exec mail_room -q -c config/mail_room.yml
|
# mail_room: bundle exec mail_room -q -c config/mail_room.yml
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -5,7 +5,7 @@ class @AwardsHandler
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
$(".emoji-menu").show()
|
$(".emoji-menu").show()
|
||||||
|
|
||||||
$("html").click ->
|
$("html").on 'click', (event) ->
|
||||||
if !$(event.target).closest(".emoji-menu").length
|
if !$(event.target).closest(".emoji-menu").length
|
||||||
if $(".emoji-menu").is(":visible")
|
if $(".emoji-menu").is(":visible")
|
||||||
$(".emoji-menu").hide()
|
$(".emoji-menu").hide()
|
||||||
|
|
@ -19,7 +19,7 @@ class @AwardsHandler
|
||||||
@addAwardToEmojiBar(emoji)
|
@addAwardToEmojiBar(emoji)
|
||||||
|
|
||||||
$(".emoji-menu").hide()
|
$(".emoji-menu").hide()
|
||||||
|
|
||||||
addAwardToEmojiBar: (emoji) ->
|
addAwardToEmojiBar: (emoji) ->
|
||||||
@addEmojiToFrequentlyUsedList(emoji)
|
@addEmojiToFrequentlyUsedList(emoji)
|
||||||
|
|
||||||
|
|
@ -66,9 +66,14 @@ class @AwardsHandler
|
||||||
|
|
||||||
addMeToAuthorList: (emoji) ->
|
addMeToAuthorList: (emoji) ->
|
||||||
award_block = @findEmojiIcon(emoji).parent()
|
award_block = @findEmojiIcon(emoji).parent()
|
||||||
authors = award_block.attr("data-original-title").split(", ")
|
authors = _.compact(award_block.attr("data-original-title").split(", "))
|
||||||
authors.push("me")
|
authors.push("me")
|
||||||
award_block.attr("title", authors.join(", "))
|
|
||||||
|
if authors.length == 1
|
||||||
|
award_block.attr("title", "me")
|
||||||
|
else
|
||||||
|
award_block.attr("title", authors.join(", "))
|
||||||
|
|
||||||
@resetTooltip(award_block)
|
@resetTooltip(award_block)
|
||||||
|
|
||||||
resetTooltip: (award) ->
|
resetTooltip: (award) ->
|
||||||
|
|
@ -78,7 +83,7 @@ class @AwardsHandler
|
||||||
setTimeout (->
|
setTimeout (->
|
||||||
award.tooltip()
|
award.tooltip()
|
||||||
), 200
|
), 200
|
||||||
|
|
||||||
|
|
||||||
createEmoji: (emoji) ->
|
createEmoji: (emoji) ->
|
||||||
emojiCssClass = @resolveNameToCssClass(emoji)
|
emojiCssClass = @resolveNameToCssClass(emoji)
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,25 @@ class @Issue
|
||||||
constructor: ->
|
constructor: ->
|
||||||
# Prevent duplicate event bindings
|
# Prevent duplicate event bindings
|
||||||
@disableTaskList()
|
@disableTaskList()
|
||||||
|
@fixAffixScroll()
|
||||||
if $('a.btn-close').length
|
if $('a.btn-close').length
|
||||||
@initTaskList()
|
@initTaskList()
|
||||||
@initIssueBtnEventListeners()
|
@initIssueBtnEventListeners()
|
||||||
|
|
||||||
|
fixAffixScroll: ->
|
||||||
|
fixAffix = ->
|
||||||
|
$discussion = $('.issuable-discussion')
|
||||||
|
$sidebar = $('.issuable-sidebar')
|
||||||
|
if $sidebar.hasClass('no-affix')
|
||||||
|
$sidebar.removeClass(['affix-top','affix'])
|
||||||
|
discussionHeight = $discussion.height()
|
||||||
|
sidebarHeight = $sidebar.height()
|
||||||
|
if sidebarHeight > discussionHeight
|
||||||
|
$discussion.height(sidebarHeight + 50)
|
||||||
|
$sidebar.addClass('no-affix')
|
||||||
|
$(window).on('resize', fixAffix)
|
||||||
|
fixAffix()
|
||||||
|
|
||||||
initTaskList: ->
|
initTaskList: ->
|
||||||
$('.detail-page-description .js-task-list-container').taskList('enable')
|
$('.detail-page-description .js-task-list-container').taskList('enable')
|
||||||
$(document).on 'tasklist:changed', '.detail-page-description .js-task-list-container', @updateTaskList
|
$(document).on 'tasklist:changed', '.detail-page-description .js-task-list-container', @updateTaskList
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,8 @@ class @MergeRequest
|
||||||
this.$('.show-all-commits').on 'click', =>
|
this.$('.show-all-commits').on 'click', =>
|
||||||
this.showAllCommits()
|
this.showAllCommits()
|
||||||
|
|
||||||
|
@fixAffixScroll();
|
||||||
|
|
||||||
@initTabs()
|
@initTabs()
|
||||||
|
|
||||||
# Prevent duplicate event bindings
|
# Prevent duplicate event bindings
|
||||||
|
|
@ -28,6 +30,20 @@ class @MergeRequest
|
||||||
$: (selector) ->
|
$: (selector) ->
|
||||||
this.$el.find(selector)
|
this.$el.find(selector)
|
||||||
|
|
||||||
|
fixAffixScroll: ->
|
||||||
|
fixAffix = ->
|
||||||
|
$discussion = $('.issuable-discussion')
|
||||||
|
$sidebar = $('.issuable-sidebar')
|
||||||
|
if $sidebar.hasClass('no-affix')
|
||||||
|
$sidebar.removeClass(['affix-top','affix'])
|
||||||
|
discussionHeight = $discussion.height()
|
||||||
|
sidebarHeight = $sidebar.height()
|
||||||
|
if sidebarHeight > discussionHeight
|
||||||
|
$discussion.height(sidebarHeight + 50)
|
||||||
|
$sidebar.addClass('no-affix')
|
||||||
|
$(window).on('resize', fixAffix)
|
||||||
|
fixAffix()
|
||||||
|
|
||||||
initTabs: ->
|
initTabs: ->
|
||||||
if @opts.action != 'new'
|
if @opts.action != 'new'
|
||||||
# `MergeRequests#new` has no tab-persisting or lazy-loading behavior
|
# `MergeRequests#new` has no tab-persisting or lazy-loading behavior
|
||||||
|
|
|
||||||
|
|
@ -320,6 +320,7 @@ class @Notes
|
||||||
form.show()
|
form.show()
|
||||||
textarea = form.find("textarea")
|
textarea = form.find("textarea")
|
||||||
textarea.focus()
|
textarea.focus()
|
||||||
|
autosize(textarea)
|
||||||
|
|
||||||
# HACK (rspeicher/DouweM): Work around a Chrome 43 bug(?).
|
# HACK (rspeicher/DouweM): Work around a Chrome 43 bug(?).
|
||||||
# The textarea has the correct value, Chrome just won't show it unless we
|
# The textarea has the correct value, Chrome just won't show it unless we
|
||||||
|
|
@ -355,7 +356,7 @@ class @Notes
|
||||||
$('.note[id="' + note_id + '"]').each ->
|
$('.note[id="' + note_id + '"]').each ->
|
||||||
note = $(this)
|
note = $(this)
|
||||||
notes = note.closest(".notes")
|
notes = note.closest(".notes")
|
||||||
count = notes.closest(".notes_holder").find(".discussion-notes-count")
|
count = notes.closest(".issuable-details").find(".notes-tab .badge")
|
||||||
|
|
||||||
# check if this is the last note for this line
|
# check if this is the last note for this line
|
||||||
if notes.find(".note").length is 1
|
if notes.find(".note").length is 1
|
||||||
|
|
@ -365,9 +366,10 @@ class @Notes
|
||||||
|
|
||||||
# for diff lines
|
# for diff lines
|
||||||
notes.closest("tr").remove()
|
notes.closest("tr").remove()
|
||||||
else
|
|
||||||
# update notes count
|
# update notes count
|
||||||
count.get(0).lastChild.nodeValue = " #{notes.children().length - 1}"
|
oldNum = parseInt(count.text())
|
||||||
|
count.text(oldNum - 1)
|
||||||
|
|
||||||
note.remove()
|
note.remove()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ class @Star
|
||||||
$starIcon = $this.find('i')
|
$starIcon = $this.find('i')
|
||||||
|
|
||||||
toggleStar = (isStarred) ->
|
toggleStar = (isStarred) ->
|
||||||
$this.parent().find('span.count').text data.star_count
|
$this.parent().find('.star-count').text data.star_count
|
||||||
if isStarred
|
if isStarred
|
||||||
$starSpan.removeClass('starred').text 'Star'
|
$starSpan.removeClass('starred').text 'Star'
|
||||||
$starIcon.removeClass('fa-star').addClass 'fa-star-o'
|
$starIcon.removeClass('fa-star').addClass 'fa-star-o'
|
||||||
|
|
@ -19,4 +19,4 @@ class @Star
|
||||||
return
|
return
|
||||||
).on 'ajax:error', (e, xhr, status, error) ->
|
).on 'ajax:error', (e, xhr, status, error) ->
|
||||||
new Flash('Star toggle failed. Try again later.', 'alert')
|
new Flash('Star toggle failed. Try again later.', 'alert')
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,8 @@ hr {
|
||||||
@include str-truncated;
|
@include str-truncated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.item-title { font-weight: 600; }
|
||||||
|
|
||||||
/** FLASH message **/
|
/** FLASH message **/
|
||||||
.author_link {
|
.author_link {
|
||||||
color: $gl-link-color;
|
color: $gl-link-color;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
.filter-item {
|
.filter-item {
|
||||||
margin-right: 15px;
|
margin-right: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 800px) {
|
@media (min-width: 800px) {
|
||||||
|
|
|
||||||
|
|
@ -3,23 +3,39 @@
|
||||||
font-family: 'Source Sans Pro';
|
font-family: 'Source Sans Pro';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
src: local('Source Sans Pro Light'), local('SourceSansPro-Light'), font-url('SourceSansPro-Light.ttf.woff');
|
src:
|
||||||
|
local('Source Sans Pro Light'),
|
||||||
|
local('SourceSansPro-Light'),
|
||||||
|
font-url('SourceSansPro-Light.ttf.woff2') format('woff2'),
|
||||||
|
font-url('SourceSansPro-Light.ttf.woff') format('woff');
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Source Sans Pro';
|
font-family: 'Source Sans Pro';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
src: local('Source Sans Pro'), local('SourceSansPro-Regular'), font-url('SourceSansPro-Regular.ttf.woff');
|
src:
|
||||||
|
local('Source Sans Pro'),
|
||||||
|
local('SourceSansPro-Regular'),
|
||||||
|
font-url('SourceSansPro-Regular.ttf.woff2') format('woff2'),
|
||||||
|
font-url('SourceSansPro-Regular.ttf.woff') format('woff');
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Source Sans Pro';
|
font-family: 'Source Sans Pro';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
src: local('Source Sans Pro Semibold'), local('SourceSansPro-Semibold'), font-url('SourceSansPro-Semibold.ttf.woff');
|
src:
|
||||||
|
local('Source Sans Pro Semibold'),
|
||||||
|
local('SourceSansPro-Semibold'),
|
||||||
|
font-url('SourceSansPro-Semibold.ttf.woff2') format('woff2'),
|
||||||
|
font-url('SourceSansPro-Semibold.ttf.woff') format('woff');
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Source Sans Pro';
|
font-family: 'Source Sans Pro';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
src: local('Source Sans Pro Bold'), local('SourceSansPro-Bold'), font-url('SourceSansPro-Bold.ttf.woff');
|
src:
|
||||||
|
local('Source Sans Pro Bold'),
|
||||||
|
local('SourceSansPro-Bold'),
|
||||||
|
font-url('SourceSansPro-Bold.ttf.woff2') format('woff2'),
|
||||||
|
font-url('SourceSansPro-Bold.ttf.woff') format('woff');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ $gl-vert-padding: 6px;
|
||||||
$gl-padding-top:10px;
|
$gl-padding-top:10px;
|
||||||
$gl-avatar-size: 46px;
|
$gl-avatar-size: 46px;
|
||||||
$secondary-text: #7f8fa4;
|
$secondary-text: #7f8fa4;
|
||||||
|
$error-exclamation-point: #E62958;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Color schema
|
* Color schema
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
.branch-name{
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
@ -2,10 +2,6 @@
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.commit-row-title .commit-title {
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.commit-author, .commit-committer{
|
.commit-author, .commit-committer{
|
||||||
display: block;
|
display: block;
|
||||||
color: #999;
|
color: #999;
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,10 @@ li.commit {
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
|
|
||||||
|
.btn-clipboard {
|
||||||
|
margin-top: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
.notes_count {
|
.notes_count {
|
||||||
float: right;
|
float: right;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-family: $monospace_font;
|
font-family: $monospace_font;
|
||||||
border: none;
|
border: none;
|
||||||
|
border-collapse: separate;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
.line_holder td {
|
.line_holder td {
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,3 @@
|
||||||
height: 42px;
|
height: 42px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-list .group-name {
|
|
||||||
font-weight: 600;
|
|
||||||
color: #4c4e54;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,11 @@
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 70px;
|
top: 70px;
|
||||||
margin-right: 35px;
|
margin-right: 35px;
|
||||||
|
|
||||||
|
&.no-affix {
|
||||||
|
position: relative;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -92,12 +92,12 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.project-repo-buttons {
|
.project-repo-buttons {
|
||||||
margin-top: 12px;
|
margin-top: 20px;
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
|
|
||||||
.count-buttons {
|
.count-buttons {
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 12px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.clone-row {
|
.clone-row {
|
||||||
|
|
@ -163,7 +163,7 @@
|
||||||
line-height: 13px;
|
line-height: 13px;
|
||||||
padding: $gl-vert-padding $gl-padding;
|
padding: $gl-vert-padding $gl-padding;
|
||||||
letter-spacing: .4px;
|
letter-spacing: .4px;
|
||||||
padding: 10px;
|
padding: 10px 14px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
touch-action: manipulation;
|
touch-action: manipulation;
|
||||||
|
|
@ -558,3 +558,9 @@ pre.light-well {
|
||||||
width: 101%;
|
width: 101%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.cannot-be-merged,
|
||||||
|
.cannot-be-merged:hover {
|
||||||
|
color: #E62958;
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,10 @@
|
||||||
border-bottom: 1px solid #DDD;
|
border-bottom: 1px solid #DDD;
|
||||||
padding-bottom: 15px;
|
padding-bottom: 15px;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
|
|
||||||
|
.term {
|
||||||
|
height: 22px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
.tag-name{
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
@ -2,6 +2,7 @@ class AbuseReportsController < ApplicationController
|
||||||
def new
|
def new
|
||||||
@abuse_report = AbuseReport.new
|
@abuse_report = AbuseReport.new
|
||||||
@abuse_report.user_id = params[:user_id]
|
@abuse_report.user_id = params[:user_id]
|
||||||
|
@ref_url = params.fetch(:ref_url, '')
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ class ApplicationController < ActionController::Base
|
||||||
# localhost/group/project
|
# localhost/group/project
|
||||||
#
|
#
|
||||||
if id =~ /\.git\Z/
|
if id =~ /\.git\Z/
|
||||||
redirect_to request.original_url.gsub(/\.git\Z/, '') and return
|
redirect_to request.original_url.gsub(/\.git\/?\Z/, '') and return
|
||||||
end
|
end
|
||||||
|
|
||||||
project_path = "#{namespace}/#{id}"
|
project_path = "#{namespace}/#{id}"
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ class Projects::ArtifactsController < Projects::ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
unless artifacts_file.exists?
|
unless artifacts_file.exists?
|
||||||
return not_found!
|
return render_404
|
||||||
end
|
end
|
||||||
|
|
||||||
send_file artifacts_file.path, disposition: 'attachment'
|
send_file artifacts_file.path, disposition: 'attachment'
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ class Projects::BuildsController < Projects::ApplicationController
|
||||||
|
|
||||||
def retry
|
def retry
|
||||||
unless @build.retryable?
|
unless @build.retryable?
|
||||||
return page_404
|
return render_404
|
||||||
end
|
end
|
||||||
|
|
||||||
build = Ci::Build.retry(@build)
|
build = Ci::Build.retry(@build)
|
||||||
|
|
@ -72,7 +72,7 @@ class Projects::BuildsController < Projects::ApplicationController
|
||||||
|
|
||||||
def authorize_manage_builds!
|
def authorize_manage_builds!
|
||||||
unless can?(current_user, :manage_builds, project)
|
unless can?(current_user, :manage_builds, project)
|
||||||
return page_404
|
return render_404
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ class Projects::CommitController < Projects::ApplicationController
|
||||||
|
|
||||||
def authorize_manage_builds!
|
def authorize_manage_builds!
|
||||||
unless can?(current_user, :manage_builds, project)
|
unless can?(current_user, :manage_builds, project)
|
||||||
return page_404
|
return render_404
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ class Projects::IssuesController < Projects::ApplicationController
|
||||||
assignee_id: ""
|
assignee_id: ""
|
||||||
)
|
)
|
||||||
|
|
||||||
@issue = @project.issues.new(issue_params)
|
@issue = @noteable = @project.issues.new(issue_params)
|
||||||
respond_with(@issue)
|
respond_with(@issue)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
|
||||||
def new
|
def new
|
||||||
params[:merge_request] ||= ActionController::Parameters.new(source_project: @project)
|
params[:merge_request] ||= ActionController::Parameters.new(source_project: @project)
|
||||||
@merge_request = MergeRequests::BuildService.new(project, current_user, merge_request_params).execute
|
@merge_request = MergeRequests::BuildService.new(project, current_user, merge_request_params).execute
|
||||||
|
@noteable = @merge_request
|
||||||
|
|
||||||
@target_branches = if @merge_request.target_project
|
@target_branches = if @merge_request.target_project
|
||||||
@merge_request.target_project.repository.branch_names
|
@merge_request.target_project.repository.branch_names
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ class Projects::SnippetsController < Projects::ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@snippet = @project.snippets.build
|
@snippet = @noteable = @project.snippets.build
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,8 @@ class IssuableFinder
|
||||||
elsif current_user && params[:authorized_only].presence && !current_user_related?
|
elsif current_user && params[:authorized_only].presence && !current_user_related?
|
||||||
@projects = current_user.authorized_projects.reorder(nil)
|
@projects = current_user.authorized_projects.reorder(nil)
|
||||||
else
|
else
|
||||||
@projects = ProjectsFinder.new.execute(current_user).reorder(nil)
|
@projects = ProjectsFinder.new.execute(current_user, group: group).
|
||||||
|
reorder(nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,26 @@ module Emails
|
||||||
def build_fail_email(build_id, to)
|
def build_fail_email(build_id, to)
|
||||||
@build = Ci::Build.find(build_id)
|
@build = Ci::Build.find(build_id)
|
||||||
@project = @build.project
|
@project = @build.project
|
||||||
|
add_project_headers
|
||||||
|
add_build_headers
|
||||||
|
headers['X-GitLab-Build-Status'] = "failed"
|
||||||
mail(to: to, subject: subject("Build failed for #{@project.name}", @build.short_sha))
|
mail(to: to, subject: subject("Build failed for #{@project.name}", @build.short_sha))
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_success_email(build_id, to)
|
def build_success_email(build_id, to)
|
||||||
@build = Ci::Build.find(build_id)
|
@build = Ci::Build.find(build_id)
|
||||||
@project = @build.project
|
@project = @build.project
|
||||||
|
add_project_headers
|
||||||
|
add_build_headers
|
||||||
|
headers['X-GitLab-Build-Status'] = "success"
|
||||||
mail(to: to, subject: subject("Build success for #{@project.name}", @build.short_sha))
|
mail(to: to, subject: subject("Build success for #{@project.name}", @build.short_sha))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def add_build_headers
|
||||||
|
headers['X-GitLab-Build-Id'] = @build.id
|
||||||
|
headers['X-GitLab-Build-Ref'] = @build.ref
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ module Emails
|
||||||
@current_user = @created_by = User.find(created_by_id)
|
@current_user = @created_by = User.find(created_by_id)
|
||||||
@access_level = access_level
|
@access_level = access_level
|
||||||
@invite_email = invite_email
|
@invite_email = invite_email
|
||||||
|
|
||||||
@target_url = namespace_project_url(@project.namespace, @project)
|
@target_url = namespace_project_url(@project.namespace, @project)
|
||||||
|
|
||||||
mail(to: @created_by.notification_email,
|
mail(to: @created_by.notification_email,
|
||||||
|
|
@ -65,6 +65,10 @@ module Emails
|
||||||
|
|
||||||
# used in notify layout
|
# used in notify layout
|
||||||
@target_url = @message.target_url
|
@target_url = @message.target_url
|
||||||
|
@project = Project.find project_id
|
||||||
|
|
||||||
|
add_project_headers
|
||||||
|
headers['X-GitLab-Author'] = @message.author_username
|
||||||
|
|
||||||
mail(from: sender(@message.author_id, @message.send_from_committer_email?),
|
mail(from: sender(@message.author_id, @message.send_from_committer_email?),
|
||||||
reply_to: @message.reply_to,
|
reply_to: @message.reply_to,
|
||||||
|
|
|
||||||
|
|
@ -100,12 +100,7 @@ class Notify < BaseMailer
|
||||||
end
|
end
|
||||||
|
|
||||||
def mail_thread(model, headers = {})
|
def mail_thread(model, headers = {})
|
||||||
if @project
|
add_project_headers
|
||||||
headers['X-GitLab-Project'] = @project.name
|
|
||||||
headers['X-GitLab-Project-Id'] = @project.id
|
|
||||||
headers['X-GitLab-Project-Path'] = @project.path_with_namespace
|
|
||||||
end
|
|
||||||
|
|
||||||
headers["X-GitLab-#{model.class.name}-ID"] = model.id
|
headers["X-GitLab-#{model.class.name}-ID"] = model.id
|
||||||
headers['X-GitLab-Reply-Key'] = reply_key
|
headers['X-GitLab-Reply-Key'] = reply_key
|
||||||
|
|
||||||
|
|
@ -152,4 +147,12 @@ class Notify < BaseMailer
|
||||||
def reply_key
|
def reply_key
|
||||||
@reply_key ||= SentNotification.reply_key
|
@reply_key ||= SentNotification.reply_key
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def add_project_headers
|
||||||
|
return unless @project
|
||||||
|
|
||||||
|
headers['X-GitLab-Project'] = @project.name
|
||||||
|
headers['X-GitLab-Project-Id'] = @project.id
|
||||||
|
headers['X-GitLab-Project-Path'] = @project.path_with_namespace
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,7 @@ class Ability
|
||||||
@project_report_rules ||= project_guest_rules + [
|
@project_report_rules ||= project_guest_rules + [
|
||||||
:create_commit_status,
|
:create_commit_status,
|
||||||
:read_commit_statuses,
|
:read_commit_statuses,
|
||||||
|
:read_build_artifacts,
|
||||||
:download_code,
|
:download_code,
|
||||||
:fork_project,
|
:fork_project,
|
||||||
:create_project_snippet,
|
:create_project_snippet,
|
||||||
|
|
@ -175,7 +176,6 @@ class Ability
|
||||||
:create_merge_request,
|
:create_merge_request,
|
||||||
:create_wiki,
|
:create_wiki,
|
||||||
:manage_builds,
|
:manage_builds,
|
||||||
:read_build_artifacts,
|
|
||||||
:push_code
|
:push_code
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ class AbuseReport < ActiveRecord::Base
|
||||||
validates :reporter, presence: true
|
validates :reporter, presence: true
|
||||||
validates :user, presence: true
|
validates :user, presence: true
|
||||||
validates :message, presence: true
|
validates :message, presence: true
|
||||||
validates :user_id, uniqueness: true
|
validates :user_id, uniqueness: { message: 'has already been reported' }
|
||||||
|
|
||||||
def remove_user
|
def remove_user
|
||||||
user.block
|
user.block
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,14 @@ module Ci
|
||||||
!self.commit.latest_builds_for_ref(self.ref).include?(self)
|
!self.commit.latest_builds_for_ref(self.ref).include?(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def depends_on_builds
|
||||||
|
# Get builds of the same type
|
||||||
|
latest_builds = self.commit.builds.similar(self).latest
|
||||||
|
|
||||||
|
# Return builds from previous stages
|
||||||
|
latest_builds.where('stage_idx < ?', stage_idx)
|
||||||
|
end
|
||||||
|
|
||||||
def trace_html
|
def trace_html
|
||||||
html = Ci::Ansi2html::convert(trace) if trace.present?
|
html = Ci::Ansi2html::convert(trace) if trace.present?
|
||||||
html || ''
|
html || ''
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,11 @@
|
||||||
# Table name: web_hooks
|
# Table name: web_hooks
|
||||||
#
|
#
|
||||||
# id :integer not null, primary key
|
# id :integer not null, primary key
|
||||||
# url :string(255)
|
# url :string(2000)
|
||||||
# project_id :integer
|
# project_id :integer
|
||||||
# created_at :datetime
|
# created_at :datetime
|
||||||
# updated_at :datetime
|
# updated_at :datetime
|
||||||
# type :string(255) default("ProjectHook")
|
# type :string default("ProjectHook")
|
||||||
# service_id :integer
|
# service_id :integer
|
||||||
# push_events :boolean default(TRUE), not null
|
# push_events :boolean default(TRUE), not null
|
||||||
# issues_events :boolean default(FALSE), not null
|
# issues_events :boolean default(FALSE), not null
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,11 @@
|
||||||
# Table name: web_hooks
|
# Table name: web_hooks
|
||||||
#
|
#
|
||||||
# id :integer not null, primary key
|
# id :integer not null, primary key
|
||||||
# url :string(255)
|
# url :string(2000)
|
||||||
# project_id :integer
|
# project_id :integer
|
||||||
# created_at :datetime
|
# created_at :datetime
|
||||||
# updated_at :datetime
|
# updated_at :datetime
|
||||||
# type :string(255) default("ProjectHook")
|
# type :string default("ProjectHook")
|
||||||
# service_id :integer
|
# service_id :integer
|
||||||
# push_events :boolean default(TRUE), not null
|
# push_events :boolean default(TRUE), not null
|
||||||
# issues_events :boolean default(FALSE), not null
|
# issues_events :boolean default(FALSE), not null
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,11 @@
|
||||||
# Table name: web_hooks
|
# Table name: web_hooks
|
||||||
#
|
#
|
||||||
# id :integer not null, primary key
|
# id :integer not null, primary key
|
||||||
# url :string(255)
|
# url :string(2000)
|
||||||
# project_id :integer
|
# project_id :integer
|
||||||
# created_at :datetime
|
# created_at :datetime
|
||||||
# updated_at :datetime
|
# updated_at :datetime
|
||||||
# type :string(255) default("ProjectHook")
|
# type :string default("ProjectHook")
|
||||||
# service_id :integer
|
# service_id :integer
|
||||||
# push_events :boolean default(TRUE), not null
|
# push_events :boolean default(TRUE), not null
|
||||||
# issues_events :boolean default(FALSE), not null
|
# issues_events :boolean default(FALSE), not null
|
||||||
|
|
|
||||||
|
|
@ -3,11 +3,11 @@
|
||||||
# Table name: web_hooks
|
# Table name: web_hooks
|
||||||
#
|
#
|
||||||
# id :integer not null, primary key
|
# id :integer not null, primary key
|
||||||
# url :string(255)
|
# url :string(2000)
|
||||||
# project_id :integer
|
# project_id :integer
|
||||||
# created_at :datetime
|
# created_at :datetime
|
||||||
# updated_at :datetime
|
# updated_at :datetime
|
||||||
# type :string(255) default("ProjectHook")
|
# type :string default("ProjectHook")
|
||||||
# service_id :integer
|
# service_id :integer
|
||||||
# push_events :boolean default(TRUE), not null
|
# push_events :boolean default(TRUE), not null
|
||||||
# issues_events :boolean default(FALSE), not null
|
# issues_events :boolean default(FALSE), not null
|
||||||
|
|
|
||||||
|
|
@ -272,6 +272,10 @@ class Project < ActiveRecord::Base
|
||||||
query: "%#{query.try(:downcase)}%")
|
query: "%#{query.try(:downcase)}%")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def search_by_visibility(level)
|
||||||
|
where(visibility_level: Gitlab::VisibilityLevel.const_get(level.upcase))
|
||||||
|
end
|
||||||
|
|
||||||
def search_by_title(query)
|
def search_by_title(query)
|
||||||
where('projects.archived = ?', false).where('LOWER(projects.name) LIKE :query', query: "%#{query.downcase}%")
|
where('projects.archived = ?', false).where('LOWER(projects.name) LIKE :query', query: "%#{query.downcase}%")
|
||||||
end
|
end
|
||||||
|
|
@ -468,12 +472,9 @@ class Project < ActiveRecord::Base
|
||||||
!external_issue_tracker
|
!external_issue_tracker
|
||||||
end
|
end
|
||||||
|
|
||||||
def external_issues_trackers
|
|
||||||
services.select(&:issue_tracker?).reject(&:default?)
|
|
||||||
end
|
|
||||||
|
|
||||||
def external_issue_tracker
|
def external_issue_tracker
|
||||||
@external_issues_tracker ||= external_issues_trackers.find(&:activated?)
|
@external_issue_tracker ||=
|
||||||
|
services.issue_trackers.active.without_defaults.first
|
||||||
end
|
end
|
||||||
|
|
||||||
def can_have_issues_tracker_id?
|
def can_have_issues_tracker_id?
|
||||||
|
|
|
||||||
|
|
@ -23,14 +23,12 @@
|
||||||
# List methods you need to implement to get your CI service
|
# List methods you need to implement to get your CI service
|
||||||
# working with GitLab Merge Requests
|
# working with GitLab Merge Requests
|
||||||
class CiService < Service
|
class CiService < Service
|
||||||
def category
|
default_value_for :category, 'ci'
|
||||||
:ci
|
|
||||||
end
|
|
||||||
|
|
||||||
def valid_token?(token)
|
def valid_token?(token)
|
||||||
self.respond_to?(:token) && self.token.present? && self.token == token
|
self.respond_to?(:token) && self.token.present? && self.token == token
|
||||||
end
|
end
|
||||||
|
|
||||||
def supported_events
|
def supported_events
|
||||||
%w(push)
|
%w(push)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,7 @@ class GitlabIssueTrackerService < IssueTrackerService
|
||||||
|
|
||||||
prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url
|
prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url
|
||||||
|
|
||||||
def default?
|
default_value_for :default, true
|
||||||
true
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_param
|
def to_param
|
||||||
'gitlab'
|
'gitlab'
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,10 @@ class IssueTrackerService < Service
|
||||||
|
|
||||||
validates :project_url, :issues_url, :new_issue_url, presence: true, if: :activated?
|
validates :project_url, :issues_url, :new_issue_url, presence: true, if: :activated?
|
||||||
|
|
||||||
def category
|
default_value_for :category, 'issue_tracker'
|
||||||
:issue_tracker
|
|
||||||
end
|
|
||||||
|
|
||||||
def default?
|
def default?
|
||||||
false
|
default
|
||||||
end
|
end
|
||||||
|
|
||||||
def issue_url(iid)
|
def issue_url(iid)
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,9 @@ class Service < ActiveRecord::Base
|
||||||
validates :project_id, presence: true, unless: Proc.new { |service| service.template? }
|
validates :project_id, presence: true, unless: Proc.new { |service| service.template? }
|
||||||
|
|
||||||
scope :visible, -> { where.not(type: ['GitlabIssueTrackerService', 'GitlabCiService']) }
|
scope :visible, -> { where.not(type: ['GitlabIssueTrackerService', 'GitlabCiService']) }
|
||||||
|
scope :issue_trackers, -> { where(category: 'issue_tracker') }
|
||||||
|
scope :active, -> { where(active: true) }
|
||||||
|
scope :without_defaults, -> { where(default: false) }
|
||||||
|
|
||||||
scope :push_hooks, -> { where(push_events: true, active: true) }
|
scope :push_hooks, -> { where(push_events: true, active: true) }
|
||||||
scope :tag_push_hooks, -> { where(tag_push_events: true, active: true) }
|
scope :tag_push_hooks, -> { where(tag_push_events: true, active: true) }
|
||||||
|
|
@ -51,6 +54,8 @@ class Service < ActiveRecord::Base
|
||||||
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) }
|
||||||
|
|
||||||
|
default_value_for :category, 'common'
|
||||||
|
|
||||||
def activated?
|
def activated?
|
||||||
active
|
active
|
||||||
end
|
end
|
||||||
|
|
@ -60,7 +65,7 @@ class Service < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def category
|
def category
|
||||||
:common
|
read_attribute(:category).to_sym
|
||||||
end
|
end
|
||||||
|
|
||||||
def initialize_properties
|
def initialize_properties
|
||||||
|
|
@ -153,7 +158,7 @@ class Service < ActiveRecord::Base
|
||||||
|
|
||||||
# Returns a hash of the properties that have been assigned a new value since last save,
|
# Returns a hash of the properties that have been assigned a new value since last save,
|
||||||
# indicating their original values (attr => original value).
|
# indicating their original values (attr => original value).
|
||||||
# ActiveRecord does not provide a mechanism to track changes in serialized keys,
|
# ActiveRecord does not provide a mechanism to track changes in serialized keys,
|
||||||
# so we need a specific implementation for service properties.
|
# so we need a specific implementation for service properties.
|
||||||
# This allows to track changes to properties set with the accessor methods,
|
# This allows to track changes to properties set with the accessor methods,
|
||||||
# but not direct manipulation of properties hash.
|
# but not direct manipulation of properties hash.
|
||||||
|
|
@ -164,7 +169,7 @@ class Service < ActiveRecord::Base
|
||||||
def reset_updated_properties
|
def reset_updated_properties
|
||||||
@updated_properties = nil
|
@updated_properties = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
def async_execute(data)
|
def async_execute(data)
|
||||||
return unless supported_events.include?(data[:object_kind])
|
return unless supported_events.include?(data[:object_kind])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -664,7 +664,10 @@ class User < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
|
|
||||||
def all_emails
|
def all_emails
|
||||||
[self.email, *self.emails.map(&:email)]
|
all_emails = []
|
||||||
|
all_emails << self.email unless self.temp_oauth_email?
|
||||||
|
all_emails.concat(self.emails.map(&:email))
|
||||||
|
all_emails
|
||||||
end
|
end
|
||||||
|
|
||||||
def hook_attrs
|
def hook_attrs
|
||||||
|
|
|
||||||
|
|
@ -376,10 +376,10 @@ class NotificationService
|
||||||
end
|
end
|
||||||
|
|
||||||
def reassign_resource_email(target, project, current_user, method)
|
def reassign_resource_email(target, project, current_user, method)
|
||||||
previous_assignee_id = previous_record(target, "assignee_id")
|
previous_assignee_id = previous_record(target, 'assignee_id')
|
||||||
previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id
|
previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id
|
||||||
|
|
||||||
recipients = build_recipients(target, project, current_user, [previous_assignee])
|
recipients = build_recipients(target, project, current_user, action: :reassign, previous_assignee: previous_assignee)
|
||||||
|
|
||||||
recipients.each do |recipient|
|
recipients.each do |recipient|
|
||||||
mailer.send(
|
mailer.send(
|
||||||
|
|
@ -400,22 +400,27 @@ class NotificationService
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_recipients(target, project, current_user, extra_recipients = nil)
|
def build_recipients(target, project, current_user, action: nil, previous_assignee: nil)
|
||||||
recipients = target.participants(current_user)
|
recipients = target.participants(current_user)
|
||||||
|
|
||||||
recipients = recipients.concat(extra_recipients).compact.uniq if extra_recipients
|
|
||||||
|
|
||||||
recipients = add_project_watchers(recipients, project)
|
recipients = add_project_watchers(recipients, project)
|
||||||
recipients = reject_mention_users(recipients, project)
|
recipients = reject_mention_users(recipients, project)
|
||||||
recipients = reject_muted_users(recipients, project)
|
|
||||||
|
|
||||||
|
# Re-assign is considered as a mention of the new assignee so we add the
|
||||||
|
# new assignee to the list of recipients after we rejected users with
|
||||||
|
# the "on mention" notification level
|
||||||
|
if action == :reassign
|
||||||
|
recipients << previous_assignee if previous_assignee
|
||||||
|
recipients << target.assignee
|
||||||
|
end
|
||||||
|
|
||||||
|
recipients = reject_muted_users(recipients, project)
|
||||||
recipients = add_subscribed_users(recipients, target)
|
recipients = add_subscribed_users(recipients, target)
|
||||||
recipients = reject_unsubscribed_users(recipients, target)
|
recipients = reject_unsubscribed_users(recipients, target)
|
||||||
|
|
||||||
recipients.delete(current_user)
|
recipients.delete(current_user)
|
||||||
recipients = recipients.uniq
|
|
||||||
|
|
||||||
recipients
|
recipients.uniq
|
||||||
end
|
end
|
||||||
|
|
||||||
def mailer
|
def mailer
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ module Projects
|
||||||
system_hook_service.execute_hooks_for(@project, :create)
|
system_hook_service.execute_hooks_for(@project, :create)
|
||||||
|
|
||||||
unless @project.group
|
unless @project.group
|
||||||
@project.team << [current_user, :master, current_user]
|
@project.team << [current_user, :master]
|
||||||
end
|
end
|
||||||
|
|
||||||
@project.import_start if @project.import?
|
@project.import_start if @project.import?
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,10 @@ class ArtifactUploader < CarrierWave::Uploader::Base
|
||||||
self.class.storage == CarrierWave::Storage::File
|
self.class.storage == CarrierWave::Storage::File
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def filename
|
||||||
|
file.try(:filename)
|
||||||
|
end
|
||||||
|
|
||||||
def exists?
|
def exists?
|
||||||
file.try(:exists?)
|
file.try(:exists?)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
.form-group
|
.form-group
|
||||||
= f.label :message, class: 'control-label'
|
= f.label :message, class: 'control-label'
|
||||||
.col-sm-10
|
.col-sm-10
|
||||||
= f.text_area :message, class: "form-control js-quick-submit", rows: 2, required: true
|
= f.text_area :message, class: "form-control js-quick-submit", rows: 2, required: true, value: sanitize(@ref_url)
|
||||||
.help-block
|
.help-block
|
||||||
Explain the problem with this user. If appropriate, provide a link to the relevant issue or comment.
|
Explain the problem with this user. If appropriate, provide a link to the relevant issue or comment.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,10 @@
|
||||||
.form-group
|
.form-group
|
||||||
= f.label :email, class: "control-label"
|
= f.label :email, class: "control-label"
|
||||||
.col-sm-10
|
.col-sm-10
|
||||||
- if @user.ldap_user?
|
- if @user.ldap_user? && @user.ldap_email?
|
||||||
= f.text_field :email, class: "form-control", required: true, readonly: true
|
= f.text_field :email, class: "form-control", required: true, readonly: true
|
||||||
%span.help-block.light
|
%span.help-block.light
|
||||||
Email is read-only for LDAP user
|
Your email address was automatically set based on the LDAP server.
|
||||||
- else
|
- else
|
||||||
- if @user.temp_oauth_email?
|
- if @user.temp_oauth_email?
|
||||||
= f.text_field :email, class: "form-control", required: true, value: nil
|
= f.text_field :email, class: "form-control", required: true, value: nil
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
%tr{ class: 'tree-item' }
|
- path_to_directory = browse_namespace_project_build_artifacts_path(@project.namespace, @project, @build, path: directory.path)
|
||||||
|
|
||||||
|
%tr.tree-item{ 'data-link' => path_to_directory}
|
||||||
%td.tree-item-file-name
|
%td.tree-item-file-name
|
||||||
= tree_icon('folder', '755', directory.name)
|
= tree_icon('folder', '755', directory.name)
|
||||||
%span.str-truncated
|
%span.str-truncated
|
||||||
= link_to directory.name, browse_namespace_project_build_artifacts_path(@project.namespace, @project, @build, path: directory.path)
|
= link_to directory.name, path_to_directory
|
||||||
%td
|
%td
|
||||||
%td
|
%td
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
%tr{ class: 'tree-item' }
|
- path_to_file = file_namespace_project_build_artifacts_path(@project.namespace, @project, @build, path: file.path)
|
||||||
|
|
||||||
|
%tr.tree-item{ 'data-link' => path_to_file }
|
||||||
%td.tree-item-file-name
|
%td.tree-item-file-name
|
||||||
= tree_icon('file', '664', file.name)
|
= tree_icon('file', '664', file.name)
|
||||||
%span.str-truncated
|
%span.str-truncated
|
||||||
= file.name
|
= link_to file.name, path_to_file
|
||||||
%td
|
%td
|
||||||
= number_to_human_size(file.metadata[:size], precision: 2)
|
= number_to_human_size(file.metadata[:size], precision: 2)
|
||||||
%td
|
%td
|
||||||
= link_to file_namespace_project_build_artifacts_path(@project.namespace, @project, @build, path: file.path),
|
= number_to_human_size(file.metadata[:zipped], precision: 2)
|
||||||
class: 'btn btn-xs btn-default artifact-download' do
|
|
||||||
= icon('download')
|
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,32 @@
|
||||||
- page_title 'Artifacts', "#{@build.name} (##{@build.id})", 'Builds'
|
- page_title 'Artifacts', "#{@build.name} (##{@build.id})", 'Builds'
|
||||||
= render 'projects/builds/header_title'
|
= render 'projects/builds/header_title'
|
||||||
|
|
||||||
#tree-holder.tree-holder
|
.top-block.gray-content-block.clearfix
|
||||||
.gray-content-block.top-block.clearfix
|
.pull-right
|
||||||
.pull-right
|
= link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, @build),
|
||||||
= link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, @build),
|
class: 'btn btn-default' do
|
||||||
class: 'btn btn-default' do
|
= icon('download')
|
||||||
= icon('download')
|
Download artifacts archive
|
||||||
Download artifacts archive
|
|
||||||
|
|
||||||
%div.tree-content-holder
|
.tree-holder
|
||||||
.table-holder
|
%div.tree-content-holder
|
||||||
%table.table.tree-table.table-striped
|
%table.table.tree-table
|
||||||
%thead
|
%thead
|
||||||
%tr
|
%tr
|
||||||
%th Name
|
%th Name
|
||||||
%th Size
|
%th Size
|
||||||
%th Download
|
%th Compressed to
|
||||||
= render partial: 'tree_directory', collection: @entry.directories(parent: true), as: :directory
|
= render partial: 'tree_directory', collection: @entry.directories(parent: true), as: :directory
|
||||||
= render partial: 'tree_file', collection: @entry.files, as: :file
|
= render partial: 'tree_file', collection: @entry.files, as: :file
|
||||||
|
|
||||||
- if @entry.empty?
|
- if @entry.empty?
|
||||||
.center Empty
|
.center Empty
|
||||||
|
|
||||||
|
:javascript
|
||||||
|
$('.tree-holder').on('click', 'tr[data-link] a', function(e) {
|
||||||
|
e.stopImmediatePropagation();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.tree-holder').on('click', 'tr[data-link]', function(e) {
|
||||||
|
window.location = this.dataset.link;
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
- commit = @repository.commit(branch.target)
|
- commit = @repository.commit(branch.target)
|
||||||
- bar_graph_width_factor = @max_commits > 0 ? 100.0/@max_commits : 0
|
- bar_graph_width_factor = @max_commits > 0 ? 100.0/@max_commits : 0
|
||||||
- diverging_commit_counts = @repository.diverging_commit_counts(branch)
|
- diverging_commit_counts = @repository.diverging_commit_counts(branch)
|
||||||
- number_commits_behind = diverging_commit_counts[:behind]
|
- number_commits_behind = diverging_commit_counts[:behind]
|
||||||
- number_commits_ahead = diverging_commit_counts[:ahead]
|
- number_commits_ahead = diverging_commit_counts[:ahead]
|
||||||
%li(class="js-branch-#{branch.name}")
|
%li(class="js-branch-#{branch.name}")
|
||||||
%div
|
%div
|
||||||
= link_to namespace_project_tree_path(@project.namespace, @project, branch.name) do
|
= link_to namespace_project_tree_path(@project.namespace, @project, branch.name) do
|
||||||
.branch-name.str-truncated= branch.name
|
%span.item-title.str-truncated= branch.name
|
||||||
|
|
||||||
- if branch.name == @repository.root_ref
|
- if branch.name == @repository.root_ref
|
||||||
%span.label.label-primary default
|
%span.label.label-primary default
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,12 @@
|
||||||
- if can?(current_user, :manage_builds, @project)
|
- if can?(current_user, :manage_builds, @project)
|
||||||
.pull-left.hidden-xs
|
.pull-left.hidden-xs
|
||||||
- if @all_builds.running_or_pending.any?
|
- if @all_builds.running_or_pending.any?
|
||||||
= link_to 'Cancel running', cancel_all_namespace_project_builds_path(@project.namespace, @project), data: { confirm: 'Are you sure?' }, class: 'btn btn-danger', method: :post
|
= link_to 'Cancel running', cancel_all_namespace_project_builds_path(@project.namespace, @project),
|
||||||
|
data: { confirm: 'Are you sure?' }, class: 'btn btn-danger', method: :post
|
||||||
|
|
||||||
|
= link_to ci_lint_path, class: 'btn btn-default' do
|
||||||
|
= icon('wrench')
|
||||||
|
%span CI Lint
|
||||||
|
|
||||||
%ul.nav-links
|
%ul.nav-links
|
||||||
%li{class: ('active' if @scope.nil?)}
|
%li{class: ('active' if @scope.nil?)}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
= cache(cache_key) do
|
= cache(cache_key) do
|
||||||
%li.commit.js-toggle-container{ id: "commit-#{commit.short_id}" }
|
%li.commit.js-toggle-container{ id: "commit-#{commit.short_id}" }
|
||||||
.commit-row-title
|
.commit-row-title
|
||||||
.commit-title.str-truncated
|
%span.item-title.str-truncated
|
||||||
= link_to_gfm commit.title, namespace_project_commit_path(project.namespace, project, commit.id), class: "commit-row-message"
|
= link_to_gfm commit.title, namespace_project_commit_path(project.namespace, project, commit.id), class: "commit-row-message"
|
||||||
- if commit.description?
|
- if commit.description?
|
||||||
%a.text-expander.js-toggle-button ...
|
%a.text-expander.js-toggle-button ...
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
%li
|
%li
|
||||||
%div
|
%div
|
||||||
= link_to namespace_project_tag_path(@project.namespace, @project, tag.name) do
|
= link_to namespace_project_tag_path(@project.namespace, @project, tag.name) do
|
||||||
.tag-name
|
%span.item-title
|
||||||
= icon('tag')
|
= icon('tag')
|
||||||
= tag.name
|
= tag.name
|
||||||
- if tag.message.present?
|
- if tag.message.present?
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@
|
||||||
.pull-right
|
.pull-right
|
||||||
= link_to namespace_project_tag_path(@project.namespace, @project, @tag.name), class: 'btn btn-remove remove-row grouped has_tooltip', title: "Delete tag", method: :delete, data: { confirm: "Deleting the '#{@tag.name}' tag cannot be undone. Are you sure?" } do
|
= link_to namespace_project_tag_path(@project.namespace, @project, @tag.name), class: 'btn btn-remove remove-row grouped has_tooltip', title: "Delete tag", method: :delete, data: { confirm: "Deleting the '#{@tag.name}' tag cannot be undone. Are you sure?" } do
|
||||||
%i.fa.fa-trash-o
|
%i.fa.fa-trash-o
|
||||||
.tag-name.title
|
.title
|
||||||
= @tag.name
|
%span.item-title= @tag.name
|
||||||
- if @tag.message.present?
|
- if @tag.message.present?
|
||||||
%span.light
|
%span.light
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@
|
||||||
%i.fa.fa-sign-out
|
%i.fa.fa-sign-out
|
||||||
|
|
||||||
= image_tag group_icon(group), class: "avatar s46 hidden-xs"
|
= image_tag group_icon(group), class: "avatar s46 hidden-xs"
|
||||||
= link_to group.name, group, class: 'group-name'
|
= link_to group, class: 'group-name' do
|
||||||
|
%span.item-title= group.name
|
||||||
|
|
||||||
- if group_member
|
- if group_member
|
||||||
as
|
as
|
||||||
|
|
@ -18,4 +19,3 @@
|
||||||
|
|
||||||
%div.light
|
%div.light
|
||||||
#{pluralize(group.projects.count, "project")}, #{pluralize(group.users.count, "user")}
|
#{pluralize(group.projects.count, "project")}, #{pluralize(group.users.count, "user")}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@
|
||||||
.value
|
.value
|
||||||
- if issuable.assignee
|
- if issuable.assignee
|
||||||
%strong= link_to_member(@project, issuable.assignee, size: 24)
|
%strong= link_to_member(@project, issuable.assignee, size: 24)
|
||||||
|
- if issuable.instance_of?(MergeRequest) && !issuable.can_be_merged_by?(issuable.assignee)
|
||||||
|
%a.pull-right.cannot-be-merged{href: '#', data: {toggle: 'tooltip'}, title: 'Not allowed to merge'}
|
||||||
|
= icon('exclamation-triangle')
|
||||||
- else
|
- else
|
||||||
.light None
|
.light None
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
%tr
|
%tr
|
||||||
%th= t('sherlock.time')
|
%th= t('sherlock.time')
|
||||||
%th= t('sherlock.query')
|
%th= t('sherlock.query')
|
||||||
%td
|
%th
|
||||||
%tbody
|
%tbody
|
||||||
- @transaction.sorted_queries.each do |query|
|
- @transaction.sorted_queries.each do |query|
|
||||||
%tr
|
%tr
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@
|
||||||
data: { toggle: 'tooltip', placement: 'left', container: 'body' }}
|
data: { toggle: 'tooltip', placement: 'left', container: 'body' }}
|
||||||
= icon('exclamation-circle')
|
= icon('exclamation-circle')
|
||||||
- else
|
- else
|
||||||
= link_to new_abuse_report_path(user_id: @user.id), class: 'btn btn-gray',
|
= link_to new_abuse_report_path(user_id: @user.id, ref_url: request.referrer), class: 'btn btn-gray',
|
||||||
title: 'Report abuse', data: {toggle: 'tooltip', placement: 'left', container: 'body'} do
|
title: 'Report abuse', data: {toggle: 'tooltip', placement: 'left', container: 'body'} do
|
||||||
= icon('exclamation-circle')
|
= icon('exclamation-circle')
|
||||||
- if current_user
|
- if current_user
|
||||||
|
|
|
||||||
|
|
@ -27,17 +27,17 @@ restart()
|
||||||
stop
|
stop
|
||||||
fi
|
fi
|
||||||
killall
|
killall
|
||||||
start_sidekiq -d -L $sidekiq_logfile
|
start_sidekiq -d -L $sidekiq_logfile >> $sidekiq_logfile 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
start_no_deamonize()
|
start_no_deamonize()
|
||||||
{
|
{
|
||||||
start_sidekiq
|
start_sidekiq >> $sidekiq_logfile 2>&1
|
||||||
}
|
}
|
||||||
|
|
||||||
start_sidekiq()
|
start_sidekiq()
|
||||||
{
|
{
|
||||||
bundle exec sidekiq -q post_receive -q mailers -q archive_repo -q system_hook -q project_web_hook -q gitlab_shell -q incoming_email -q runner -q common -q default -e $RAILS_ENV -P $sidekiq_pidfile $@ >> $sidekiq_logfile 2>&1
|
bundle exec sidekiq -q post_receive -q mailers -q archive_repo -q system_hook -q project_web_hook -q gitlab_shell -q incoming_email -q runner -q common -q default -e $RAILS_ENV -P $sidekiq_pidfile "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
load_ok()
|
load_ok()
|
||||||
|
|
@ -66,6 +66,9 @@ case "$1" in
|
||||||
start_no_deamonize)
|
start_no_deamonize)
|
||||||
start_no_deamonize
|
start_no_deamonize
|
||||||
;;
|
;;
|
||||||
|
start_foreground)
|
||||||
|
start_sidekiq
|
||||||
|
;;
|
||||||
restart)
|
restart)
|
||||||
restart
|
restart
|
||||||
;;
|
;;
|
||||||
|
|
|
||||||
11
bin/web
11
bin/web
|
|
@ -5,6 +5,7 @@ app_root=$(pwd)
|
||||||
|
|
||||||
unicorn_pidfile="$app_root/tmp/pids/unicorn.pid"
|
unicorn_pidfile="$app_root/tmp/pids/unicorn.pid"
|
||||||
unicorn_config="$app_root/config/unicorn.rb"
|
unicorn_config="$app_root/config/unicorn.rb"
|
||||||
|
unicorn_cmd="bundle exec unicorn_rails -c $unicorn_config -E $RAILS_ENV"
|
||||||
|
|
||||||
get_unicorn_pid()
|
get_unicorn_pid()
|
||||||
{
|
{
|
||||||
|
|
@ -18,7 +19,12 @@ get_unicorn_pid()
|
||||||
|
|
||||||
start()
|
start()
|
||||||
{
|
{
|
||||||
bundle exec unicorn_rails -D -c $unicorn_config -E $RAILS_ENV
|
$unicorn_cmd -D
|
||||||
|
}
|
||||||
|
|
||||||
|
start_foreground()
|
||||||
|
{
|
||||||
|
$unicorn_cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
stop()
|
stop()
|
||||||
|
|
@ -37,6 +43,9 @@ case "$1" in
|
||||||
start)
|
start)
|
||||||
start
|
start
|
||||||
;;
|
;;
|
||||||
|
start_foreground)
|
||||||
|
start_foreground
|
||||||
|
;;
|
||||||
stop)
|
stop)
|
||||||
stop
|
stop
|
||||||
;;
|
;;
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,9 @@ Rails.application.configure do
|
||||||
# Print deprecation notices to the Rails logger
|
# Print deprecation notices to the Rails logger
|
||||||
config.active_support.deprecation = :log
|
config.active_support.deprecation = :log
|
||||||
|
|
||||||
|
# Raise an error on page load if there are pending migrations
|
||||||
|
config.active_record.migration_error = :page_load
|
||||||
|
|
||||||
# Only use best-standards-support built into browsers
|
# Only use best-standards-support built into browsers
|
||||||
config.action_dispatch.best_standards_support = :builtin
|
config.action_dispatch.best_standards_support = :builtin
|
||||||
|
|
||||||
|
|
@ -34,6 +37,8 @@ Rails.application.configure do
|
||||||
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
|
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
|
||||||
# Open sent mails in browser
|
# Open sent mails in browser
|
||||||
config.action_mailer.delivery_method = :letter_opener
|
config.action_mailer.delivery_method = :letter_opener
|
||||||
|
# Don't make a mess when bootstrapping a development environment
|
||||||
|
config.action_mailer.perform_deliveries = (ENV['BOOTSTRAP'] != '1')
|
||||||
|
|
||||||
config.eager_load = false
|
config.eager_load = false
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -9,13 +9,8 @@ class Settings < Settingslogic
|
||||||
gitlab.port.to_i == (gitlab.https ? 443 : 80)
|
gitlab.port.to_i == (gitlab.https ? 443 : 80)
|
||||||
end
|
end
|
||||||
|
|
||||||
# get host without www, thanks to http://stackoverflow.com/a/6674363/1233435
|
def host_without_www(url)
|
||||||
def get_host_without_www(url)
|
host(url).sub('www.', '')
|
||||||
url = CGI.escape(url)
|
|
||||||
uri = URI.parse(url)
|
|
||||||
uri = URI.parse("http://#{url}") if uri.scheme.nil?
|
|
||||||
host = uri.host.downcase
|
|
||||||
host.start_with?('www.') ? host[4..-1] : host
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_gitlab_ci_url
|
def build_gitlab_ci_url
|
||||||
|
|
@ -87,6 +82,17 @@ class Settings < Settingslogic
|
||||||
custom_port
|
custom_port
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Extract the host part of the given +url+.
|
||||||
|
def host(url)
|
||||||
|
url = url.downcase
|
||||||
|
url = "http://#{url}" unless url.start_with?('http')
|
||||||
|
|
||||||
|
# Get rid of the path so that we don't even have to encode it
|
||||||
|
url_without_path = url.sub(%r{(https?://[^\/]+)/?.*}, '\1')
|
||||||
|
|
||||||
|
URI.parse(url_without_path).host
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -228,7 +234,7 @@ Settings['gravatar'] ||= Settingslogic.new({})
|
||||||
Settings.gravatar['enabled'] = true if Settings.gravatar['enabled'].nil?
|
Settings.gravatar['enabled'] = true if Settings.gravatar['enabled'].nil?
|
||||||
Settings.gravatar['plain_url'] ||= 'http://www.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon'
|
Settings.gravatar['plain_url'] ||= 'http://www.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon'
|
||||||
Settings.gravatar['ssl_url'] ||= 'https://secure.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon'
|
Settings.gravatar['ssl_url'] ||= 'https://secure.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon'
|
||||||
Settings.gravatar['host'] = Settings.get_host_without_www(Settings.gravatar['plain_url'])
|
Settings.gravatar['host'] = Settings.host_without_www(Settings.gravatar['plain_url'])
|
||||||
|
|
||||||
#
|
#
|
||||||
# Cron Jobs
|
# Cron Jobs
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,12 @@ if Gitlab::Metrics.enabled?
|
||||||
|
|
||||||
config.instrument_methods(const) if const.is_a?(Module)
|
config.instrument_methods(const) if const.is_a?(Module)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Dir[Rails.root.join('app', 'finders', '*.rb')].each do |path|
|
||||||
|
const = File.basename(path, '.rb').camelize.constantize
|
||||||
|
|
||||||
|
config.instrument_instance_methods(const)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
GC::Profiler.enable
|
GC::Profiler.enable
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
class RaiseHookUrlLimit < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
change_column :web_hooks, :url, :string, limit: 2000
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
class AddServicesCategory < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
add_column :services, :category, :string, default: 'common', null: false
|
||||||
|
|
||||||
|
category = quote_column_name('category')
|
||||||
|
type = quote_column_name('type')
|
||||||
|
|
||||||
|
execute <<-EOF
|
||||||
|
UPDATE services
|
||||||
|
SET #{category} = 'issue_tracker'
|
||||||
|
WHERE #{type} IN (
|
||||||
|
'CustomIssueTrackerService',
|
||||||
|
'GitlabIssueTrackerService',
|
||||||
|
'IssueTrackerService',
|
||||||
|
'JiraService',
|
||||||
|
'RedmineService'
|
||||||
|
);
|
||||||
|
EOF
|
||||||
|
|
||||||
|
execute <<-EOF
|
||||||
|
UPDATE services
|
||||||
|
SET #{category} = 'ci'
|
||||||
|
WHERE #{type} IN (
|
||||||
|
'BambooService',
|
||||||
|
'BuildkiteService',
|
||||||
|
'CiService',
|
||||||
|
'DroneCiService',
|
||||||
|
'GitlabCiService',
|
||||||
|
'TeamcityService'
|
||||||
|
);
|
||||||
|
EOF
|
||||||
|
|
||||||
|
add_index :services, :category
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
remove_column :services, :category
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
class AddServicesDefault < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
add_column :services, :default, :boolean, default: false
|
||||||
|
|
||||||
|
default = quote_column_name('default')
|
||||||
|
type = quote_column_name('type')
|
||||||
|
|
||||||
|
execute <<-EOF
|
||||||
|
UPDATE services
|
||||||
|
SET #{default} = true
|
||||||
|
WHERE #{type} = 'GitlabIssueTrackerService'
|
||||||
|
EOF
|
||||||
|
|
||||||
|
add_index :services, :default
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
remove_column :services, :default
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
class AddLdapEmailToUsers < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
add_column :users, :ldap_email, :boolean, default: false, null: false
|
||||||
|
|
||||||
|
if Gitlab::Database.mysql?
|
||||||
|
execute %{
|
||||||
|
UPDATE users, identities
|
||||||
|
SET users.ldap_email = TRUE
|
||||||
|
WHERE identities.user_id = users.id
|
||||||
|
AND users.email LIKE 'temp-email-for-oauth%'
|
||||||
|
AND identities.provider LIKE 'ldap%'
|
||||||
|
AND identities.extern_uid IS NOT NULL
|
||||||
|
}
|
||||||
|
else
|
||||||
|
execute %{
|
||||||
|
UPDATE users
|
||||||
|
SET ldap_email = TRUE
|
||||||
|
FROM identities
|
||||||
|
WHERE identities.user_id = users.id
|
||||||
|
AND users.email LIKE 'temp-email-for-oauth%'
|
||||||
|
AND identities.provider LIKE 'ldap%'
|
||||||
|
AND identities.extern_uid IS NOT NULL
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
remove_column :users, :ldap_email
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -6,5 +6,6 @@ class LimitsToMysql < ActiveRecord::Migration
|
||||||
change_column :merge_request_diffs, :st_diffs, :text, limit: 2147483647
|
change_column :merge_request_diffs, :st_diffs, :text, limit: 2147483647
|
||||||
change_column :snippets, :content, :text, limit: 2147483647
|
change_column :snippets, :content, :text, limit: 2147483647
|
||||||
change_column :notes, :st_diff, :text, limit: 2147483647
|
change_column :notes, :st_diff, :text, limit: 2147483647
|
||||||
|
change_column :events, :data, :text, limit: 2147483647
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
45
db/schema.rb
45
db/schema.rb
|
|
@ -11,7 +11,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 20160113111034) do
|
ActiveRecord::Schema.define(version: 20160119145451) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
|
|
@ -725,20 +725,24 @@ ActiveRecord::Schema.define(version: 20160113111034) do
|
||||||
t.string "type"
|
t.string "type"
|
||||||
t.string "title"
|
t.string "title"
|
||||||
t.integer "project_id"
|
t.integer "project_id"
|
||||||
t.datetime "created_at"
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at"
|
t.datetime "updated_at", null: false
|
||||||
t.boolean "active", default: false, null: false
|
t.boolean "active", null: false
|
||||||
t.text "properties"
|
t.text "properties"
|
||||||
t.boolean "template", default: false
|
t.boolean "template", default: false
|
||||||
t.boolean "push_events", default: true
|
t.boolean "push_events", default: true
|
||||||
t.boolean "issues_events", default: true
|
t.boolean "issues_events", default: true
|
||||||
t.boolean "merge_requests_events", default: true
|
t.boolean "merge_requests_events", default: true
|
||||||
t.boolean "tag_push_events", default: true
|
t.boolean "tag_push_events", default: true
|
||||||
t.boolean "note_events", default: true, null: false
|
t.boolean "note_events", default: true, null: false
|
||||||
t.boolean "build_events", default: false, null: false
|
t.boolean "build_events", default: false, null: false
|
||||||
|
t.string "category", default: "common", null: false
|
||||||
|
t.boolean "default", default: false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
add_index "services", ["category"], name: "index_services_on_category", using: :btree
|
||||||
add_index "services", ["created_at", "id"], name: "index_services_on_created_at_and_id", using: :btree
|
add_index "services", ["created_at", "id"], name: "index_services_on_created_at_and_id", using: :btree
|
||||||
|
add_index "services", ["default"], name: "index_services_on_default", using: :btree
|
||||||
add_index "services", ["project_id"], name: "index_services_on_project_id", using: :btree
|
add_index "services", ["project_id"], name: "index_services_on_project_id", using: :btree
|
||||||
add_index "services", ["template"], name: "index_services_on_template", using: :btree
|
add_index "services", ["template"], name: "index_services_on_template", using: :btree
|
||||||
|
|
||||||
|
|
@ -850,6 +854,7 @@ ActiveRecord::Schema.define(version: 20160113111034) do
|
||||||
t.boolean "hide_project_limit", default: false
|
t.boolean "hide_project_limit", default: false
|
||||||
t.string "unlock_token"
|
t.string "unlock_token"
|
||||||
t.datetime "otp_grace_period_started_at"
|
t.datetime "otp_grace_period_started_at"
|
||||||
|
t.boolean "ldap_email", default: false, null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "users", ["admin"], name: "index_users_on_admin", using: :btree
|
add_index "users", ["admin"], name: "index_users_on_admin", using: :btree
|
||||||
|
|
@ -874,19 +879,19 @@ ActiveRecord::Schema.define(version: 20160113111034) do
|
||||||
add_index "users_star_projects", ["user_id"], name: "index_users_star_projects_on_user_id", using: :btree
|
add_index "users_star_projects", ["user_id"], name: "index_users_star_projects_on_user_id", using: :btree
|
||||||
|
|
||||||
create_table "web_hooks", force: :cascade do |t|
|
create_table "web_hooks", force: :cascade do |t|
|
||||||
t.string "url"
|
t.string "url", limit: 2000
|
||||||
t.integer "project_id"
|
t.integer "project_id"
|
||||||
t.datetime "created_at"
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at"
|
t.datetime "updated_at"
|
||||||
t.string "type", default: "ProjectHook"
|
t.string "type", default: "ProjectHook"
|
||||||
t.integer "service_id"
|
t.integer "service_id"
|
||||||
t.boolean "push_events", default: true, null: false
|
t.boolean "push_events", default: true, null: false
|
||||||
t.boolean "issues_events", default: false, null: false
|
t.boolean "issues_events", default: false, null: false
|
||||||
t.boolean "merge_requests_events", default: false, null: false
|
t.boolean "merge_requests_events", default: false, null: false
|
||||||
t.boolean "tag_push_events", default: false
|
t.boolean "tag_push_events", default: false
|
||||||
t.boolean "note_events", default: false, null: false
|
t.boolean "note_events", default: false, null: false
|
||||||
t.boolean "enable_ssl_verification", default: true
|
t.boolean "enable_ssl_verification", default: true
|
||||||
t.boolean "build_events", default: false, null: false
|
t.boolean "build_events", default: false, null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "web_hooks", ["created_at", "id"], name: "index_web_hooks_on_created_at_and_id", using: :btree
|
add_index "web_hooks", ["created_at", "id"], name: "index_web_hooks_on_created_at_and_id", using: :btree
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,53 @@ When listing resources you can pass the following parameters:
|
||||||
- `page` (default: `1`) - page number
|
- `page` (default: `1`) - page number
|
||||||
- `per_page` (default: `20`, max: `100`) - number of items to list per page
|
- `per_page` (default: `20`, max: `100`) - number of items to list per page
|
||||||
|
|
||||||
[Link headers](http://www.w3.org/wiki/LinkHeader) are send back with each response. These have `rel` prev/next/first/last and contain the relevant URL. Please use these instead of generating your own URLs.
|
### Pagination Link header
|
||||||
|
|
||||||
|
[Link headers](http://www.w3.org/wiki/LinkHeader) are sent back with each
|
||||||
|
response. They have `rel` set to prev/next/first/last and contain the relevant
|
||||||
|
URL. Please use these links instead of generating your own URLs.
|
||||||
|
|
||||||
|
In the cURL example below, we limit the output to 3 items per page (`per_page=3`)
|
||||||
|
and we request the second page (`page=2`) of [comments](notes.md) of the issue
|
||||||
|
with ID `8` which belongs to the project with ID `8`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -I -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/projects/8/issues/8/notes?per_page=3&page=2
|
||||||
|
```
|
||||||
|
|
||||||
|
The response will then be:
|
||||||
|
|
||||||
|
```
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Cache-Control: no-cache
|
||||||
|
Content-Length: 1103
|
||||||
|
Content-Type: application/json
|
||||||
|
Date: Mon, 18 Jan 2016 09:43:18 GMT
|
||||||
|
Link: <https://gitlab.example.com/api/v3/projects/8/issues/8/notes?page=1&per_page=3>; rel="prev", <https://gitlab.example.com/api/v3/projects/8/issues/8/notes?page=3&per_page=3>; rel="next", <https://gitlab.example.com/api/v3/projects/8/issues/8/notes?page=1&per_page=3>; rel="first", <https://gitlab.example.com/api/v3/projects/8/issues/8/notes?page=3&per_page=3>; rel="last"
|
||||||
|
Status: 200 OK
|
||||||
|
Vary: Origin
|
||||||
|
X-Next-Page: 3
|
||||||
|
X-Page: 2
|
||||||
|
X-Per-Page: 3
|
||||||
|
X-Prev-Page: 1
|
||||||
|
X-Request-Id: 732ad4ee-9870-4866-a199-a9db0cde3c86
|
||||||
|
X-Runtime: 0.108688
|
||||||
|
X-Total: 8
|
||||||
|
X-Total-Pages: 3
|
||||||
|
```
|
||||||
|
|
||||||
|
### Other pagination headers
|
||||||
|
|
||||||
|
Additional pagination headers are also sent back.
|
||||||
|
|
||||||
|
| Header | Description |
|
||||||
|
| ------ | ----------- |
|
||||||
|
| `X-Total` | The total number of items |
|
||||||
|
| `X-Total-Pages` | The total number of pages |
|
||||||
|
| `X-Per-Page` | The number of items per page |
|
||||||
|
| `X-Page` | The index of the current page (starting at 1) |
|
||||||
|
| `X-Next-Page` | The index of the next page |
|
||||||
|
| `X-Prev-Page` | The index of the previous page |
|
||||||
|
|
||||||
## id vs iid
|
## id vs iid
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ GET /groups/:id/projects
|
||||||
Parameters:
|
Parameters:
|
||||||
|
|
||||||
- `archived` (optional) - if passed, limit by archived status
|
- `archived` (optional) - if passed, limit by archived status
|
||||||
|
- `visibility` (optional) - if passed, limit by visibility `public`, `internal`, `private`
|
||||||
- `order_by` (optional) - Return requests ordered by `id`, `name`, `path`, `created_at`, `updated_at` or `last_activity_at` fields. Default is `created_at`
|
- `order_by` (optional) - Return requests ordered by `id`, `name`, `path`, `created_at`, `updated_at` or `last_activity_at` fields. Default is `created_at`
|
||||||
- `sort` (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc`
|
- `sort` (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc`
|
||||||
- `search` (optional) - Return list of authorized projects according to a search criteria
|
- `search` (optional) - Return list of authorized projects according to a search criteria
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ GET /projects
|
||||||
Parameters:
|
Parameters:
|
||||||
|
|
||||||
- `archived` (optional) - if passed, limit by archived status
|
- `archived` (optional) - if passed, limit by archived status
|
||||||
|
- `visibility` (optional) - if passed, limit by visibility `public`, `internal`, `private`
|
||||||
- `order_by` (optional) - Return requests ordered by `id`, `name`, `path`, `created_at`, `updated_at` or `last_activity_at` fields. Default is `created_at`
|
- `order_by` (optional) - Return requests ordered by `id`, `name`, `path`, `created_at`, `updated_at` or `last_activity_at` fields. Default is `created_at`
|
||||||
- `sort` (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc`
|
- `sort` (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc`
|
||||||
- `search` (optional) - Return list of authorized projects according to a search criteria
|
- `search` (optional) - Return list of authorized projects according to a search criteria
|
||||||
|
|
@ -152,6 +153,7 @@ GET /projects/owned
|
||||||
Parameters:
|
Parameters:
|
||||||
|
|
||||||
- `archived` (optional) - if passed, limit by archived status
|
- `archived` (optional) - if passed, limit by archived status
|
||||||
|
- `visibility` (optional) - if passed, limit by visibility `public`, `internal`, `private`
|
||||||
- `order_by` (optional) - Return requests ordered by `id`, `name`, `path`, `created_at`, `updated_at` or `last_activity_at` fields. Default is `created_at`
|
- `order_by` (optional) - Return requests ordered by `id`, `name`, `path`, `created_at`, `updated_at` or `last_activity_at` fields. Default is `created_at`
|
||||||
- `sort` (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc`
|
- `sort` (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc`
|
||||||
- `search` (optional) - Return list of authorized projects according to a search criteria
|
- `search` (optional) - Return list of authorized projects according to a search criteria
|
||||||
|
|
@ -167,6 +169,7 @@ GET /projects/starred
|
||||||
Parameters:
|
Parameters:
|
||||||
|
|
||||||
- `archived` (optional) - if passed, limit by archived status
|
- `archived` (optional) - if passed, limit by archived status
|
||||||
|
- `visibility` (optional) - if passed, limit by visibility `public`, `internal`, `private`
|
||||||
- `order_by` (optional) - Return requests ordered by `id`, `name`, `path`, `created_at`, `updated_at` or `last_activity_at` fields. Default is `created_at`
|
- `order_by` (optional) - Return requests ordered by `id`, `name`, `path`, `created_at`, `updated_at` or `last_activity_at` fields. Default is `created_at`
|
||||||
- `sort` (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc`
|
- `sort` (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc`
|
||||||
- `search` (optional) - Return list of authorized projects according to a search criteria
|
- `search` (optional) - Return list of authorized projects according to a search criteria
|
||||||
|
|
@ -182,6 +185,7 @@ GET /projects/all
|
||||||
Parameters:
|
Parameters:
|
||||||
|
|
||||||
- `archived` (optional) - if passed, limit by archived status
|
- `archived` (optional) - if passed, limit by archived status
|
||||||
|
- `visibility` (optional) - if passed, limit by visibility `public`, `internal`, `private`
|
||||||
- `order_by` (optional) - Return requests ordered by `id`, `name`, `path`, `created_at`, `updated_at` or `last_activity_at` fields. Default is `created_at`
|
- `order_by` (optional) - Return requests ordered by `id`, `name`, `path`, `created_at`, `updated_at` or `last_activity_at` fields. Default is `created_at`
|
||||||
- `sort` (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc`
|
- `sort` (optional) - Return requests sorted in `asc` or `desc` order. Default is `desc`
|
||||||
- `search` (optional) - Return list of authorized projects according to a search criteria
|
- `search` (optional) - Return list of authorized projects according to a search criteria
|
||||||
|
|
|
||||||
|
|
@ -18,18 +18,62 @@ Returns:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"id" : 79,
|
"id": 48584,
|
||||||
"commands" : "",
|
"ref": "0.1.1",
|
||||||
"path" : "",
|
"tag": true,
|
||||||
"ref" : "",
|
"sha": "d63117656af6ff57d99e50cc270f854691f335ad",
|
||||||
"sha" : "",
|
"status": "success",
|
||||||
"project_id" : 6,
|
"name": "pages",
|
||||||
"repo_url" : "git@demo.gitlab.com:gitlab/gitlab-shell.git",
|
"token": "9dd60b4f1a439d1765357446c1084c",
|
||||||
"before_sha" : ""
|
"stage": "test",
|
||||||
|
"project_id": 479,
|
||||||
|
"project_name": "test",
|
||||||
|
"commands": "echo commands",
|
||||||
|
"repo_url": "http://gitlab-ci-token:token@gitlab.example/group/test.git",
|
||||||
|
"before_sha": "0000000000000000000000000000000000000000",
|
||||||
|
"allow_git_fetch": false,
|
||||||
|
"options": {
|
||||||
|
"image": "docker:image",
|
||||||
|
"artifacts": {
|
||||||
|
"paths": [
|
||||||
|
"public"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"cache": {
|
||||||
|
"paths": [
|
||||||
|
"vendor"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"timeout": 3600,
|
||||||
|
"variables": [
|
||||||
|
{
|
||||||
|
"key": "CI_BUILD_TAG",
|
||||||
|
"value": "0.1.1",
|
||||||
|
"public": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"depends_on_builds": [
|
||||||
|
{
|
||||||
|
"id": 48584,
|
||||||
|
"ref": "0.1.1",
|
||||||
|
"tag": true,
|
||||||
|
"sha": "d63117656af6ff57d99e50cc270f854691f335ad",
|
||||||
|
"status": "success",
|
||||||
|
"name": "build",
|
||||||
|
"token": "9dd60b4f1a439d1765357446c1084c",
|
||||||
|
"stage": "build",
|
||||||
|
"project_id": 479,
|
||||||
|
"project_name": "test",
|
||||||
|
"artifacts_file": {
|
||||||
|
"filename": "artifacts.zip",
|
||||||
|
"size": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Update details of an existing build
|
### Update details of an existing build
|
||||||
|
|
||||||
PUT /ci/builds/:id
|
PUT /ci/builds/:id
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ We do not recommend using MySQL due to various issues. For example, case [(in)se
|
||||||
|
|
||||||
# Install the database packages
|
# Install the database packages
|
||||||
sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev
|
sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev
|
||||||
|
|
||||||
# Ensure you have MySQL version 5.5.14 or later
|
# Ensure you have MySQL version 5.5.14 or later
|
||||||
mysql --version
|
mysql --version
|
||||||
|
|
||||||
|
|
@ -31,7 +31,7 @@ We do not recommend using MySQL due to various issues. For example, case [(in)se
|
||||||
# Ensure you can use the InnoDB engine which is necessary to support long indexes
|
# Ensure you can use the InnoDB engine which is necessary to support long indexes
|
||||||
# If this fails, check your MySQL config files (e.g. `/etc/mysql/*.cnf`, `/etc/mysql/conf.d/*`) for the setting "innodb = off"
|
# If this fails, check your MySQL config files (e.g. `/etc/mysql/*.cnf`, `/etc/mysql/conf.d/*`) for the setting "innodb = off"
|
||||||
mysql> SET storage_engine=INNODB;
|
mysql> SET storage_engine=INNODB;
|
||||||
|
|
||||||
# Create the GitLab production database
|
# Create the GitLab production database
|
||||||
mysql> CREATE DATABASE IF NOT EXISTS `gitlabhq_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`;
|
mysql> CREATE DATABASE IF NOT EXISTS `gitlabhq_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`;
|
||||||
|
|
||||||
|
|
@ -52,3 +52,25 @@ We do not recommend using MySQL due to various issues. For example, case [(in)se
|
||||||
mysql> \q
|
mysql> \q
|
||||||
|
|
||||||
# You are done installing the database and can go back to the rest of the installation.
|
# You are done installing the database and can go back to the rest of the installation.
|
||||||
|
|
||||||
|
## MySQL strings limits
|
||||||
|
|
||||||
|
After installation or upgrade, remember to run the `add_limits_mysql` Rake task:
|
||||||
|
|
||||||
|
```
|
||||||
|
bundle exec rake add_limits_mysql
|
||||||
|
```
|
||||||
|
|
||||||
|
The `text` type in MySQL has a different size limit than the `text` type in
|
||||||
|
PostgreSQL. In MySQL `text` columns are limited to ~65kB, whereas in PostgreSQL
|
||||||
|
`text` columns are limited up to ~1GB!
|
||||||
|
|
||||||
|
The `add_limits_mysql` Rake task converts some important `text` columns in the
|
||||||
|
GitLab database to `longtext` columns, which can persist values of up to 4GB
|
||||||
|
(sometimes less if the value contains multibyte characters).
|
||||||
|
|
||||||
|
Details can be found in the [PostgreSQL][postgres-text-type] and
|
||||||
|
[MySQL][mysql-text-types] manuals.
|
||||||
|
|
||||||
|
[postgres-text-type]: http://www.postgresql.org/docs/9.1/static/datatype-character.html
|
||||||
|
[mysql-text-types]: http://dev.mysql.com/doc/refman/5.7/en/string-type-overview.html
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,18 @@ On the sign in page there should now be a SAML button below the regular sign in
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
If you see a "500 error" in GitLab when you are redirected back from the SAML sign in page, this likely indicates that GitLab could not get the email address for the SAML user.
|
If you see a "500 error" in GitLab when you are redirected back from the SAML sign in page,
|
||||||
|
this likely indicates that GitLab could not get the email address for the SAML user.
|
||||||
|
|
||||||
Make sure the IdP provides a claim containing the user's email address, using claim name 'email' or 'mail'. The email will be used to automatically generate the GitLab username.
|
Make sure the IdP provides a claim containing the user's email address, using claim name
|
||||||
|
'email' or 'mail'. The email will be used to automatically generate the GitLab username.
|
||||||
|
|
||||||
|
If after signing in into your SAML server you are redirected back to the sign in page and
|
||||||
|
no error is displayed, check your `production.log` file. It will most likely contain the
|
||||||
|
message `Can't verify CSRF token authenticity`. This means that there is an error during
|
||||||
|
the SAML request, but this error never reaches GitLab due to the CSRF check.
|
||||||
|
|
||||||
|
To bypass this you can add `skip_before_action :verify_authenticity_token` to the
|
||||||
|
`omniauth_callbacks_controller.rb` file. This will allow the error to hit GitLab,
|
||||||
|
where it can then be seen in the usual logs, or as a flash message in the login
|
||||||
|
screen.
|
||||||
|
|
@ -48,7 +48,7 @@ which should already be on your system from GitLab 8.1.
|
||||||
```bash
|
```bash
|
||||||
cd /home/git/gitlab-workhorse
|
cd /home/git/gitlab-workhorse
|
||||||
sudo -u git -H git fetch --all
|
sudo -u git -H git fetch --all
|
||||||
sudo -u git -H git checkout 0.5.4
|
sudo -u git -H git checkout 0.6.0
|
||||||
sudo -u git -H make
|
sudo -u git -H make
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,3 +14,4 @@ Depending on the installation method and your GitLab version, there are multiple
|
||||||
## Miscellaneous
|
## Miscellaneous
|
||||||
|
|
||||||
- [MySQL to PostgreSQL](mysql_to_postgresql.md) guides you through migrating your database from MySQL to PostgreSQL.
|
- [MySQL to PostgreSQL](mysql_to_postgresql.md) guides you through migrating your database from MySQL to PostgreSQL.
|
||||||
|
- [MySQL installation guide](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/install/database_mysql.md) contains additional information about configuring GitLab to work with a MySQL database.
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 38 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 45 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue