Commit 4f529a88 authored by Alfredo Sumaran's avatar Alfredo Sumaran

Merge branch 'master' into issue_13212

parents 45c29fa2 eb9838d3
......@@ -3,6 +3,12 @@ Please view this file on the master branch, on stable branches it's out of date.
v 8.6.0 (unreleased)
- Improve the formatting for the user page bio (Connor Shea)
- Fix avatar stretching by providing a cropping feature (Johann Pardanaud)
- Strip leading and trailing spaces in URL validator (evuez)
- Update documentation to reflect Guest role not being enforced on internal projects
v 8.5.2
- Fix sidebar overlapping content when screen width was below 1200px
- Fix error 500 when commenting on a commit
v 8.5.1
- Fix group projects styles
......@@ -23,9 +29,6 @@ v 8.5.1
- Update sentry-raven gem to 0.15.6
- Add build coverage in project's builds page (Steffen Köhler)
v 8.5.2
- Fix error 500 when commenting on a commit
v 8.5.0
- Fix duplicate "me" in tooltip of the "thumbsup" awards Emoji (Stan Hu)
- Cache various Repository methods to improve performance (Yorick Peterse)
......
......@@ -213,7 +213,6 @@ gem 'jquery-atwho-rails', '~> 1.3.2'
gem 'jquery-rails', '~> 4.0.0'
gem 'jquery-scrollto-rails', '~> 1.4.3'
gem 'jquery-ui-rails', '~> 5.0.0'
gem 'nprogress-rails', '~> 0.1.6.7'
gem 'raphael-rails', '~> 2.1.2'
gem 'request_store', '~> 1.2.0'
gem 'select2-rails', '~> 3.5.9'
......
......@@ -483,7 +483,6 @@ GEM
newrelic_rpm (3.14.1.311)
nokogiri (1.6.7.2)
mini_portile2 (~> 2.0.0.rc2)
nprogress-rails (0.1.6.7)
oauth (0.4.7)
oauth2 (1.0.0)
faraday (>= 0.8, < 0.10)
......@@ -964,7 +963,6 @@ DEPENDENCIES
net-ssh (~> 3.0.1)
newrelic_rpm (~> 3.14)
nokogiri (~> 1.6.7, >= 1.6.7.2)
nprogress-rails (~> 0.1.6.7)
oauth2 (~> 1.0.0)
octokit (~> 3.8.0)
omniauth (~> 1.3.1)
......
......@@ -31,8 +31,6 @@
#= require ace/ace
#= require ace/ext-searchbox
#= require underscore
#= require nprogress
#= require nprogress-turbolinks
#= require dropzone
#= require mousetrap
#= require mousetrap/pause
......
NProgress.configure(showSpinner: false)
Turbolinks.enableProgressBar();
defaultClass = 'tanuki-shape'
pieces = [
......
......@@ -25,12 +25,6 @@
*/
@import "framework";
/*
* NProgress load bar css
*/
@import 'nprogress';
@import 'nprogress-bootstrap';
/*
* Font icons
*/
......
......@@ -26,6 +26,7 @@
@import "framework/mobile.scss";
@import "framework/nav.scss";
@import "framework/pagination.scss";
@import "framework/progress.scss";
@import "framework/panels.scss";
@import "framework/selects.scss";
@import "framework/sidebar.scss";
......
html.turbolinks-progress-bar::before {
background-color: $progress-color!important;
height: 2px!important;
box-shadow: 0 0 10px $progress-color, 0 0 5px $progress-color;
}
......@@ -7,7 +7,7 @@ $gl-header-color: #323232;
$gl-link-color: #333c48;
$md-text-color: #444;
$md-link-color: #3084bb;
$nprogress-color: #c0392b;
$progress-color: #c0392b;
$gl-font-size: 15px;
$list-font-size: 15px;
$sidebar_collapsed_width: 62px;
......
.appearance-logo-preview {
max-width: 400px;
margin-bottom: 20px;
}
.appearance-light-logo-preview {
background-color: $background-color;
max-width: 72px;
padding: 10px;
margin-bottom: 10px;
}
......@@ -12,29 +12,10 @@
}
}
.todos {
.panel {
border-top: none;
margin-bottom: 0;
}
}
.todo-item {
font-size: $gl-font-size;
padding: $gl-padding-top 0 $gl-padding-top ($gl-avatar-size + $gl-padding-top);
border-bottom: 1px solid $table-border-color;
color: #7f8fa4;
&.todo-inline {
.avatar {
position: relative;
top: -2px;
}
.todo-title {
line-height: 40px;
}
}
padding-left: $gl-avatar-size + $gl-padding-top;
color: $secondary-text;
a {
color: #4c4e54;
......@@ -48,7 +29,7 @@
@include str-truncated(calc(100% - 174px));
font-weight: 600;
.author_name {
.author-name {
color: #333;
}
}
......@@ -88,17 +69,7 @@
margin-bottom: 0;
}
}
.todo-note-icon {
color: #777;
float: left;
font-size: $gl-font-size;
line-height: 16px;
margin-right: 5px;
}
}
&:last-child { border:none }
}
@media (max-width: $screen-xs-max) {
......
class Admin::AppearancesController < Admin::ApplicationController
before_action :set_appearance, except: :create
def show
end
def preview
end
def create
@appearance = Appearance.new(appearance_params)
if @appearance.save
redirect_to admin_appearances_path, notice: 'Appearance was successfully created.'
else
render action: 'show'
end
end
def update
if @appearance.update(appearance_params)
redirect_to admin_appearances_path, notice: 'Appearance was successfully updated.'
else
render action: 'show'
end
end
def logo
@appearance.remove_logo!
@appearance.save
redirect_to admin_appearances_path, notice: 'Logo was succesfully removed.'
end
def header_logos
@appearance.remove_header_logo!
@appearance.save
redirect_to admin_appearances_path, notice: 'Header logo was succesfully removed.'
end
private
# Use callbacks to share common setup or constraints between actions.
def set_appearance
@appearance = Appearance.last || Appearance.new
end
# Only allow a trusted parameter "white list" through.
def appearance_params
params.require(:appearance).permit(
:title, :description, :logo, :logo_cache, :header_logo, :header_logo_cache,
:updated_by
)
end
end
......@@ -4,12 +4,22 @@ class Projects::ForksController < Projects::ApplicationController
before_action :authorize_download_code!
def index
@sort = params[:sort] || 'id_desc'
@all_forks = project.forks.includes(:creator).order_by(@sort)
@public_forks, @protected_forks = @all_forks.partition do |project|
can?(current_user, :read_project, project)
end
base_query = project.forks.includes(:creator)
@forks = if current_user
base_query.where('projects.visibility_level IN (?) OR projects.id IN (?)',
Project.public_and_internal_levels,
current_user.authorized_projects.pluck(:id))
else
base_query.where('projects.visibility_level = ?', Project::PUBLIC)
end
@total_forks_count = base_query.size
@private_forks_count = @total_forks_count - @forks.size
@public_forks_count = @total_forks_count - @private_forks_count
@sort = params[:sort] || 'id_desc'
@forks = @forks.order_by(@sort).page(params[:page]).per(PER_PAGE)
end
def new
......
......@@ -55,14 +55,15 @@ class UploadsController < ApplicationController
"user" => User,
"project" => Project,
"note" => Note,
"group" => Group
"group" => Group,
"appearance" => Appearance
}
upload_models[params[:model]]
end
def upload_mount
upload_mounts = %w(avatar attachment file)
upload_mounts = %w(avatar attachment file logo header_logo)
if upload_mounts.include?(params[:mounted_as])
params[:mounted_as]
......
module AppearancesHelper
def brand_item
nil
end
def brand_title
'GitLab Community Edition'
if brand_item && brand_item.title
brand_item.title
else
'GitLab Community Edition'
end
end
def brand_image
nil
if brand_item.logo?
image_tag brand_item.logo
else
nil
end
end
def brand_text
nil
markdown(brand_item.description)
end
def brand_item
@appearance ||= Appearance.first
end
def brand_header_logo
render 'shared/logo.svg'
if brand_item && brand_item.header_logo?
image_tag brand_item.header_logo
else
render 'shared/logo.svg'
end
end
end
class Appearance < ActiveRecord::Base
validates :title, presence: true
validates :description, presence: true
validates :logo, file_size: { maximum: 1.megabyte }
validates :header_logo, file_size: { maximum: 1.megabyte }
mount_uploader :logo, AttachmentUploader
mount_uploader :header_logo, AttachmentUploader
end
......@@ -27,7 +27,7 @@ class Milestone < ActiveRecord::Base
belongs_to :project
has_many :issues
has_many :labels, through: :issues
has_many :labels, -> { distinct.reorder('labels.title') }, through: :issues
has_many :merge_requests
has_many :participants, through: :issues, source: :assignee
......
......@@ -29,8 +29,11 @@ class UrlValidator < ActiveModel::EachValidator
end
def valid_url?(value)
return false if value.nil?
options = default_options.merge(self.options)
value.strip!
value =~ /\A#{URI.regexp(options[:protocols])}\z/
end
end
= form_for @appearance, url: admin_appearances_path, html: { class: 'form-horizontal'} do |f|
- if @appearance.errors.any?
.alert.alert-danger
- @appearance.errors.full_messages.each do |msg|
%p= msg
%fieldset.sign-in
%legend
Sign in/Sign up pages:
.form-group
= f.label :title, class: 'control-label'
.col-sm-10
= f.text_field :title, class: "form-control"
.form-group
= f.label :description, class: 'control-label'
.col-sm-10
= f.text_area :description, class: "form-control", rows: 10
.hint
Description parsed with #{link_to "GitLab Flavored Markdown", help_page_path('markdown', 'markdown'), target: '_blank'}.
.form-group
= f.label :logo, class: 'control-label'
.col-sm-10
- if @appearance.logo?
= image_tag @appearance.logo_url, class: 'appearance-logo-preview'
- if @appearance.persisted?
%br
= link_to 'Remove logo', logo_admin_appearances_path, data: { confirm: "Logo will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-small remove-logo"
%hr
= f.hidden_field :logo_cache
= f.file_field :logo, class: ""
.hint
Maximum file size is 1MB. Pages are optimized for a 640x360 px logo.
%fieldset.app_logo
%legend
Navigation bar:
.form-group
= f.label :header_logo, 'Header logo', class: 'control-label'
.col-sm-10
- if @appearance.header_logo?
= image_tag @appearance.header_logo_url, class: 'appearance-light-logo-preview'
- if @appearance.persisted?
%br
= link_to 'Remove header logo', header_logos_admin_appearances_path, data: { confirm: "Header logo will be removed. Are you sure?"}, method: :delete, class: "btn btn-remove btn-small remove-logo"
%hr
= f.hidden_field :header_logo_cache
= f.file_field :header_logo, class: ""
.hint
Maximum file size is 1MB. Pages are optimized for a 72x72 px header logo
.form-actions
= f.submit 'Save', class: 'btn btn-save'
- if @appearance.persisted?
= link_to 'Preview last save', preview_admin_appearances_path, class: 'btn', target: '_blank'
- if @appearance.updated_at
%span.pull-right
Last edit #{time_ago_with_tooltip(@appearance.updated_at)}
- page_title "Preview | Appearance"
%h3.page-title
Appearance settings - Preview
%hr
.ui-box
.title
Sign-in page
%div
.login-page
.container
.content
.login-title
%h1= brand_title
%hr
.container
.content
.row
.col-sm-7
.brand-image
= brand_image
.brand_text
= brand_text
.col-sm-4
.login-box
%h3.page-title Sign in
= text_field_tag :login, nil, class: "form-control top", placeholder: "Username or Email"
= password_field_tag :password, nil, class: "form-control bottom", placeholder: "Password"
= button_tag "Sign in", class: "btn-create btn"
- page_title "Appearance"
%h3.page-title
Appearance settings
%p.light
You can modify the look and feel of GitLab here
= render 'form'
%li{class: "todo todo-#{todo.done? ? 'done' : 'pending'}", id: dom_id(todo) }
.todo-item{class: 'todo-block'}
.todo-item.todo-block
= image_tag avatar_icon(todo.author_email, 40), class: 'avatar s40', alt:''
.todo-title
%span.author_name
%span.author-name
= link_to_author todo
%span.todo_label
%span.todo-label
= todo_action_name(todo)
= todo_target_link(todo)
......
......@@ -56,6 +56,11 @@
= icon('cog fw')
%span
Background Jobs
= nav_link(controller: :appearances) do
= link_to admin_appearances_path, title: 'Appearances' do
= icon('image')
%span
Appearance
= nav_link(controller: :applications) do
= link_to admin_applications_path, title: 'Applications' do
......
......@@ -3,17 +3,16 @@
Too many changes to show.
.pull-right
- unless diff_hard_limit_enabled?
= link_to "Reload with full diff", url_for(params.merge(force_show_diff: true, format: nil)), class: "btn btn-sm btn-warning"
= link_to "Reload with full diff", url_for(params.merge(force_show_diff: true, format: nil)), class: "btn btn-sm"
- if current_controller?(:commit) or current_controller?(:merge_requests)
- if current_controller?(:commit)
= link_to "Plain diff", namespace_project_commit_path(@project.namespace, @project, @commit, format: :diff), class: "btn btn-warning btn-sm"
= link_to "Email patch", namespace_project_commit_path(@project.namespace, @project, @commit, format: :patch), class: "btn btn-warning btn-sm"
= link_to "Plain diff", namespace_project_commit_path(@project.namespace, @project, @commit, format: :diff), class: "btn btn-sm"
= link_to "Email patch", namespace_project_commit_path(@project.namespace, @project, @commit, format: :patch), class: "btn btn-sm"
- elsif @merge_request && @merge_request.persisted?
= link_to "Plain diff", merge_request_path(@merge_request, format: :diff), class: "btn btn-warning btn-sm"
= link_to "Email patch", merge_request_path(@merge_request, format: :patch), class: "btn btn-warning btn-sm"
= link_to "Plain diff", merge_request_path(@merge_request, format: :diff), class: "btn btn-sm"
= link_to "Email patch", merge_request_path(@merge_request, format: :patch), class: "btn btn-sm"
%p
To preserve performance only
%strong #{shown_files_count} of #{diffs.size}
files are displayed.
.top-area
.nav-text
- public_count = @public_forks.size
- protected_count = @protected_forks.size
- full_count_title = "#{public_count} public and #{protected_count} private"
== #{pluralize(@all_forks.size, 'fork')}: #{full_count_title}
- full_count_title = "#{@public_forks_count} public and #{@private_forks_count} private"
== #{pluralize(@total_forks_count, 'fork')}: #{full_count_title}
.nav-controls
= search_field_tag :filter_projects, nil, placeholder: 'Search forks', class: 'projects-list-filter project-filter-form-field form-control input-short',
......@@ -41,17 +39,17 @@
.projects-list-holder
- if @public_forks.blank?
- if @forks.blank?
%ul.content-list
%li
.nothing-here-block No forks to show
- else
= render 'shared/projects/list', projects: @public_forks, use_creator_avatar: true,
= render 'shared/projects/list', projects: @forks, use_creator_avatar: true,
forks: true, show_last_commit_as_description: true
- if protected_count > 0
- if @private_forks_count > 0
%ul.projects-list.private-forks-notice
%li.project-row
= icon('lock fw', base: 'circle', class: 'fa-lg private-fork-icon')
%strong= pluralize(protected_count, 'private fork')
%strong= pluralize(@private_forks_count, 'private fork')
%span you have no access to.
......@@ -156,6 +156,11 @@ Rails.application.routes.draw do
to: "uploads#show",
constraints: { model: /note|user|group|project/, mounted_as: /avatar|attachment/, filename: /[^\/]+/ }
# Appearance
get ":model/:mounted_as/:id/:filename",
to: "uploads#show",
constraints: { model: /appearance/, mounted_as: /logo|header_logo/, filename: /.+/ }
# Project markdown uploads
get ":namespace_id/:project_id/:secret/:filename",
to: "projects/uploads#show",
......@@ -253,6 +258,14 @@ Rails.application.routes.draw do
end
end
resource :appearances, path: 'appearance' do
member do
get :preview
delete :logo
delete :header_logos
end
end
resource :application_settings, only: [:show, :update] do
resources :services
put :reset_runners_token
......
class CreateAppearancesCe < ActiveRecord::Migration
def change
unless table_exists?(:appearances)
create_table :appearances do |t|
t.string :title
t.text :description
t.string :header_logo
t.string :logo
t.timestamps null: false
end
end
end
end
......@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20160220123949) do
ActiveRecord::Schema.define(version: 20160222153918) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......@@ -24,6 +24,15 @@ ActiveRecord::Schema.define(version: 20160220123949) do
t.datetime "updated_at"
end
create_table "appearances", force: :cascade do |t|
t.string "title"
t.text "description"
t.string "header_logo"
t.string "logo"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "application_settings", force: :cascade do |t|
t.integer "default_projects_limit"
t.boolean "signup_enabled"
......
......@@ -16,40 +16,42 @@
- [Web hooks](web_hooks/web_hooks.md) Let GitLab notify you when new code has been pushed to your project.
- [Workflow](workflow/README.md) Using GitLab functionality and importing projects from GitHub and SVN.
## CI Documentation
## CI User documentation
- [Quick Start](ci/quick_start/README.md)
- [Enable or disable GitLab CI](ci/enable_or_disable_ci.md)
- [Configuring project (.gitlab-ci.yml)](ci/yaml/README.md)
- [Configuring runner](ci/runners/README.md)
- [Configuring deployment](ci/deployment/README.md)
- [Using Docker Images](ci/docker/using_docker_images.md)
- [Using Docker Build](ci/docker/using_docker_build.md)
- [Using Variables](ci/variables/README.md)
- [Using SSH keys](ci/ssh_keys/README.md)
- [Get started with GitLab CI](ci/quick_start/README.md)
- [Learn how to enable or disable GitLab CI](ci/enable_or_disable_ci.md)
- [Learn how `.gitlab-ci.yml` works](ci/yaml/README.md)
- [Configure a Runner, the application that runs your builds](ci/runners/README.md)
- [Use Docker images with GitLab Runner](ci/docker/using_docker_images.md)
- [Use CI to build Docker images](ci/docker/using_docker_build.md)
- [Use variables in your `.gitlab-ci.yml`](ci/variables/README.md)
- [Use SSH keys in your build environment](ci/ssh_keys/README.md)
- [Trigger builds through the API](ci/triggers/README.md)
- [Build artifacts](ci/build_artifacts/README.md)
- [User permissions](ci/permissions/README.md)
- [API](ci/api/README.md)
- [Triggering builds through the API](ci/triggers/README.md)
- [Build artifacts](ci/build_artifacts/README.md)
### CI Languages
### CI Examples
- [Testing PHP](ci/languages/php.md)
- [The .gitlab-ci.yml file for GitLab itself](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/.gitlab-ci.yml)
- [Test your PHP applications](ci/examples/php.md)
- [Test and deploy Ruby applications to Heroku](ci/examples/test-and-deploy-ruby-application-to-heroku.md)
- [Test and deploy Python applications to Heroku](ci/examples/test-and-deploy-python-application-to-heroku.md)
- [Test Clojure applications](ci/examples/test-clojure-application.md)
- [Using `dpl` as deployment tool](ci/deployment/README.md)
- Help your favorite programming language and GitLab by sending a merge request
with a guide for that language.
### CI Services
GitLab CI uses the `services` keyword to define what docker containers should
be linked with your base image. Below is a list of examples you may use:
- [Using MySQL](ci/services/mysql.md)
- [Using PostgreSQL](ci/services/postgres.md)
- [Using Redis](ci/services/redis.md)
- [Using Other Services](ci/docker/using_docker_images.md#how-to-use-other-images-as-services)
### CI Examples
- [Test and deploy Ruby applications to Heroku](ci/examples/test-and-deploy-ruby-application-to-heroku.md)
- [Test and deploy Python applications to Heroku](ci/examples/test-and-deploy-python-application-to-heroku.md)
- [Test Clojure applications](ci/examples/test-clojure-application.md)
- Help your favorite programming language and GitLab by sending a merge request with a guide for that language.
## Administrator documentation
- [Custom git hooks](hooks/custom_hooks.md) Custom git hooks (on the filesystem) for when web hooks aren't enough.
......
## GitLab CI Documentation
### User documentation
* [Quick Start](quick_start/README.md)
* [Enable or disable GitLab CI](enable_or_disable_ci.md)
* [Configuring project (.gitlab-ci.yml)](yaml/README.md)
* [Configuring runner](runners/README.md)
* [Configuring deployment](deployment/README.md)
* [Using Docker Images](docker/using_docker_images.md)
* [Using Docker Build](docker/using_docker_build.md)
* [Using Variables](variables/README.md)
* [Using SSH keys](ssh_keys/README.md)
* [Triggering builds through the API](triggers/README.md)
* [Build artifacts](build_artifacts/README.md)
### Languages
* [Testing PHP](languages/php.md)
### Services
* [Using MySQL](services/mysql.md)
* [Using PostgreSQL](services/postgres.md)
* [Using Redis](services/redis.md)
* [Using Other Services](docker/using_docker_images.md#how-to-use-other-images-as-services)
### Examples
+ [The .gitlab-ci.yml file for GitLab itself](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/.gitlab-ci.yml)
+ [Test and deploy Ruby applications to Heroku](examples/test-and-deploy-ruby-application-to-heroku.md)
+ [Test and deploy Python applications to Heroku](examples/test-and-deploy-python-application-to-heroku.md)
+ [Test Clojure applications](examples/test-clojure-application.md)
+ Help your favorite programming language and GitLab by sending a merge request with a guide for that language.
### Administrator documentation
* [User permissions](permissions/README.md)
* [API](api/README.md)
### CI User documentation
- [Get started with GitLab CI](quick_start/README.md)
- [Learn how to enable or disable GitLab CI](enable_or_disable_ci.md)
- [Learn how `.gitlab-ci.yml` works](yaml/README.md)
- [Configure a Runner, the application that runs your builds](runners/README.md)
- [Use Docker images with GitLab Runner](docker/using_docker_images.md)
- [Use CI to build Docker images](docker/using_docker_build.md)
- [Use variables in your `.gitlab-ci.yml`](variables/README.md)
- [Use SSH keys in your build environment](ssh_keys/README.md)
- [Trigger builds through the API](triggers/README.md)
- [Build artifacts](build_artifacts/README.md)
- [User permissions](permissions/README.md)
- [API](api/README.md)
### CI Examples
- [The .gitlab-ci.yml file for GitLab itself](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/.gitlab-ci.yml)
- [Test your PHP applications](examples/php.md)
- [Test and deploy Ruby applications to Heroku](examples/test-and-deploy-ruby-application-to-heroku.md)
- [Test and deploy Python applications to Heroku](examples/test-and-deploy-python-application-to-heroku.md)
- [Test Clojure applications](examples/test-clojure-application.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.
### CI Services
GitLab CI uses the `services` keyword to define what docker containers should
be linked with your base image. Below is a list of examples you may use:
- [Using MySQL](services/mysql.md)
- [Using PostgreSQL](services/postgres.md)
- [Using Redis](services/redis.md)
- [Using Other Services](docker/using_docker_images.md#how-to-use-other-images-as-services)
# Build script examples
## Build script examples
+ [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)
- [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)
## Languages
This is a list of languages you can test with GitLab CI. Each section has
comprehensive documentation and comes with a test repository hosted on
GitLab.com.
- [Testing PHP](php.md)
### Languages
This is a list of languages you can test with GitLab CI. Each section has
comprehensive documentation and comes with a test repository hosted on
GitLab.com
+ [Testing PHP](php.md)
......@@ -201,6 +201,11 @@ You can access a builds badge image using following link:
http://example.gitlab.com/namespace/project/badges/branch/build.svg
```
## Examples
Visit the [examples README][examples] to see a list of examples using GitLab
CI with various languages.
## Next steps
Awesome! You started using CI in GitLab!
......@@ -212,3 +217,4 @@ Visit our various languages examples at <https://gitlab.com/groups/gitlab-exampl
[runner-install]: https://gitlab.com/gitlab-org/gitlab-ci-multi-runner/tree/master#installation
[blog-ci]: https://about.gitlab.com/2015/05/06/why-were-replacing-gitlab-ci-jobs-with-gitlab-ci-dot-yml/
[examples]: ../examples/README.md
## GitLab CI Services
GitLab CI uses the `services` keyword to define what docker containers should be
linked with your base image. Below is a list of examples you may use.
GitLab CI uses the `services` keyword to define what docker containers should
be linked with your base image. Below is a list of examples you may use.
+ [Using MySQL](mysql.md)
+ [Using PostgreSQL](postgres.md)
+ [Using Redis](redis.md)
+ [Using Other Services](../docker/using_docker_images.md#how-to-use-other-images-as-services)
- [Using MySQL](mysql.md)
- [Using PostgreSQL](postgres.md)
- [Using Redis](redis.md)
- [Using Other Services](../docker/using_docker_images.md#how-to-use-other-images-as-services)
......@@ -518,3 +518,10 @@ You can find the link under `/ci/lint` of your gitlab instance.
If your commit message contains `[ci skip]`, the commit will be created but the
builds will be skipped.
## Examples
Visit the [examples README][examples] to see a list of examples using GitLab
CI with various languages.
[examples]: ../examples/README.md
# Changing the appearance of the login page
GitLab Community Edition offers a way to put your company's identity on the login page of your GitLab server and make it a branded login page.
By default, the page shows the GitLab logo and description.
![default_login_page](branded_login_page/default_login_page.png)
## Changing the appearance of the login page
Navigate to the **Admin** area and go to the **Appearance** page.
Fill in the required details like Title, Description and upload the company logo.
![appearance](branded_login_page/appearance.png)
After saving the page, your GitLab login page will have the details you filled in:
![company_login_page](branded_login_page/custom_sign_in.png)
# Customize the complete sign-in page (GitLab Enterprise Edition only)
# Customize the complete sign-in page
Please see [Branded login page](http://doc.gitlab.com/ee/customization/branded_login_page.html)
Please see [Branded login page](branded_login_page.md)
# Add a welcome message to the sign-in page (GitLab Community Edition)
It is possible to add a markdown-formatted welcome message to your GitLab
sign-in page. Users of GitLab Enterprise Edition should use the [branded login
page feature](/ee/customization/branded_login_page.html) instead.
page feature](branded_login_page.md) instead.
The welcome message (extra_sign_in_text) can now be set/changed in the Admin UI.
Admin area > Settings
\ No newline at end of file
Admin area > Settings
# Development
- [Architecture](architecture.md) of GitLab
- [Shell commands](shell_commands.md) in the GitLab codebase
- [Rake tasks](rake_tasks.md) for development
- [Benchmarking](benchmarking.md)
- [CI setup](ci_setup.md) for testing GitLab
- [Gotchas](gotchas.md) to avoid
- [How to dump production data to staging](db_dump.md)
- [Migration Style Guide](migration_style_guide.md) for creating safe migrations
- [Rake tasks](rake_tasks.md) for development
- [Shell commands](shell_commands.md) in the GitLab codebase
- [Sidekiq debugging](sidekiq_debugging.md)
- [UI guide](ui_guide.md) for building GitLab with existing css styles and elements
- [Migration Style Guide](migration_style_guide.md) for creating safe migrations
- [How to dump production data to staging](dump_db.md)
- [Benchmarking](benchmarking.md)
# Gotchas
The purpose of this guide is to document potential "gotchas" that contributors
might encounter or should avoid during development of GitLab CE and EE.
## Don't `describe` symbols
Consider the following model spec:
```ruby
require 'rails_helper'
describe User do
describe :to_param do
it 'converts the username to a param' do
user = described_class.new(username: 'John Smith')
expect(user.to_param).to eq 'john-smith'
end
end
end
```
When run, this spec doesn't do what we might expect:
```sh
spec/models/user_spec.rb|6 error| Failure/Error: u = described_class.new NoMethodError: undefined method `new' for :to_param:Symbol
```
### Solution
Except for the top-level `describe` block, always provide a String argument to
`describe`.
## Don't `rescue Exception`
See ["Why is it bad style to `rescue Exception => e` in Ruby?"][Exception].
_**Note:** This rule is [enforced automatically by
Rubocop](https://gitlab.com/gitlab-org/gitlab-ce/blob/8-4-stable/.rubocop.yml#L911-914)._
[Exception]: http://stackoverflow.com/q/10048173/223897
## Don't use inline CoffeeScript in views
Using the inline `:coffee` or `:coffeescript` Haml filters comes with a
performance overhead.
_**Note:** We've [removed these two filters](https://gitlab.com/gitlab-org/gitlab-ce/blob/8-5-stable/config/initializers/haml.rb)
in an initializer._
### Further reading
- Pull Request: [Replace CoffeeScript block into JavaScript in Views](https://git.io/vztMu)
- Stack Overflow: [Performance implications of using :coffescript filter inside HAML templates?](http://stackoverflow.com/a/17571242/223897)
## ID-based CSS selectors need to be a bit more specific
Normally, because HTML `id` attributes need to be unique to the page, it's
perfectly fine to write some JavaScript like the following:
```javascript
$('#js-my-selector').hide();
```
However, there's a feature of GitLab's Markdown processing that [automatically
adds anchors to header elements][ToC Processing], with the `id` attribute being
automatically generated based on the content of the header.
Unfortunately, this feature makes it possible for user-generated content to
create a header element with the same `id` attribute we're using in our
selector, potentially breaking the JavaScript behavior. A user could break the
above example with the following Markdown:
```markdown
## JS My Selector
```
Which gets converted to the following HTML:
```html
<h2>
<a id="js-my-selector" class="anchor" href="#js-my-selector" aria-hidden="true"></a>
JS My Selector
</h2>
```
[ToC Processing]: https://gitlab.com/gitlab-org/gitlab-ce/blob/8-4-stable/lib/banzai/filter/table_of_contents_filter.rb#L31-37
### Solution
The current recommended fix for this is to make our selectors slightly more
specific:
```javascript
$('div#js-my-selector').hide();
```
### Further reading
- Issue: [Merge request ToC anchor conflicts with tabs](https://gitlab.com/gitlab-org/gitlab-ce/issues/3908)
- Merge Request: [Make tab target selectors less naive](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/2023)
- Merge Request: [Make cross-project reference's clipboard target less naive](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/2024)
......@@ -6,7 +6,7 @@ If a user is both in a project group and in the project itself, the highest perm
If a user is a GitLab administrator they receive all permissions.
On public projects the Guest role is not enforced.
On public and internal projects the Guest role is not enforced.
All users will be able to create issues, leave comments, and pull or download the project code.
To add or import a user, you can follow the [project users and members
......
Feature: Admin Appearance
Scenario: Create new appearance
Given I sign in as an admin
And I visit admin appearance page
When submit form with new appearance
Then I should be redirected to admin appearance page
And I should see newly created appearance
Scenario: Preview appearance
Given application has custom appearance
And I sign in as an admin
When I visit admin appearance page
And I click preview button
Then I should see a customized appearance
Scenario: Custom sign-in page
Given application has custom appearance
When I visit login page
Then I should see a customized appearance
Scenario: Appearance logo
Given application has custom appearance
And I sign in as an admin
And I visit admin appearance page
When I attach a logo
Then I should see a logo
And I remove the logo
Then I should see logo removed
Scenario: Header logos
Given application has custom appearance
And I sign in as an admin
And I visit admin appearance page
When I attach header logos
Then I should see header logos
And I remove the header logos
Then I should see header logos removed
......@@ -13,6 +13,7 @@ Feature: Project Milestone
Given I visit project "Shop" milestones page
And I click link "v2.2"
Then I should see the labels "bug", "enhancement" and "feature"
And I should see the "bug" label listed only once
@javascript
Scenario: Listing labels from labels tab
......
class Spinach::Features::AdminAppearance < Spinach::FeatureSteps
include SharedAuthentication
include SharedPaths
step 'submit form with new appearance' do
fill_in 'appearance_title', with: 'MyCompany'
fill_in 'appearance_description', with: 'dev server'
click_button 'Save'
end
step 'I should be redirected to admin appearance page' do
expect(current_path).to eq admin_appearances_path
expect(page).to have_content 'Appearance settings'
end
step 'I should see newly created appearance' do
expect(page).to have_field('appearance_title', with: 'MyCompany')
expect(page).to have_field('appearance_description', with: 'dev server')
expect(page).to have_content 'Last edit'
end
step 'I click preview button' do
click_link "Preview"
end
step 'application has custom appearance' do
create(:appearance)
end
step 'I should see a customized appearance' do
expect(page).to have_content appearance.title
expect(page).to have_content appearance.description
end
step 'I attach a logo' do
attach_file(:appearance_logo, Rails.root.join('spec', 'fixtures', 'dk.png'))
click_button 'Save'
end
step 'I attach header logos' do
attach_file(:appearance_header_logo, Rails.root.join('spec', 'fixtures', 'dk.png'))
click_button 'Save'
end
step 'I should see a logo' do
expect(page).to have_xpath('//img[@src="/uploads/appearance/logo/1/dk.png"]')
end
step 'I should see header logos' do
expect(page).to have_xpath('//img[@src="/uploads/appearance/header_logo/1/dk.png"]')
end
step 'I remove the logo' do
click_link 'Remove logo'
end
step 'I remove the header logos' do
click_link 'Remove header logo'
end
step 'I should see logo removed' do
expect(page).not_to have_xpath('//img[@src="/uploads/appearance/logo/1/gitlab_logo.png"]')
end
step 'I should see header logos removed' do
expect(page).not_to have_xpath('//img[@src="/uploads/appearance/header_logo/1/header_logo_light.png"]')
end
def appearance
Appearance.last
end
end
......@@ -41,6 +41,12 @@ class Spinach::Features::ProjectMilestone < Spinach::FeatureSteps
end
end
step 'I should see the "bug" label listed only once' do
page.within('#tab-labels') do
expect(page).to have_content('bug', count: 1)
end
end
step 'I click link "v2.2"' do
click_link "v2.2"
end
......
......@@ -7,6 +7,10 @@ module SharedPaths
visit new_project_path
end
step 'I visit login page' do
visit new_user_session_path
end
# ----------------------------------------
# User
# ----------------------------------------
......@@ -187,6 +191,10 @@ module SharedPaths
visit admin_groups_path
end
step 'I visit admin appearance page' do
visit admin_appearances_path
end
step 'I visit admin teams page' do
visit admin_teams_path
end
......
......@@ -7,6 +7,8 @@ module Banzai
#
# Extends HTML::Pipeline::SanitizationFilter with a custom whitelist.
class SanitizationFilter < HTML::Pipeline::SanitizationFilter
UNSAFE_PROTOCOLS = %w(javascript :javascript data vbscript).freeze
def whitelist
whitelist = super
......@@ -43,8 +45,8 @@ module Banzai
# Allow any protocol in `a` elements...
whitelist[:protocols].delete('a')
# ...but then remove links with the `javascript` protocol
whitelist[:transformers].push(remove_javascript_links)
# ...but then remove links with unsafe protocols
whitelist[:transformers].push(remove_unsafe_links)
# Remove `rel` attribute from `a` elements
whitelist[:transformers].push(remove_rel)
......@@ -55,14 +57,14 @@ module Banzai
whitelist
end
def remove_javascript_links
def remove_unsafe_links
lambda do |env|
node = env[:node]
return unless node.name == 'a'
return unless node.has_attribute?('href')
if node['href'].start_with?('javascript', ':javascript')
if node['href'].start_with?(*UNSAFE_PROTOCOLS)
node.remove_attribute('href')
end
end
......
# Read about factories at https://github.com/thoughtbot/factory_girl
FactoryGirl.define do
factory :appearance do
title "MepMep"
description "This is my Community Edition instance"
end
end
......@@ -13,7 +13,7 @@ feature 'Issue filtering by Milestone', feature: true do
visit_issues(project)
filter_by_milestone(Milestone::None.title)
expect(page).to have_css('.title', count: 1)
expect(page).to have_css('.issue .title', count: 1)
end
scenario 'filters by a specific Milestone', js: true do
......@@ -23,7 +23,7 @@ feature 'Issue filtering by Milestone', feature: true do
visit_issues(project)
filter_by_milestone(milestone.title)
expect(page).to have_css('.title', count: 1)
expect(page).to have_css('.issue .title', count: 1)
end
def visit_issues(project)
......
......@@ -156,13 +156,27 @@ describe Banzai::Filter::SanitizationFilter, lib: true do
}
protocols.each do |name, data|
it "handles #{name}" do
it "disallows #{name}" do
doc = filter(data[:input])
expect(doc.to_html).to eq data[:output]
end
end
it 'disallows data links' do
input = '<a href="data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K">XSS</a>'
output = filter(input)
expect(output.to_html).to eq '<a>XSS</a>'
end
it 'disallows vbscript links' do
input = '<a href="vbscript:alert(document.domain)">XSS</a>'
output = filter(input)
expect(output.to_html).to eq '<a>XSS</a>'
end
it 'allows non-standard anchor schemes' do
exp = %q{<a href="irc://irc.freenode.net/git">IRC</a>}
act = filter(exp)
......
require 'rails_helper'
RSpec.describe Appearance, type: :model do
subject { create(:appearance) }
it { is_expected.to be_valid }
it { is_expected.to validate_presence_of(:title) }
it { is_expected.to validate_presence_of(:description) }
end
......@@ -19,6 +19,10 @@
require 'spec_helper'
describe ProjectHook, models: true do
describe "Associations" do
it { is_expected.to belong_to :project }
end
describe '.push_hooks' do
it 'should return hooks for push events only' do
hook = create(:project_hook, push_events: true)
......
......@@ -18,20 +18,14 @@
require 'spec_helper'
describe ProjectHook, models: true do
describe "Associations" do
it { is_expected.to belong_to :project }
end
describe "Mass assignment" do
end
describe WebHook, models: true do
describe "Validations" do
it { is_expected.to validate_presence_of(:url) }
context "url format" do
describe 'url' do
it { is_expected.to allow_value("http://example.com").for(:url) }
it { is_expected.to allow_value("https://excample.com").for(:url) }
it { is_expected.to allow_value("https://example.com").for(:url) }
it { is_expected.to allow_value(" https://example.com ").for(:url) }
it { is_expected.to allow_value("http://test.com/api").for(:url) }
it { is_expected.to allow_value("http://test.com/api?key=abc").for(:url) }
it { is_expected.to allow_value("http://test.com/api?key=abc&type=def").for(:url) }
......@@ -39,6 +33,12 @@ describe ProjectHook, models: true do
it { is_expected.not_to allow_value("example.com").for(:url) }
it { is_expected.not_to allow_value("ftp://example.com").for(:url) }
it { is_expected.not_to allow_value("herp-and-derp").for(:url) }
it 'strips :url before saving it' do
hook = create(:project_hook, url: ' https://example.com ')
expect(hook.url).to eq('https://example.com')
end
end
end
......
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