Commit 565a5e36 authored by Kamil Trzcinski's avatar Kamil Trzcinski

Merge branch 'docker-registry' into docker-registry-view

parents 5196f8e9 c78b97df
...@@ -953,10 +953,9 @@ Performance/DoubleStartEndWith: ...@@ -953,10 +953,9 @@ Performance/DoubleStartEndWith:
Performance/EndWith: Performance/EndWith:
Enabled: false Enabled: false
# TODO: Enable LstripRstrip Cop.
# Use `strip` instead of `lstrip.rstrip`. # Use `strip` instead of `lstrip.rstrip`.
Performance/LstripRstrip: Performance/LstripRstrip:
Enabled: false Enabled: true
# TODO: Enable RangeInclude Cop. # TODO: Enable RangeInclude Cop.
# Use `Range#cover?` instead of `Range#include?`. # Use `Range#cover?` instead of `Range#include?`.
......
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.8.0 (unreleased)
- Assign labels and milestone to target project when moving issue. !3934 (Long Nguyen)
- Project#open_branches has been cleaned up and no longer loads entire records into memory.
- Log to application.log when an admin starts and stops impersonating a user
- Updated gitlab_git to 10.1.0
- GitAccess#protected_tag? no longer loads all tags just to check if a single one exists
- Reduce delay in destroying a project from 1-minute to immediately
- Make build status canceled if any of the jobs was canceled and none failed - Make build status canceled if any of the jobs was canceled and none failed
- Upgrade Sidekiq to 4.1.2
- Sanitize repo paths in new project error message
- Bump mail_room to 0.7.0 to fix stuck IDLE connections
- Remove future dates from contribution calendar graph. - Remove future dates from contribution calendar graph.
- Support e-mail notifications for comments on project snippets
- Use ActionDispatch Remote IP for Akismet checking - Use ActionDispatch Remote IP for Akismet checking
- Fix error when visiting commit builds page before build was updated - Fix error when visiting commit builds page before build was updated
- 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
- Update SVG sanitizer to conform to SVG 1.1
- Updated search UI - Updated search UI
- Added authentication service for Container Registry
- Display informative message when new milestone is created - Display informative message when new milestone is created
- Replace Devise Async with Devise ActiveJob integration. !3902 (Connor Shea)
- Allow "NEWS" and "CHANGES" as alternative names for CHANGELOG. !3768 (Connor Shea) - Allow "NEWS" and "CHANGES" as alternative names for CHANGELOG. !3768 (Connor Shea)
- Added button to toggle whitespaces changes on diff view - Added button to toggle whitespaces changes on diff view
- Backport GitLab Enterprise support from EE - Backport GitHub Enterprise import support from EE
- Create tags using Rugged for performance reasons. !3745
- Files over 5MB can only be viewed in their raw form, files over 1MB without highlighting !3718 - Files over 5MB can only be viewed in their raw form, files over 1MB without highlighting !3718
- Add support for supressing text diffs using .gitattributes on the default branch (Matt Oakes) - Add support for supressing text diffs using .gitattributes on the default branch (Matt Oakes)
- Added multiple colors for labels in dropdowns when dups happen.
- Improve description for the Two-factor Authentication sign-in screen. (Connor Shea)
- API support for the 'since' and 'until' operators on commit requests (Paco Guzman)
- Fix Gravatar hint in user profile when Gravatar is disabled. !3988 (Artem Sidorenko)
- Expire repository exists? and has_visible_content? caches after a push if necessary
- Fix unintentional filtering bug in issues sorted by milestone due (Takuya Noguchi)
v 8.7.3
- Emails, Gitlab::Email::Message, Gitlab::Diff, and Premailer::Adapter::Nokogiri are now instrumented
- Merge request widget displays TeamCity build state and code coverage correctly again.
- Fix the line code when importing PR review comments from GitHub. !4010
- Wikis are now initialized on legacy projects when checking repositories
v 8.7.2 v 8.7.2
- The "New Branch" button is now loaded asynchronously - The "New Branch" button is now loaded asynchronously
- Fix error 500 when trying to create a wiki page
- Updated spacing between notification label and button
- Label titles in filters are now escaped properly
v 8.7.1 v 8.7.1
- Throttle the update of `project.last_activity_at` to 1 minute. !3848 - Throttle the update of `project.last_activity_at` to 1 minute. !3848
...@@ -138,13 +165,25 @@ v 8.7.0 ...@@ -138,13 +165,25 @@ v 8.7.0
- Import GitHub labels - Import GitHub labels
- Add option to filter by "Owned projects" on dashboard page - Add option to filter by "Owned projects" on dashboard page
- Import GitHub milestones - Import GitHub milestones
- Fix emoji catgories in the emoji picker
- Execute system web hooks on push to the project - Execute system web hooks on push to the project
- Allow enable/disable push events for system hooks - Allow enable/disable push events for system hooks
- Fix GitHub project's link in the import page when provider has a custom URL - 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 RAW build trace output and button on build page
- Add incremental build trace update into CI API - Add incremental build trace update into CI API
v 8.6.8
- Prevent privilege escalation via "impersonate" feature
- Prevent privilege escalation via notes API
- Prevent privilege escalation via project webhook API
- Prevent XSS via Git branch and tag names
- Prevent XSS via custom issue tracker URL
- Prevent XSS via `window.opener`
- Prevent XSS via label drop-down
- Prevent information disclosure via milestone API
- Prevent information disclosure via snippet API
- Prevent information disclosure via project labels
- Prevent information disclosure via new merge request page
v 8.6.7 v 8.6.7
- Fix persistent XSS vulnerability in `commit_person_link` helper - Fix persistent XSS vulnerability in `commit_person_link` helper
- Fix persistent XSS vulnerability in Label and Milestone dropdowns - Fix persistent XSS vulnerability in Label and Milestone dropdowns
...@@ -286,6 +325,17 @@ v 8.6.0 ...@@ -286,6 +325,17 @@ v 8.6.0
- Trigger a todo for mentions on commits page - Trigger a todo for mentions on commits page
- Let project owners and admins soft delete issues and merge requests - Let project owners and admins soft delete issues and merge requests
v 8.5.12
- Prevent privilege escalation via "impersonate" feature
- Prevent privilege escalation via notes API
- Prevent privilege escalation via project webhook API
- Prevent XSS via Git branch and tag names
- Prevent XSS via custom issue tracker URL
- Prevent XSS via `window.opener`
- Prevent information disclosure via snippet API
- Prevent information disclosure via project labels
- Prevent information disclosure via new merge request page
v 8.5.11 v 8.5.11
- Fix persistent XSS vulnerability in `commit_person_link` helper - Fix persistent XSS vulnerability in `commit_person_link` helper
...@@ -436,6 +486,17 @@ v 8.5.0 ...@@ -436,6 +486,17 @@ v 8.5.0
- Show label row when filtering issues or merge requests by label (Nuttanart Pornprasitsakul) - Show label row when filtering issues or merge requests by label (Nuttanart Pornprasitsakul)
- Add Todos - Add Todos
v 8.4.10
- Prevent privilege escalation via "impersonate" feature
- Prevent privilege escalation via notes API
- Prevent privilege escalation via project webhook API
- Prevent XSS via Git branch and tag names
- Prevent XSS via custom issue tracker URL
- Prevent XSS via `window.opener`
- Prevent information disclosure via snippet API
- Prevent information disclosure via project labels
- Prevent information disclosure via new merge request page
v 8.4.9 v 8.4.9
- Fix persistent XSS vulnerability in `commit_person_link` helper - Fix persistent XSS vulnerability in `commit_person_link` helper
...@@ -561,6 +622,15 @@ v 8.4.0 ...@@ -561,6 +622,15 @@ v 8.4.0
- Add IP check against DNSBLs at account sign-up - Add IP check against DNSBLs at account sign-up
- Added cache:key to .gitlab-ci.yml allowing to fine tune the caching - Added cache:key to .gitlab-ci.yml allowing to fine tune the caching
v 8.3.9
- Prevent privilege escalation via "impersonate" feature
- Prevent privilege escalation via notes API
- Prevent privilege escalation via project webhook API
- Prevent XSS via custom issue tracker URL
- Prevent XSS via `window.opener`
- Prevent information disclosure via project labels
- Prevent information disclosure via new merge request page
v 8.3.8 v 8.3.8
- Fix persistent XSS vulnerability in `commit_person_link` helper - Fix persistent XSS vulnerability in `commit_person_link` helper
...@@ -670,6 +740,17 @@ v 8.3.0 ...@@ -670,6 +740,17 @@ v 8.3.0
- Expose Git's version in the admin area - Expose Git's version in the admin area
- Show "New Merge Request" buttons on canonical repos when you have a fork (Josh Frye) - Show "New Merge Request" buttons on canonical repos when you have a fork (Josh Frye)
v 8.2.5
- Prevent privilege escalation via "impersonate" feature
- Prevent privilege escalation via notes API
- Prevent privilege escalation via project webhook API
- Prevent XSS via `window.opener`
- Prevent information disclosure via project labels
- Prevent information disclosure via new merge request page
v 8.2.4
- Bump Git version requirement to 2.7.4
v 8.2.3 v 8.2.3
- Fix application settings cache not expiring after changes (Stan Hu) - Fix application settings cache not expiring after changes (Stan Hu)
- Fix Error 500s when creating global milestones with Unicode characters (Stan Hu) - Fix Error 500s when creating global milestones with Unicode characters (Stan Hu)
......
...@@ -142,6 +142,16 @@ code snippet right after your description in a new line: `~"feature proposal"`. ...@@ -142,6 +142,16 @@ code snippet right after your description in a new line: `~"feature proposal"`.
Please keep feature proposals as small and simple as possible, complex ones Please keep feature proposals as small and simple as possible, complex ones
might be edited to make them small and simple. might be edited to make them small and simple.
You are encouraged to use the template below for feature proposals.
```
## Description including problem, use cases, benefits, and/or goals
## Proposal
## Links / references
```
For changes in the interface, it can be helpful to create a mockup first. For changes in the interface, it can be helpful to create a mockup first.
If you want to create something yourself, consider opening an issue first to If you want to create something yourself, consider opening an issue first to
discuss whether it is interesting to include this in GitLab. discuss whether it is interesting to include this in GitLab.
...@@ -349,7 +359,7 @@ on your merge request feel free to mention one of the Merge Marshalls in the ...@@ -349,7 +359,7 @@ on your merge request feel free to mention one of the Merge Marshalls in the
Please ensure that your merge request meets the contribution acceptance criteria. Please ensure that your merge request meets the contribution acceptance criteria.
When having your code reviewed and when reviewing merge requests please take the When having your code reviewed and when reviewing merge requests please take the
[Thoughtbot code review guide] into account. [code review guidelines](doc/development/code_review.md) into account.
### Merge request description format ### Merge request description format
...@@ -523,4 +533,3 @@ available at [http://contributor-covenant.org/version/1/1/0/](http://contributor ...@@ -523,4 +533,3 @@ available at [http://contributor-covenant.org/version/1/1/0/](http://contributor
[gitlab-design]: https://gitlab.com/gitlab-org/gitlab-design [gitlab-design]: https://gitlab.com/gitlab-org/gitlab-design
[free Antetype viewer (Mac OSX only)]: https://itunes.apple.com/us/app/antetype-viewer/id824152298?mt=12 [free Antetype viewer (Mac OSX only)]: https://itunes.apple.com/us/app/antetype-viewer/id824152298?mt=12
[`gitlab1.atype` file]: https://gitlab.com/gitlab-org/gitlab-design/tree/master/gitlab1.atype/ [`gitlab1.atype` file]: https://gitlab.com/gitlab-org/gitlab-design/tree/master/gitlab1.atype/
[Thoughtbot code review guide]: https://github.com/thoughtbot/guides/tree/master/code-review
...@@ -19,7 +19,8 @@ gem "pg", '~> 0.18.2', group: :postgres ...@@ -19,7 +19,8 @@ gem "pg", '~> 0.18.2', group: :postgres
# Authentication libraries # Authentication libraries
gem 'devise', '~> 3.5.4' gem 'devise', '~> 3.5.4'
gem 'doorkeeper', '~> 2.2.0' gem 'doorkeeper', '~> 3.1'
gem 'devise-async', '~> 0.9.0'
gem 'omniauth', '~> 1.3.1' gem 'omniauth', '~> 1.3.1'
gem 'omniauth-auth0', '~> 1.4.1' gem 'omniauth-auth0', '~> 1.4.1'
gem 'omniauth-azure-oauth2', '~> 0.0.6' gem 'omniauth-azure-oauth2', '~> 0.0.6'
...@@ -271,7 +272,7 @@ group :development, :test do ...@@ -271,7 +272,7 @@ group :development, :test do
gem 'database_cleaner', '~> 1.4.0' gem 'database_cleaner', '~> 1.4.0'
gem 'factory_girl_rails', '~> 4.6.0' gem 'factory_girl_rails', '~> 4.6.0'
gem 'rspec-rails', '~> 3.3.0' gem 'rspec-rails', '~> 3.4.0'
gem 'rspec-retry' gem 'rspec-retry'
gem 'spinach-rails', '~> 0.2.1' gem 'spinach-rails', '~> 0.2.1'
gem 'spinach-rerun-reporter', '~> 0.0.2' gem 'spinach-rerun-reporter', '~> 0.0.2'
...@@ -321,7 +322,7 @@ gem "newrelic_rpm", '~> 3.14' ...@@ -321,7 +322,7 @@ gem "newrelic_rpm", '~> 3.14'
gem 'octokit', '~> 4.3.0' gem 'octokit', '~> 4.3.0'
gem "mail_room", "~> 0.6.1" gem "mail_room", "~> 0.7"
gem 'email_reply_parser', '~> 0.5.8' gem 'email_reply_parser', '~> 0.5.8'
......
...@@ -135,7 +135,7 @@ GEM ...@@ -135,7 +135,7 @@ GEM
execjs execjs
coffee-script-source (1.10.0) coffee-script-source (1.10.0)
colorize (0.7.7) colorize (0.7.7)
concurrent-ruby (1.0.1) concurrent-ruby (1.0.2)
connection_pool (2.2.0) connection_pool (2.2.0)
coveralls (0.8.13) coveralls (0.8.13)
json (~> 1.8) json (~> 1.8)
...@@ -165,6 +165,8 @@ GEM ...@@ -165,6 +165,8 @@ GEM
responders responders
thread_safe (~> 0.1) thread_safe (~> 0.1)
warden (~> 1.2.3) warden (~> 1.2.3)
devise-async (0.9.0)
devise (~> 3.2)
devise-two-factor (2.0.1) devise-two-factor (2.0.1)
activesupport activesupport
attr_encrypted (~> 1.3.2) attr_encrypted (~> 1.3.2)
...@@ -174,7 +176,7 @@ GEM ...@@ -174,7 +176,7 @@ GEM
diff-lcs (1.2.5) diff-lcs (1.2.5)
diffy (3.0.7) diffy (3.0.7)
docile (1.1.5) docile (1.1.5)
doorkeeper (2.2.2) doorkeeper (3.1.0)
railties (>= 3.2) railties (>= 3.2)
dropzonejs-rails (0.7.2) dropzonejs-rails (0.7.2)
rails (> 3.1) rails (> 3.1)
...@@ -352,7 +354,7 @@ GEM ...@@ -352,7 +354,7 @@ GEM
posix-spawn (~> 0.3) posix-spawn (~> 0.3)
gitlab_emoji (0.3.1) gitlab_emoji (0.3.1)
gemojione (~> 2.2, >= 2.2.1) gemojione (~> 2.2, >= 2.2.1)
gitlab_git (10.0.1) gitlab_git (10.1.0)
activesupport (~> 4.0) activesupport (~> 4.0)
charlock_holmes (~> 0.7.3) charlock_holmes (~> 0.7.3)
github-linguist (~> 4.7.0) github-linguist (~> 4.7.0)
...@@ -466,7 +468,7 @@ GEM ...@@ -466,7 +468,7 @@ GEM
systemu (~> 2.6.2) systemu (~> 2.6.2)
mail (2.6.4) mail (2.6.4)
mime-types (>= 1.16, < 4) mime-types (>= 1.16, < 4)
mail_room (0.6.1) mail_room (0.7.0)
method_source (0.8.2) method_source (0.8.2)
mime-types (2.99.1) mime-types (2.99.1)
mimemagic (0.3.0) mimemagic (0.3.0)
...@@ -663,29 +665,29 @@ GEM ...@@ -663,29 +665,29 @@ GEM
chunky_png chunky_png
rqrcode-rails3 (0.1.7) rqrcode-rails3 (0.1.7)
rqrcode (>= 0.4.2) rqrcode (>= 0.4.2)
rspec (3.3.0) rspec (3.4.0)
rspec-core (~> 3.3.0) rspec-core (~> 3.4.0)
rspec-expectations (~> 3.3.0) rspec-expectations (~> 3.4.0)
rspec-mocks (~> 3.3.0) rspec-mocks (~> 3.4.0)
rspec-core (3.3.2) rspec-core (3.4.4)
rspec-support (~> 3.3.0) rspec-support (~> 3.4.0)
rspec-expectations (3.3.1) rspec-expectations (3.4.0)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.3.0) rspec-support (~> 3.4.0)
rspec-mocks (3.3.2) rspec-mocks (3.4.1)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.3.0) rspec-support (~> 3.4.0)
rspec-rails (3.3.3) rspec-rails (3.4.2)
actionpack (>= 3.0, < 4.3) actionpack (>= 3.0, < 4.3)
activesupport (>= 3.0, < 4.3) activesupport (>= 3.0, < 4.3)
railties (>= 3.0, < 4.3) railties (>= 3.0, < 4.3)
rspec-core (~> 3.3.0) rspec-core (~> 3.4.0)
rspec-expectations (~> 3.3.0) rspec-expectations (~> 3.4.0)
rspec-mocks (~> 3.3.0) rspec-mocks (~> 3.4.0)
rspec-support (~> 3.3.0) rspec-support (~> 3.4.0)
rspec-retry (0.4.5) rspec-retry (0.4.5)
rspec-core rspec-core
rspec-support (3.3.0) rspec-support (3.4.1)
rubocop (0.38.0) rubocop (0.38.0)
parser (>= 2.3.0.6, < 3.0) parser (>= 2.3.0.6, < 3.0)
powerpack (~> 0.1) powerpack (~> 0.1)
...@@ -739,7 +741,7 @@ GEM ...@@ -739,7 +741,7 @@ GEM
rack rack
shoulda-matchers (2.8.0) shoulda-matchers (2.8.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
sidekiq (4.1.1) sidekiq (4.1.2)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
connection_pool (~> 2.2, >= 2.2.0) connection_pool (~> 2.2, >= 2.2.0)
redis (~> 3.2, >= 3.2.1) redis (~> 3.2, >= 3.2.1)
...@@ -922,9 +924,10 @@ DEPENDENCIES ...@@ -922,9 +924,10 @@ DEPENDENCIES
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.4) devise (~> 3.5.4)
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)
doorkeeper (~> 2.2.0) doorkeeper (~> 3.1)
dropzonejs-rails (~> 0.7.1) dropzonejs-rails (~> 0.7.1)
email_reply_parser (~> 0.5.8) email_reply_parser (~> 0.5.8)
email_spec (~> 1.6.0) email_spec (~> 1.6.0)
...@@ -964,7 +967,7 @@ DEPENDENCIES ...@@ -964,7 +967,7 @@ DEPENDENCIES
letter_opener_web (~> 1.3.0) letter_opener_web (~> 1.3.0)
licensee (~> 8.0.0) licensee (~> 8.0.0)
loofah (~> 2.0.3) loofah (~> 2.0.3)
mail_room (~> 0.6.1) mail_room (~> 0.7)
method_source (~> 0.8) method_source (~> 0.8)
minitest (~> 5.7.0) minitest (~> 5.7.0)
mousetrap-rails (~> 1.4.6) mousetrap-rails (~> 1.4.6)
...@@ -1014,7 +1017,7 @@ DEPENDENCIES ...@@ -1014,7 +1017,7 @@ DEPENDENCIES
responders (~> 2.0) responders (~> 2.0)
rouge (~> 1.10.1) rouge (~> 1.10.1)
rqrcode-rails3 (~> 0.1.7) rqrcode-rails3 (~> 0.1.7)
rspec-rails (~> 3.3.0) rspec-rails (~> 3.4.0)
rspec-retry rspec-retry
rubocop (~> 0.38.0) rubocop (~> 0.38.0)
ruby-fogbugz (~> 0.2.1) ruby-fogbugz (~> 0.2.1)
...@@ -1061,4 +1064,4 @@ DEPENDENCIES ...@@ -1061,4 +1064,4 @@ DEPENDENCIES
wikicloth (= 0.8.1) wikicloth (= 0.8.1)
BUNDLED WITH BUNDLED WITH
1.11.2 1.12.1
# GitLab # GitLab
[![build status](https://ci.gitlab.com/projects/1/status.svg?ref=master)](https://ci.gitlab.com/projects/1?ref=master) [![build status](https://gitlab.com/gitlab-org/gitlab-ce/badges/master/build.svg)](https://gitlab.com/gitlab-org/gitlab-ce/commits/master)
[![Build Status](https://semaphoreci.com/api/v1/projects/2f1a5809-418b-4cc2-a1f4-819607579fe7/400484/shields_badge.svg)](https://semaphoreci.com/gitlabhq/gitlabhq) [![Build Status](https://semaphoreci.com/api/v1/projects/2f1a5809-418b-4cc2-a1f4-819607579fe7/400484/shields_badge.svg)](https://semaphoreci.com/gitlabhq/gitlabhq)
[![Code Climate](https://codeclimate.com/github/gitlabhq/gitlabhq.svg)](https://codeclimate.com/github/gitlabhq/gitlabhq) [![Code Climate](https://codeclimate.com/github/gitlabhq/gitlabhq.svg)](https://codeclimate.com/github/gitlabhq/gitlabhq)
[![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.svg?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq?branch=master) [![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.svg?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq?branch=master)
...@@ -20,6 +20,10 @@ To see how GitLab looks please see the [features page on our website](https://ab ...@@ -20,6 +20,10 @@ To see how GitLab looks please see the [features page on our website](https://ab
- Completely free and open source (MIT Expat license) - Completely free and open source (MIT Expat license)
- Powered by [Ruby on Rails](https://github.com/rails/rails) - Powered by [Ruby on Rails](https://github.com/rails/rails)
## Hiring
We're hiring developers, support people, and production engineers all the time, please see our [jobs page](https://about.gitlab.com/jobs/).
## Editions ## Editions
There are two editions of GitLab: There are two editions of GitLab:
...@@ -80,7 +84,7 @@ There are a lot of [third-party applications integrating with GitLab](https://ab ...@@ -80,7 +84,7 @@ There are a lot of [third-party applications integrating with GitLab](https://ab
## GitLab release cycle ## GitLab release cycle
For more information about the release process see the [release documentation](http://doc.gitlab.com/ce/release/). For more information about the release process see the [release documentation](https://gitlab.com/gitlab-org/release-tools/blob/master/README.md).
## Upgrading ## Upgrading
......
...@@ -163,6 +163,21 @@ class @LabelsSelect ...@@ -163,6 +163,21 @@ class @LabelsSelect
$.ajax( $.ajax(
url: labelUrl url: labelUrl
).done (data) -> ).done (data) ->
data = _.chain data
.groupBy (label) ->
label.title
.map (label) ->
color = _.map label, (dup) ->
dup.color
return {
id: label[0].id
title: label[0].title
color: color
duplicate: color.length > 1
}
.value()
if $dropdown.hasClass 'js-extra-options' if $dropdown.hasClass 'js-extra-options'
if showNo if showNo
data.unshift( data.unshift(
...@@ -178,6 +193,7 @@ class @LabelsSelect ...@@ -178,6 +193,7 @@ class @LabelsSelect
if data.length > 2 if data.length > 2
data.splice 2, 0, 'divider' data.splice 2, 0, 'divider'
callback data callback data
renderRow: (label) -> renderRow: (label) ->
...@@ -192,11 +208,31 @@ class @LabelsSelect ...@@ -192,11 +208,31 @@ class @LabelsSelect
if $dropdown.hasClass('js-multiselect') and removesAll if $dropdown.hasClass('js-multiselect') and removesAll
selectedClass.push 'dropdown-clear-active' selectedClass.push 'dropdown-clear-active'
color = if label.color? then "<span class='dropdown-label-box' style='background-color: #{label.color}'></span>" else "" if label.duplicate
spacing = 100 / label.color.length
# Reduce the colors to 4
label.color = label.color.filter (color, i) ->
i < 4
color = _.map(label.color, (color, i) ->
percentFirst = Math.floor(spacing * i)
percentSecond = Math.floor(spacing * (i + 1))
"#{color} #{percentFirst}%,#{color} #{percentSecond}% "
).join(',')
color = "linear-gradient(#{color})"
else
if label.color?
color = label.color[0]
if color
colorEl = "<span class='dropdown-label-box' style='background: #{color}'></span>"
else
colorEl = ''
"<li> "<li>
<a href='#' class='#{selectedClass.join(' ')}'> <a href='#' class='#{selectedClass.join(' ')}'>
#{color} #{colorEl}
#{_.escape(label.title)} #{_.escape(label.title)}
</a> </a>
</li>" </li>"
......
...@@ -68,20 +68,18 @@ class @MergeRequestWidget ...@@ -68,20 +68,18 @@ class @MergeRequestWidget
$.getJSON @opts.ci_status_url, (data) => $.getJSON @opts.ci_status_url, (data) =>
@readyForCICheck = true @readyForCICheck = true
if @firstCICheck if data.status is ''
@firstCICheck = false
@opts.ci_status = data.status
if @opts.ci_status is ''
@opts.ci_status = data.status
return return
if data.status isnt @opts.ci_status and data.status? if @firstCiCheck || data.status isnt @opts.ci_status and data.status?
@opts.ci_status = data.status
@showCIStatus data.status @showCIStatus data.status
if data.coverage if data.coverage
@showCICoverage data.coverage @showCICoverage data.coverage
if showNotification # The first check should only update the UI, a notification
# should only be displayed on status changes
if showNotification and not @firstCiCheck
status = @ciLabelForStatus(data.status) status = @ciLabelForStatus(data.status)
if status is "preparing" if status is "preparing"
...@@ -104,8 +102,7 @@ class @MergeRequestWidget ...@@ -104,8 +102,7 @@ class @MergeRequestWidget
@close() @close()
Turbolinks.visit _this.opts.builds_path Turbolinks.visit _this.opts.builds_path
) )
@firstCiCheck = false
@opts.ci_status = data.status
showCIStatus: (state) -> showCIStatus: (state) ->
$('.ci_widget').hide() $('.ci_widget').hide()
......
...@@ -167,8 +167,8 @@ class @Notes ...@@ -167,8 +167,8 @@ class @Notes
return return
if note.award if note.award
awards_handler.addAwardToEmojiBar(note.note) awardsHandler.addAwardToEmojiBar(note.note)
awards_handler.scrollToAwards() awardsHandler.scrollToAwards()
# render note if it not present in loaded list # render note if it not present in loaded list
# or skip if rendered # or skip if rendered
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
@import "framework/lists.scss"; @import "framework/lists.scss";
@import "framework/markdown_area.scss"; @import "framework/markdown_area.scss";
@import "framework/mobile.scss"; @import "framework/mobile.scss";
@import "framework/modal.scss";
@import "framework/nav.scss"; @import "framework/nav.scss";
@import "framework/pagination.scss"; @import "framework/pagination.scss";
@import "framework/progress.scss"; @import "framework/progress.scss";
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
&.s46 { width: 46px; height: 46px; margin-right: 15px; } &.s46 { width: 46px; height: 46px; margin-right: 15px; }
&.s48 { width: 48px; height: 48px; margin-right: 10px; } &.s48 { width: 48px; height: 48px; margin-right: 10px; }
&.s60 { width: 60px; height: 60px; margin-right: 12px; } &.s60 { width: 60px; height: 60px; margin-right: 12px; }
&.s70 { width: 70px; height: 70px; margin-right: 14px; }
&.s90 { width: 90px; height: 90px; margin-right: 15px; } &.s90 { width: 90px; height: 90px; margin-right: 15px; }
&.s110 { width: 110px; height: 110px; margin-right: 15px; } &.s110 { width: 110px; height: 110px; margin-right: 15px; }
&.s140 { width: 140px; height: 140px; margin-right: 20px; } &.s140 { width: 140px; height: 140px; margin-right: 20px; }
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
line-height: 36px; line-height: 36px;
} }
.gray-content-block { .row-content-block {
margin-top: 0; margin-top: 0;
margin-bottom: -$gl-padding; margin-bottom: -$gl-padding;
background-color: $background-color; background-color: $background-color;
...@@ -81,6 +81,11 @@ ...@@ -81,6 +81,11 @@
margin-left: 10px; margin-left: 10px;
} }
} }
&.build-content {
background-color: $white-light;
border-top: none;
}
} }
.cover-block { .cover-block {
...@@ -113,7 +118,7 @@ ...@@ -113,7 +118,7 @@
line-height: 1.1; line-height: 1.1;
h1 { h1 {
color: #313236; color: $gl-gray-dark;
margin-bottom: 6px; margin-bottom: 6px;
font-size: 23px; font-size: 23px;
} }
...@@ -150,6 +155,41 @@ ...@@ -150,6 +155,41 @@
right: auto; right: auto;
} }
} }
&.groups-cover-block {
background: $white-light;
border-bottom: 1px solid $border-color;
text-align: left;
padding: 24px 0;
.group-info {
.cover-title {
margin-top: 9px;
}
p {
margin-bottom: 0;
}
}
@media (max-width: $screen-xs-max) {
text-align: center;
.avatar {
float: none;
}
}
}
.group-info {
h1 {
display: inline;
font-weight: normal;
font-size: 24px;
color: $gl-title-color;
}
}
} }
.block-connector { .block-connector {
......
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
} }
@mixin btn-gray { @mixin btn-gray {
@include btn-color($gray-light, $border-gray-light, $gray-normal, $border-gray-light, $gray-dark, $border-gray-dark, #313236); @include btn-color($gray-light, $border-gray-light, $gray-normal, $border-gray-light, $gray-dark, $border-gray-dark, $gl-gray-dark);
} }
@mixin btn-white { @mixin btn-white {
...@@ -251,3 +251,10 @@ ...@@ -251,3 +251,10 @@
.btn-file-option { .btn-file-option {
background: linear-gradient(180deg, $white-light 25%, $gray-light 100%); background: linear-gradient(180deg, $white-light 25%, $gray-light 100%);
} }
.btn-build {
margin-left: 10px;
i {
color: $gl-icon-color;
}
}
...@@ -30,6 +30,10 @@ header { ...@@ -30,6 +30,10 @@ header {
border: none; border: none;
border-bottom: 1px solid $border-color; border-bottom: 1px solid $border-color;
&.with-horizontal-nav {
border-bottom: none;
}
.container-fluid { .container-fluid {
width: 100% !important; width: 100% !important;
filter: none; filter: none;
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
} }
.rss-btn { .rss-btn {
display: none !important; display: none;
} }
.project-home-links { .project-home-links {
......
.modal-body {
position: relative;
overflow-y: auto;
padding: 15px;
.form-actions {
margin: -$gl-padding+1;
margin-top: 15px;
}
.text-danger {
font-weight: bold;
}
}
body.modal-open {
overflow: hidden;
}
.modal .modal-dialog {
width: 860px;
}
...@@ -26,8 +26,8 @@ ...@@ -26,8 +26,8 @@
} }
&.active a { &.active a {
color: #000; border-bottom: 2px solid $link-underline-blue;
border-bottom: 2px solid #4688f1; color: $black;
} }
.badge { .badge {
...@@ -140,6 +140,12 @@ ...@@ -140,6 +140,12 @@
} }
} }
.project-filter-form {
input {
background-color: $background-color;
}
}
@media (max-width: $screen-xs-max) { @media (max-width: $screen-xs-max) {
padding-bottom: 0; padding-bottom: 0;
...@@ -187,13 +193,31 @@ ...@@ -187,13 +193,31 @@
} }
.layout-nav { .layout-nav {
position: fixed;
top: $header-height;
width: 100%;
z-index: 1;
background: $background-color; background: $background-color;
border-bottom: 1px solid $border-color; border-bottom: 1px solid $border-color;
transition-duration: .3s;
.controls { .controls {
float: right; float: right;
position: relative; padding: 7px 5px 0 0;
top: 10px;
i {
color: $layout-link-gray;
}
.fa-rss,
.fa-cog {
font-size: 16px;
}
.fa-caret-down {
margin-left: 5px;
color: $gl-icon-color;
}
.dropdown { .dropdown {
margin-left: 7px; margin-left: 7px;
...@@ -202,5 +226,34 @@ ...@@ -202,5 +226,34 @@
.nav-links { .nav-links {
border-bottom: none; border-bottom: none;
height: 51px;
white-space: nowrap;
overflow-x: auto;
li {
a {
padding-top: 10px;
}
a, i {
color: $layout-link-gray;
}
&.active {
a, i {
color: $black;
}
}
.badge {
color: $gl-icon-color;
}
}
} }
}
.page-with-layout-nav {
margin-top: 50px;
} }
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
position: absolute; position: absolute;
width: 58px; width: 58px;
cursor: pointer; cursor: pointer;
margin-top: 8px;
} }
.page-with-sidebar { .page-with-sidebar {
...@@ -62,7 +63,7 @@ ...@@ -62,7 +63,7 @@
float: left; float: left;
height: $header-height; height: $header-height;
width: 100%; width: 100%;
padding: 11px 0 11px 22px; padding-left: 22px;
overflow: hidden; overflow: hidden;
outline: none; outline: none;
transition-duration: .3s; transition-duration: .3s;
...@@ -85,7 +86,7 @@ ...@@ -85,7 +86,7 @@
margin: 0; margin: 0;
margin-left: 50px; margin-left: 50px;
font-size: 19px; font-size: 19px;
line-height: 41px; line-height: 50px;
font-weight: normal; font-weight: normal;
} }
} }
...@@ -254,6 +255,10 @@ ...@@ -254,6 +255,10 @@
} }
} }
} }
.layout-nav {
padding-right: $sidebar_collapsed_width;
}
} }
.page-sidebar-expanded { .page-sidebar-expanded {
...@@ -280,6 +285,10 @@ ...@@ -280,6 +285,10 @@
} }
} }
} }
.layout-nav {
padding-right: $sidebar_width;
}
} }
.right-sidebar-collapsed { .right-sidebar-collapsed {
......
...@@ -32,13 +32,11 @@ table { ...@@ -32,13 +32,11 @@ table {
th { th {
background-color: $background-color; background-color: $background-color;
font-weight: normal; font-weight: normal;
font-size: 15px; border-bottom: none;
border-bottom: 1px solid $border-color;
} }
td { td {
border-color: $table-border-color; border-color: $table-border-color;
border-bottom: 1px solid $border-color;
} }
} }
} }
......
...@@ -81,7 +81,7 @@ ...@@ -81,7 +81,7 @@
// Labels // Labels
.label { .label {
padding: 2px 4px; padding: 4px 5px;
font-size: 13px; font-size: 13px;
font-style: normal; font-style: normal;
font-weight: normal; font-weight: normal;
......
...@@ -42,14 +42,14 @@ ...@@ -42,14 +42,14 @@
margin: 24px 0 12px; margin: 24px 0 12px;
padding: 0 0 10px; padding: 0 0 10px;
border-bottom: 1px solid #e7e9ed; border-bottom: 1px solid #e7e9ed;
color: #313236; color: $gl-gray-dark;
} }
h2 { h2 {
font-size: 1.2em; font-size: 1.2em;
font-weight: 600; font-weight: 600;
margin: 24px 0 12px; margin: 24px 0 12px;
color: #313236; color: $gl-gray-dark;
} }
h3 { h3 {
......
...@@ -12,7 +12,7 @@ $gutter_inner_width: 258px; ...@@ -12,7 +12,7 @@ $gutter_inner_width: 258px;
*/ */
$border-color: #e5e5e5; $border-color: #e5e5e5;
$focus-border-color: #3aabf0; $focus-border-color: #3aabf0;
$table-border-color: #eef0f2; $table-border-color: #ececec;
$background-color: #fafafa; $background-color: #fafafa;
/* /*
...@@ -20,7 +20,7 @@ $background-color: #fafafa; ...@@ -20,7 +20,7 @@ $background-color: #fafafa;
*/ */
$gl-font-size: 15px; $gl-font-size: 15px;
$gl-title-color: #333; $gl-title-color: #333;
$gl-text-color: #555; $gl-text-color: #5c5c5c;
$gl-text-green: #4a2; $gl-text-green: #4a2;
$gl-text-red: #d12f19; $gl-text-red: #d12f19;
$gl-text-orange: #d90; $gl-text-orange: #d90;
...@@ -30,6 +30,7 @@ $gl-placeholder-color: #8f8f8f; ...@@ -30,6 +30,7 @@ $gl-placeholder-color: #8f8f8f;
$gl-icon-color: $gl-placeholder-color; $gl-icon-color: $gl-placeholder-color;
$gl-grayish-blue: #7f8fa4; $gl-grayish-blue: #7f8fa4;
$gl-gray: $gl-text-color; $gl-gray: $gl-text-color;
$gl-gray-dark: #313236;
$gl-header-color: $gl-title-color; $gl-header-color: $gl-title-color;
/* /*
...@@ -65,7 +66,7 @@ $gl-padding-top: 10px; ...@@ -65,7 +66,7 @@ $gl-padding-top: 10px;
$row-hover: #f4f8fe; $row-hover: #f4f8fe;
$progress-color: #c0392b; $progress-color: #c0392b;
$avatar_radius: 50%; $avatar_radius: 50%;
$header-height: 58px; $header-height: 50px;
$fixed-layout-width: 1280px; $fixed-layout-width: 1280px;
$gl-avatar-size: 40px; $gl-avatar-size: 40px;
$error-exclamation-point: #e62958; $error-exclamation-point: #e62958;
...@@ -74,6 +75,9 @@ $btn-transparent-color: #8f8f8f; ...@@ -74,6 +75,9 @@ $btn-transparent-color: #8f8f8f;
$settings-icon-size: 18px; $settings-icon-size: 18px;
$provider-btn-group-border: #e5e5e5; $provider-btn-group-border: #e5e5e5;
$provider-btn-not-active-color: #4688f1; $provider-btn-not-active-color: #4688f1;
$link-underline-blue: #4a8bee;
$layout-link-gray: #7e7c7c;
$todo-alert-blue: #428bca;
/* /*
* Color schema * Color schema
...@@ -108,6 +112,7 @@ $red-light: #e52c5a; ...@@ -108,6 +112,7 @@ $red-light: #e52c5a;
$red-normal: #d22852; $red-normal: #d22852;
$red-dark: darken($red-normal, 5%); $red-dark: darken($red-normal, 5%);
$black: #000;
$black-transparent: rgba(0, 0, 0, 0.3); $black-transparent: rgba(0, 0, 0, 0.3);
$border-white-light: #f1f2f4; $border-white-light: #f1f2f4;
......
...@@ -83,3 +83,12 @@ ...@@ -83,3 +83,12 @@
} }
} }
} }
table.builds {
.build-link {
a {
color: $gl-dark-link-color;
}
}
}
...@@ -31,9 +31,23 @@ ...@@ -31,9 +31,23 @@
} }
.commit-committer-link, .commit-committer-link,
.commit-author-link { .commit-author-link {
color: #444; color: $gl-gray;
font-weight: bold; font-weight: bold;
} }
.time_ago {
margin-left: 8px;
}
.fa-clipboard {
color: $dropdown-title-btn-color;
}
.commit-info {
&.branches {
margin-left: 8px;
}
}
} }
.commit-box { .commit-box {
...@@ -42,7 +56,7 @@ ...@@ -42,7 +56,7 @@
.commit-title { .commit-title {
margin: 0; margin: 0;
font-size: 23px; font-size: 23px;
color: #313236; color: $gl-gray-dark;
} }
.commit-description { .commit-description {
...@@ -83,6 +97,14 @@ ...@@ -83,6 +97,14 @@
} }
} }
.commit-action-buttons {
i {
color: $gl-icon-color;
font-size: 13px;
margin-right: 3px;
}
}
/* /*
* Commit message textarea for web editor and * Commit message textarea for web editor and
* custom merge request message * custom merge request message
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
.title { .title {
margin: 0; margin: 0;
font-size: 23px; font-size: 23px;
color: #313236; color: $gl-gray-dark;
} }
.description { .description {
......
...@@ -55,25 +55,6 @@ ...@@ -55,25 +55,6 @@
} }
} }
.modal-body {
position: relative;
overflow-y: auto;
padding: 15px;
.form-actions {
margin: -$gl-padding+1;
margin-top: 15px;
}
}
body.modal-open {
overflow: hidden;
}
.modal .modal-dialog {
width: 860px;
}
.documentation { .documentation {
padding: 7px; padding: 7px;
} }
...@@ -104,7 +104,7 @@ ...@@ -104,7 +104,7 @@
font-weight: 600; font-weight: 600;
font-size: 17px; font-size: 17px;
margin: 5px 0; margin: 5px 0;
color: #313236; color: $gl-gray-dark;
} }
p:last-child { p:last-child {
...@@ -136,7 +136,7 @@ ...@@ -136,7 +136,7 @@
} }
.label-branch { .label-branch {
color: #313236; color: $gl-gray-dark;
font-family: $monospace_font; font-family: $monospace_font;
font-weight: bold; font-weight: bold;
overflow: hidden; overflow: hidden;
...@@ -272,3 +272,19 @@ ...@@ -272,3 +272,19 @@
display: inline-block; display: inline-block;
width: 250px; width: 250px;
} }
.table-holder {
.builds {
th {
background-color: $white-light;
color: $gl-placeholder-color;
}
th,
td {
padding: 16px;
}
}
}
...@@ -28,7 +28,7 @@ li.milestone { ...@@ -28,7 +28,7 @@ li.milestone {
// Issue title // Issue title
span a { span a {
color: rgba(0,0,0,0.64); color: $gl-text-color;
} }
} }
} }
...@@ -51,7 +51,7 @@ li.milestone { ...@@ -51,7 +51,7 @@ li.milestone {
margin-top: 7px; margin-top: 7px;
.issuable-number { .issuable-number {
color: rgba(0,0,0,0.44); color: $gl-placeholder-color;
margin-right: 5px; margin-right: 5px;
} }
.avatar { .avatar {
......
...@@ -114,10 +114,6 @@ ul.notes { ...@@ -114,10 +114,6 @@ ul.notes {
word-break: keep-all; word-break: keep-all;
} }
} }
a {
word-break: break-all;
}
} }
.note-header { .note-header {
...@@ -172,6 +168,11 @@ ul.notes { ...@@ -172,6 +168,11 @@ ul.notes {
.notes { .notes {
background-color: $white-light; background-color: $white-light;
} }
a code {
top: 0;
margin-right: 0;
}
} }
} }
} }
......
...@@ -205,3 +205,21 @@ ...@@ -205,3 +205,21 @@
text-align: center; text-align: center;
} }
} }
.user-profile {
@media (max-width: $screen-xs-max) {
.cover-block {
padding-top: 20px;
}
.cover-controls {
position: static;
margin-bottom: 20px;
.btn {
display: inline-block;
width: 48%;
}
}
}
}
...@@ -178,7 +178,7 @@ ...@@ -178,7 +178,7 @@
.option-title { .option-title {
font-weight: normal; font-weight: normal;
display: inline-block; display: inline-block;
color: #313236; color: $gl-gray-dark;
} }
.option-descr { .option-descr {
......
.container-fluid { .container-fluid {
.ci-status { .ci-status {
padding: 2px 7px; padding: 2px 7px;
margin-right: 5px; margin-right: 10px;
border: 1px solid #eee; border: 1px solid #eee;
white-space: nowrap; white-space: nowrap;
@include border-radius(4px); @include border-radius(4px);
......
...@@ -6,9 +6,16 @@ ...@@ -6,9 +6,16 @@
.navbar-nav { .navbar-nav {
li { li {
.badge.todos-pending-count { .badge.todos-pending-count {
background-color: $gl-icon-color;
margin-top: -5px; margin-top: -5px;
font-weight: normal; font-weight: normal;
background: $todo-alert-blue;
margin-left: -17px;
font-size: 11px;
color: white;
padding: 3px;
padding-top: 1px;
padding-bottom: 1px;
border-radius: 3px;
} }
} }
} }
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
tr { tr {
> td, > th { > td, > th {
line-height: 26px; line-height: 23px;
} }
&:hover { &:hover {
......
...@@ -6,12 +6,6 @@ class Admin::ApplicationController < ApplicationController ...@@ -6,12 +6,6 @@ class Admin::ApplicationController < ApplicationController
layout 'admin' layout 'admin'
def authenticate_admin! def authenticate_admin!
return render_404 unless current_user.is_admin? render_404 unless current_user.is_admin?
end
def authorize_impersonator!
if session[:impersonator_id]
User.find_by!(username: session[:impersonator_id]).admin?
end
end end
end end
...@@ -39,6 +39,12 @@ class Admin::HooksController < Admin::ApplicationController ...@@ -39,6 +39,12 @@ class Admin::HooksController < Admin::ApplicationController
end end
def hook_params def hook_params
params.require(:hook).permit(:url, :enable_ssl_verification, :push_events, :tag_push_events) params.require(:hook).permit(
:enable_ssl_verification,
:push_events,
:tag_push_events,
:token,
:url
)
end end
end end
class Admin::ImpersonationController < Admin::ApplicationController
skip_before_action :authenticate_admin!, only: :destroy
before_action :user
before_action :authorize_impersonator!
def create
if @user.blocked?
flash[:alert] = "You cannot impersonate a blocked user"
redirect_to admin_user_path(@user)
else
session[:impersonator_id] = current_user.username
session[:impersonator_return_to] = admin_user_path(@user)
warden.set_user(user, scope: 'user')
flash[:alert] = "You are impersonating #{user.username}."
redirect_to root_path
end
end
def destroy
redirect = session[:impersonator_return_to]
warden.set_user(user, scope: 'user')
session[:impersonator_return_to] = nil
session[:impersonator_id] = nil
redirect_to redirect || root_path
end
def user
@user ||= User.find_by!(username: params[:id] || session[:impersonator_id])
end
end
class Admin::ImpersonationsController < Admin::ApplicationController
skip_before_action :authenticate_admin!
before_action :authenticate_impersonator!
def destroy
original_user = current_user
warden.set_user(impersonator, scope: :user)
Gitlab::AppLogger.info("User #{original_user.username} has stopped impersonating #{impersonator.username}")
session[:impersonator_id] = nil
redirect_to admin_user_path(original_user)
end
private
def impersonator
@impersonator ||= User.find(session[:impersonator_id]) if session[:impersonator_id]
end
def authenticate_impersonator!
render_404 unless impersonator && impersonator.is_admin? && !impersonator.blocked?
end
end
...@@ -31,6 +31,24 @@ class Admin::UsersController < Admin::ApplicationController ...@@ -31,6 +31,24 @@ class Admin::UsersController < Admin::ApplicationController
user user
end end
def impersonate
if user.blocked?
flash[:alert] = "You cannot impersonate a blocked user"
redirect_to admin_user_path(user)
else
session[:impersonator_id] = current_user.id
warden.set_user(user, scope: :user)
Gitlab::AppLogger.info("User #{current_user.username} has started impersonating #{user.username}")
flash[:alert] = "You are now impersonating #{user.username}"
redirect_to root_path
end
end
def block def block
if user.block if user.block
redirect_back_or_admin_user(notice: "Successfully blocked") redirect_back_or_admin_user(notice: "Successfully blocked")
......
...@@ -117,7 +117,7 @@ class ApplicationController < ActionController::Base ...@@ -117,7 +117,7 @@ class ApplicationController < ActionController::Base
end end
def after_sign_out_path_for(resource) def after_sign_out_path_for(resource)
current_application_settings.after_sign_out_path || new_user_session_path current_application_settings.after_sign_out_path.presence || new_user_session_path
end end
def abilities def abilities
......
...@@ -3,13 +3,14 @@ class JwtController < ApplicationController ...@@ -3,13 +3,14 @@ class JwtController < ApplicationController
skip_before_action :verify_authenticity_token skip_before_action :verify_authenticity_token
SERVICES = { SERVICES = {
'docker' => Jwt::DockerAuthenticationService, 'container_registry' => Jwt::ContainerRegistryAuthenticationService,
} }
def auth def auth
@authenticated = authenticate_with_http_basic do |login, password| @authenticated = authenticate_with_http_basic do |login, password|
@ci_project = ci_project(login, password) # if it's possible we first try to authenticate project with login and password
@user = authenticate_user(login, password) unless @ci_project @project = authenticate_project(login, password)
@user = authenticate_user(login, password) unless @project
end end
unless @authenticated unless @authenticated
...@@ -19,7 +20,7 @@ class JwtController < ApplicationController ...@@ -19,7 +20,7 @@ class JwtController < ApplicationController
service = SERVICES[params[:service]] service = SERVICES[params[:service]]
head :not_found unless service head :not_found unless service
result = service.new(@ci_project, @user, auth_params).execute result = service.new(@project, @user, auth_params).execute
return head result[:http_status] if result[:http_status] return head result[:http_status] if result[:http_status]
render json: result render json: result
...@@ -31,7 +32,7 @@ class JwtController < ApplicationController ...@@ -31,7 +32,7 @@ class JwtController < ApplicationController
params.permit(:service, :scope, :offline_token, :account, :client_id) params.permit(:service, :scope, :offline_token, :account, :client_id)
end end
def ci_project(login, password) def authenticate_project(login, password)
matched_login = /(?<s>^[a-zA-Z]*-ci)-token$/.match(login) matched_login = /(?<s>^[a-zA-Z]*-ci)-token$/.match(login)
if matched_login.present? if matched_login.present?
......
...@@ -15,7 +15,7 @@ class Projects::CommitsController < Projects::ApplicationController ...@@ -15,7 +15,7 @@ class Projects::CommitsController < Projects::ApplicationController
if search.present? if search.present?
@repository.find_commits_by_message(search, @ref, @path, @limit, @offset).compact @repository.find_commits_by_message(search, @ref, @path, @limit, @offset).compact
else else
@repository.commits(@ref, @path, @limit, @offset) @repository.commits(@ref, path: @path, limit: @limit, offset: @offset)
end end
@note_counts = project.notes.where(commit_id: @commits.map(&:id)). @note_counts = project.notes.where(commit_id: @commits.map(&:id)).
......
...@@ -17,7 +17,7 @@ class Projects::GraphsController < Projects::ApplicationController ...@@ -17,7 +17,7 @@ class Projects::GraphsController < Projects::ApplicationController
end end
def commits def commits
@commits = @project.repository.commits(@ref, nil, 2000, 0, true) @commits = @project.repository.commits(@ref, limit: 2000, skip_merges: true)
@commits_graph = Gitlab::Graphs::Commits.new(@commits) @commits_graph = Gitlab::Graphs::Commits.new(@commits)
@commits_per_week_days = @commits_graph.commits_per_week_days @commits_per_week_days = @commits_graph.commits_per_week_days
@commits_per_time = @commits_graph.commits_per_time @commits_per_time = @commits_graph.commits_per_time
...@@ -55,7 +55,7 @@ class Projects::GraphsController < Projects::ApplicationController ...@@ -55,7 +55,7 @@ class Projects::GraphsController < Projects::ApplicationController
private private
def fetch_graph def fetch_graph
@commits = @project.repository.commits(@ref, nil, 6000, 0, true) @commits = @project.repository.commits(@ref, limit: 6000, skip_merges: true)
@log = [] @log = []
@commits.each do |commit| @commits.each do |commit|
......
...@@ -52,8 +52,16 @@ class Projects::HooksController < Projects::ApplicationController ...@@ -52,8 +52,16 @@ class Projects::HooksController < Projects::ApplicationController
end end
def hook_params def hook_params
params.require(:hook).permit(:url, :push_events, :issues_events, params.require(:hook).permit(
:merge_requests_events, :tag_push_events, :note_events, :build_events,
:build_events, :enable_ssl_verification) :enable_ssl_verification,
:issues_events,
:merge_requests_events,
:note_events,
:push_events,
:tag_push_events,
:token,
:url
)
end end
end end
...@@ -96,6 +96,8 @@ class Projects::IssuesController < Projects::ApplicationController ...@@ -96,6 +96,8 @@ class Projects::IssuesController < Projects::ApplicationController
if params[:move_to_project_id].to_i > 0 if params[:move_to_project_id].to_i > 0
new_project = Project.find(params[:move_to_project_id]) new_project = Project.find(params[:move_to_project_id])
return render_404 unless issue.can_move?(current_user, new_project)
move_service = Issues::MoveService.new(project, current_user) move_service = Issues::MoveService.new(project, current_user)
@issue = move_service.execute(@issue, new_project) @issue = move_service.execute(@issue, new_project)
end end
......
...@@ -40,10 +40,10 @@ class Projects::WikisController < Projects::ApplicationController ...@@ -40,10 +40,10 @@ class Projects::WikisController < Projects::ApplicationController
end end
def update def update
@page = @project_wiki.find_page(params[:id])
return render('empty') unless can?(current_user, :create_wiki, @project) return render('empty') unless can?(current_user, :create_wiki, @project)
@page = @project_wiki.find_page(params[:id])
if @page = WikiPages::UpdateService.new(@project, current_user, wiki_params).execute(@page) 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),
......
...@@ -235,7 +235,7 @@ class ProjectsController < Projects::ApplicationController ...@@ -235,7 +235,7 @@ class ProjectsController < Projects::ApplicationController
def project_params def project_params
params.require(:project).permit( params.require(:project).permit(
:name, :path, :description, :issues_tracker, :tag_list, :runners_token, :name, :path, :description, :issues_tracker, :tag_list, :runners_token,
:issues_enabled, :merge_requests_enabled, :snippets_enabled, :images_enabled, :issues_enabled, :merge_requests_enabled, :snippets_enabled, :container_registry_enabled,
:issues_tracker_id, :default_branch, :issues_tracker_id, :default_branch,
:wiki_enabled, :visibility_level, :import_url, :last_activity_at, :namespace_id, :avatar, :wiki_enabled, :visibility_level, :import_url, :last_activity_at, :namespace_id, :avatar,
:builds_enabled, :build_allow_git_fetch, :build_timeout_in_minutes, :build_coverage_regex, :builds_enabled, :build_allow_git_fetch, :build_timeout_in_minutes, :build_coverage_regex,
......
...@@ -8,6 +8,13 @@ class RegistrationsController < Devise::RegistrationsController ...@@ -8,6 +8,13 @@ class RegistrationsController < Devise::RegistrationsController
def create def create
if !Gitlab::Recaptcha.load_configurations! || verify_recaptcha if !Gitlab::Recaptcha.load_configurations! || verify_recaptcha
# To avoid duplicate form fields on the login page, the registration form
# names fields using `new_user`, but Devise still wants the params in
# `user`.
if params["new_#{resource_name}"].present? && params[resource_name].blank?
params[resource_name] = params.delete(:"new_#{resource_name}")
end
super super
else else
flash[:alert] = "There was an error with the reCAPTCHA code below. Please re-enter the code." flash[:alert] = "There was an error with the reCAPTCHA code below. Please re-enter the code."
......
...@@ -51,7 +51,7 @@ class SnippetsFinder ...@@ -51,7 +51,7 @@ class SnippetsFinder
snippets = project.snippets.fresh snippets = project.snippets.fresh
if current_user if current_user
if project.team.member?(current_user.id) if project.team.member?(current_user.id) || current_user.admin?
snippets snippets
else else
snippets.public_and_internal snippets.public_and_internal
......
...@@ -131,7 +131,7 @@ module BlobHelper ...@@ -131,7 +131,7 @@ module BlobHelper
# elements and attributes. Note that this whitelist is by no means complete # elements and attributes. Note that this whitelist is by no means complete
# and may omit some elements. # and may omit some elements.
def sanitize_svg(blob) def sanitize_svg(blob)
blob.data = Loofah.scrub_fragment(blob.data, :strip).to_xml blob.data = Gitlab::Sanitizers::SVG.clean(blob.data)
blob blob
end end
......
...@@ -16,31 +16,49 @@ module IssuesHelper ...@@ -16,31 +16,49 @@ module IssuesHelper
def url_for_project_issues(project = @project, options = {}) def url_for_project_issues(project = @project, options = {})
return '' if project.nil? return '' if project.nil?
url =
if options[:only_path] if options[:only_path]
project.issues_tracker.project_path project.issues_tracker.project_path
else else
project.issues_tracker.project_url project.issues_tracker.project_url
end end
# Ensure we return a valid URL to prevent possible XSS.
URI.parse(url).to_s
rescue URI::InvalidURIError
''
end end
def url_for_new_issue(project = @project, options = {}) def url_for_new_issue(project = @project, options = {})
return '' if project.nil? return '' if project.nil?
url =
if options[:only_path] if options[:only_path]
project.issues_tracker.new_issue_path project.issues_tracker.new_issue_path
else else
project.issues_tracker.new_issue_url project.issues_tracker.new_issue_url
end end
# Ensure we return a valid URL to prevent possible XSS.
URI.parse(url).to_s
rescue URI::InvalidURIError
''
end end
def url_for_issue(issue_iid, project = @project, options = {}) def url_for_issue(issue_iid, project = @project, options = {})
return '' if project.nil? return '' if project.nil?
url =
if options[:only_path] if options[:only_path]
project.issues_tracker.issue_path(issue_iid) project.issues_tracker.issue_path(issue_iid)
else else
project.issues_tracker.issue_url(issue_iid) project.issues_tracker.issue_url(issue_iid)
end end
# Ensure we return a valid URL to prevent possible XSS.
URI.parse(url).to_s
rescue URI::InvalidURIError
''
end end
def bulk_update_milestone_options def bulk_update_milestone_options
......
...@@ -34,10 +34,13 @@ module NavHelper ...@@ -34,10 +34,13 @@ module NavHelper
end end
def nav_header_class def nav_header_class
class_name =
if nav_menu_collapsed? if nav_menu_collapsed?
"header-collapsed" "header-collapsed"
else else
"header-expanded" "header-expanded"
end end
class_name += " with-horizontal-nav" if defined?(nav) && nav
class_name
end end
end end
...@@ -204,12 +204,8 @@ module ProjectsHelper ...@@ -204,12 +204,8 @@ module ProjectsHelper
end end
def repository_size(project = @project) def repository_size(project = @project)
"#{project.repository_size} MB" size_in_bytes = project.repository_size * 1.megabyte
rescue number_to_human_size(size_in_bytes, delimiter: ',', precision: 2)
# In order to prevent 500 error
# when application cannot allocate memory
# to calculate repo size - just show 'Unknown'
'unknown'
end end
def default_url_to_repo(project = @project) def default_url_to_repo(project = @project)
...@@ -345,4 +341,10 @@ module ProjectsHelper ...@@ -345,4 +341,10 @@ module ProjectsHelper
) )
end end
end end
def sanitize_repo_path(message)
return '' unless message.present?
message.strip.gsub(Gitlab.config.gitlab_shell.repos_path.chomp('/'), "[REPOS PATH]")
end
end end
...@@ -28,6 +28,14 @@ module Emails ...@@ -28,6 +28,14 @@ module Emails
mail_answer_thread(@merge_request, note_thread_options(recipient_id)) mail_answer_thread(@merge_request, note_thread_options(recipient_id))
end end
def note_snippet_email(recipient_id, note_id)
setup_note_mail(note_id, recipient_id)
@snippet = @note.noteable
@target_url = namespace_project_snippet_url(*note_target_url_options)
mail_answer_thread(@snippet, note_thread_options(recipient_id))
end
private private
def note_target_url_options def note_target_url_options
......
...@@ -203,7 +203,7 @@ class Ability ...@@ -203,7 +203,7 @@ class Ability
:admin_label, :admin_label,
:read_commit_status, :read_commit_status,
:read_build, :read_build,
:read_image, :read_container_registry,
] ]
end end
...@@ -218,8 +218,8 @@ class Ability ...@@ -218,8 +218,8 @@ class Ability
:create_merge_request, :create_merge_request,
:create_wiki, :create_wiki,
:push_code, :push_code,
:create_image, :create_container_registry,
:update_image, :update_container_registry,
] ]
end end
...@@ -246,7 +246,7 @@ class Ability ...@@ -246,7 +246,7 @@ class Ability
:admin_project, :admin_project,
:admin_commit_status, :admin_commit_status,
:admin_build, :admin_build,
:admin_image :admin_container_registry,
] ]
end end
...@@ -291,6 +291,10 @@ class Ability ...@@ -291,6 +291,10 @@ class Ability
rules += named_abilities('build') rules += named_abilities('build')
end end
unless project.container_registry_enabled
rules += named_abilities('container_registry')
end
rules rules
end end
......
# == Schema Information
#
# Table name: appearances
#
# id :integer not null, primary key
# title :string
# description :text
# header_logo :string
# logo :string
# created_at :datetime not null
# updated_at :datetime not null
#
class Appearance < ActiveRecord::Base class Appearance < ActiveRecord::Base
validates :title, presence: true validates :title, presence: true
validates :description, presence: true validates :description, presence: true
......
...@@ -10,21 +10,20 @@ ...@@ -10,21 +10,20 @@
# sign_in_text :text # sign_in_text :text
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
# home_page_url :string(255) # home_page_url :string
# default_branch_protection :integer default(2) # default_branch_protection :integer default(2)
# restricted_visibility_levels :text # restricted_visibility_levels :text
# version_check_enabled :boolean default(TRUE) # version_check_enabled :boolean default(TRUE)
# max_attachment_size :integer default(10), not null # max_attachment_size :integer default(10), not null
# default_project_visibility :integer # default_project_visibility :integer
# default_snippet_visibility :integer # default_snippet_visibility :integer
# default_group_visibility :integer
# restricted_signup_domains :text # restricted_signup_domains :text
# user_oauth_applications :boolean default(TRUE) # user_oauth_applications :boolean default(TRUE)
# after_sign_out_path :string(255) # after_sign_out_path :string
# session_expire_delay :integer default(10080), not null # session_expire_delay :integer default(10080), not null
# import_sources :text # import_sources :text
# help_page_text :text # help_page_text :text
# admin_notification_email :string(255) # admin_notification_email :string
# shared_runners_enabled :boolean default(TRUE), not null # shared_runners_enabled :boolean default(TRUE), not null
# max_artifacts_size :integer default(100), not null # max_artifacts_size :integer default(100), not null
# runners_registration_token :string # runners_registration_token :string
...@@ -32,8 +31,6 @@ ...@@ -32,8 +31,6 @@
# two_factor_grace_period :integer default(48) # two_factor_grace_period :integer default(48)
# metrics_enabled :boolean default(FALSE) # metrics_enabled :boolean default(FALSE)
# metrics_host :string default("localhost") # metrics_host :string default("localhost")
# metrics_username :string
# metrics_password :string
# metrics_pool_size :integer default(16) # metrics_pool_size :integer default(16)
# metrics_timeout :integer default(10) # metrics_timeout :integer default(10)
# metrics_method_call_threshold :integer default(10) # metrics_method_call_threshold :integer default(10)
...@@ -41,9 +38,16 @@ ...@@ -41,9 +38,16 @@
# recaptcha_site_key :string # recaptcha_site_key :string
# recaptcha_private_key :string # recaptcha_private_key :string
# metrics_port :integer default(8089) # metrics_port :integer default(8089)
# metrics_sample_interval :integer default(15)
# sentry_enabled :boolean default(FALSE) # sentry_enabled :boolean default(FALSE)
# sentry_dsn :string # sentry_dsn :string
# akismet_enabled :boolean default(FALSE)
# akismet_api_key :string
# email_author_in_body :boolean default(FALSE) # email_author_in_body :boolean default(FALSE)
# default_group_visibility :integer
# repository_checks_enabled :boolean default(FALSE)
# metrics_packet_size :integer default(1)
# shared_runners_text :text
# #
class ApplicationSetting < ActiveRecord::Base class ApplicationSetting < ActiveRecord::Base
......
...@@ -4,9 +4,9 @@ ...@@ -4,9 +4,9 @@
# #
# id :integer not null, primary key # id :integer not null, primary key
# author_id :integer not null # author_id :integer not null
# type :string(255) not null # type :string not null
# entity_id :integer not null # entity_id :integer not null
# entity_type :string(255) not null # entity_type :string not null
# details :text # details :text
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
......
...@@ -8,8 +8,8 @@ ...@@ -8,8 +8,8 @@
# ends_at :datetime # ends_at :datetime
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
# color :string(255) # color :string
# font :string(255) # font :string
# #
class BroadcastMessage < ActiveRecord::Base class BroadcastMessage < ActiveRecord::Base
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# #
# id :integer not null, primary key # id :integer not null, primary key
# project_id :integer # project_id :integer
# status :string(255) # status :string
# finished_at :datetime # finished_at :datetime
# trace :text # trace :text
# created_at :datetime # created_at :datetime
...@@ -15,19 +15,19 @@ ...@@ -15,19 +15,19 @@
# commit_id :integer # commit_id :integer
# commands :text # commands :text
# job_id :integer # job_id :integer
# name :string(255) # name :string
# deploy :boolean default(FALSE) # deploy :boolean default(FALSE)
# options :text # options :text
# allow_failure :boolean default(FALSE), not null # allow_failure :boolean default(FALSE), not null
# stage :string(255) # stage :string
# trigger_request_id :integer # trigger_request_id :integer
# stage_idx :integer # stage_idx :integer
# tag :boolean # tag :boolean
# ref :string(255) # ref :string
# user_id :integer # user_id :integer
# type :string(255) # type :string
# target_url :string(255) # target_url :string
# description :string(255) # description :string
# artifacts_file :text # artifacts_file :text
# gl_project_id :integer # gl_project_id :integer
# artifacts_metadata :text # artifacts_metadata :text
...@@ -426,7 +426,6 @@ module Ci ...@@ -426,7 +426,6 @@ module Ci
variables << { key: :CI_BUILD_NAME, value: name, public: true } variables << { key: :CI_BUILD_NAME, value: name, public: true }
variables << { key: :CI_BUILD_STAGE, value: stage, public: true } variables << { key: :CI_BUILD_STAGE, value: stage, public: true }
variables << { key: :CI_BUILD_TRIGGERED, value: 'true', public: true } if trigger_request variables << { key: :CI_BUILD_TRIGGERED, value: 'true', public: true } if trigger_request
variables << { key: :CI_DOCKER_REGISTRY, value: project.registry_repository_url, public: true } if project.registry_repository_url
variables variables
end end
end end
......
...@@ -4,9 +4,9 @@ ...@@ -4,9 +4,9 @@
# #
# id :integer not null, primary key # id :integer not null, primary key
# project_id :integer # project_id :integer
# ref :string(255) # ref :string
# sha :string(255) # sha :string
# before_sha :string(255) # before_sha :string
# push_data :text # push_data :text
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
...@@ -14,6 +14,10 @@ ...@@ -14,6 +14,10 @@
# yaml_errors :text # yaml_errors :text
# committed_at :datetime # committed_at :datetime
# gl_project_id :integer # gl_project_id :integer
# status :string
# started_at :datetime
# finished_at :datetime
# duration :integer
# #
module Ci module Ci
......
...@@ -3,18 +3,18 @@ ...@@ -3,18 +3,18 @@
# Table name: ci_runners # Table name: ci_runners
# #
# id :integer not null, primary key # id :integer not null, primary key
# token :string(255) # token :string
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
# description :string(255) # description :string
# contacted_at :datetime # contacted_at :datetime
# active :boolean default(TRUE), not null # active :boolean default(TRUE), not null
# is_shared :boolean default(FALSE) # is_shared :boolean default(FALSE)
# name :string(255) # name :string
# version :string(255) # version :string
# revision :string(255) # revision :string
# platform :string(255) # platform :string
# architecture :string(255) # architecture :string
# #
module Ci module Ci
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# Table name: ci_triggers # Table name: ci_triggers
# #
# id :integer not null, primary key # id :integer not null, primary key
# token :string(255) # token :string
# project_id :integer # project_id :integer
# deleted_at :datetime # deleted_at :datetime
# created_at :datetime # created_at :datetime
......
...@@ -4,11 +4,11 @@ ...@@ -4,11 +4,11 @@
# #
# id :integer not null, primary key # id :integer not null, primary key
# project_id :integer # project_id :integer
# key :string(255) # key :string
# value :text # value :text
# encrypted_value :text # encrypted_value :text
# encrypted_value_salt :string(255) # encrypted_value_salt :string
# encrypted_value_iv :string(255) # encrypted_value_iv :string
# gl_project_id :integer # gl_project_id :integer
# #
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# #
# id :integer not null, primary key # id :integer not null, primary key
# project_id :integer # project_id :integer
# status :string(255) # status :string
# finished_at :datetime # finished_at :datetime
# trace :text # trace :text
# created_at :datetime # created_at :datetime
...@@ -15,21 +15,24 @@ ...@@ -15,21 +15,24 @@
# commit_id :integer # commit_id :integer
# commands :text # commands :text
# job_id :integer # job_id :integer
# name :string(255) # name :string
# deploy :boolean default(FALSE) # deploy :boolean default(FALSE)
# options :text # options :text
# allow_failure :boolean default(FALSE), not null # allow_failure :boolean default(FALSE), not null
# stage :string(255) # stage :string
# trigger_request_id :integer # trigger_request_id :integer
# stage_idx :integer # stage_idx :integer
# tag :boolean # tag :boolean
# ref :string(255) # ref :string
# user_id :integer # user_id :integer
# type :string(255) # type :string
# target_url :string(255) # target_url :string
# description :string(255) # description :string
# artifacts_file :text # artifacts_file :text
# gl_project_id :integer # gl_project_id :integer
# artifacts_metadata :text
# erased_by_id :integer
# erased_at :datetime
# #
class CommitStatus < ActiveRecord::Base class CommitStatus < ActiveRecord::Base
......
...@@ -35,13 +35,14 @@ module Issuable ...@@ -35,13 +35,14 @@ module Issuable
scope :only_opened, -> { with_state(:opened) } scope :only_opened, -> { with_state(:opened) }
scope :only_reopened, -> { with_state(:reopened) } scope :only_reopened, -> { with_state(:reopened) }
scope :closed, -> { with_state(:closed) } scope :closed, -> { with_state(:closed) }
scope :order_milestone_due_desc, -> { joins(:milestone).reorder('milestones.due_date DESC, milestones.id DESC') } scope :order_milestone_due_desc, -> { outer_join_milestone.reorder('milestones.due_date IS NULL ASC, milestones.due_date DESC, milestones.id DESC') }
scope :order_milestone_due_asc, -> { joins(:milestone).reorder('milestones.due_date ASC, milestones.id ASC') } scope :order_milestone_due_asc, -> { outer_join_milestone.reorder('milestones.due_date IS NULL ASC, milestones.due_date ASC, milestones.id ASC') }
scope :without_label, -> { joins("LEFT OUTER JOIN label_links ON label_links.target_type = '#{name}' AND label_links.target_id = #{table_name}.id").where(label_links: { id: nil }) } scope :without_label, -> { joins("LEFT OUTER JOIN label_links ON label_links.target_type = '#{name}' AND label_links.target_id = #{table_name}.id").where(label_links: { id: nil }) }
scope :join_project, -> { joins(:project) } scope :join_project, -> { joins(:project) }
scope :references_project, -> { references(:project) } scope :references_project, -> { references(:project) }
scope :non_archived, -> { join_project.where(projects: { archived: false }) } scope :non_archived, -> { join_project.where(projects: { archived: false }) }
scope :outer_join_milestone, -> { joins("LEFT OUTER JOIN milestones ON milestones.id = #{table_name}.milestone_id") }
delegate :name, delegate :name,
:email, :email,
......
...@@ -7,9 +7,9 @@ ...@@ -7,9 +7,9 @@
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
# key :text # key :text
# title :string(255) # title :string
# type :string(255) # type :string
# fingerprint :string(255) # fingerprint :string
# public :boolean default(FALSE), not null # public :boolean default(FALSE), not null
# #
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# #
# id :integer not null, primary key # id :integer not null, primary key
# user_id :integer not null # user_id :integer not null
# email :string(255) not null # email :string not null
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
# #
......
...@@ -3,9 +3,9 @@ ...@@ -3,9 +3,9 @@
# Table name: events # Table name: events
# #
# id :integer not null, primary key # id :integer not null, primary key
# target_type :string(255) # target_type :string
# target_id :integer # target_id :integer
# title :string(255) # title :string
# data :text # data :text
# project_id :integer # project_id :integer
# created_at :datetime # created_at :datetime
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# #
# id :integer not null, primary key # id :integer not null, primary key
# project_id :integer # project_id :integer
# status :string(255) # status :string
# finished_at :datetime # finished_at :datetime
# trace :text # trace :text
# created_at :datetime # created_at :datetime
...@@ -15,21 +15,24 @@ ...@@ -15,21 +15,24 @@
# commit_id :integer # commit_id :integer
# commands :text # commands :text
# job_id :integer # job_id :integer
# name :string(255) # name :string
# deploy :boolean default(FALSE) # deploy :boolean default(FALSE)
# options :text # options :text
# allow_failure :boolean default(FALSE), not null # allow_failure :boolean default(FALSE), not null
# stage :string(255) # stage :string
# trigger_request_id :integer # trigger_request_id :integer
# stage_idx :integer # stage_idx :integer
# tag :boolean # tag :boolean
# ref :string(255) # ref :string
# user_id :integer # user_id :integer
# type :string(255) # type :string
# target_url :string(255) # target_url :string
# description :string(255) # description :string
# artifacts_file :text # artifacts_file :text
# gl_project_id :integer # gl_project_id :integer
# artifacts_metadata :text
# erased_by_id :integer
# erased_at :datetime
# #
class GenericCommitStatus < CommitStatus class GenericCommitStatus < CommitStatus
......
...@@ -3,15 +3,16 @@ ...@@ -3,15 +3,16 @@
# Table name: namespaces # Table name: namespaces
# #
# id :integer not null, primary key # id :integer not null, primary key
# name :string(255) not null # name :string not null
# path :string(255) not null # path :string not null
# owner_id :integer # owner_id :integer
# visibility_level :integer default(20), not null
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
# type :string(255) # type :string
# description :string(255) default(""), not null # description :string default(""), not null
# avatar :string(255) # avatar :string
# share_with_group_lock :boolean default(FALSE)
# visibility_level :integer default(20), not null
# #
require 'carrierwave/orm/activerecord' require 'carrierwave/orm/activerecord'
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
# note_events :boolean default(FALSE), not null # note_events :boolean default(FALSE), not null
# enable_ssl_verification :boolean default(TRUE) # enable_ssl_verification :boolean default(TRUE)
# build_events :boolean default(FALSE), not null # build_events :boolean default(FALSE), not null
# wiki_page_events :boolean default(FALSE), not null
# token :string
# #
class ProjectHook < WebHook class ProjectHook < WebHook
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
# note_events :boolean default(FALSE), not null # note_events :boolean default(FALSE), not null
# enable_ssl_verification :boolean default(TRUE) # enable_ssl_verification :boolean default(TRUE)
# build_events :boolean default(FALSE), not null # build_events :boolean default(FALSE), not null
# wiki_page_events :boolean default(FALSE), not null
# token :string
# #
class ServiceHook < WebHook class ServiceHook < WebHook
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
# note_events :boolean default(FALSE), not null # note_events :boolean default(FALSE), not null
# enable_ssl_verification :boolean default(TRUE) # enable_ssl_verification :boolean default(TRUE)
# build_events :boolean default(FALSE), not null # build_events :boolean default(FALSE), not null
# wiki_page_events :boolean default(FALSE), not null
# token :string
# #
class SystemHook < WebHook class SystemHook < WebHook
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
# note_events :boolean default(FALSE), not null # note_events :boolean default(FALSE), not null
# enable_ssl_verification :boolean default(TRUE) # enable_ssl_verification :boolean default(TRUE)
# build_events :boolean default(FALSE), not null # build_events :boolean default(FALSE), not null
# wiki_page_events :boolean default(FALSE), not null
# token :string
# #
class WebHook < ActiveRecord::Base class WebHook < ActiveRecord::Base
...@@ -43,23 +45,17 @@ class WebHook < ActiveRecord::Base ...@@ -43,23 +45,17 @@ class WebHook < ActiveRecord::Base
if parsed_url.userinfo.blank? if parsed_url.userinfo.blank?
response = WebHook.post(url, response = WebHook.post(url,
body: data.to_json, body: data.to_json,
headers: { headers: build_headers(hook_name),
"Content-Type" => "application/json",
"X-Gitlab-Event" => hook_name.singularize.titleize
},
verify: enable_ssl_verification) verify: enable_ssl_verification)
else else
post_url = url.gsub("#{parsed_url.userinfo}@", "") post_url = url.gsub("#{parsed_url.userinfo}@", '')
auth = { auth = {
username: CGI.unescape(parsed_url.user), username: CGI.unescape(parsed_url.user),
password: CGI.unescape(parsed_url.password), password: CGI.unescape(parsed_url.password),
} }
response = WebHook.post(post_url, response = WebHook.post(post_url,
body: data.to_json, body: data.to_json,
headers: { headers: build_headers(hook_name),
"Content-Type" => "application/json",
"X-Gitlab-Event" => hook_name.singularize.titleize
},
verify: enable_ssl_verification, verify: enable_ssl_verification,
basic_auth: auth) basic_auth: auth)
end end
...@@ -73,4 +69,15 @@ class WebHook < ActiveRecord::Base ...@@ -73,4 +69,15 @@ class WebHook < ActiveRecord::Base
def async_execute(data, hook_name) def async_execute(data, hook_name)
Sidekiq::Client.enqueue(ProjectWebHookWorker, id, data, hook_name) Sidekiq::Client.enqueue(ProjectWebHookWorker, id, data, hook_name)
end end
private
def build_headers(hook_name)
headers = {
'Content-Type' => 'application/json',
'X-Gitlab-Event' => hook_name.singularize.titleize
}
headers['X-Gitlab-Token'] = token if token.present?
headers
end
end end
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
# Table name: identities # Table name: identities
# #
# id :integer not null, primary key # id :integer not null, primary key
# extern_uid :string(255) # extern_uid :string
# provider :string(255) # provider :string
# user_id :integer # user_id :integer
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
......
...@@ -3,20 +3,23 @@ ...@@ -3,20 +3,23 @@
# Table name: issues # Table name: issues
# #
# id :integer not null, primary key # id :integer not null, primary key
# title :string(255) # title :string
# assignee_id :integer # assignee_id :integer
# author_id :integer # author_id :integer
# project_id :integer # project_id :integer
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
# position :integer default(0) # position :integer default(0)
# branch_name :string(255) # branch_name :string
# description :text # description :text
# milestone_id :integer # milestone_id :integer
# state :string(255) # state :string
# iid :integer # iid :integer
# updated_by_id :integer # updated_by_id :integer
# moved_to_id :integer # moved_to_id :integer
# confidential :boolean default(FALSE)
# deleted_at :datetime
# due_date :date
# #
require 'carrierwave/orm/activerecord' require 'carrierwave/orm/activerecord'
......
...@@ -7,9 +7,9 @@ ...@@ -7,9 +7,9 @@
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
# key :text # key :text
# title :string(255) # title :string
# type :string(255) # type :string
# fingerprint :string(255) # fingerprint :string
# public :boolean default(FALSE), not null # public :boolean default(FALSE), not null
# #
......
...@@ -3,13 +3,13 @@ ...@@ -3,13 +3,13 @@
# Table name: labels # Table name: labels
# #
# id :integer not null, primary key # id :integer not null, primary key
# title :string(255) # title :string
# color :string(255) # color :string
# project_id :integer # project_id :integer
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
# template :boolean default(FALSE) # template :boolean default(FALSE)
# description :string(255) # description :string
# #
class Label < ActiveRecord::Base class Label < ActiveRecord::Base
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
# id :integer not null, primary key # id :integer not null, primary key
# label_id :integer # label_id :integer
# target_id :integer # target_id :integer
# target_type :string(255) # target_type :string
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
# #
......
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
# Table name: lfs_objects # Table name: lfs_objects
# #
# id :integer not null, primary key # id :integer not null, primary key
# oid :string(255) not null # oid :string not null
# size :integer not null # size :integer not null
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
# file :string(255) # file :string
# #
class LfsObject < ActiveRecord::Base class LfsObject < ActiveRecord::Base
......
...@@ -5,15 +5,15 @@ ...@@ -5,15 +5,15 @@
# id :integer not null, primary key # id :integer not null, primary key
# access_level :integer not null # access_level :integer not null
# source_id :integer not null # source_id :integer not null
# source_type :string(255) not null # source_type :string not null
# user_id :integer # user_id :integer
# notification_level :integer not null # notification_level :integer not null
# type :string(255) # type :string
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
# created_by_id :integer # created_by_id :integer
# invite_email :string(255) # invite_email :string
# invite_token :string(255) # invite_token :string
# invite_accepted_at :datetime # invite_accepted_at :datetime
# #
......
...@@ -5,15 +5,15 @@ ...@@ -5,15 +5,15 @@
# id :integer not null, primary key # id :integer not null, primary key
# access_level :integer not null # access_level :integer not null
# source_id :integer not null # source_id :integer not null
# source_type :string(255) not null # source_type :string not null
# user_id :integer # user_id :integer
# notification_level :integer not null # notification_level :integer not null
# type :string(255) # type :string
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
# created_by_id :integer # created_by_id :integer
# invite_email :string(255) # invite_email :string
# invite_token :string(255) # invite_token :string
# invite_accepted_at :datetime # invite_accepted_at :datetime
# #
......
...@@ -5,15 +5,15 @@ ...@@ -5,15 +5,15 @@
# id :integer not null, primary key # id :integer not null, primary key
# access_level :integer not null # access_level :integer not null
# source_id :integer not null # source_id :integer not null
# source_type :string(255) not null # source_type :string not null
# user_id :integer # user_id :integer
# notification_level :integer not null # notification_level :integer not null
# type :string(255) # type :string
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
# created_by_id :integer # created_by_id :integer
# invite_email :string(255) # invite_email :string
# invite_token :string(255) # invite_token :string
# invite_accepted_at :datetime # invite_accepted_at :datetime
# #
......
...@@ -3,28 +3,29 @@ ...@@ -3,28 +3,29 @@
# Table name: merge_requests # Table name: merge_requests
# #
# id :integer not null, primary key # id :integer not null, primary key
# target_branch :string(255) not null # target_branch :string not null
# source_branch :string(255) not null # source_branch :string not null
# source_project_id :integer not null # source_project_id :integer not null
# author_id :integer # author_id :integer
# assignee_id :integer # assignee_id :integer
# title :string(255) # title :string
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
# milestone_id :integer # milestone_id :integer
# state :string(255) # state :string
# merge_status :string(255) # merge_status :string
# target_project_id :integer not null # target_project_id :integer not null
# iid :integer # iid :integer
# description :text # description :text
# position :integer default(0) # position :integer default(0)
# locked_at :datetime # locked_at :datetime
# updated_by_id :integer # updated_by_id :integer
# merge_error :string(255) # merge_error :string
# merge_params :text # merge_params :text
# merge_when_build_succeeds :boolean default(FALSE), not null # merge_when_build_succeeds :boolean default(FALSE), not null
# merge_user_id :integer # merge_user_id :integer
# merge_commit_sha :string # merge_commit_sha :string
# deleted_at :datetime
# #
class MergeRequest < ActiveRecord::Base class MergeRequest < ActiveRecord::Base
......
...@@ -3,12 +3,14 @@ ...@@ -3,12 +3,14 @@
# Table name: merge_request_diffs # Table name: merge_request_diffs
# #
# id :integer not null, primary key # id :integer not null, primary key
# state :string(255) # state :string
# st_commits :text # st_commits :text
# st_diffs :text # st_diffs :text
# merge_request_id :integer not null # merge_request_id :integer not null
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
# base_commit_sha :string
# real_size :string
# #
class MergeRequestDiff < ActiveRecord::Base class MergeRequestDiff < ActiveRecord::Base
......
...@@ -3,13 +3,13 @@ ...@@ -3,13 +3,13 @@
# Table name: milestones # Table name: milestones
# #
# id :integer not null, primary key # id :integer not null, primary key
# title :string(255) not null # title :string not null
# project_id :integer not null # project_id :integer not null
# description :text # description :text
# due_date :date # due_date :date
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
# state :string(255) # state :string
# iid :integer # iid :integer
# #
......
...@@ -3,14 +3,16 @@ ...@@ -3,14 +3,16 @@
# Table name: namespaces # Table name: namespaces
# #
# id :integer not null, primary key # id :integer not null, primary key
# name :string(255) not null # name :string not null
# path :string(255) not null # path :string not null
# owner_id :integer # owner_id :integer
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
# type :string(255) # type :string
# description :string(255) default(""), not null # description :string default(""), not null
# avatar :string(255) # avatar :string
# share_with_group_lock :boolean default(FALSE)
# visibility_level :integer default(20), not null
# #
class Namespace < ActiveRecord::Base class Namespace < ActiveRecord::Base
......
...@@ -4,14 +4,14 @@ ...@@ -4,14 +4,14 @@
# #
# id :integer not null, primary key # id :integer not null, primary key
# note :text # note :text
# noteable_type :string(255) # noteable_type :string
# author_id :integer # author_id :integer
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
# project_id :integer # project_id :integer
# attachment :string(255) # attachment :string
# line_code :string(255) # line_code :string
# commit_id :string(255) # commit_id :string
# noteable_id :integer # noteable_id :integer
# system :boolean default(FALSE), not null # system :boolean default(FALSE), not null
# st_diff :text # st_diff :text
......
# == Schema Information
#
# Table name: notification_settings
#
# id :integer not null, primary key
# user_id :integer not null
# source_id :integer not null
# source_type :string not null
# level :integer default(0), not null
# created_at :datetime not null
# updated_at :datetime not null
#
class NotificationSetting < ActiveRecord::Base class NotificationSetting < ActiveRecord::Base
enum level: { disabled: 0, participating: 1, watch: 2, global: 3, mention: 4 } enum level: { disabled: 0, participating: 1, watch: 2, global: 3, mention: 4 }
......
...@@ -3,14 +3,14 @@ ...@@ -3,14 +3,14 @@
# Table name: snippets # Table name: snippets
# #
# id :integer not null, primary key # id :integer not null, primary key
# title :string(255) # title :string
# content :text # content :text
# author_id :integer not null # author_id :integer not null
# project_id :integer # project_id :integer
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
# file_name :string(255) # file_name :string
# type :string(255) # type :string
# visibility_level :integer default(0), not null # visibility_level :integer default(0), not null
# #
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
# Table name: projects # Table name: projects
# #
# id :integer not null, primary key # id :integer not null, primary key
# name :string(255) # name :string
# path :string(255) # path :string
# description :text # description :text
# created_at :datetime # created_at :datetime
# updated_at :datetime # updated_at :datetime
...@@ -14,19 +14,19 @@ ...@@ -14,19 +14,19 @@
# merge_requests_enabled :boolean default(TRUE), not null # merge_requests_enabled :boolean default(TRUE), not null
# wiki_enabled :boolean default(TRUE), not null # wiki_enabled :boolean default(TRUE), not null
# namespace_id :integer # namespace_id :integer
# issues_tracker :string(255) default("gitlab"), not null # issues_tracker :string default("gitlab"), not null
# issues_tracker_id :string(255) # issues_tracker_id :string
# snippets_enabled :boolean default(TRUE), not null # snippets_enabled :boolean default(TRUE), not null
# last_activity_at :datetime # last_activity_at :datetime
# import_url :string(255) # import_url :string
# visibility_level :integer default(0), not null # visibility_level :integer default(0), not null
# archived :boolean default(FALSE), not null # archived :boolean default(FALSE), not null
# avatar :string(255) # avatar :string
# import_status :string(255) # import_status :string
# repository_size :float default(0.0) # repository_size :float default(0.0)
# star_count :integer default(0), not null # star_count :integer default(0), not null
# import_type :string(255) # import_type :string
# import_source :string(255) # import_source :string
# commit_count :integer default(0) # commit_count :integer default(0)
# import_error :text # import_error :text
# ci_id :integer # ci_id :integer
...@@ -36,7 +36,12 @@ ...@@ -36,7 +36,12 @@
# build_coverage_regex :string # build_coverage_regex :string
# build_allow_git_fetch :boolean default(TRUE), not null # build_allow_git_fetch :boolean default(TRUE), not null
# build_timeout :integer default(3600), not null # build_timeout :integer default(3600), not null
# pending_delete :boolean # pending_delete :boolean default(FALSE)
# public_builds :boolean default(TRUE), not null
# main_language :string
# pushes_since_gc :integer default(0)
# last_repository_check_failed :boolean
# last_repository_check_at :datetime
# #
require 'carrierwave/orm/activerecord' require 'carrierwave/orm/activerecord'
...@@ -64,7 +69,7 @@ class Project < ActiveRecord::Base ...@@ -64,7 +69,7 @@ class Project < ActiveRecord::Base
default_value_for :wiki_enabled, gitlab_config_features.wiki default_value_for :wiki_enabled, gitlab_config_features.wiki
default_value_for :wall_enabled, false default_value_for :wall_enabled, false
default_value_for :snippets_enabled, gitlab_config_features.snippets default_value_for :snippets_enabled, gitlab_config_features.snippets
default_value_for :images_enabled, gitlab_config_features.images default_value_for :container_registry_enabled, gitlab_config_features.container_registry
default_value_for(:shared_runners_enabled) { current_application_settings.shared_runners_enabled } default_value_for(:shared_runners_enabled) { current_application_settings.shared_runners_enabled }
# set last_activity_at to the same as created_at # set last_activity_at to the same as created_at
...@@ -376,8 +381,10 @@ class Project < ActiveRecord::Base ...@@ -376,8 +381,10 @@ class Project < ActiveRecord::Base
@container_registry ||= ImageRegistry::Repository.new(@registry, path_with_namespace) @container_registry ||= ImageRegistry::Repository.new(@registry, path_with_namespace)
end end
def registry_repository_url def container_registry_url
"#{Gitlab.config.registry.host_with_port}/#{path_with_namespace}" if images_enabled? && Gitlab.config.registry.enabled if container_registry_enabled? && Gitlab.config.registry.enabled
"#{Gitlab.config.registry.host_with_port}/#{path_with_namespace}"
end
end end
def commit(id = 'HEAD') def commit(id = 'HEAD')
...@@ -746,19 +753,17 @@ class Project < ActiveRecord::Base ...@@ -746,19 +753,17 @@ class Project < ActiveRecord::Base
end end
def open_branches def open_branches
all_branches = repository.branches # We're using a Set here as checking values in a large Set is faster than
# checking values in a large Array.
protected_set = Set.new(protected_branch_names)
if protected_branches.present? repository.branches.reject do |branch|
all_branches.reject! do |branch| protected_set.include?(branch.name)
protected_branches_names.include?(branch.name)
end
end end
all_branches
end end
def protected_branches_names def protected_branch_names
@protected_branches_names ||= protected_branches.map(&:name) @protected_branch_names ||= protected_branches.pluck(:name)
end end
def root_ref?(branch) def root_ref?(branch)
...@@ -775,7 +780,7 @@ class Project < ActiveRecord::Base ...@@ -775,7 +780,7 @@ class Project < ActiveRecord::Base
# Check if current branch name is marked as protected in the system # Check if current branch name is marked as protected in the system
def protected_branch?(branch_name) def protected_branch?(branch_name)
protected_branches_names.include?(branch_name) protected_branches.where(name: branch_name).any?
end end
def developers_can_push_to_protected_branch?(branch_name) def developers_can_push_to_protected_branch?(branch_name)
...@@ -1047,4 +1052,11 @@ class Project < ActiveRecord::Base ...@@ -1047,4 +1052,11 @@ class Project < ActiveRecord::Base
def wiki def wiki
@wiki ||= ProjectWiki.new(self, self.owner) @wiki ||= ProjectWiki.new(self, self.owner)
end end
def schedule_delete!(user_id, params)
# Queue this task for after the commit, so once we mark pending_delete it will run
run_after_commit { ProjectDestroyWorker.perform_async(id, user_id, params) }
update_attribute(:pending_delete, true)
end
end end
# == Schema Information
#
# Table name: project_group_links
#
# id :integer not null, primary key
# project_id :integer not null
# group_id :integer not null
# created_at :datetime
# updated_at :datetime
# group_access :integer default(30), not null
#
class ProjectGroupLink < ActiveRecord::Base class ProjectGroupLink < ActiveRecord::Base
GUEST = 10 GUEST = 10
REPORTER = 20 REPORTER = 20
......
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
# id :integer not null, primary key # id :integer not null, primary key
# project_id :integer # project_id :integer
# data :text # data :text
# encrypted_credentials :text
# encrypted_credentials_iv :string
# encrypted_credentials_salt :string
# #
require 'carrierwave/orm/activerecord' require 'carrierwave/orm/activerecord'
......
...@@ -3,12 +3,12 @@ ...@@ -3,12 +3,12 @@
# Table name: services # Table name: services
# #
# id :integer not null, primary key # id :integer not null, primary key
# type :string(255) # type :string
# title :string(255) # title :string
# project_id :integer # project_id :integer
# created_at :datetime # created_at :datetime not null
# updated_at :datetime # updated_at :datetime not null
# active :boolean default(FALSE), not null # active :boolean not null
# properties :text # properties :text
# template :boolean default(FALSE) # template :boolean default(FALSE)
# push_events :boolean default(TRUE) # push_events :boolean default(TRUE)
...@@ -17,6 +17,9 @@ ...@@ -17,6 +17,9 @@
# tag_push_events :boolean default(TRUE) # tag_push_events :boolean default(TRUE)
# note_events :boolean default(TRUE), not null # note_events :boolean default(TRUE), not null
# build_events :boolean default(FALSE), not null # build_events :boolean default(FALSE), not null
# category :string default("common"), not null
# default :boolean default(FALSE)
# wiki_page_events :boolean default(TRUE)
# #
require 'asana' require 'asana'
......
...@@ -3,12 +3,12 @@ ...@@ -3,12 +3,12 @@
# Table name: services # Table name: services
# #
# id :integer not null, primary key # id :integer not null, primary key
# type :string(255) # type :string
# title :string(255) # title :string
# project_id :integer # project_id :integer
# created_at :datetime # created_at :datetime not null
# updated_at :datetime # updated_at :datetime not null
# active :boolean default(FALSE), not null # active :boolean not null
# properties :text # properties :text
# template :boolean default(FALSE) # template :boolean default(FALSE)
# push_events :boolean default(TRUE) # push_events :boolean default(TRUE)
...@@ -17,6 +17,9 @@ ...@@ -17,6 +17,9 @@
# tag_push_events :boolean default(TRUE) # tag_push_events :boolean default(TRUE)
# note_events :boolean default(TRUE), not null # note_events :boolean default(TRUE), not null
# build_events :boolean default(FALSE), not null # build_events :boolean default(FALSE), not null
# category :string default("common"), not null
# default :boolean default(FALSE)
# wiki_page_events :boolean default(TRUE)
# #
class AssemblaService < Service class AssemblaService < Service
......
...@@ -3,12 +3,12 @@ ...@@ -3,12 +3,12 @@
# Table name: services # Table name: services
# #
# id :integer not null, primary key # id :integer not null, primary key
# type :string(255) # type :string
# title :string(255) # title :string
# project_id :integer # project_id :integer
# created_at :datetime # created_at :datetime not null
# updated_at :datetime # updated_at :datetime not null
# active :boolean default(FALSE), not null # active :boolean not null
# properties :text # properties :text
# template :boolean default(FALSE) # template :boolean default(FALSE)
# push_events :boolean default(TRUE) # push_events :boolean default(TRUE)
...@@ -17,6 +17,9 @@ ...@@ -17,6 +17,9 @@
# tag_push_events :boolean default(TRUE) # tag_push_events :boolean default(TRUE)
# note_events :boolean default(TRUE), not null # note_events :boolean default(TRUE), not null
# build_events :boolean default(FALSE), not null # build_events :boolean default(FALSE), not null
# category :string default("common"), not null
# default :boolean default(FALSE)
# wiki_page_events :boolean default(TRUE)
# #
class BambooService < CiService class BambooService < CiService
......
...@@ -3,12 +3,12 @@ ...@@ -3,12 +3,12 @@
# Table name: services # Table name: services
# #
# id :integer not null, primary key # id :integer not null, primary key
# type :string(255) # type :string
# title :string(255) # title :string
# project_id :integer # project_id :integer
# created_at :datetime # created_at :datetime not null
# updated_at :datetime # updated_at :datetime not null
# active :boolean default(FALSE), not null # active :boolean not null
# properties :text # properties :text
# template :boolean default(FALSE) # template :boolean default(FALSE)
# push_events :boolean default(TRUE) # push_events :boolean default(TRUE)
...@@ -17,6 +17,9 @@ ...@@ -17,6 +17,9 @@
# tag_push_events :boolean default(TRUE) # tag_push_events :boolean default(TRUE)
# note_events :boolean default(TRUE), not null # note_events :boolean default(TRUE), not null
# build_events :boolean default(FALSE), not null # build_events :boolean default(FALSE), not null
# category :string default("common"), not null
# default :boolean default(FALSE)
# wiki_page_events :boolean default(TRUE)
# #
require "addressable/uri" require "addressable/uri"
...@@ -26,7 +29,7 @@ class BuildkiteService < CiService ...@@ -26,7 +29,7 @@ class BuildkiteService < CiService
prop_accessor :project_url, :token, :enable_ssl_verification prop_accessor :project_url, :token, :enable_ssl_verification
validates :project_url, presence: true, if: :activated? validates :project_url, presence: true, url: true, if: :activated?
validates :token, presence: true, if: :activated? validates :token, presence: true, if: :activated?
after_save :compose_service_hook, if: :activated? after_save :compose_service_hook, if: :activated?
......
...@@ -3,12 +3,12 @@ ...@@ -3,12 +3,12 @@
# Table name: services # Table name: services
# #
# id :integer not null, primary key # id :integer not null, primary key
# type :string(255) # type :string
# title :string(255) # title :string
# project_id :integer # project_id :integer
# created_at :datetime # created_at :datetime not null
# updated_at :datetime # updated_at :datetime not null
# active :boolean default(FALSE), not null # active :boolean not null
# properties :text # properties :text
# template :boolean default(FALSE) # template :boolean default(FALSE)
# push_events :boolean default(TRUE) # push_events :boolean default(TRUE)
...@@ -17,6 +17,9 @@ ...@@ -17,6 +17,9 @@
# tag_push_events :boolean default(TRUE) # tag_push_events :boolean default(TRUE)
# note_events :boolean default(TRUE), not null # note_events :boolean default(TRUE), not null
# build_events :boolean default(FALSE), not null # build_events :boolean default(FALSE), not null
# category :string default("common"), not null
# default :boolean default(FALSE)
# wiki_page_events :boolean default(TRUE)
# #
class BuildsEmailService < Service class BuildsEmailService < Service
......
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.
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.
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