Commit 22c9def0 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge remote-tracking branch 'ce-com/master' into ce-to-ee

Signed-off-by: default avatarDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
parents 951cd3c3 5a9554bb
...@@ -524,6 +524,8 @@ lint:javascript:report: ...@@ -524,6 +524,8 @@ lint:javascript:report:
<<: *except-docs <<: *except-docs
<<: *pull-cache <<: *pull-cache
stage: post-test stage: post-test
dependencies:
- setup-test-env
before_script: [] before_script: []
script: script:
- find app/ spec/ -name '*.js' -exec sed --in-place 's|/\* eslint-disable .*\*/||' {} \; # run report over all files - find app/ spec/ -name '*.js' -exec sed --in-place 's|/\* eslint-disable .*\*/||' {} \; # run report over all files
......
...@@ -565,7 +565,7 @@ Style/Proc: ...@@ -565,7 +565,7 @@ Style/Proc:
# branches, and conditions. # branches, and conditions.
Metrics/AbcSize: Metrics/AbcSize:
Enabled: true Enabled: true
Max: 57.08 Max: 56.96
# This cop checks if the length of a block exceeds some maximum value. # This cop checks if the length of a block exceeds some maximum value.
Metrics/BlockLength: Metrics/BlockLength:
......
...@@ -15,8 +15,8 @@ entry. ...@@ -15,8 +15,8 @@ entry.
- Omit trailing / leading hyphens in CI_COMMIT_REF_SLUG variable to make it usable as a hostname. !11218 (Stefan Hanreich) - Omit trailing / leading hyphens in CI_COMMIT_REF_SLUG variable to make it usable as a hostname. !11218 (Stefan Hanreich)
- Moved "Members in a project" menu entry and path locations. !11560 - Moved "Members in a project" menu entry and path locations. !11560
- Additional Prometheus metrics support. !11712 - Additional Prometheus metrics support. !11712
- Move uploads from `uploads/system` to `uploads/-/system` to free up `system` as a group name. !11713
- Rename all reserved paths that could have been created. !11713 - Rename all reserved paths that could have been created. !11713
- Move uploads from `uploads/system` to `uploads/-/system` to free up `system` as a group name. !11713
- Fix offline runner detection. !11751 (Alessio Caiazza) - Fix offline runner detection. !11751 (Alessio Caiazza)
- Use authorize_update_pipeline_schedule in PipelineSchedulesController. !11846 - Use authorize_update_pipeline_schedule in PipelineSchedulesController. !11846
- Rollback project repo move if there is an error in Projects::TransferService. !11877 - Rollback project repo move if there is an error in Projects::TransferService. !11877
...@@ -37,6 +37,7 @@ entry. ...@@ -37,6 +37,7 @@ entry.
- Supplement Bulgarian translation of Project Page & Repository Page. !12083 (Lyubomir Vasilev) - Supplement Bulgarian translation of Project Page & Repository Page. !12083 (Lyubomir Vasilev)
- Removes deleted_at and pending_delete occurrences in Project related queries. !12091 - Removes deleted_at and pending_delete occurrences in Project related queries. !12091
- Provide hint to create a personal access token for Git over HTTP. !12105 (Robin Bobbitt) - Provide hint to create a personal access token for Git over HTTP. !12105 (Robin Bobbitt)
- Display own user id in account settings page. !12141 (Riccardo Padovani)
- Accept image for avatar in user API. !12143 (Ivan Chernov) - Accept image for avatar in user API. !12143 (Ivan Chernov)
- Disable fork button on project limit. !12145 (Ivan Chernov) - Disable fork button on project limit. !12145 (Ivan Chernov)
- Added "created_after" and "created_before" params to issuables. !12151 (Kyle Bishop @kybishop) - Added "created_after" and "created_before" params to issuables. !12151 (Kyle Bishop @kybishop)
...@@ -123,8 +124,13 @@ entry. ...@@ -123,8 +124,13 @@ entry.
- Bump Faraday and dependent OAuth2 gem version to support no_proxy variable. - Bump Faraday and dependent OAuth2 gem version to support no_proxy variable.
- Renders 404 if given project is not readable by the user on Todos dashboard. - Renders 404 if given project is not readable by the user on Todos dashboard.
- Render CI statuses with warnings in orange. - Render CI statuses with warnings in orange.
<<<<<<< HEAD
- Add wells to admin dashboard overview to fix spacing problems. - Add wells to admin dashboard overview to fix spacing problems.
- Document the Delete Merged Branches functionality. - Document the Delete Merged Branches functionality.
=======
- Document the Delete Merged Branches functionality.
- Add wells to admin dashboard overview to fix spacing problems.
>>>>>>> ce-com/master
- Removes hover style for nodes that are either links or buttons in the pipeline graph. - Removes hover style for nodes that are either links or buttons in the pipeline graph.
- more visual contrast in pagination widget. - more visual contrast in pagination widget.
- Deprecate Healthcheck Access Token in favor of IP whitelist. - Deprecate Healthcheck Access Token in favor of IP whitelist.
......
9.4.0-pre 9.5.0-pre
...@@ -86,10 +86,23 @@ export default class IssuableBulkUpdateSidebar { ...@@ -86,10 +86,23 @@ export default class IssuableBulkUpdateSidebar {
this.toggleCheckboxDisplay(enable); this.toggleCheckboxDisplay(enable);
if (enable) { if (enable) {
this.initAffix();
SidebarHeightManager.init(); SidebarHeightManager.init();
} }
} }
initAffix() {
if (!this.$sidebar.hasClass('affix-top')) {
const offsetTop = $('.scrolling-tabs-container').outerHeight() + $('.sub-nav-scroll').outerHeight();
this.$sidebar.affix({
offset: {
top: offsetTop,
},
});
}
}
updateSelectedIssuableIds() { updateSelectedIssuableIds() {
this.$issuableIdsInput.val(IssuableBulkUpdateSidebar.getCheckedIssueIds()); this.$issuableIdsInput.val(IssuableBulkUpdateSidebar.getCheckedIssueIds());
} }
......
...@@ -190,14 +190,6 @@ ...@@ -190,14 +190,6 @@
display: none; display: none;
} }
.btn,
.dropdown,
.dropdown-toggle,
input,
form {
height: 35px;
}
input { input {
display: inline-block; display: inline-block;
position: relative; position: relative;
......
...@@ -92,7 +92,6 @@ ...@@ -92,7 +92,6 @@
@mixin maintain-sidebar-dimensions { @mixin maintain-sidebar-dimensions {
display: block; display: block;
width: $gutter-width; width: $gutter-width;
padding: 10px 0;
} }
.issues-bulk-update.right-sidebar { .issues-bulk-update.right-sidebar {
...@@ -104,6 +103,15 @@ ...@@ -104,6 +103,15 @@
&.right-sidebar-expanded { &.right-sidebar-expanded {
@include maintain-sidebar-dimensions; @include maintain-sidebar-dimensions;
width: $gutter-width; width: $gutter-width;
.issuable-sidebar-header {
// matches `.top-area .nav-controls` for issuable index pages
padding: 11px 0;
}
.block:last-of-type {
border: none;
}
} }
&.right-sidebar-collapsed { &.right-sidebar-collapsed {
......
...@@ -41,10 +41,22 @@ header.navbar-gitlab-new { ...@@ -41,10 +41,22 @@ header.navbar-gitlab-new {
} }
} }
.logo-text {
line-height: initial;
svg {
width: 55px;
height: 15px;
margin: 0;
fill: $white-light;
}
}
&:hover, &:hover,
&:focus { &:focus {
color: $tanuki-yellow; .logo-text svg {
text-decoration: none; fill: $tanuki-yellow;
}
} }
} }
} }
......
...@@ -23,6 +23,10 @@ $new-sidebar-width: 220px; ...@@ -23,6 +23,10 @@ $new-sidebar-width: 220px;
position: fixed; position: fixed;
height: 100%; height: 100%;
} }
.issues-bulk-update.right-sidebar.right-sidebar-expanded .issuable-sidebar-header {
padding: 10px 0 15px;
}
} }
.context-header { .context-header {
......
...@@ -54,7 +54,11 @@ ...@@ -54,7 +54,11 @@
.mr-widget-pipeline-graph { .mr-widget-pipeline-graph {
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
margin: 0 -6px 0 0; margin-right: 4px;
.stage-cell .stage-container {
margin: 3px 3px 3px 0;
}
.dropdown-menu { .dropdown-menu {
margin-top: 11px; margin-top: 11px;
......
...@@ -3,18 +3,9 @@ class Admin::ProjectsController < Admin::ApplicationController ...@@ -3,18 +3,9 @@ class Admin::ProjectsController < Admin::ApplicationController
before_action :group, only: [:show, :transfer] before_action :group, only: [:show, :transfer]
def index def index
params[:sort] ||= 'latest_activity_desc' finder = Admin::ProjectsFinder.new(params: params, current_user: current_user)
@projects = Project.with_statistics @projects = finder.execute
@projects = @projects.in_namespace(params[:namespace_id]) if params[:namespace_id].present? @sort = finder.sort
@projects = @projects.where(visibility_level: params[:visibility_level]) if params[:visibility_level].present?
@projects = @projects.with_push if params[:with_push].present?
@projects = @projects.abandoned if params[:abandoned].present?
@projects = @projects.where(last_repository_check_failed: true) if params[:last_repository_check_failed].present?
@projects = @projects.non_archived unless params[:archived].present?
@projects = @projects.personal(current_user) if params[:personal].present?
@projects = @projects.search(params[:name]) if params[:name].present?
@projects = @projects.sort(@sort = params[:sort])
@projects = @projects.includes(:namespace).order("namespaces.path, projects.name ASC").page(params[:page])
respond_to do |format| respond_to do |format|
format.html format.html
......
...@@ -3,11 +3,11 @@ class Projects::BadgesController < Projects::ApplicationController ...@@ -3,11 +3,11 @@ class Projects::BadgesController < Projects::ApplicationController
before_action :authorize_admin_project!, only: [:index] before_action :authorize_admin_project!, only: [:index]
before_action :no_cache_headers, except: [:index] before_action :no_cache_headers, except: [:index]
def build def pipeline
build_status = Gitlab::Badge::Build::Status pipeline_status = Gitlab::Badge::Pipeline::Status
.new(project, params[:ref]) .new(project, params[:ref])
render_badge build_status render_badge pipeline_status
end end
def coverage def coverage
......
...@@ -35,7 +35,7 @@ module Projects ...@@ -35,7 +35,7 @@ module Projects
def define_badges_variables def define_badges_variables
@ref = params[:ref] || @project.default_branch || 'master' @ref = params[:ref] || @project.default_branch || 'master'
@badges = [Gitlab::Badge::Build::Status, @badges = [Gitlab::Badge::Pipeline::Status,
Gitlab::Badge::Coverage::Report] Gitlab::Badge::Coverage::Report]
@badges.map! do |badge| @badges.map! do |badge|
......
class Admin::ProjectsFinder
attr_reader :sort, :namespace_id, :visibility_level, :with_push,
:abandoned, :last_repository_check_failed, :archived,
:personal, :name, :page, :current_user
def initialize(params:, current_user:)
@current_user = current_user
@sort = params.fetch(:sort) { 'latest_activity_desc' }
@namespace_id = params[:namespace_id]
@visibility_level = params[:visibility_level]
@with_push = params[:with_push]
@abandoned = params[:abandoned]
@last_repository_check_failed = params[:last_repository_check_failed]
@archived = params[:archived]
@personal = params[:personal]
@name = params[:name]
@page = params[:page]
end
def execute
items = Project.with_statistics
items = items.in_namespace(namespace_id) if namespace_id.present?
items = items.where(visibility_level: visibility_level) if visibility_level.present?
items = items.with_push if with_push.present?
items = items.abandoned if abandoned.present?
items = items.where(last_repository_check_failed: true) if last_repository_check_failed.present?
items = items.non_archived unless archived.present?
items = items.personal(current_user) if personal.present?
items = items.search(name) if name.present?
items = items.sort(sort)
items.includes(:namespace).order("namespaces.path, projects.name ASC").page(page)
end
end
...@@ -13,7 +13,7 @@ module Projects ...@@ -13,7 +13,7 @@ module Projects
project.change_repository_storage(params.delete(:repository_storage)) project.change_repository_storage(params.delete(:repository_storage))
end end
if project.has_container_registry_tags? if renaming_project_with_container_registry_tags?
return error('Cannot rename project because it contains container registry tags!') return error('Cannot rename project because it contains container registry tags!')
end end
...@@ -59,6 +59,13 @@ module Projects ...@@ -59,6 +59,13 @@ module Projects
can?(current_user, :change_repository_storage, project) can?(current_user, :change_repository_storage, project)
end end
def renaming_project_with_container_registry_tags?
new_path = params[:path]
new_path && new_path != project.path &&
project.has_container_registry_tags?
end
def changing_default_branch? def changing_default_branch?
new_branch = params[:default_branch] new_branch = params[:default_branch]
......
...@@ -7,6 +7,6 @@ ...@@ -7,6 +7,6 @@
%span.light %span.light
- has_icon = provider_has_icon?(provider) - has_icon = provider_has_icon?(provider)
= link_to provider_image_tag(provider), omniauth_authorize_path(:user, provider), method: :post, class: 'oauth-login' + (has_icon ? ' oauth-image-link' : ' btn'), id: "oauth-login-#{provider}" = link_to provider_image_tag(provider), omniauth_authorize_path(:user, provider), method: :post, class: 'oauth-login' + (has_icon ? ' oauth-image-link' : ' btn'), id: "oauth-login-#{provider}"
%fieldset %fieldset.prepend-top-10
= check_box_tag :remember_me = check_box_tag :remember_me
= label_tag :remember_me, 'Remember Me' = label_tag :remember_me, 'Remember me'
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
%h1.title %h1.title
= link_to root_path, title: 'Dashboard' do = link_to root_path, title: 'Dashboard' do
= brand_header_logo = brand_header_logo
%span.hidden-xs %span.logo-text.hidden-xs
GitLab = render 'shared/logo_type.svg'
- if current_user - if current_user
= render "layouts/nav/new_dashboard" = render "layouts/nav/new_dashboard"
......
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 617 169"><path d="M315.26 2.97h-21.8l.1 162.5h88.3v-20.1h-66.5l-.1-142.4M465.89 136.95c-5.5 5.7-14.6 11.4-27 11.4-16.6 0-23.3-8.2-23.3-18.9 0-16.1 11.2-23.8 35-23.8 4.5 0 11.7.5 15.4 1.2v30.1h-.1m-22.6-98.5c-17.6 0-33.8 6.2-46.4 16.7l7.7 13.4c8.9-5.2 19.8-10.4 35.5-10.4 17.9 0 25.8 9.2 25.8 24.6v7.9c-3.5-.7-10.7-1.2-15.1-1.2-38.2 0-57.6 13.4-57.6 41.4 0 25.1 15.4 37.7 38.7 37.7 15.7 0 30.8-7.2 36-18.9l4 15.9h15.4v-83.2c-.1-26.3-11.5-43.9-44-43.9M557.63 149.1c-8.2 0-15.4-1-20.8-3.5V70.5c7.4-6.2 16.6-10.7 28.3-10.7 21.1 0 29.2 14.9 29.2 39 0 34.2-13.1 50.3-36.7 50.3m9.2-110.6c-19.5 0-30 13.3-30 13.3v-21l-.1-27.8h-21.3l.1 158.5c10.7 4.5 25.3 6.9 41.2 6.9 40.7 0 60.3-26 60.3-70.9-.1-35.5-18.2-59-50.2-59M77.9 20.6c19.3 0 31.8 6.4 39.9 12.9l9.4-16.3C114.5 6 97.3 0 78.9 0 32.5 0 0 28.3 0 85.4c0 59.8 35.1 83.1 75.2 83.1 20.1 0 37.2-4.7 48.4-9.4l-.5-63.9V75.1H63.6v20.1h38l.5 48.5c-5 2.5-13.6 4.5-25.3 4.5-32.2 0-53.8-20.3-53.8-63-.1-43.5 22.2-64.6 54.9-64.6M231.43 2.95h-21.3l.1 27.3v94.3c0 26.3 11.4 43.9 43.9 43.9 4.5 0 8.9-.4 13.1-1.2v-19.1c-3.1.5-6.4.7-9.9.7-17.9 0-25.8-9.2-25.8-24.6v-65h35.7v-17.8h-35.7l-.1-38.5M155.96 165.47h21.3v-124h-21.3v124M155.96 24.37h21.3V3.07h-21.3v21.3"/></svg>
- type = local_assigns.fetch(:type) - type = local_assigns.fetch(:type)
%aside.issues-bulk-update.js-right-sidebar.right-sidebar.affix-top{ data: { "offset-top" => "50", "spy" => "affix" }, "aria-live" => "polite" } %aside.issues-bulk-update.js-right-sidebar.right-sidebar{ "aria-live" => "polite", data: { 'signed-in': current_user.present? } }
.issuable-sidebar.hidden .issuable-sidebar.hidden
= form_tag [:bulk_update, @project.namespace.becomes(Namespace), @project, type], method: :post, class: "bulk-update" do = form_tag [:bulk_update, @project.namespace.becomes(Namespace), @project, type], method: :post, class: "bulk-update" do
.block .block.issuable-sidebar-header
.filter-item.inline.update-issues-btn.pull-left .filter-item.inline.update-issues-btn.pull-left
= button_tag "Update all", class: "btn update-selected-issues btn-info", disabled: true = button_tag "Update all", class: "btn update-selected-issues btn-info", disabled: true
= button_tag "Cancel", class: "btn btn-default js-bulk-update-menu-hide pull-right" = button_tag "Cancel", class: "btn btn-default js-bulk-update-menu-hide pull-right"
......
---
title: Decrease ABC threshold to 56.96
merge_request: 11227
author: Maxim Rydkin
---
title: Make font size of contextual sub menu items 14px
merge_request:
author:
---
title: Fix margins in the mini graph for pipeline in commits box
merge_request:
author:
---
title: Fix some invalid entries in PO files
merge_request: 13032
author:
---
title: Fix editing project with container images present
merge_request: 13028
author:
---
title: Fix an infinite loop when handling user-supplied regular expressions
merge_request:
author:
---
title: Update build badges to be pipeline badges and display passing instead of success
merge_request:
author:
- group: HA Proxy
priority: 10
metrics:
- title: "Throughput"
y_label: "Requests / Sec"
required_metrics:
- haproxy_frontend_http_requests_total
weight: 1
queries:
- query_range: 'sum(rate(haproxy_frontend_http_requests_total{%{environment_filter}}[2m]))'
label: Total
unit: req / sec
- title: "HTTP Error Rate"
y_label: "Error Rate (%)"
required_metrics:
- haproxy_frontend_http_responses_total
weight: 1
queries:
- query_range: 'sum(rate(haproxy_frontend_http_responses_total{code="5xx",%{environment_filter}}[2m])) / sum(rate(haproxy_frontend_http_responses_total{%{environment_filter}}[2m]))'
label: HTTP Errors
unit: "%"
- group: AWS Elastic Load Balancer - group: AWS Elastic Load Balancer
priority: 10 priority: 10
metrics: metrics:
...@@ -56,7 +77,7 @@ ...@@ -56,7 +77,7 @@
- nginx_responses_total - nginx_responses_total
weight: 1 weight: 1
queries: queries:
- query_range: 'sum(nginx_responses_total{status_code="5xx", %{environment_filter}}) / sum(nginx_responses_total{server_zone!="*", server_zone!="_", %{environment_filter}})' - query_range: 'sum(rate(nginx_responses_total{status_code="5xx", %{environment_filter}}[2m])) / sum(rate(nginx_requests_total{server_zone!="*", server_zone!="_", %{environment_filter}}[2m]))'
label: HTTP Errors label: HTTP Errors
unit: "%" unit: "%"
- group: Kubernetes - group: Kubernetes
......
...@@ -422,7 +422,9 @@ constraints(ProjectUrlConstrainer.new) do ...@@ -422,7 +422,9 @@ constraints(ProjectUrlConstrainer.new) do
collection do collection do
scope '*ref', constraints: { ref: Gitlab::PathRegex.git_reference_regex } do scope '*ref', constraints: { ref: Gitlab::PathRegex.git_reference_regex } do
constraints format: /svg/ do constraints format: /svg/ do
get :build # Keep around until 10.0, see gitlab-org/gitlab-ce#35307
get :build, to: "badges#pipeline"
get :pipeline
get :coverage get :coverage
end end
end end
......
...@@ -250,7 +250,7 @@ Tip: If you want to limit access to the nested members of an Active Directory ...@@ -250,7 +250,7 @@ Tip: If you want to limit access to the nested members of an Active Directory
group you can use the following syntax: group you can use the following syntax:
``` ```
(memberOf:1.2.840.113556.1.4.1941=CN=My Group,DC=Example,DC=com) (memberOf:1.2.840.113556.1.4.1941:=CN=My Group,DC=Example,DC=com)
``` ```
Find more information about this "LDAP_MATCHING_RULE_IN_CHAIN" filter at Find more information about this "LDAP_MATCHING_RULE_IN_CHAIN" filter at
......
...@@ -36,3 +36,10 @@ slow jobs blocking work (even for different jobs) on the shared queue. ...@@ -36,3 +36,10 @@ slow jobs blocking work (even for different jobs) on the shared queue.
Each Sidekiq worker must be tested using RSpec, just like any other class. These Each Sidekiq worker must be tested using RSpec, just like any other class. These
tests should be placed in `spec/workers`. tests should be placed in `spec/workers`.
## Removing or renaming queues
Try to avoid renaming or removing queues in minor and patch releases.
During online update instance can have pending jobs and removing the queue can
lead to those jobs being stuck forever. If you can't write migration for those
Sidekiq jobs, please consider doing rename or remove queue in major release only.
\ No newline at end of file
# Monitoring HA Proxy
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/12621) in GitLab 9.4
GitLab has support for automatically detecting and monitoring HA Proxy. This is provided by leveraging the [HA Proxy Exporter](https://github.com/hnlq715/nginx-vts-exporter), which translates HA Proxy statistics into a Prometheus readable form.
## Metrics supported
| Name | Query |
| ---- | ----- |
| Throughput (req/sec) | sum(rate(haproxy_frontend_http_requests_total{%{environment_filter}}[2m])) |
| HTTP Error Rate (%) | sum(rate(haproxy_frontend_http_requests_total{code="5xx",%{environment_filter}}[2m])) / sum(rate(haproxy_frontend_http_requests_total{%{environment_filter}}[2m])) |
## Configuring Prometheus to monitor for HA Proxy metrics
To get started with NGINX monitoring, you should install and configure the [HA Proxy exporter](https://github.com/prometheus/haproxy_exporter) which parses these statistics and translates them into a Prometheus monitoring endpoint.
## Specifying the Environment label
In order to isolate and only display relevant metrics for a given environment
however, GitLab needs a method to detect which labels are associated. To do this, GitLab will [look for an `environment` label](metrics.md#identifying-environments).
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
GitLab offers automatic detection of select [Prometheus exporters](https://prometheus.io/docs/instrumenting/exporters/). Currently supported exporters are: GitLab offers automatic detection of select [Prometheus exporters](https://prometheus.io/docs/instrumenting/exporters/). Currently supported exporters are:
* [Kubernetes](kubernetes.md) * [Kubernetes](kubernetes.md)
* [NGINX](nginx.md) * [NGINX](nginx.md)
* [HA Proxy](haproxy.md)
* [Amazon Cloud Watch](cloudwatch.md) * [Amazon Cloud Watch](cloudwatch.md)
We have tried to surface the most important metrics for each exporter, and will be continuing to add support for additional exporters in future releases. If you would like to add support for other official exporters, [contributions](#adding-to-the-library) are welcome. We have tried to surface the most important metrics for each exporter, and will be continuing to add support for additional exporters in future releases. If you would like to add support for other official exporters, [contributions](#adding-to-the-library) are welcome.
......
...@@ -9,7 +9,7 @@ GitLab has support for automatically detecting and monitoring NGINX. This is pro ...@@ -9,7 +9,7 @@ GitLab has support for automatically detecting and monitoring NGINX. This is pro
| ---- | ----- | | ---- | ----- |
| Throughput (req/sec) | sum(rate(nginx_requests_total{server_zone!="*", server_zone!="_", %{environment_filter}}[2m])) | | Throughput (req/sec) | sum(rate(nginx_requests_total{server_zone!="*", server_zone!="_", %{environment_filter}}[2m])) |
| Latency (ms) | avg(nginx_upstream_response_msecs_avg{%{environment_filter}}) * 1000 | | Latency (ms) | avg(nginx_upstream_response_msecs_avg{%{environment_filter}}) * 1000 |
| HTTP Error Rate (%) | sum(nginx_responses_total{status_code="5xx", %{environment_filter}}) / sum(nginx_responses_total{server_zone!="*", server_zone!="_", %{environment_filter}}) | | HTTP Error Rate (%) | sum(rate(haproxy_frontend_http_responses_total{code="5xx",%{environment_filter}}[2m])) / sum(rate(haproxy_frontend_http_responses_total{%{environment_filter}}[2m])) |
## Configuring Prometheus to monitor for NGINX metrics ## Configuring Prometheus to monitor for NGINX metrics
......
Feature: Project Badges Build
Background:
Given I sign in as a user
And I own a project
And project has CI enabled
And project has a recent build
Scenario: I want to see a badge for successfully built project
Given recent build is successful
When I display builds badge for a master branch
Then I should see a build success badge
Scenario: I want to see a badge for project with failed builds
Given recent build failed
When I display builds badge for a master branch
Then I should see a build failed badge
Scenario: I want to see a badge for project with running builds
Given recent build is successful
And project has another build that is running
When I display builds badge for a master branch
Then I should see a build running badge
Scenario: I want to see a fresh badge on each request
Given recent build is successful
When I display builds badge for a master branch
Then I should see a badge that has not been cached
class Spinach::Features::ProjectBadgesBuild < Spinach::FeatureSteps
include SharedAuthentication
include SharedProject
include SharedBuilds
include RepoHelpers
step 'I display builds badge for a master branch' do
visit build_project_badges_path(@project, ref: :master, format: :svg)
end
step 'I should see a build success badge' do
expect_badge('success')
end
step 'I should see a build failed badge' do
expect_badge('failed')
end
step 'I should see a build running badge' do
expect_badge('running')
end
step 'I should see a badge that has not been cached' do
expect(page.response_headers['Cache-Control']).to include 'no-cache'
end
def expect_badge(status)
svg = Nokogiri::XML.parse(page.body)
expect(page.response_headers['Content-Type']).to include('image/svg+xml')
expect(svg.at(%Q{text:contains("#{status}")})).to be_truthy
end
end
...@@ -52,7 +52,7 @@ module Ci ...@@ -52,7 +52,7 @@ module Ci
# when old API will be removed (planned for August 2017). # when old API will be removed (planned for August 2017).
model.options.dup.tap do |options| model.options.dup.tap do |options|
options[:image] = options[:image][:name] if options[:image].is_a?(Hash) options[:image] = options[:image][:name] if options[:image].is_a?(Hash)
options[:services].map! do |service| options[:services]&.map! do |service|
if service.is_a?(Hash) if service.is_a?(Hash)
service[:name] service[:name]
else else
......
module Gitlab module Gitlab
module Badge module Badge
module Build module Pipeline
## ##
# Class that describes build badge metadata # Class that describes pipeline badge metadata
# #
class Metadata < Badge::Metadata class Metadata < Badge::Metadata
def initialize(badge) def initialize(badge)
...@@ -11,11 +11,11 @@ module Gitlab ...@@ -11,11 +11,11 @@ module Gitlab
end end
def title def title
'build status' 'pipeline status'
end end
def image_url def image_url
build_project_badges_url(@project, @ref, format: :svg) pipeline_project_badges_url(@project, @ref, format: :svg)
end end
def link_url def link_url
......
module Gitlab module Gitlab
module Badge module Badge
module Build module Pipeline
## ##
# Build status badge # Pipeline status badge
# #
class Status < Badge::Base class Status < Badge::Base
attr_reader :project, :ref attr_reader :project, :ref
...@@ -15,7 +15,7 @@ module Gitlab ...@@ -15,7 +15,7 @@ module Gitlab
end end
def entity def entity
'build' 'pipeline'
end end
def status def status
...@@ -25,11 +25,11 @@ module Gitlab ...@@ -25,11 +25,11 @@ module Gitlab
end end
def metadata def metadata
@metadata ||= Build::Metadata.new(self) @metadata ||= Pipeline::Metadata.new(self)
end end
def template def template
@template ||= Build::Template.new(self) @template ||= Pipeline::Template.new(self)
end end
end end
end end
......
module Gitlab module Gitlab
module Badge module Badge
module Build module Pipeline
## ##
# Class that represents a build badge template. # Class that represents a pipeline badge template.
# #
# Template object will be passed to badge.svg.erb template. # Template object will be passed to badge.svg.erb template.
# #
class Template < Badge::Template class Template < Badge::Template
STATUS_RENAME = { 'success' => 'passed' }.freeze
STATUS_COLOR = { STATUS_COLOR = {
success: '#4c1', success: '#4c1',
failed: '#e05d44', failed: '#e05d44',
...@@ -27,11 +28,11 @@ module Gitlab ...@@ -27,11 +28,11 @@ module Gitlab
end end
def value_text def value_text
@status.to_s STATUS_RENAME[@status.to_s] || @status.to_s
end end
def key_width def key_width
38 62
end end
def value_width def value_width
......
...@@ -67,13 +67,14 @@ module Gitlab ...@@ -67,13 +67,14 @@ module Gitlab
def extract_coverage(regex) def extract_coverage(regex)
return unless valid? return unless valid?
return unless regex return unless regex.present?
regex = Gitlab::UntrustedRegexp.new(regex) regex = Gitlab::UntrustedRegexp.new(regex)
match = "" match = ""
reverse_line do |line| reverse_line do |line|
line.chomp!
matches = regex.scan(line) matches = regex.scan(line)
next unless matches.is_a?(Array) next unless matches.is_a?(Array)
next if matches.empty? next if matches.empty?
......
...@@ -7,10 +7,10 @@ module Gitlab ...@@ -7,10 +7,10 @@ module Gitlab
'es' => 'Español', 'es' => 'Español',
'de' => 'Deutsch', 'de' => 'Deutsch',
'fr' => 'Français', 'fr' => 'Français',
'pt_BR' => 'Português(Brasil)', 'pt_BR' => 'Português (Brasil)',
'zh_CN' => '简体中文', 'zh_CN' => '简体中文',
'zh_HK' => '繁體中文(香港)', 'zh_HK' => '繁體中文 (香港)',
'zh_TW' => '繁體中文(臺灣)', 'zh_TW' => '繁體中文 (臺灣)',
'bg' => 'български', 'bg' => 'български',
'ru' => 'Русский', 'ru' => 'Русский',
'eo' => 'Esperanto', 'eo' => 'Esperanto',
......
...@@ -39,7 +39,12 @@ module Gitlab ...@@ -39,7 +39,12 @@ module Gitlab
groups[1..-1] groups[1..-1]
end end
text.slice!(0, match.end(0) || 1) matchsize = match.end(0)
# No further matches
break unless matchsize.present?
text.slice!(0, matchsize)
break unless text.present? break unless text.present?
end end
......
...@@ -33,7 +33,8 @@ msgstr "%{commit_author_link}は%{commit_timeago}前、コミットしました ...@@ -33,7 +33,8 @@ msgstr "%{commit_author_link}は%{commit_timeago}前、コミットしました
msgid "1 pipeline" msgid "1 pipeline"
msgid_plural "%d pipelines" msgid_plural "%d pipelines"
msgstr[0] "%d 個のパイプライン" msgstr[0] "1 個のパイプライン"
msgstr[1] "%d 個のパイプライン"
msgid "A collection of graphs regarding Continuous Integration" msgid "A collection of graphs regarding Continuous Integration"
msgstr "CIについてのグラフ" msgstr "CIについてのグラフ"
...@@ -1135,8 +1136,7 @@ msgstr "" ...@@ -1135,8 +1136,7 @@ msgstr ""
msgid "" msgid ""
"You are going to remove the fork relationship to source project " "You are going to remove the fork relationship to source project "
"%{forked_from_project}. Are you ABSOLUTELY sure?" "%{forked_from_project}. Are you ABSOLUTELY sure?"
msgstr "元のプロジェクト (%{forked_from_project}) とのリレーションを削除しようとしています。\n" msgstr "元のプロジェクト (%{forked_from_project}) とのリレーションを削除しようとしています。本当によろしいですか?"
"本当によろしいですか?"
msgid "" msgid ""
"You are going to transfer %{project_name_with_namespace} to another owner. " "You are going to transfer %{project_name_with_namespace} to another owner. "
...@@ -1201,4 +1201,3 @@ msgstr "メール通知" ...@@ -1201,4 +1201,3 @@ msgstr "メール通知"
msgid "parent" msgid "parent"
msgid_plural "parents" msgid_plural "parents"
msgstr[0] "親" msgstr[0] "親"
...@@ -6,13 +6,13 @@ msgid "" ...@@ -6,13 +6,13 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: gitlab 1.0.0\n" "Project-Id-Version: gitlab 1.0.0\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-06-28 13:32+0200\n" "POT-Creation-Date: 2017-07-05 08:50-0500\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"PO-Revision-Date: 2017-07-12 09:05-0400\n"
"Last-Translator: Leandro Nunes dos Santos <leandronunes@gmail.com>\n"
"Language-Team: Portuguese (Brazil) (https://translate.zanata.org/project/view/GitLab)\n" "Language-Team: Portuguese (Brazil) (https://translate.zanata.org/project/view/GitLab)\n"
"PO-Revision-Date: 2017-07-14 01:17-0400\n"
"Last-Translator: Huang Tao <htve@outlook.com>\n"
"Language: pt-BR\n" "Language: pt-BR\n"
"X-Generator: Zanata 3.9.6\n" "X-Generator: Zanata 3.9.6\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n"
...@@ -644,6 +644,12 @@ msgstr "Todos" ...@@ -644,6 +644,12 @@ msgstr "Todos"
msgid "PipelineSchedules|Inactive" msgid "PipelineSchedules|Inactive"
msgstr "Inativo" msgstr "Inativo"
msgid "PipelineSchedules|Input variable key"
msgstr "PipelineSchedules|Chave da variável de entrada"
msgid "PipelineSchedules|Input variable value"
msgstr "PipelineSchedules|Valor da variável de entrada"
msgid "PipelineSchedules|Next Run" msgid "PipelineSchedules|Next Run"
msgstr "Próxima Execução" msgstr "Próxima Execução"
...@@ -653,12 +659,18 @@ msgstr "Nenhum" ...@@ -653,12 +659,18 @@ msgstr "Nenhum"
msgid "PipelineSchedules|Provide a short description for this pipeline" msgid "PipelineSchedules|Provide a short description for this pipeline"
msgstr "Digite uma descrição curta para esta pipeline" msgstr "Digite uma descrição curta para esta pipeline"
msgid "PipelineSchedules|Remove variable row"
msgstr "PipelineSchedules|Remova a linha da variável"
msgid "PipelineSchedules|Take ownership" msgid "PipelineSchedules|Take ownership"
msgstr "Tornar-se proprietário" msgstr "Tornar-se proprietário"
msgid "PipelineSchedules|Target" msgid "PipelineSchedules|Target"
msgstr "Destino" msgstr "Destino"
msgid "PipelineSchedules|Variables"
msgstr "PipelineSchedules|Variáveis"
msgid "PipelineSheduleIntervalPattern|Custom" msgid "PipelineSheduleIntervalPattern|Custom"
msgstr "Personalizado" msgstr "Personalizado"
...@@ -1150,6 +1162,15 @@ msgstr "Esta etapa não possui dados suficientes para exibição." ...@@ -1150,6 +1162,15 @@ msgstr "Esta etapa não possui dados suficientes para exibição."
msgid "Withdraw Access Request" msgid "Withdraw Access Request"
msgstr "Remover Requisição de Acesso" msgstr "Remover Requisição de Acesso"
msgid ""
"You are going to remove %{group_name}.\n"
"Removed groups CANNOT be restored!\n"
"Are you ABSOLUTELY sure?"
msgstr ""
"Você vai remover %{group_name}.\n"
"Grupos removidos NÃO PODEM ser restaurados!\n"
"Você está ABSOLUTAMENTE certo?"
msgid "" msgid ""
"You are going to remove %{project_name_with_namespace}.\n" "You are going to remove %{project_name_with_namespace}.\n"
"Removed project CANNOT be restored!\n" "Removed project CANNOT be restored!\n"
......
...@@ -379,7 +379,7 @@ msgid "Edit" ...@@ -379,7 +379,7 @@ msgid "Edit"
msgstr "Редагувати" msgstr "Редагувати"
msgid "Edit Pipeline Schedule %{id}" msgid "Edit Pipeline Schedule %{id}"
msgstr "Редагувати Розклад Конвеєра % {id}" msgstr "Редагувати Розклад Конвеєра %{id}"
msgid "Every day (at 4:00am)" msgid "Every day (at 4:00am)"
msgstr "Кожен день (в 4:00 ранку)" msgstr "Кожен день (в 4:00 ранку)"
...@@ -1231,4 +1231,3 @@ msgid_plural "parents" ...@@ -1231,4 +1231,3 @@ msgid_plural "parents"
msgstr[0] "джерело" msgstr[0] "джерело"
msgstr[1] "джерела" msgstr[1] "джерела"
msgstr[2] "джерел" msgstr[2] "джерел"
...@@ -29,7 +29,8 @@ msgstr "由 %{commit_author_link} 提交于 %{commit_timeago}" ...@@ -29,7 +29,8 @@ msgstr "由 %{commit_author_link} 提交于 %{commit_timeago}"
msgid "1 pipeline" msgid "1 pipeline"
msgid_plural "%d pipelines" msgid_plural "%d pipelines"
msgstr[0] "%d 条流水线" msgstr[0] "1 条流水线"
msgstr[1] "%d 条流水线"
msgid "A collection of graphs regarding Continuous Integration" msgid "A collection of graphs regarding Continuous Integration"
msgstr "持续集成数据图" msgstr "持续集成数据图"
...@@ -236,7 +237,7 @@ msgstr "创建新目录" ...@@ -236,7 +237,7 @@ msgstr "创建新目录"
msgid "" msgid ""
"Create a personal access token on your account to pull or push via " "Create a personal access token on your account to pull or push via "
"%{protocol}." "%{protocol}."
msgstr "在帐户上创建个人访问令牌,以通过%{protocol}来拉取或推送。" msgstr "在帐户上创建个人访问令牌,以通过 %{protocol} 来拉取或推送。"
msgid "Create directory" msgid "Create directory"
msgstr "创建目录" msgstr "创建目录"
...@@ -1109,9 +1110,7 @@ msgid "" ...@@ -1109,9 +1110,7 @@ msgid ""
"You are going to remove %{project_name_with_namespace}.\n" "You are going to remove %{project_name_with_namespace}.\n"
"Removed project CANNOT be restored!\n" "Removed project CANNOT be restored!\n"
"Are you ABSOLUTELY sure?" "Are you ABSOLUTELY sure?"
msgstr "即将要删除 %{project_name_with_namespace}。\n" msgstr "即将要删除 %{project_name_with_namespace}。已删除的项目无法恢复!确定继续吗?"
"已删除的项目无法恢复!\n"
"确定继续吗?"
msgid "" msgid ""
"You are going to remove the fork relationship to source project " "You are going to remove the fork relationship to source project "
...@@ -1179,4 +1178,3 @@ msgstr "通知邮件" ...@@ -1179,4 +1178,3 @@ msgstr "通知邮件"
msgid "parent" msgid "parent"
msgid_plural "parents" msgid_plural "parents"
msgstr[0] "父级" msgstr[0] "父级"
...@@ -28,7 +28,8 @@ msgstr "由 %{commit_author_link} 提交於 %{commit_timeago}" ...@@ -28,7 +28,8 @@ msgstr "由 %{commit_author_link} 提交於 %{commit_timeago}"
msgid "1 pipeline" msgid "1 pipeline"
msgid_plural "%d pipelines" msgid_plural "%d pipelines"
msgstr[0] "%d 條流水線" msgstr[0] "1 條流水線"
msgstr[1] "%d 條流水線"
msgid "A collection of graphs regarding Continuous Integration" msgid "A collection of graphs regarding Continuous Integration"
msgstr "相關持續集成的圖像集合" msgstr "相關持續集成的圖像集合"
...@@ -1108,9 +1109,7 @@ msgid "" ...@@ -1108,9 +1109,7 @@ msgid ""
"You are going to remove %{project_name_with_namespace}.\n" "You are going to remove %{project_name_with_namespace}.\n"
"Removed project CANNOT be restored!\n" "Removed project CANNOT be restored!\n"
"Are you ABSOLUTELY sure?" "Are you ABSOLUTELY sure?"
msgstr "即將要刪除 %{project_name_with_namespace}。\n" msgstr "即將要刪除 %{project_name_with_namespace}。已刪除的項目無法恢複!確定繼續嗎?"
"已刪除的項目無法恢複!\n"
"確定繼續嗎?"
msgid "" msgid ""
"You are going to remove the fork relationship to source project " "You are going to remove the fork relationship to source project "
...@@ -1178,4 +1177,3 @@ msgstr "通知郵件" ...@@ -1178,4 +1177,3 @@ msgstr "通知郵件"
msgid "parent" msgid "parent"
msgid_plural "parents" msgid_plural "parents"
msgstr[0] "父級" msgstr[0] "父級"
...@@ -32,7 +32,8 @@ msgstr "%{commit_author_link} 在 %{commit_timeago} 送交" ...@@ -32,7 +32,8 @@ msgstr "%{commit_author_link} 在 %{commit_timeago} 送交"
msgid "1 pipeline" msgid "1 pipeline"
msgid_plural "%d pipelines" msgid_plural "%d pipelines"
msgstr[0] "%d 條流水線" msgstr[0] "1 條流水線"
msgstr[1] "%d 條流水線"
msgid "A collection of graphs regarding Continuous Integration" msgid "A collection of graphs regarding Continuous Integration"
msgstr "持續整合 (CI) 相關的圖表" msgstr "持續整合 (CI) 相關的圖表"
...@@ -1193,4 +1194,3 @@ msgstr "通知信" ...@@ -1193,4 +1194,3 @@ msgstr "通知信"
msgid "parent" msgid "parent"
msgid_plural "parents" msgid_plural "parents"
msgstr[0] "上層" msgstr[0] "上層"
require 'spec_helper'
describe Projects::BadgesController do
let(:project) { pipeline.project }
let!(:pipeline) { create(:ci_empty_pipeline) }
let(:user) { create(:user) }
before do
project.add_master(user)
sign_in(user)
end
it 'requests the pipeline badge successfully' do
get_badge(:pipeline)
expect(response).to have_http_status(:ok)
end
it 'requests the coverage badge successfully' do
get_badge(:coverage)
expect(response).to have_http_status(:ok)
end
def get_badge(badge)
get badge, namespace_id: project.namespace.to_param, project_id: project, ref: pipeline.ref, format: :svg
end
end
require 'spec_helper' require 'spec_helper'
feature 'Top Plus Menu', feature: true, js: true do feature 'Top Plus Menu', feature: true, js: true do
let(:user) { create :user } let(:user) { create(:user) }
let(:guest_user) { create :user}
let(:group) { create(:group) } let(:group) { create(:group) }
let(:project) { create(:project, :repository, creator: user, namespace: user.namespace) } let(:project) { create(:project, :repository, creator: user, namespace: user.namespace) }
let(:public_project) { create(:project, :public) } let(:public_project) { create(:project, :public) }
before do before do
group.add_owner(user) group.add_owner(user)
group.add_guest(guest_user)
project.add_guest(guest_user)
end end
context 'used by full user' do context 'used by full user' do
...@@ -102,7 +98,12 @@ feature 'Top Plus Menu', feature: true, js: true do ...@@ -102,7 +98,12 @@ feature 'Top Plus Menu', feature: true, js: true do
end end
context 'used by guest user' do context 'used by guest user' do
let(:guest_user) { create(:user) }
before do before do
group.add_guest(guest_user)
project.add_guest(guest_user)
sign_in(guest_user) sign_in(guest_user)
end end
......
...@@ -10,16 +10,16 @@ feature 'list of badges' do ...@@ -10,16 +10,16 @@ feature 'list of badges' do
end end
scenario 'user wants to see build status badge' do scenario 'user wants to see build status badge' do
page.within('.build-status') do page.within('.pipeline-status') do
expect(page).to have_content 'build status' expect(page).to have_content 'pipeline status'
expect(page).to have_content 'Markdown' expect(page).to have_content 'Markdown'
expect(page).to have_content 'HTML' expect(page).to have_content 'HTML'
expect(page).to have_content 'AsciiDoc' expect(page).to have_content 'AsciiDoc'
expect(page).to have_css('.highlight', count: 3) expect(page).to have_css('.highlight', count: 3)
expect(page).to have_xpath("//img[@alt='build status']") expect(page).to have_xpath("//img[@alt='pipeline status']")
page.within('.highlight', match: :first) do page.within('.highlight', match: :first) do
expect(page).to have_content 'badges/master/build.svg' expect(page).to have_content 'badges/master/pipeline.svg'
end end
end end
end end
...@@ -40,14 +40,14 @@ feature 'list of badges' do ...@@ -40,14 +40,14 @@ feature 'list of badges' do
end end
scenario 'user changes current ref of build status badge', js: true do scenario 'user changes current ref of build status badge', js: true do
page.within('.build-status') do page.within('.pipeline-status') do
first('.js-project-refs-dropdown').click first('.js-project-refs-dropdown').click
page.within '.project-refs-form' do page.within '.project-refs-form' do
click_link 'improve/awesome' click_link 'improve/awesome'
end end
expect(page).to have_content 'badges/improve/awesome/build.svg' expect(page).to have_content 'badges/improve/awesome/pipeline.svg'
end end
end end
end end
require 'spec_helper'
feature 'Pipeline Badge' do
set(:project) { create(:project, :repository, :public) }
let(:ref) { project.default_branch }
# this can't be tested in the controller, as it bypasses the rails router
# and constructs a route based on the controller being tested
# Keep around until 10.0, see gitlab-org/gitlab-ce#35307
context 'when the deprecated badge is requested' do
it 'displays the badge' do
visit build_project_badges_path(project, ref: ref, format: :svg)
expect(page.status_code).to eq(200)
end
end
context 'when the project has a pipeline' do
let!(:pipeline) { create(:ci_empty_pipeline, project: project, ref: ref, sha: project.commit(ref).sha) }
let!(:job) { create(:ci_build, pipeline: pipeline) }
context 'when the pipeline was successfull' do
it 'displays so on the badge' do
job.success
visit pipeline_project_badges_path(project, ref: ref, format: :svg)
expect(page.status_code).to eq(200)
expect_badge('passed')
end
end
context 'when the pipeline failed' do
it 'shows displays so on the badge' do
job.drop
visit pipeline_project_badges_path(project, ref: ref, format: :svg)
expect(page.status_code).to eq(200)
expect_badge('failed')
end
end
context 'when the pipeline is running' do
it 'shows displays so on the badge' do
create(:ci_build, pipeline: pipeline, name: 'second build', status_event: 'run')
visit pipeline_project_badges_path(project, ref: ref, format: :svg)
expect(page.status_code).to eq(200)
expect_badge('running')
end
end
context 'when a new pipeline is created' do
it 'shows a fresh badge' do
visit pipeline_project_badges_path(project, ref: ref, format: :svg)
expect(page.status_code).to eq(200)
expect(page.response_headers['Cache-Control']).to include 'no-cache'
end
end
def expect_badge(status)
svg = Nokogiri::XML.parse(page.body)
expect(page.response_headers['Content-Type']).to include('image/svg+xml')
expect(svg.at(%Q{text:contains("#{status}")})).to be_truthy
end
end
end
require 'spec_helper'
describe Admin::ProjectsFinder do
describe '#execute' do
let(:user) { create(:user) }
let(:group) { create(:group, :public) }
let!(:private_project) do
create(:empty_project, :private, name: 'A', path: 'A')
end
let!(:internal_project) do
create(:empty_project, :internal, group: group, name: 'B', path: 'B')
end
let!(:public_project) do
create(:empty_project, :public, group: group, name: 'C', path: 'C')
end
let!(:shared_project) do
create(:empty_project, :private, name: 'D', path: 'D')
end
let(:params) { {} }
let(:current_user) { user }
let(:project_ids_relation) { nil }
let(:finder) { described_class.new(params: params, current_user: current_user) }
subject { finder.execute.to_a }
context 'without a user' do
let(:current_user) { nil }
it { is_expected.to eq([shared_project, public_project, internal_project, private_project]) }
end
context 'with a user' do
it { is_expected.to eq([shared_project, public_project, internal_project, private_project]) }
end
context 'filter by namespace_id' do
let(:namespace) { create(:namespace) }
let!(:project_in_namespace) { create(:empty_project, namespace: namespace) }
let(:params) { { namespace_id: namespace.id } }
it { is_expected.to eq([project_in_namespace]) }
end
context 'filter by visibility_level' do
before do
private_project.add_master(user)
end
context 'private' do
let(:params) { { visibility_level: Gitlab::VisibilityLevel::PRIVATE } }
it { is_expected.to eq([shared_project, private_project]) }
end
context 'internal' do
let(:params) { { visibility_level: Gitlab::VisibilityLevel::INTERNAL } }
it { is_expected.to eq([internal_project]) }
end
context 'public' do
let(:params) { { visibility_level: Gitlab::VisibilityLevel::PUBLIC } }
it { is_expected.to eq([public_project]) }
end
end
context 'filter by push' do
let(:pushed_event) { create(:event, :pushed) }
let!(:project_with_push) { pushed_event.project }
let(:params) { { with_push: true } }
it { is_expected.to eq([project_with_push]) }
end
context 'filter by abandoned' do
before do
private_project.update(last_activity_at: Time.zone.now - 6.months - 1.minute)
end
let(:params) { { abandoned: true } }
it { is_expected.to eq([private_project]) }
end
context 'filter by last_repository_check_failed' do
before do
private_project.update(last_repository_check_failed: true)
end
let(:params) { { last_repository_check_failed: true } }
it { is_expected.to eq([private_project]) }
end
context 'filter by archived' do
let!(:archived_project) { create(:empty_project, :public, :archived, name: 'E', path: 'E') }
context 'archived=false' do
let(:params) { { archived: false } }
it { is_expected.to match_array([shared_project, public_project, internal_project, private_project]) }
end
context 'archived=true' do
let(:params) { { archived: true } }
it { is_expected.to match_array([archived_project, shared_project, public_project, internal_project, private_project]) }
end
end
context 'filter by personal' do
let!(:personal_project) { create(:empty_project, namespace: user.namespace) }
let(:params) { { personal: true } }
it { is_expected.to eq([personal_project]) }
end
context 'filter by name' do
let(:params) { { name: 'C' } }
it { is_expected.to eq([shared_project, public_project, private_project]) }
end
context 'sorting' do
let(:params) { { sort: 'name_asc' } }
it { is_expected.to eq([private_project, internal_project, public_project, shared_project]) }
end
end
end
require 'spec_helper' require 'spec_helper'
require 'lib/gitlab/badge/shared/metadata' require 'lib/gitlab/badge/shared/metadata'
describe Gitlab::Badge::Build::Metadata do describe Gitlab::Badge::Pipeline::Metadata do
let(:badge) { double(project: create(:empty_project), ref: 'feature') } let(:badge) { double(project: create(:empty_project), ref: 'feature') }
let(:metadata) { described_class.new(badge) } let(:metadata) { described_class.new(badge) }
...@@ -9,13 +9,13 @@ describe Gitlab::Badge::Build::Metadata do ...@@ -9,13 +9,13 @@ describe Gitlab::Badge::Build::Metadata do
describe '#title' do describe '#title' do
it 'returns build status title' do it 'returns build status title' do
expect(metadata.title).to eq 'build status' expect(metadata.title).to eq 'pipeline status'
end end
end end
describe '#image_url' do describe '#image_url' do
it 'returns valid url' do it 'returns valid url' do
expect(metadata.image_url).to include 'badges/feature/build.svg' expect(metadata.image_url).to include 'badges/feature/pipeline.svg'
end end
end end
......
require 'spec_helper' require 'spec_helper'
describe Gitlab::Badge::Build::Status do describe Gitlab::Badge::Pipeline::Status do
let(:project) { create(:project, :repository) } let(:project) { create(:project, :repository) }
let(:sha) { project.commit.sha } let(:sha) { project.commit.sha }
let(:branch) { 'master' } let(:branch) { 'master' }
let(:badge) { described_class.new(project, branch) } let(:badge) { described_class.new(project, branch) }
describe '#entity' do describe '#entity' do
it 'always says build' do it 'always says pipeline' do
expect(badge.entity).to eq 'build' expect(badge.entity).to eq 'pipeline'
end end
end end
describe '#template' do describe '#template' do
it 'returns badge template' do it 'returns badge template' do
expect(badge.template.key_text).to eq 'build' expect(badge.template.key_text).to eq 'pipeline'
end end
end end
describe '#metadata' do describe '#metadata' do
it 'returns badge metadata' do it 'returns badge metadata' do
expect(badge.metadata.image_url) expect(badge.metadata.image_url).to include 'badges/master/pipeline.svg'
.to include 'badges/master/build.svg'
end end
end end
context 'build exists' do context 'pipeline exists' do
let!(:build) { create_build(project, sha, branch) } let!(:pipeline) { create_pipeline(project, sha, branch) }
context 'build success' do context 'pipeline success' do
before do before do
build.success! pipeline.success!
end end
describe '#status' do describe '#status' do
...@@ -40,9 +39,9 @@ describe Gitlab::Badge::Build::Status do ...@@ -40,9 +39,9 @@ describe Gitlab::Badge::Build::Status do
end end
end end
context 'build failed' do context 'pipeline failed' do
before do before do
build.drop! pipeline.drop!
end end
describe '#status' do describe '#status' do
...@@ -54,10 +53,10 @@ describe Gitlab::Badge::Build::Status do ...@@ -54,10 +53,10 @@ describe Gitlab::Badge::Build::Status do
context 'when outdated pipeline for given ref exists' do context 'when outdated pipeline for given ref exists' do
before do before do
build.success! pipeline.success!
old_build = create_build(project, '11eeffdd', branch) old_pipeline = create_pipeline(project, '11eeffdd', branch)
old_build.drop! old_pipeline.drop!
end end
it 'does not take outdated pipeline into account' do it 'does not take outdated pipeline into account' do
...@@ -67,10 +66,10 @@ describe Gitlab::Badge::Build::Status do ...@@ -67,10 +66,10 @@ describe Gitlab::Badge::Build::Status do
context 'when multiple pipelines exist for given sha' do context 'when multiple pipelines exist for given sha' do
before do before do
build.drop! pipeline.drop!
new_build = create_build(project, sha, branch) new_pipeline = create_pipeline(project, sha, branch)
new_build.success! new_pipeline.success!
end end
it 'does not take outdated pipeline into account' do it 'does not take outdated pipeline into account' do
...@@ -87,7 +86,7 @@ describe Gitlab::Badge::Build::Status do ...@@ -87,7 +86,7 @@ describe Gitlab::Badge::Build::Status do
end end
end end
def create_build(project, sha, branch) def create_pipeline(project, sha, branch)
pipeline = create(:ci_empty_pipeline, pipeline = create(:ci_empty_pipeline,
project: project, project: project,
sha: sha, sha: sha,
......
require 'spec_helper' require 'spec_helper'
describe Gitlab::Badge::Build::Template do describe Gitlab::Badge::Pipeline::Template do
let(:badge) { double(entity: 'build', status: 'success') } let(:badge) { double(entity: 'pipeline', status: 'success') }
let(:template) { described_class.new(badge) } let(:template) { described_class.new(badge) }
describe '#key_text' do describe '#key_text' do
it 'is always says build' do it 'is always says pipeline' do
expect(template.key_text).to eq 'build' expect(template.key_text).to eq 'pipeline'
end end
end end
describe '#value_text' do describe '#value_text' do
it 'is status value' do it 'is status value' do
expect(template.value_text).to eq 'success' expect(template.value_text).to eq 'passed'
end end
end end
describe 'widths and text anchors' do describe 'widths and text anchors' do
it 'has fixed width and text anchors' do it 'has fixed width and text anchors' do
expect(template.width).to eq 92 expect(template.width).to eq 116
expect(template.key_width).to eq 38 expect(template.key_width).to eq 62
expect(template.value_width).to eq 54 expect(template.value_width).to eq 54
expect(template.key_text_anchor).to eq 19 expect(template.key_text_anchor).to eq 31
expect(template.value_text_anchor).to eq 65 expect(template.value_text_anchor).to eq 89
end end
end end
......
...@@ -300,5 +300,34 @@ describe Gitlab::Ci::Trace::Stream do ...@@ -300,5 +300,34 @@ describe Gitlab::Ci::Trace::Stream do
include_examples 'malicious regexp' include_examples 'malicious regexp'
end end
context 'multi-line data with rooted regexp' do
let(:data) { "\n65%\n" }
let(:regex) { '^(\d+)\%$' }
it { is_expected.to eq('65') }
end
context 'empty regex' do
let(:data) { 'foo' }
let(:regex) { '' }
it 'skips processing' do
expect(stream).not_to receive(:read)
is_expected.to be_nil
end
end
context 'nil regex' do
let(:data) { 'foo' }
let(:regex) { nil }
it 'skips processing' do
expect(stream).not_to receive(:read)
is_expected.to be_nil
end
end
end end
end end
...@@ -55,7 +55,7 @@ describe Gitlab::UntrustedRegexp do ...@@ -55,7 +55,7 @@ describe Gitlab::UntrustedRegexp do
let(:text) { 'foo' } let(:text) { 'foo' }
it 'returns an array of empty matches' do it 'returns an array of empty matches' do
is_expected.to eq(['', '', '']) is_expected.to eq([''])
end end
end end
...@@ -63,8 +63,8 @@ describe Gitlab::UntrustedRegexp do ...@@ -63,8 +63,8 @@ describe Gitlab::UntrustedRegexp do
let(:regexp) { '()' } let(:regexp) { '()' }
let(:text) { 'foo' } let(:text) { 'foo' }
it 'returns arrays of empty matches in an array' do it 'returns an array of empty matches in an array' do
is_expected.to eq([[''], [''], ['']]) is_expected.to eq([['']])
end end
end end
......
...@@ -69,6 +69,72 @@ describe Ci::API::Builds do ...@@ -69,6 +69,72 @@ describe Ci::API::Builds do
end end
end end
context 'when an old image syntax is used' do
before do
build.update!(options: { image: 'codeclimate' })
end
it 'starts a build' do
register_builds info: { platform: :darwin }
expect(response).to have_http_status(201)
expect(json_response["options"]).to eq({ "image" => "codeclimate" })
end
end
context 'when a new image syntax is used' do
before do
build.update!(options: { image: { name: 'codeclimate' } })
end
it 'starts a build' do
register_builds info: { platform: :darwin }
expect(response).to have_http_status(201)
expect(json_response["options"]).to eq({ "image" => "codeclimate" })
end
end
context 'when an old service syntax is used' do
before do
build.update!(options: { services: ['mysql'] })
end
it 'starts a build' do
register_builds info: { platform: :darwin }
expect(response).to have_http_status(201)
expect(json_response["options"]).to eq({ "services" => ["mysql"] })
end
end
context 'when a new service syntax is used' do
before do
build.update!(options: { services: [name: 'mysql'] })
end
it 'starts a build' do
register_builds info: { platform: :darwin }
expect(response).to have_http_status(201)
expect(json_response["options"]).to eq({ "services" => ["mysql"] })
end
end
context 'when no image or service is defined' do
before do
build.update!(options: {})
end
it 'starts a build' do
register_builds info: { platform: :darwin }
expect(response).to have_http_status(201)
expect(json_response["options"]).to be_empty
end
end
context 'when there is a pending build' do context 'when there is a pending build' do
it 'starts a build' do it 'starts a build' do
register_builds info: { platform: :darwin } register_builds info: { platform: :darwin }
......
...@@ -103,7 +103,7 @@ describe Projects::UpdateService, '#execute', :services do ...@@ -103,7 +103,7 @@ describe Projects::UpdateService, '#execute', :services do
end end
end end
context 'when renaming project that contains container images' do context 'when updating a project that contains container images' do
before do before do
stub_container_registry_config(enabled: true) stub_container_registry_config(enabled: true)
stub_container_registry_tags(repository: /image/, tags: %w[rc1]) stub_container_registry_tags(repository: /image/, tags: %w[rc1])
...@@ -116,6 +116,13 @@ describe Projects::UpdateService, '#execute', :services do ...@@ -116,6 +116,13 @@ describe Projects::UpdateService, '#execute', :services do
expect(result).to include(status: :error) expect(result).to include(status: :error)
expect(result[:message]).to match(/contains container registry tags/) expect(result[:message]).to match(/contains container registry tags/)
end end
it 'allows to update other settings' do
result = update_project(project, admin, public_builds: true)
expect(result[:status]).to eq :success
expect(project.reload.public_builds).to be true
end
end end
context 'when passing invalid parameters' do context 'when passing invalid parameters' do
......
...@@ -5,8 +5,6 @@ shared_examples 'issuable record that supports quick actions in its description ...@@ -5,8 +5,6 @@ shared_examples 'issuable record that supports quick actions in its description
include QuickActionsHelpers include QuickActionsHelpers
let(:master) { create(:user) } let(:master) { create(:user) }
let(:assignee) { create(:user, username: 'bob') }
let(:guest) { create(:user) }
let(:project) { create(:project, :public) } let(:project) { create(:project, :public) }
let!(:milestone) { create(:milestone, project: project, title: 'ASAP') } let!(:milestone) { create(:milestone, project: project, title: 'ASAP') }
let!(:label_bug) { create(:label, project: project, title: 'bug') } let!(:label_bug) { create(:label, project: project, title: 'bug') }
...@@ -15,8 +13,6 @@ shared_examples 'issuable record that supports quick actions in its description ...@@ -15,8 +13,6 @@ shared_examples 'issuable record that supports quick actions in its description
before do before do
project.team << [master, :master] project.team << [master, :master]
project.team << [assignee, :developer]
project.team << [guest, :guest]
sign_in(master) sign_in(master)
end end
...@@ -57,6 +53,7 @@ shared_examples 'issuable record that supports quick actions in its description ...@@ -57,6 +53,7 @@ shared_examples 'issuable record that supports quick actions in its description
context 'with a note containing commands' do context 'with a note containing commands' do
it 'creates a note without the commands and interpret the commands accordingly' do it 'creates a note without the commands and interpret the commands accordingly' do
assignee = create(:user, username: 'bob')
write_note("Awesome!\n/assign @bob\n/label ~bug\n/milestone %\"ASAP\"") write_note("Awesome!\n/assign @bob\n/label ~bug\n/milestone %\"ASAP\"")
expect(page).to have_content 'Awesome!' expect(page).to have_content 'Awesome!'
...@@ -77,6 +74,7 @@ shared_examples 'issuable record that supports quick actions in its description ...@@ -77,6 +74,7 @@ shared_examples 'issuable record that supports quick actions in its description
context 'with a note containing only commands' do context 'with a note containing only commands' do
it 'does not create a note but interpret the commands accordingly' do it 'does not create a note but interpret the commands accordingly' do
assignee = create(:user, username: 'bob')
write_note("/assign @bob\n/label ~bug\n/milestone %\"ASAP\"") write_note("/assign @bob\n/label ~bug\n/milestone %\"ASAP\"")
expect(page).not_to have_content '/assign @bob' expect(page).not_to have_content '/assign @bob'
...@@ -111,8 +109,12 @@ shared_examples 'issuable record that supports quick actions in its description ...@@ -111,8 +109,12 @@ shared_examples 'issuable record that supports quick actions in its description
context "when current user cannot close #{issuable_type}" do context "when current user cannot close #{issuable_type}" do
before do before do
guest = create(:user)
project.add_guest(guest)
sign_out(:user) sign_out(:user)
sign_in(guest) sign_in(guest)
visit public_send("namespace_project_#{issuable_type}_path", project.namespace, project, issuable) visit public_send("namespace_project_#{issuable_type}_path", project.namespace, project, issuable)
end end
...@@ -146,8 +148,12 @@ shared_examples 'issuable record that supports quick actions in its description ...@@ -146,8 +148,12 @@ shared_examples 'issuable record that supports quick actions in its description
context "when current user cannot reopen #{issuable_type}" do context "when current user cannot reopen #{issuable_type}" do
before do before do
guest = create(:user)
project.add_guest(guest)
sign_out(:user) sign_out(:user)
sign_in(guest) sign_in(guest)
visit public_send("namespace_project_#{issuable_type}_path", project.namespace, project, issuable) visit public_send("namespace_project_#{issuable_type}_path", project.namespace, project, issuable)
end end
...@@ -176,6 +182,9 @@ shared_examples 'issuable record that supports quick actions in its description ...@@ -176,6 +182,9 @@ shared_examples 'issuable record that supports quick actions in its description
context "when current user cannot change title of #{issuable_type}" do context "when current user cannot change title of #{issuable_type}" do
before do before do
guest = create(:user)
project.add_guest(guest)
sign_out(:user) sign_out(:user)
sign_in(guest) sign_in(guest)
visit public_send("namespace_project_#{issuable_type}_path", project.namespace, project, issuable) visit public_send("namespace_project_#{issuable_type}_path", project.namespace, project, issuable)
...@@ -267,6 +276,8 @@ shared_examples 'issuable record that supports quick actions in its description ...@@ -267,6 +276,8 @@ shared_examples 'issuable record that supports quick actions in its description
describe "preview of note on #{issuable_type}" do describe "preview of note on #{issuable_type}" do
it 'removes quick actions from note and explains them' do it 'removes quick actions from note and explains them' do
create(:user, username: 'bob')
visit public_send("namespace_project_#{issuable_type}_path", project.namespace, project, issuable) visit public_send("namespace_project_#{issuable_type}_path", project.namespace, project, issuable)
page.within('.js-main-target-form') do page.within('.js-main-target-form') do
......
...@@ -64,7 +64,7 @@ module LoginHelpers ...@@ -64,7 +64,7 @@ module LoginHelpers
visit new_user_session_path visit new_user_session_path
expect(page).to have_content('Sign in with') expect(page).to have_content('Sign in with')
check 'Remember Me' if remember_me check 'remember_me' if remember_me
click_link "oauth-login-#{provider}" click_link "oauth-login-#{provider}"
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