Commit 618033fb authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce

parents 8b2cdced 898f6130
......@@ -3,6 +3,8 @@ Please view this file on the master branch, on stable branches it's out of date.
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.
- Escape HTML in commit titles in system note messages
- Improve multiple branch push performance by memoizing permission checking
- 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
......@@ -16,6 +18,7 @@ v 8.8.0 (unreleased)
- Use ActionDispatch Remote IP for Akismet checking
- 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
- Update SVG sanitizer to conform to SVG 1.1
- Updated search UI
- Display informative message when new milestone is created
- Allow "NEWS" and "CHANGES" as alternative names for CHANGELOG. !3768 (Connor Shea)
......@@ -31,6 +34,10 @@ v 8.8.0 (unreleased)
- 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.4
- Fix always showing build notification message when switching between merge requests
- Fix links on wiki pages for relative url setups. !4026 (Artem Sidorenko)
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.
......
......@@ -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)
- 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
There are two editions of GitLab:
......
......@@ -9,11 +9,12 @@ class @MergeRequestWidget
constructor: (@opts) ->
$('#modal_merge_info').modal(show: false)
@firstCICheck = true
@readyForCICheck = true
@readyForCICheck = false
clearInterval @fetchBuildStatusInterval
@clearEventListeners()
@addEventListeners()
@getCIStatus(false)
@pollCIStatus()
notifyPermissions()
......@@ -71,7 +72,7 @@ class @MergeRequestWidget
if data.status is ''
return
if @firstCiCheck || 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
if data.coverage
......@@ -79,7 +80,7 @@ class @MergeRequestWidget
# The first check should only update the UI, a notification
# should only be displayed on status changes
if showNotification and not @firstCiCheck
if showNotification and not @firstCICheck
status = @ciLabelForStatus(data.status)
if status is "preparing"
......@@ -102,7 +103,7 @@ class @MergeRequestWidget
@close()
Turbolinks.visit _this.opts.builds_path
)
@firstCiCheck = false
@firstCICheck = false
showCIStatus: (state) ->
$('.ci_widget').hide()
......
......@@ -131,7 +131,7 @@ module BlobHelper
# elements and attributes. Note that this whitelist is by no means complete
# and may omit some elements.
def sanitize_svg(blob)
blob.data = Loofah.scrub_fragment(blob.data, :strip).to_xml
blob.data = Gitlab::Sanitizers::SVG.clean(blob.data)
blob
end
......
......@@ -10,7 +10,6 @@
# updated_at :datetime
# creator_id :integer
# issues_enabled :boolean default(TRUE), not null
# wall_enabled :boolean default(TRUE), not null
# merge_requests_enabled :boolean default(TRUE), not null
# wiki_enabled :boolean default(TRUE), not null
# namespace_id :integer
......@@ -67,7 +66,6 @@ class Project < ActiveRecord::Base
default_value_for :merge_requests_enabled, gitlab_config_features.merge_requests
default_value_for :builds_enabled, gitlab_config_features.builds
default_value_for :wiki_enabled, gitlab_config_features.wiki
default_value_for :wall_enabled, false
default_value_for :snippets_enabled, gitlab_config_features.snippets
default_value_for(:shared_runners_enabled) { current_application_settings.shared_runners_enabled }
......@@ -767,7 +765,7 @@ class Project < ActiveRecord::Base
# Check if current branch name is marked as protected in the system
def protected_branch?(branch_name)
protected_branches.where(name: branch_name).any?
protected_branch_names.include?(branch_name)
end
def developers_can_push_to_protected_branch?(branch_name)
......
......@@ -40,7 +40,7 @@ class ProjectWiki
end
def wiki_base_path
["/", @project.path_with_namespace, "/wikis"].join('')
[Gitlab.config.gitlab.url, "/", @project.path_with_namespace, "/wikis"].join('')
end
# Returns the Gollum::Wiki object.
......
......@@ -351,7 +351,7 @@ class SystemNoteService
# Returns an Array of Strings
def self.new_commit_summary(new_commits)
new_commits.collect do |commit|
"* #{commit.short_id} - #{commit.title}"
"* #{commit.short_id} - #{escape_html(commit.title)}"
end
end
......@@ -433,4 +433,8 @@ class SystemNoteService
body = "Moved #{direction} #{cross_reference}"
create_note(noteable: noteable, project: project, author: author, note: body)
end
def self.escape_html(text)
Rack::Utils.escape_html(text)
end
end
......@@ -41,9 +41,4 @@
.ci_widget.ci-error{style: "display:none"}
= icon("times-circle")
Could not connect to the CI server. Please check your settings and try again.
:javascript
$(function() {
merge_request_widget.getCIStatus(false);
});
Could not connect to the CI server. Please check your settings and try again.
\ No newline at end of file
......@@ -15,7 +15,6 @@ production: &base
issues: true
merge_requests: true
wiki: true
wall: false
snippets: false
visibility_level: "private" # can be "private" | "internal" | "public"
......
Rails.application.config.action_dispatch.trusted_proxies =
Rails.application.config.action_dispatch.trusted_proxies = (
[ '127.0.0.1', '::1' ] + Array(Gitlab.config.gitlab.trusted_proxies)
).map { |proxy| IPAddr.new(proxy) }
class RemoveWallEnabledFromProjects < ActiveRecord::Migration
def change
remove_column :projects, :wall_enabled, :boolean, default: true, null: false
end
end
......@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20160421130527) do
ActiveRecord::Schema.define(version: 20160508194200) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......@@ -728,7 +728,6 @@ ActiveRecord::Schema.define(version: 20160421130527) do
t.datetime "updated_at"
t.integer "creator_id"
t.boolean "issues_enabled", default: true, null: false
t.boolean "wall_enabled", default: true, null: false
t.boolean "merge_requests_enabled", default: true, null: false
t.boolean "wiki_enabled", default: true, null: false
t.integer "namespace_id"
......
......@@ -20,6 +20,7 @@ GET /users
"name": "John Smith",
"state": "active",
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/cd8.jpeg",
"web_url": "http://localhost:3000/u/john_smith"
},
{
"id": 2,
......@@ -27,6 +28,7 @@ GET /users
"name": "Jack Smith",
"state": "blocked",
"avatar_url": "http://gravatar.com/../e32131cd8.jpeg",
"web_url": "http://localhost:3000/u/jack_smith"
}
]
```
......@@ -45,21 +47,31 @@ GET /users
"email": "john@example.com",
"name": "John Smith",
"state": "active",
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/index.jpg",
"web_url": "http://localhost:3000/u/john_smith",
"created_at": "2012-05-23T08:00:58Z",
"is_admin": false,
"bio": null,
"location": null,
"skype": "",
"linkedin": "",
"twitter": "",
"website_url": "",
"extern_uid": "john.smith",
"provider": "provider_name",
"last_sign_in_at": "2012-06-01T11:41:01Z",
"confirmed_at": "2012-05-23T09:05:22Z",
"theme_id": 1,
"color_scheme_id": 2,
"is_admin": false,
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/cd8.jpeg",
"projects_limit": 100,
"current_sign_in_at": "2012-06-02T06:36:55Z",
"identities": [
{"provider": "github", "extern_uid": "2435223452345"},
{"provider": "bitbucket", "extern_uid": "john.smith"},
{"provider": "google_oauth2", "extern_uid": "8776128412476123468721346"}
],
"can_create_group": true,
"current_sign_in_at": "2014-03-19T13:12:15Z",
"two_factor_enabled": true
"can_create_project": true,
"two_factor_enabled": true,
"external": false
},
{
"id": 2,
......@@ -67,24 +79,27 @@ GET /users
"email": "jack@example.com",
"name": "Jack Smith",
"state": "blocked",
"avatar_url": "http://localhost:3000/uploads/user/avatar/2/index.jpg",
"web_url": "http://localhost:3000/u/jack_smith",
"created_at": "2012-05-23T08:01:01Z",
"is_admin": false,
"bio": null,
"location": null,
"skype": "",
"linkedin": "",
"twitter": "",
"website_url": "",
"extern_uid": "jack.smith",
"provider": "provider_name",
"last_sign_in_at": null,
"confirmed_at": "2012-05-30T16:53:06.148Z",
"theme_id": 1,
"color_scheme_id": 3,
"is_admin": false,
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/cd8.jpeg",
"can_create_group": true,
"can_create_project": true,
"projects_limit": 100,
"current_sign_in_at": "2014-03-19T17:54:13Z",
"two_factor_enabled": false
"identities": [],
"can_create_group": true,
"can_create_project": true,
"two_factor_enabled": true,
"external": false
}
]
```
......@@ -124,6 +139,7 @@ Parameters:
"name": "John Smith",
"state": "active",
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/cd8.jpeg",
"web_url": "http://localhost:3000/u/john_smith",
"created_at": "2012-05-23T08:00:58Z",
"is_admin": false,
"bio": null,
......@@ -152,23 +168,31 @@ Parameters:
"email": "john@example.com",
"name": "John Smith",
"state": "active",
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/index.jpg",
"web_url": "http://localhost:3000/u/john_smith",
"created_at": "2012-05-23T08:00:58Z",
"confirmed_at": "2012-05-23T08:00:58Z",
"last_sign_in_at": "2015-03-23T08:00:58Z",
"is_admin": false,
"bio": null,
"location": null,
"skype": "",
"linkedin": "",
"twitter": "",
"website_url": "",
"extern_uid": "john.smith",
"provider": "provider_name",
"last_sign_in_at": "2012-06-01T11:41:01Z",
"confirmed_at": "2012-05-23T09:05:22Z",
"theme_id": 1,
"color_scheme_id": 2,
"is_admin": false,
"projects_limit": 100,
"current_sign_in_at": "2012-06-02T06:36:55Z",
"identities": [
{"provider": "github", "extern_uid": "2435223452345"},
{"provider": "bitbucket", "extern_uid": "john.smith"},
{"provider": "google_oauth2", "extern_uid": "8776128412476123468721346"}
],
"can_create_group": true,
"can_create_project": true,
"projects_limit": 100
"two_factor_enabled": true,
"external": false
}
```
......@@ -261,21 +285,33 @@ GET /user
"username": "john_smith",
"email": "john@example.com",
"name": "John Smith",
"private_token": "dd34asd13as",
"state": "active",
"avatar_url": "http://localhost:3000/uploads/user/avatar/1/index.jpg",
"web_url": "http://localhost:3000/u/john_smith",
"created_at": "2012-05-23T08:00:58Z",
"is_admin": false,
"bio": null,
"location": null,
"skype": "",
"linkedin": "",
"twitter": "",
"website_url": "",
"last_sign_in_at": "2012-06-01T11:41:01Z",
"confirmed_at": "2012-05-23T09:05:22Z",
"theme_id": 1,
"color_scheme_id": 2,
"is_admin": false,
"projects_limit": 100,
"current_sign_in_at": "2012-06-02T06:36:55Z",
"identities": [
{"provider": "github", "extern_uid": "2435223452345"},
{"provider": "bitbucket", "extern_uid": "john_smith"},
{"provider": "google_oauth2", "extern_uid": "8776128412476123468721346"}
],
"can_create_group": true,
"can_create_project": true,
"projects_limit": 100
"two_factor_enabled": true,
"external": false,
"private_token": "dd34asd13as"
}
```
......
......@@ -41,9 +41,9 @@ GitLab Runner then executes build scripts as `gitlab-runner` user.
--description "My Runner"
```
2. Install Docker on server.
2. Install Docker Engine on server.
For more information how to install Docker on different systems checkout the [Supported installations](https://docs.docker.com/installation/).
For more information how to install Docker Engine on different systems checkout the [Supported installations](https://docs.docker.com/engine/installation/).
3. Add `gitlab-runner` user to `docker` group:
......@@ -151,4 +151,4 @@ In order to do that follow the steps:
An example project using this approach can be found here: https://gitlab.com/gitlab-examples/docker.
[docker-in-docker]: https://blog.docker.com/2013/09/docker-can-now-run-within-docker/
[docker-cap]: https://docs.docker.com/reference/run/#runtime-privilege-and-linux-capabilities
[docker-cap]: https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities
......@@ -64,7 +64,7 @@ You can see some widely used services examples in the relevant documentation of
### How is service linked to the build
To better understand how the container linking works, read
[Linking containers together](https://docs.docker.com/userguide/dockerlinks/).
[Linking containers together][linking-containers].
To summarize, if you add `mysql` as service to your application, the image will
then be used to create a container that is linked to the build container.
......@@ -273,7 +273,7 @@ creation.
[Docker Fundamentals]: https://docs.docker.com/engine/understanding-docker/
[hub]: https://hub.docker.com/
[linking-containers]: https://docs.docker.com/engine/userguide/networking/default_network/dockerlinks/
[tutum/wordpress]: https://registry.hub.docker.com/u/tutum/wordpress/
[postgres-hub]: https://registry.hub.docker.com/u/library/postgres/
[mysql-hub]: https://registry.hub.docker.com/u/library/mysql/
[tutum/wordpress]: https://hub.docker.com/r/tutum/wordpress/
[postgres-hub]: https://hub.docker.com/r/_/postgres/
[mysql-hub]: https://hub.docker.com/r/_/mysql/
[runner-priv-reg]: https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/blob/master/docs/configuration/advanced-configuration.md#using-a-private-docker-registry
......@@ -4,12 +4,12 @@
- [Test and deploy a Ruby application to Heroku](test-and-deploy-ruby-application-to-heroku.md)
- [Test and deploy a Python application to Heroku](test-and-deploy-python-application-to-heroku.md)
- [Test a Clojure application](test-clojure-application.md)
- [Using `dpl` as deployment tool](deployment/README.md)
- [Using `dpl` as deployment tool](../deployment/README.md)
- Help your favorite programming language and GitLab by sending a merge request
with a guide for that language.
## Outside the documentation
- [Blost post about using GitLab CI for iOS projects](https://about.gitlab.com/2016/03/10/setting-up-gitlab-ci-for-ios-projects/)
- [Blog post about using GitLab CI for iOS projects](https://about.gitlab.com/2016/03/10/setting-up-gitlab-ci-for-ios-projects/)
- [Repo's with examples for various languages](https://gitlab.com/groups/gitlab-examples)
- [The .gitlab-ci.yml file for GitLab itself](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/.gitlab-ci.yml)
......@@ -60,7 +60,7 @@ docker-php-ext-install pdo_mysql
You might wonder what `docker-php-ext-install` is. In short, it is a script
provided by the official php docker image that you can use to easilly install
extensions. For more information read the the documentation at
<https://hub.docker.com/_/php/>.
<https://hub.docker.com/r/_/php/>.
Now that we created the script that contains all prerequisites for our build
environment, let's add it in `.gitlab-ci.yml`:
......@@ -92,7 +92,7 @@ Finally, commit your files and push them to GitLab to see your build succeeding
The final `.gitlab-ci.yml` should look similar to this:
```yaml
# Select image from https://hub.docker.com/_/php/
# Select image from https://hub.docker.com/r/_/php/
image: php:5.6
before_script:
......@@ -278,7 +278,7 @@ that runs on [GitLab.com](https://gitlab.com) using our publicly available
Want to hack on it? Simply fork it, commit and push your changes. Within a few
moments the changes will be picked by a public runner and the build will begin.
[php-hub]: https://hub.docker.com/_/php/
[php-hub]: https://hub.docker.com/r/_/php/
[phpenv]: https://github.com/phpenv/phpenv
[phpenv-installation]: https://github.com/phpenv/phpenv#installation
[php-example-repo]: https://gitlab.com/gitlab-examples/php
......@@ -8,7 +8,7 @@ This is what the `.gitlab-ci.yml` file looks like for this project:
```yaml
test:
script:
# this configures django application to use attached postgres database that is run on `postgres` host
# this configures Django application to use attached postgres database that is run on `postgres` host
- export DATABASE_URL=postgres://postgres:@postgres:5432/python-test-app
- apt-get update -qy
- apt-get install -y python-dev python-pip
......@@ -37,7 +37,7 @@ production:
```
This project has three jobs:
1. `test` - used to test rails application,
1. `test` - used to test Django application,
2. `staging` - used to automatically deploy staging environment every push to `master` branch
3. `production` - used to automatically deploy production environmnet for every created tag
......@@ -61,12 +61,12 @@ gitlab-ci-multi-runner register \
--non-interactive \
--url "https://gitlab.com/ci/" \
--registration-token "PROJECT_REGISTRATION_TOKEN" \
--description "python-3.2" \
--description "python-3.5" \
--executor "docker" \
--docker-image python:3.2 \
--docker-image python:3.5 \
--docker-postgres latest
```
With the command above, you create a runner that uses [python:3.2](https://registry.hub.docker.com/u/library/python/) image and uses [postgres](https://registry.hub.docker.com/u/library/postgres/) database.
With the command above, you create a runner that uses [python:3.5](https://hub.docker.com/r/_/python/) image and uses [postgres](https://hub.docker.com/r/_/postgres/) database.
To access PostgreSQL database you need to connect to `host: postgres` as user `postgres` without password.
## Test and Deploy a ruby application
This example will guide you how to run tests in your Ruby application and deploy it automatically as Heroku application.
This example will guide you how to run tests in your Ruby on Rails application and deploy it automatically as Heroku application.
You can checkout the example [source](https://gitlab.com/ayufan/ruby-getting-started) and check [CI status](https://gitlab.com/ayufan/ruby-getting-started/builds?scope=all).
......@@ -32,7 +32,7 @@ production:
```
This project has three jobs:
1. `test` - used to test rails application,
1. `test` - used to test Rails application,
2. `staging` - used to automatically deploy staging environment every push to `master` branch
3. `production` - used to automatically deploy production environmnet for every created tag
......@@ -62,6 +62,6 @@ gitlab-ci-multi-runner register \
--docker-postgres latest
```
With the command above, you create a runner that uses [ruby:2.2](https://registry.hub.docker.com/u/library/ruby/) image and uses [postgres](https://registry.hub.docker.com/u/library/postgres/) database.
With the command above, you create a runner that uses [ruby:2.2](https://hub.docker.com/r/_/ruby/) image and uses [postgres](https://hub.docker.com/r/_/postgres/) database.
To access PostgreSQL database you need to connect to `host: postgres` as user `postgres` without password.
......@@ -16,7 +16,7 @@ services:
- mysql:latest
variables:
# Configure mysql environment variables (https://hub.docker.com/_/mysql/)
# Configure mysql environment variables (https://hub.docker.com/r/_/mysql/)
MYSQL_DATABASE: el_duderino
MYSQL_ROOT_PASSWORD: mysql_strong_password
```
......@@ -114,5 +114,5 @@ available [shared runners](../runners/README.md).
Want to hack on it? Simply fork it, commit and push your changes. Within a few
moments the changes will be picked by a public runner and the build will begin.
[hub-mysql]: https://hub.docker.com/_/mysql/
[hub-mysql]: https://hub.docker.com/r/_/mysql/
[mysql-example-repo]: https://gitlab.com/gitlab-examples/mysql
......@@ -110,5 +110,5 @@ available [shared runners](../runners/README.md).
Want to hack on it? Simply fork it, commit and push your changes. Within a few
moments the changes will be picked by a public runner and the build will begin.
[hub-pg]: https://hub.docker.com/_/postgres/
[hub-pg]: https://hub.docker.com/r/_/postgres/
[postgres-example-repo]: https://gitlab.com/gitlab-examples/postgres
......@@ -65,5 +65,5 @@ that runs on [GitLab.com](https://gitlab.com) using our publicly available
Want to hack on it? Simply fork it, commit and push your changes. Within a few
moments the changes will be picked by a public runner and the build will begin.
[hub-redis]: https://hub.docker.com/_/redis/
[hub-redis]: https://hub.docker.com/r/_/redis/
[redis-example-repo]: https://gitlab.com/gitlab-examples/redis
# Instrumenting Ruby Code
GitLab Performance Monitoring allows instrumenting of custom blocks of Ruby
code. This can be used to measure the time spent in a specific part of a larger
chunk of code. The resulting data is stored as a field in the transaction that
executed the block.
GitLab Performance Monitoring allows instrumenting of both methods and custom
blocks of Ruby code. Method instrumentation is the primary form of
instrumentation with block-based instrumentation only being used when we want to
drill down to specific regions of code within a method.
To start measuring a block of Ruby code you should use `Gitlab::Metrics.measure`
and give it a name:
## Instrumenting Methods
Instrumenting methods is done by using the `Gitlab::Metrics::Instrumentation`
module. This module offers a few different methods that can be used to
instrument code:
* `instrument_method`: instruments a single class method.
* `instrument_instance_method`: instruments a single instance method.
* `instrument_class_hierarchy`: given a Class this method will recursively
instrument all sub-classes (both class and instance methods).
* `instrument_methods`: instruments all public class methods of a Module.
* `instrument_instance_methods`: instruments all public instance methods of a
Module.
To remove the need for typing the full `Gitlab::Metrics::Instrumentation`
namespace you can use the `configure` class method. This method simply yields
the supplied block while passing `Gitlab::Metrics::Instrumentation` as its
argument. An example:
```
Gitlab::Metrics::Instrumentation.configure do |conf|
conf.instrument_method(Foo, :bar)
conf.instrument_method(Foo, :baz)
end
```
Using this method is in general preferred over directly calling the various
instrumentation methods.
Method instrumentation should be added in the initializer
`config/initializers/metrics.rb`.
### Examples
Instrumenting a single method:
```
Gitlab::Metrics::Instrumentation.configure do |conf|
conf.instrument_method(User, :find_by)
end
```
Instrumenting an entire class hierarchy:
```
Gitlab::Metrics::Instrumentation.configure do |conf|
conf.instrument_class_hierarchy(ActiveRecord::Base)
end
```
Instrumenting all public class methods:
```
Gitlab::Metrics::Instrumentation.configure do |conf|
conf.instrument_methods(User)
end
```
### Checking Instrumented Methods
The easiest way to check if a method has been instrumented is to check its
source location. For example:
```
method = Rugged::TagCollection.instance_method(:[])
method.source_location
```
If the source location points to `lib/gitlab/metrics/instrumentation.rb` you
know the method has been instrumented.
If you're using Pry you can use the `$` command to display the source code of a
method (along with its source location), this is easier than running the above
Ruby code. In case of the above snippet you'd run the following:
```
$ Rugged::TagCollection#[]
```
This will print out something along the lines of:
```
From: /path/to/your/gitlab/lib/gitlab/metrics/instrumentation.rb @ line 148:
Owner: #<Module:0x0055f0865c6d50>
Visibility: public
Number of lines: 21
def #{name}(#{args_signature})
trans = Gitlab::Metrics::Instrumentation.transaction
if trans
start = Time.now
retval = super
duration = (Time.now - start) * 1000.0
if duration >= Gitlab::Metrics.method_call_threshold
trans.increment(:method_duration, duration)
trans.add_metric(Gitlab::Metrics::Instrumentation::SERIES,
{ duration: duration },
method: #{label.inspect})
end
retval
else
super
end
end
```
## Instrumenting Ruby Blocks
Measuring blocks of Ruby code is done by calling `Gitlab::Metrics.measure` and
passing it a block. For example:
```ruby
Gitlab::Metrics.measure(:foo) do
......@@ -14,6 +127,10 @@ Gitlab::Metrics.measure(:foo) do
end
```
The block is executed and the execution time is stored as a set of fields in the
currently running transaction. If no transaction is present the block is yielded
without measuring anything.
3 values are measured for a block:
1. The real time elapsed, stored in NAME_real_time.
......
# GitLab Docker images
* The official GitLab Community Edition Docker image is [available on Docker Hub](https://registry.hub.docker.com/u/gitlab/gitlab-ce/).
* The official GitLab Enterprise Edition Docker image is [available on Docker Hub](https://registry.hub.docker.com/u/gitlab/gitlab-ee/).
* The official GitLab Community Edition Docker image is [available on Docker Hub](https://hub.docker.com/r/gitlab/gitlab-ce/).
* The official GitLab Enterprise Edition Docker image is [available on Docker Hub](https://hub.docker.com/r/gitlab/gitlab-ee/).
* The complete usage guide can be found in [Using GitLab Docker images](http://doc.gitlab.com/omnibus/docker/)
* The Dockerfile used for building public images is in [Omnibus Repository](https://gitlab.com/gitlab-org/omnibus-gitlab/tree/master/docker)
* Check the guide for [creating Omnibus-based Docker Image](http://doc.gitlab.com/omnibus/build/README.html#Build-Docker-image)
* Check the guide for [creating Omnibus-based Docker Image](http://doc.gitlab.com/omnibus/build/README.html#build-docker-image)
......@@ -122,6 +122,11 @@ module Gitlab
build_status_object(true)
end
def can_user_do_action?(action)
@permission_cache ||= {}
@permission_cache[action] ||= user.can?(action, project)
end
def change_access_check(change)
oldrev, newrev, ref = change.split(' ')
......@@ -135,7 +140,7 @@ module Gitlab
:push_code
end
unless user.can?(action, project)
unless can_user_do_action?(action)
status =
case action
when :force_push_code_to_protected_branches
......
require_relative "svg/whitelist"
module Gitlab
module Sanitizers
module SVG
def self.clean(data)
Loofah.xml_document(data).scrub!(Scrubber.new).to_s
end
class Scrubber < Loofah::Scrubber
# http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#embedding-custom-non-visible-data-with-the-data-*-attributes
DATA_ATTR_PATTERN = /\Adata-(?!xml)[a-z_][\w.\u00E0-\u00F6\u00F8-\u017F\u01DD-\u02AF-]*\z/u
def scrub(node)
unless ALLOWED_ELEMENTS.include?(node.name)
node.unlink
else
node.attributes.each do |attr_name, attr|
valid_attributes = ALLOWED_ATTRIBUTES[node.name]
unless valid_attributes && valid_attributes.include?(attr_name)
if ALLOWED_DATA_ATTRIBUTES_IN_ELEMENTS.include?(node.name) &&
attr_name.start_with?('data-')
# Arbitrary data attributes are allowed. Verify that the attribute
# is a valid data attribute.
attr.unlink unless attr_name =~ DATA_ATTR_PATTERN
else
attr.unlink
end
end
end
end
end
end
end
end
end
This diff is collapsed.
......@@ -62,7 +62,7 @@ module Gitlab
end
def wiki_page_url
"#{Gitlab.config.gitlab.url}#{object.wiki.wiki_base_path}/#{object.slug}"
"#{object.wiki.wiki_base_path}/#{object.slug}"
end
end
end
......@@ -10,7 +10,6 @@
# updated_at :datetime
# creator_id :integer
# issues_enabled :boolean default(TRUE), not null
# wall_enabled :boolean default(TRUE), not null
# merge_requests_enabled :boolean default(TRUE), not null
# wiki_enabled :boolean default(TRUE), not null
# namespace_id :integer
......
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 622 682">
<defs>
<style>.cls-1{fill:#30353e;}.cls-2{fill:#8c929d;}.cls-3{fill:#fc6d26;}.cls-4{fill:#e24329;}.cls-5{fill:#fca326;}</style>
</defs>
<title>stacked_wm</title>
<path id="bg" class="cls-1" d="M622,681H0V-1H622V681h0Z"/>
<g id="g12">
<path id="path14" class="cls-2" d="M316.89,497.72h-19l0.06,141.74H375V621.93h-58l-0.06-124.22h0Z"/>
</g>
<g id="g24">
<path id="path26" class="cls-2" d="M448.32,614.57a32.46,32.46,0,0,1-23.59,10c-14.5,0-20.35-7.14-20.35-16.45,0-14.07,9.74-20.77,30.52-20.77a86.46,86.46,0,0,1,13.42,1.08v26.19h0Zm-19.7-85.91a63.45,63.45,0,0,0-40.5,14.53l6.73,11.66c7.79-4.54,17.32-9.09,31-9.09,15.58,0,22.51,8,22.51,21.42v6.93a81.48,81.48,0,0,0-13.2-1.08c-33.33,0-50.22,11.69-50.22,36.14,0,21.86,13.42,32.89,33.76,32.89,13.71,0,26.84-6.28,31.38-16.45l3.46,13.85h13.42V567c0-22.94-10-38.3-38.31-38.3h0Z"/>
</g>
<g id="g28">
<path id="path30" class="cls-2" d="M528.4,625.18c-7.14,0-13.42-.87-18.18-3V556.58c6.49-5.41,14.5-9.31,24.68-9.31,18.4,0,25.54,13,25.54,34,0,29.86-11.47,43.93-32,43.93m8-96.52a34.88,34.88,0,0,0-26.19,11.58V522l-0.06-24.24H491.54L491.6,636c9.31,3.9,22.08,6.06,35.93,6.06,35.5,0,52.6-22.72,52.6-61.89,0-30.95-15.8-51.51-43.73-51.51"/>
</g>
<g id="g32">
<path id="path34" class="cls-2" d="M109.84,513.08c16.88,0,27.7,5.63,34.85,11.25l8.19-14.18c-11.16-9.78-26.16-15-42.17-15-40.47,0-68.83,24.67-68.83,74.44,0,52.15,30.59,72.5,65.58,72.5a111,111,0,0,0,42.21-8.22l-0.4-55.72V560.58H97.32v17.53h33.12l0.4,42.31c-4.33,2.16-11.9,3.9-22.08,3.9-28.14,0-47-17.7-47-55,0-37.87,19.48-56.26,48.05-56.26"/>
</g>
<g id="g36">
<path id="path38" class="cls-2" d="M243.79,497.72H225.17l0.06,23.8v82.23c0,22.94,10,38.3,38.31,38.3A64.16,64.16,0,0,0,275,641V624.31a57,57,0,0,1-8.66.65c-15.58,0-22.51-8-22.51-21.42v-56.7H275V531.26H243.85l-0.06-33.54h0Z"/>
</g>
<path id="path40" class="cls-2" d="M177.94,639.46h18.61V531.26H177.94v108.2h0Z"/>
<path id="path42" class="cls-2" d="M177.94,516.33h18.61V497.72H177.94v18.61h0Z"/>
<g id="g44">
<path id="path46" class="cls-3" d="M525.05,266.23l-24-74L453.36,45.6a8.19,8.19,0,0,0-15.58,0L390.12,192.24H231.88L184.22,45.6a8.19,8.19,0,0,0-15.58,0L121,192.24l-24,74a16.38,16.38,0,0,0,6,18.31L311,435.71,519.1,284.54a16.38,16.38,0,0,0,6-18.31"/>
</g>
<g id="g48">
<path id="path50" class="cls-4" d="M311,435.71h0l79.12-243.47H231.88L311,435.71h0Z"/>
</g>
<g id="g56">
<path id="path58" class="cls-3" d="M311,435.71L231.88,192.24H121L311,435.71h0Z"/>
</g>
<g id="g64">
<path id="path66" class="cls-5" d="M121,192.24h0l-24,74a16.37,16.37,0,0,0,6,18.31L311,435.7,121,192.24h0Z"/>
</g>
<g id="g72">
<path id="path74" class="cls-4" d="M121,192.24H231.88L184.22,45.6a8.19,8.19,0,0,0-15.58,0L121,192.24h0Z"/>
</g>
<g id="g76">
<path id="path78" class="cls-3" d="M311,435.71l79.12-243.47H501L311,435.71h0Z"/>
</g>
<g id="g80">
<path id="path82" class="cls-5" d="M501,192.24h0l24,74a16.37,16.37,0,0,1-6,18.31L311,435.7,501,192.24h0Z"/>
</g>
<g id="g84">
<path id="path86" class="cls-4" d="M501,192.24H390.12L437.78,45.6a8.19,8.19,0,0,1,15.58,0L501,192.24h0Z"/>
</g>
</svg>
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg" id="Layer_1" data-name="Layer 1" viewBox="0 0 622 682" filterMe="test">
<iframe src="http://www.google.com"></iframe>
<defs>
<style>.cls-1{fill:#30353e;}.cls-2{fill:#8c929d;}.cls-3{fill:#fc6d26;}.cls-4{fill:#e24329;}.cls-5{fill:#fca326;}</style>
</defs>
<title>stacked_wm</title>
<path id="bg" class="cls-1" d="M622,681H0V-1H622V681h0Z"/>
<g id="g12">
<path id="path14" class="cls-2" d="M316.89,497.72h-19l0.06,141.74H375V621.93h-58l-0.06-124.22h0Z"/>
</g>
<g id="g24">
<path id="path26" class="cls-2" d="M448.32,614.57a32.46,32.46,0,0,1-23.59,10c-14.5,0-20.35-7.14-20.35-16.45,0-14.07,9.74-20.77,30.52-20.77a86.46,86.46,0,0,1,13.42,1.08v26.19h0Zm-19.7-85.91a63.45,63.45,0,0,0-40.5,14.53l6.73,11.66c7.79-4.54,17.32-9.09,31-9.09,15.58,0,22.51,8,22.51,21.42v6.93a81.48,81.48,0,0,0-13.2-1.08c-33.33,0-50.22,11.69-50.22,36.14,0,21.86,13.42,32.89,33.76,32.89,13.71,0,26.84-6.28,31.38-16.45l3.46,13.85h13.42V567c0-22.94-10-38.3-38.31-38.3h0Z"/>
</g>
<g id="g28">
<path id="path30" class="cls-2" d="M528.4,625.18c-7.14,0-13.42-.87-18.18-3V556.58c6.49-5.41,14.5-9.31,24.68-9.31,18.4,0,25.54,13,25.54,34,0,29.86-11.47,43.93-32,43.93m8-96.52a34.88,34.88,0,0,0-26.19,11.58V522l-0.06-24.24H491.54L491.6,636c9.31,3.9,22.08,6.06,35.93,6.06,35.5,0,52.6-22.72,52.6-61.89,0-30.95-15.8-51.51-43.73-51.51"/>
</g>
<g id="g32">
<path id="path34" class="cls-2" d="M109.84,513.08c16.88,0,27.7,5.63,34.85,11.25l8.19-14.18c-11.16-9.78-26.16-15-42.17-15-40.47,0-68.83,24.67-68.83,74.44,0,52.15,30.59,72.5,65.58,72.5a111,111,0,0,0,42.21-8.22l-0.4-55.72V560.58H97.32v17.53h33.12l0.4,42.31c-4.33,2.16-11.9,3.9-22.08,3.9-28.14,0-47-17.7-47-55,0-37.87,19.48-56.26,48.05-56.26"/>
</g>
<g id="g36">
<path id="path38" class="cls-2" d="M243.79,497.72H225.17l0.06,23.8v82.23c0,22.94,10,38.3,38.31,38.3A64.16,64.16,0,0,0,275,641V624.31a57,57,0,0,1-8.66.65c-15.58,0-22.51-8-22.51-21.42v-56.7H275V531.26H243.85l-0.06-33.54h0Z"/>
</g>
<path id="path40" class="cls-2" d="M177.94,639.46h18.61V531.26H177.94v108.2h0Z"/>
<path id="path42" class="cls-2" d="M177.94,516.33h18.61V497.72H177.94v18.61h0Z"/>
<g id="g44">
<path id="path46" class="cls-3" d="M525.05,266.23l-24-74L453.36,45.6a8.19,8.19,0,0,0-15.58,0L390.12,192.24H231.88L184.22,45.6a8.19,8.19,0,0,0-15.58,0L121,192.24l-24,74a16.38,16.38,0,0,0,6,18.31L311,435.71,519.1,284.54a16.38,16.38,0,0,0,6-18.31"/>
</g>
<g id="g48">
<path id="path50" class="cls-4" d="M311,435.71h0l79.12-243.47H231.88L311,435.71h0Z"/>
</g>
<g id="g56">
<path id="path58" class="cls-3" d="M311,435.71L231.88,192.24H121L311,435.71h0Z"/>
</g>
<g id="g64">
<path id="path66" class="cls-5" d="M121,192.24h0l-24,74a16.37,16.37,0,0,0,6,18.31L311,435.7,121,192.24h0Z"/>
</g>
<g id="g72">
<path id="path74" class="cls-4" d="M121,192.24H231.88L184.22,45.6a8.19,8.19,0,0,0-15.58,0L121,192.24h0Z"/>
</g>
<g id="g76">
<path id="path78" class="cls-3" d="M311,435.71l79.12-243.47H501L311,435.71h0Z"/>
</g>
<g id="g80">
<path id="path82" class="cls-5" d="M501,192.24h0l24,74a16.37,16.37,0,0,1-6,18.31L311,435.7,501,192.24h0Z"/>
</g>
<g id="g84">
<path id="path86" class="cls-4" d="M501,192.24H390.12L437.78,45.6a8.19,8.19,0,0,1,15.58,0L501,192.24h0Z"/>
</g>
</svg>
......@@ -67,4 +67,16 @@ describe BlobHelper do
expect(result).to eq(expected)
end
end
describe "#sanitize_svg" do
let(:input_svg_path) { File.join(Rails.root, 'spec', 'fixtures', 'unsanitized.svg') }
let(:data) { open(input_svg_path).read }
let(:expected_svg_path) { File.join(Rails.root, 'spec', 'fixtures', 'sanitized.svg') }
let(:expected) { open(expected_svg_path).read }
it 'should retain essential elements' do
blob = OpenStruct.new(data: data)
expect(sanitize_svg(blob).data).to eq(expected)
end
end
end
require 'spec_helper'
describe 'trusted_proxies', lib: true do
context 'with default config' do
before do
set_trusted_proxies([])
end
it 'preserves private IPs as remote_ip' do
request = stub_request('HTTP_X_FORWARDED_FOR' => '10.1.5.89')
expect(request.remote_ip).to eq('10.1.5.89')
end
it 'filters out localhost from remote_ip' do
request = stub_request('HTTP_X_FORWARDED_FOR' => '1.1.1.1, 10.1.5.89, 127.0.0.1')
expect(request.remote_ip).to eq('10.1.5.89')
end
end
context 'with private IP ranges added' do
before do
set_trusted_proxies([ "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16" ])
end
it 'filters out private and local IPs from remote_ip' do
request = stub_request('HTTP_X_FORWARDED_FOR' => '1.2.3.6, 1.1.1.1, 10.1.5.89, 127.0.0.1')
expect(request.remote_ip).to eq('1.1.1.1')
end
end
context 'with proxy IP added' do
before do
set_trusted_proxies([ "60.98.25.47" ])
end
it 'filters out proxy IP from remote_ip' do
request = stub_request('HTTP_X_FORWARDED_FOR' => '1.2.3.6, 1.1.1.1, 60.98.25.47, 127.0.0.1')
expect(request.remote_ip).to eq('1.1.1.1')
end
end
def stub_request(headers = {})
ActionDispatch::RemoteIp.new(Proc.new { }, false, Rails.application.config.action_dispatch.trusted_proxies).call(headers)
ActionDispatch::Request.new(headers)
end
def set_trusted_proxies(proxies = [])
stub_config_setting('trusted_proxies' => proxies)
load File.join(__dir__, '../../config/initializers/trusted_proxies.rb')
end
end
......@@ -47,3 +47,9 @@ describe 'MergeRequestWidget', ->
spy = spyOn(@class, 'showCICoverage').and.stub()
@class.getCIStatus(false)
expect(spy).not.toHaveBeenCalled()
it 'should not display a notification on the first check after the widget has been created', ->
spy = spyOn(window, 'notify')
@class = new MergeRequestWidget(@opts)
@class.getCIStatus(true)
expect(spy).not.toHaveBeenCalled()
......@@ -112,7 +112,7 @@ describe Gitlab::UrlBuilder, lib: true do
wiki_page = build(:wiki_page)
url = described_class.build(wiki_page)
expect(url).to eq "#{Gitlab.config.gitlab.url}#{wiki_page.wiki.wiki_base_path}/#{wiki_page.slug}"
expect(url).to eq "#{Gitlab.config.gitlab.url}/#{wiki_page.wiki.project.path_with_namespace}/wikis/#{wiki_page.slug}"
end
end
end
......
......@@ -10,7 +10,6 @@
# updated_at :datetime
# creator_id :integer
# issues_enabled :boolean default(TRUE), not null
# wall_enabled :boolean default(TRUE), not null
# merge_requests_enabled :boolean default(TRUE), not null
# wiki_enabled :boolean default(TRUE), not null
# namespace_id :integer
......
......@@ -38,7 +38,9 @@ describe ProjectWiki, models: true do
describe "#wiki_base_path" do
it "returns the wiki base path" do
wiki_base_path = "/#{project.path_with_namespace}/wikis"
gitlab_url = Gitlab.config.gitlab.url
wiki_base_path = "#{gitlab_url}/#{project.path_with_namespace}/wikis"
expect(subject.wiki_base_path).to eq(wiki_base_path)
end
end
......
......@@ -506,6 +506,15 @@ describe SystemNoteService, services: true do
end
end
describe '.new_commit_summary' do
it 'escapes HTML titles' do
commit = double(title: '<pre>This is a test</pre>', short_id: '12345678')
escaped = '* 12345678 - &lt;pre&gt;This is a test&lt;&#x2F;pre&gt;'
expect(described_class.new_commit_summary([commit])).to eq([escaped])
end
end
include JiraServiceHelper
describe 'JIRA integration' do
......
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