Commit 8ae26d70 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent fc1df8c8
...@@ -283,6 +283,10 @@ class Snippet < ApplicationRecord ...@@ -283,6 +283,10 @@ class Snippet < ApplicationRecord
end end
end end
def url_to_repo
Gitlab::Shell.url_to_repo(full_path.delete('@'))
end
def repository_storage def repository_storage
snippet_repository&.shard_name || snippet_repository&.shard_name ||
Gitlab::CurrentSettings.pick_repository_storage Gitlab::CurrentSettings.pick_repository_storage
......
...@@ -159,6 +159,8 @@ ...@@ -159,6 +159,8 @@
%span.badge.badge-pill.count.merge_counter.js-merge-counter.fly-out-badge %span.badge.badge-pill.count.merge_counter.js-merge-counter.fly-out-badge
= number_with_delimiter(@project.open_merge_requests_count) = number_with_delimiter(@project.open_merge_requests_count)
= render_if_exists "layouts/nav/requirements_link", project: @project
- if project_nav_tab? :pipelines - if project_nav_tab? :pipelines
= nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :artifacts], unless: -> { current_path?('projects/pipelines#charts') }) do = nav_link(controller: [:pipelines, :builds, :jobs, :pipeline_schedules, :artifacts], unless: -> { current_path?('projects/pipelines#charts') }) do
= link_to project_pipelines_path(@project), class: 'shortcuts-pipelines qa-link-pipelines rspec-link-pipelines', data: { qa_selector: 'ci_cd_link' } do = link_to project_pipelines_path(@project), class: 'shortcuts-pipelines qa-link-pipelines rspec-link-pipelines', data: { qa_selector: 'ci_cd_link' } do
......
...@@ -13,6 +13,17 @@ module ApplicationWorker ...@@ -13,6 +13,17 @@ module ApplicationWorker
included do included do
set_queue set_queue
def structured_payload(payload = {})
context = Labkit::Context.current.to_h.merge(
'class' => self.class,
'job_status' => 'running',
'queue' => self.class.queue,
'jid' => jid
)
payload.stringify_keys.merge(context)
end
end end
class_methods do class_methods do
......
---
title: Fix project moved message after git operation
merge_request: 27341
author:
type: fixed
---
title: Fix remove special chars from snippet url_to_repo
merge_request: 27390
author:
type: fixed
...@@ -232,6 +232,8 @@ ...@@ -232,6 +232,8 @@
- 2 - 2
- - service_desk_email_receiver - - service_desk_email_receiver
- 1 - 1
- - status_page_publish_incident
- 1
- - sync_seat_link_request - - sync_seat_link_request
- 1 - 1
- - system_hook_push - - system_hook_push
......
...@@ -182,7 +182,7 @@ Unicorn specific metrics, when Unicorn is used. ...@@ -182,7 +182,7 @@ Unicorn specific metrics, when Unicorn is used.
| `unicorn_queued_connections` | Gauge | 11.0 | The number of queued Unicorn connections | | `unicorn_queued_connections` | Gauge | 11.0 | The number of queued Unicorn connections |
| `unicorn_workers` | Gauge | 12.0 | The number of Unicorn workers | | `unicorn_workers` | Gauge | 12.0 | The number of Unicorn workers |
## Puma Metrics **(EXPERIMENTAL)** ## Puma Metrics
When Puma is used instead of Unicorn, the following metrics are available: When Puma is used instead of Unicorn, the following metrics are available:
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
## Puma ## Puma
GitLab plans to use [Puma](https://github.com/puma/puma) to replace As of GitLab 12.9, [Puma](https://github.com/puma/puma) has replaced [Unicorn](https://bogomips.org/unicorn/).
[Unicorn](https://bogomips.org/unicorn/). as the default web server.
## Why switch to Puma? ## Why switch to Puma?
......
...@@ -11,9 +11,8 @@ dependency proxies, see the [user guide](../../user/group/dependency_proxy/index ...@@ -11,9 +11,8 @@ dependency proxies, see the [user guide](../../user/group/dependency_proxy/index
NOTE: **Note:** NOTE: **Note:**
Dependency proxy requires the Puma web server to be enabled. Dependency proxy requires the Puma web server to be enabled.
Puma support is EXPERIMENTAL at this time.
To enable the Dependency proxy feature: To enable the dependency proxy feature:
**Omnibus GitLab installations** **Omnibus GitLab installations**
...@@ -37,7 +36,9 @@ To enable the Dependency proxy feature: ...@@ -37,7 +36,9 @@ To enable the Dependency proxy feature:
``` ```
1. [Restart GitLab](../restart_gitlab.md#installations-from-source "How to restart GitLab") for the changes to take effect. 1. [Restart GitLab](../restart_gitlab.md#installations-from-source "How to restart GitLab") for the changes to take effect.
1. Enable the [Puma web server](../../install/installation.md#using-puma).
Since Puma is already the default web server for installations from source as of GitLab 12.9,
no further changes are needed.
## Changing the storage path ## Changing the storage path
......
...@@ -566,6 +566,51 @@ GitLab Pages are part of the [regular backup][backup], so there is no separate b ...@@ -566,6 +566,51 @@ GitLab Pages are part of the [regular backup][backup], so there is no separate b
You should strongly consider running GitLab Pages under a different hostname You should strongly consider running GitLab Pages under a different hostname
than GitLab to prevent XSS attacks. than GitLab to prevent XSS attacks.
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
one might have when setting this up, or when something is changed, or on upgrading, it's
important to describe those, too. Think of things that may go wrong and include them here.
This is important to minimize requests for support, and to avoid doc comments with
questions that you know someone might ask.
Each scenario can be a third-level heading, e.g. `### Getting error message X`.
If you have none to add when creating a doc, leave this section in place
but commented out to help encourage others to add to it in the future. -->
## Troubleshooting
### `open /etc/ssl/ca-bundle.pem: permission denied`
GitLab Pages runs inside a `chroot` jail, usually in a uniquely numbered directory like
`/tmp/gitlab-pages-*`.
Within the jail, a bundle of trusted certificates is
provided at `/etc/ssl/ca-bundle.pem`. It's
[copied there](https://gitlab.com/gitlab-org/gitlab-pages/-/merge_requests/51)
from `/opt/gitlab/embedded/ssl/certs/cacert.pem`
as part of starting up Pages.
If the permissions on the source file are incorrect (they should be `0644`) then
the file inside the `chroot` jail will also be wrong.
Pages will log errors in `/var/log/gitlab/gitlab-pages/current` like:
```plaintext
x509: failed to load system roots and no roots provided
open /etc/ssl/ca-bundle.pem: permission denied
```
The use of a `chroot` jail makes this error misleading, as it is not
referring to `/etc/ssl` on the root filesystem.
The fix is to correct the source file permissions and restart Pages:
```shell
sudo chmod 644 /opt/gitlab/embedded/ssl/certs/cacert.pem
sudo gitlab-ctl restart gitlab-pages
```
[backup]: ../../raketasks/backup_restore.md [backup]: ../../raketasks/backup_restore.md
[ce-14605]: https://gitlab.com/gitlab-org/gitlab-foss/issues/14605 [ce-14605]: https://gitlab.com/gitlab-org/gitlab-foss/issues/14605
[ee-80]: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80 [ee-80]: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80
......
...@@ -163,6 +163,7 @@ Complementary reads: ...@@ -163,6 +163,7 @@ Complementary reads:
- [Jira Connect app](integrations/jira_connect.md) - [Jira Connect app](integrations/jira_connect.md)
- [Security Scanners](integrations/secure.md) - [Security Scanners](integrations/secure.md)
- [Secure Partner Integration](integrations/secure_partner_integration.md)
## Testing guides ## Testing guides
......
# Secure Partner Integration - Onboarding Process
If you want to integrate your product with the [Secure Stage](https://about.gitlab.com/direction/secure),
this page will help you understand the developer workflow GitLab intends for
our users to follow with regards to security results. These should be used as
guidelines so you can build an integration that fits with the workflow GitLab
users are already familiar with.
This page also provides resources for the technical work associated
with [onboarding as a partner](https://about.gitlab.com/partners/integrate/).
The steps below are a high-level view of what needs to be done to complete an
integration as well as linking to more detailed resources for how to do so.
## What is the GitLab Developer Workflow?
This workflow is how GitLab users interact with our product and expect it to
function. Understanding how users use GitLab today will help you choose the
best place to integrate your own product and its results into GitLab.
- Developers want to write code without using a new tool to consume results
or address feedback about the item they are working on. Staying inside a
single tool, GitLab, helps them to stay focused on finishing the code and
projects they are working on.
- Developers commit code to a Git branch. The developer creates a merge request (MR)
inside GitLab where these changes can be reviewed. The MR triggers a GitLab
pipeline to run associated jobs, including security checks, on the code.
- Pipeline jobs serve a variety of purposes. Jobs can do scanning for and have
implications for app security, corporate policy, or compliance. When complete,
the job reports back on its status and creates a
[job artifact](../../user/project/pipelines/job_artifacts.md) as a result.
- The [Merge Request Security Widget](../../user/project/merge_requests/index.md#security-reports-ultimate)
displays the results of the pipeline's security checks and the developer can
review them. The developer can review both a summary and a detailed version
of the results.
- If certain policies (such as [merge request approvals](../../user/project/merge_requests/merge_request_approvals.md))
are in place for a project, developers must resolve specific findings or get
an approval from a specific list of people.
- The [security dashboard](../../user/application_security/security_dashboard/index.md#gitlab-security-dashboard-ultimate)
also shows results which can developers can use to quickly see all the
vulnerabilities that need to be addressed in the code.
- When the developer reads the details about a vulnerability, they are
presented with additional information and choices on next steps:
1. Create Issue (Confirm finding): Creates a new issue to be prioritized.
1. Add Comment and Dismiss Vulnerability: When dismissing a finding, users
can comment to note items that they
have mitigated, that they accept the vulnerability, or that the
vulnerability is a false positive.
1. Auto-Remediation / Create Merge Request: A fix for the vulnerability can
be offered, allowing an easy solution that does not require extra effort
from users. This should be offered whenever possible.
1. Links: Vulnerabilities can link out external sites or sources for users
to get more data around the vulnerability.
## How to onboard
This section describes the steps you need to complete to onboard as a partner
and complete an intgration with the Secure stage.
1. Read about our [partnerships](https://about.gitlab.com/partners/integrate/index.md).
1. [Create an issue](https://gitlab.com/gitlab-com/alliances/alliances/issues/new?issuable_template=new_partner)
using our new partner issue template to begin the discussion.
1. Get a test account to begin developing your integration. You can
request a [GitLab.com Gold Subscription Sandbox](https://about.gitlab.com/partners/integrate/index.md#gitlabcom-gold-subscription-sandbox-request)
or an [EE Developer License](https://about.gitlab.com/partners/integrate/index.md#requesting-ee-dev-license-for-rd).
1. Provide a [pipeline job](../../development/pipelines.md)
template that users could integrate into their own GitLab pipelines.
1. Create a report artifact with your pipeline jobs.
1. Ensure your pipeline jobs create a report artifact that GitLab can process
to successfully display your own product's results with the rest of GitLab.
- See detailed [technical directions](secure.md) for this step.
- Read more about [job report artifacts](../../ci/yaml/README.md#artifactsreports).
- Read about [job artifacts](../../user/project/pipelines/job_artifacts.md).
- Your report artifact must be in one of our currently supported formats.
For more information, see the [documentation on reports](secure.md#report).
- Documentation for [SAST reports](../../user/application_security/sast/index.md#reports-json-format).
- Documentation for [Dependency Scanning reports](../../user/application_security/dependency_scanning/index.md#reports-json-format).
- Documentation for [Container Scanning reports](../../user/application_security/container_scanning/index.md#reports-json-format).
- See this [example secure job definition that also defines the artifact created](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml).
- If you need a new kind of scan or report, [create an issue](https://gitlab.com/gitlab-org/gitlab/issues/new#)
and add the label `devops::secure`.
- Once the job is completed, the data can be seen:
- In the [Merge Request Security Report](../../user/project/merge_requests/index.md#security-reports-ultimate) ([MR Security Report data flow](https://gitlab.com/snippets/1910005#merge-request-view)).
- While [browsing a Job Artifact](../../user/project/pipelines/job_artifacts.md).
- In the [Security Dashboard](../../user/application_security/security_dashboard/index.md) ([Dashboard data flow](https://gitlab.com/snippets/1910005#project-and-group-dashboards)).
1. Optional: Provide a way to interact with results as Vulnerabilities:
- Users can interact with the findings from your artifact within their workflow. They can dismiss the findings or accept them and create a backlog issue.
- To automatically create issues without user interaction, use the [issue API](../../api/issues.md). This will be replaced by [Standalone Vulnerabilities](https://gitlab.com/groups/gitlab-org/-/epics/634) in the future.
1. Optional: Provide auto-remediation steps:
- If you specified `remediations` in your artifact, it is proposed through our [auto-remediation](../../user/application_security/index.md#solutions-for-vulnerabilities-auto-remediation)
interface.
1. Demo the integration to GitLab:
- After you have tested and are ready to demo your integration please
[reach out](https://about.gitlab.com/partners/integrate/index.md) to us. If you
skip this step you won’t be able to do supported marketing.
1. Begin doing supported marketing of your GitLab integration.
- Work with our [partner team](https://about.gitlab.com/partners/integrate/index.md)
to support your go-to-market as appropriate.
- Examples of supported marketing could include being listed on our [Security Partner page](https://about.gitlab.com/partners/index.md#security),
doing an [Unfiltered blog post](https://about.gitlab.com/handbook/marketing/blog/unfiltered/index.md),
doing a co-branded webinar, or producing a co-branded whitepaper.
If you have any issues while working through your integration or the steps
above, please create an issue to discuss with us further.
...@@ -457,16 +457,13 @@ sudo chmod -R u+rwX shared/artifacts/ ...@@ -457,16 +457,13 @@ sudo chmod -R u+rwX shared/artifacts/
# Change the permissions of the directory where GitLab Pages are stored # Change the permissions of the directory where GitLab Pages are stored
sudo chmod -R ug+rwX shared/pages/ sudo chmod -R ug+rwX shared/pages/
# Copy the example Unicorn config # Copy the example Puma config
sudo -u git -H cp config/unicorn.rb.example config/unicorn.rb sudo -u git -H cp config/puma.rb.example config/puma.rb
# Find number of cores # Refer to https://github.com/puma/puma#configuration for more information.
nproc # You should scale Puma workers and threads based on the number of CPU
# cores you have available. You can get that number via the `nproc` command.
# Enable cluster mode if you expect to have a high load instance sudo -u git -H editor config/puma.rb
# Set the number of workers to at least the number of cores
# Ex. change the amount of workers to 3 for 2GB RAM server
sudo -u git -H editor config/unicorn.rb
# Copy the example Rack attack config # Copy the example Rack attack config
sudo -u git -H cp config/initializers/rack_attack.rb.example config/initializers/rack_attack.rb sudo -u git -H cp config/initializers/rack_attack.rb.example config/initializers/rack_attack.rb
...@@ -495,8 +492,8 @@ sudo -u git -H editor config/resque.yml ...@@ -495,8 +492,8 @@ sudo -u git -H editor config/resque.yml
``` ```
CAUTION: **Caution:** CAUTION: **Caution:**
Make sure to edit both `gitlab.yml` and `unicorn.rb` to match your setup. Make sure to edit both `gitlab.yml` and `puma.rb` to match your setup.
If you want to use Puma web server, see [Using Puma](#using-puma) for the additional steps. If you want to use the Unicorn web server, see [Using Unicorn](#using-unicorn) for the additional steps.
NOTE: **Note:** NOTE: **Note:**
If you want to use HTTPS, see [Using HTTPS](#using-https) for the additional steps. If you want to use HTTPS, see [Using HTTPS](#using-https) for the additional steps.
...@@ -947,23 +944,22 @@ You also need to change the corresponding options (e.g. `ssh_user`, `ssh_host`, ...@@ -947,23 +944,22 @@ You also need to change the corresponding options (e.g. `ssh_user`, `ssh_host`,
Apart from the always supported Markdown style, there are other rich text files that GitLab can display. But you might have to install a dependency to do so. See the [`github-markup` gem README](https://github.com/gitlabhq/markup#markups) for more information. Apart from the always supported Markdown style, there are other rich text files that GitLab can display. But you might have to install a dependency to do so. See the [`github-markup` gem README](https://github.com/gitlabhq/markup#markups) for more information.
### Using Puma ### Using Unicorn
Puma is a multi-threaded HTTP 1.1 server for Ruby applications.
To use GitLab with Puma: As of GitLab 12.9, [Puma](https://github.com/puma/puma) has replaced Unicorn as the default web server for installations from source.
If you want to switch back to Unicorn, follow these steps:
1. Finish GitLab setup so you have it up and running. 1. Finish the GitLab setup so you have it up and running.
1. Copy the supplied example Puma config file into place: 1. Copy the supplied example Unicorn config file into place:
```shell ```shell
cd /home/git/gitlab cd /home/git/gitlab
# Copy config file for the web server # Copy config file for the web server
sudo -u git -H cp config/puma.rb.example config/puma.rb sudo -u git -H cp config/unicorn.rb.example config/unicorn.rb
``` ```
1. Edit the system `init.d` script to use `EXPERIMENTAL_PUMA=1` flag. If you have `/etc/default/gitlab`, then you should edit it instead. 1. Edit the system `init.d` script to set the `USE_UNICORN=1` flag. If you have `/etc/default/gitlab`, then you should edit it instead.
1. Restart GitLab. 1. Restart GitLab.
## Troubleshooting ## Troubleshooting
......
...@@ -14,7 +14,7 @@ shows such a visualization for all the epics which are under a group and/or its ...@@ -14,7 +14,7 @@ shows such a visualization for all the epics which are under a group and/or its
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/5164) in GitLab 12.9. > [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/5164) in GitLab 12.9.
On the epic bars, you can see their title, progress, and completed weight percentage. On the epic bars, you can see their title, progress, and completed weight percentage.
When you hover over an epic bar, a popover appears with its description, start and due dates, and weight completed. When you hover over an epic bar, a popover appears with its title, start and due dates, and weight completed.
![roadmap view](img/roadmap_view_v12_9.png) ![roadmap view](img/roadmap_view_v12_9.png)
......
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
module Gitlab module Gitlab
module Checks module Checks
class PostPushMessage class PostPushMessage
def initialize(project, user, protocol) def initialize(repository, user, protocol)
@project = project @repository = repository
@user = user @user = user
@protocol = protocol @protocol = protocol
end end
...@@ -34,14 +34,21 @@ module Gitlab ...@@ -34,14 +34,21 @@ module Gitlab
protected protected
attr_reader :project, :user, :protocol attr_reader :repository, :user, :protocol
delegate :project, to: :repository, allow_nil: true
delegate :container, to: :repository, allow_nil: false
def self.message_key(user_id, project_id) def self.message_key(user_id, project_id)
raise NotImplementedError raise NotImplementedError
end end
def url_to_repo def url_to_repo
protocol == 'ssh' ? project.ssh_url_to_repo : project.http_url_to_repo protocol == 'ssh' ? message_subject.ssh_url_to_repo : message_subject.http_url_to_repo
end
def message_subject
repository.repo_type.wiki? ? project.wiki : container
end end
end end
end end
......
...@@ -5,10 +5,10 @@ module Gitlab ...@@ -5,10 +5,10 @@ module Gitlab
class ProjectMoved < PostPushMessage class ProjectMoved < PostPushMessage
REDIRECT_NAMESPACE = "redirect_namespace" REDIRECT_NAMESPACE = "redirect_namespace"
def initialize(project, user, protocol, redirected_path) def initialize(repository, user, protocol, redirected_path)
@redirected_path = redirected_path @redirected_path = redirected_path
super(project, user, protocol) super(repository, user, protocol)
end end
def message def message
......
...@@ -188,7 +188,7 @@ module Gitlab ...@@ -188,7 +188,7 @@ module Gitlab
def add_project_moved_message! def add_project_moved_message!
return if redirected_path.nil? return if redirected_path.nil?
project_moved = Checks::ProjectMoved.new(project, user, protocol, redirected_path) project_moved = Checks::ProjectMoved.new(repository, user, protocol, redirected_path)
project_moved.add_message project_moved.add_message
end end
...@@ -250,7 +250,7 @@ module Gitlab ...@@ -250,7 +250,7 @@ module Gitlab
@project = project @project = project
user_access.project = @project user_access.project = @project
Checks::ProjectCreated.new(project, user, protocol).add_message Checks::ProjectCreated.new(repository, user, protocol).add_message
end end
def check_repository_existence! def check_repository_existence!
......
...@@ -39,11 +39,11 @@ module Gitlab ...@@ -39,11 +39,11 @@ module Gitlab
override :check_project! override :check_project!
def check_project!(cmd, changes) def check_project!(cmd, changes)
if snippet.is_a?(ProjectSnippet) return unless snippet.is_a?(ProjectSnippet)
check_namespace!
check_project_accessibility! check_namespace!
# TODO add add_project_moved_message! to handle non-project repo https://gitlab.com/gitlab-org/gitlab/issues/205646 check_project_accessibility!
end add_project_moved_message!
end end
override :check_push_access! override :check_push_access!
......
...@@ -19,8 +19,7 @@ module Gitlab ...@@ -19,8 +19,7 @@ module Gitlab
# Removing the suffix (.wiki, .design, ...) from the project path # Removing the suffix (.wiki, .design, ...) from the project path
full_path = repo_path.chomp(type.path_suffix) full_path = repo_path.chomp(type.path_suffix)
container, project, was_redirected = find_container(type, full_path) container, project, redirected_path = find_container(type, full_path)
redirected_path = repo_path if was_redirected
return [container, project, type, redirected_path] if container return [container, project, type, redirected_path] if container
end end
...@@ -33,22 +32,23 @@ module Gitlab ...@@ -33,22 +32,23 @@ module Gitlab
def self.find_container(type, full_path) def self.find_container(type, full_path)
if type.snippet? if type.snippet?
snippet, was_redirected = find_snippet(full_path) snippet, redirected_path = find_snippet(full_path)
[snippet, snippet&.project, was_redirected] [snippet, snippet&.project, redirected_path]
else else
project, was_redirected = find_project(full_path) project, redirected_path = find_project(full_path)
[project, project, was_redirected] [project, project, redirected_path]
end end
end end
def self.find_project(project_path) def self.find_project(project_path)
return [nil, false] if project_path.blank? return [nil, nil] if project_path.blank?
project = Project.find_by_full_path(project_path, follow_redirects: true) project = Project.find_by_full_path(project_path, follow_redirects: true)
redirected_path = redirected?(project, project_path) ? project_path : nil
[project, redirected?(project, project_path)] [project, redirected_path]
end end
def self.redirected?(project, project_path) def self.redirected?(project, project_path)
...@@ -59,12 +59,12 @@ module Gitlab ...@@ -59,12 +59,12 @@ module Gitlab
# - snippets/1 # - snippets/1
# - h5bp/html5-boilerplate/snippets/53 # - h5bp/html5-boilerplate/snippets/53
def self.find_snippet(snippet_path) def self.find_snippet(snippet_path)
return [nil, false] if snippet_path.blank? return [nil, nil] if snippet_path.blank?
snippet_id, project_path = extract_snippet_info(snippet_path) snippet_id, project_path = extract_snippet_info(snippet_path)
project, was_redirected = find_project(project_path) project, redirected_path = find_project(project_path)
[Snippet.find_by_id_and_project(id: snippet_id, project: project), was_redirected] [Snippet.find_by_id_and_project(id: snippet_id, project: project), redirected_path]
end end
def self.extract_snippet_info(snippet_path) def self.extract_snippet_info(snippet_path)
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
### Environment variables ### Environment variables
RAILS_ENV="production" RAILS_ENV="production"
EXPERIMENTAL_PUMA="" USE_UNICORN=""
# Script variable names should be lower-case not to conflict with # Script variable names should be lower-case not to conflict with
# internal /bin/sh variables such as PATH, EDITOR or SHELL. # internal /bin/sh variables such as PATH, EDITOR or SHELL.
...@@ -68,10 +68,10 @@ if ! cd "$app_root" ; then ...@@ -68,10 +68,10 @@ if ! cd "$app_root" ; then
fi fi
# Select the web server to use # Select the web server to use
if [ -z "$EXPERIMENTAL_PUMA" ]; then if [ -z "$USE_UNICORN" ]; then
use_web_server="unicorn"
else
use_web_server="puma" use_web_server="puma"
else
use_web_server="unicorn"
fi fi
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
# Normal values are "production", "test" and "development". # Normal values are "production", "test" and "development".
RAILS_ENV="production" RAILS_ENV="production"
# Uncomment the line below to enable Puma web server instead of Unicorn. # Uncomment the line below to enable the Unicorn web server instead of Puma.
# EXPERIMENTAL_PUMA=1 # USE_UNICORN=1
# app_user defines the user that GitLab is run as. # app_user defines the user that GitLab is run as.
# The default is "git". # The default is "git".
......
...@@ -16775,6 +16775,9 @@ msgstr "" ...@@ -16775,6 +16775,9 @@ msgstr ""
msgid "Require users to prove ownership of custom domains" msgid "Require users to prove ownership of custom domains"
msgstr "" msgstr ""
msgid "Requirements"
msgstr ""
msgid "Requires approval from %{names}." msgid "Requires approval from %{names}."
msgid_plural "Requires %{count} more approvals from %{names}." msgid_plural "Requires %{count} more approvals from %{names}."
msgstr[0] "" msgstr[0] ""
......
...@@ -18,6 +18,13 @@ describe 'Project navbar' do ...@@ -18,6 +18,13 @@ describe 'Project navbar' do
} }
end end
let(:requirements_nav_item) do
{
nav_item: _('Requirements'),
nav_sub_items: [_('List')]
}
end
let(:structure) do let(:structure) do
[ [
{ {
...@@ -54,6 +61,7 @@ describe 'Project navbar' do ...@@ -54,6 +61,7 @@ describe 'Project navbar' do
nav_item: _('Merge Requests'), nav_item: _('Merge Requests'),
nav_sub_items: [] nav_sub_items: []
}, },
(requirements_nav_item if Gitlab.ee?),
{ {
nav_item: _('CI / CD'), nav_item: _('CI / CD'),
nav_sub_items: [ nav_sub_items: [
...@@ -100,6 +108,7 @@ describe 'Project navbar' do ...@@ -100,6 +108,7 @@ describe 'Project navbar' do
end end
before do before do
stub_licensed_features(requirements: false)
project.add_maintainer(user) project.add_maintainer(user)
sign_in(user) sign_in(user)
end end
...@@ -123,5 +132,15 @@ describe 'Project navbar' do ...@@ -123,5 +132,15 @@ describe 'Project navbar' do
it_behaves_like 'verified navigation bar' it_behaves_like 'verified navigation bar'
end end
context 'when requirements is available' do
before do
stub_licensed_features(requirements: true)
visit project_path(project)
end
it_behaves_like 'verified navigation bar'
end
end end
end end
...@@ -3,24 +3,29 @@ ...@@ -3,24 +3,29 @@
require 'spec_helper' require 'spec_helper'
describe Gitlab::Checks::ProjectCreated, :clean_gitlab_redis_shared_state do describe Gitlab::Checks::ProjectCreated, :clean_gitlab_redis_shared_state do
let(:user) { create(:user) } let_it_be(:user) { create(:user) }
let(:project) { create(:project) } let_it_be(:project) { create(:project, :repository, namespace: user.namespace) }
let(:protocol) { 'http' }
let(:git_user) { user }
let(:repository) { project.repository }
subject { described_class.new(repository, git_user, 'http') }
describe '.fetch_message' do describe '.fetch_message' do
context 'with a project created message queue' do context 'with a project created message queue' do
let(:project_created) { described_class.new(project, user, 'http') }
before do before do
project_created.add_message subject.add_message
end end
it 'returns project created message' do it 'returns project created message' do
expect(described_class.fetch_message(user.id, project.id)).to eq(project_created.message) expect(described_class.fetch_message(user.id, project.id)).to eq(subject.message)
end end
it 'deletes the project created message from redis' do it 'deletes the project created message from redis' do
expect(Gitlab::Redis::SharedState.with { |redis| redis.get("project_created:#{user.id}:#{project.id}") }).not_to be_nil expect(Gitlab::Redis::SharedState.with { |redis| redis.get("project_created:#{user.id}:#{project.id}") }).not_to be_nil
described_class.fetch_message(user.id, project.id) described_class.fetch_message(user.id, project.id)
expect(Gitlab::Redis::SharedState.with { |redis| redis.get("project_created:#{user.id}:#{project.id}") }).to be_nil expect(Gitlab::Redis::SharedState.with { |redis| redis.get("project_created:#{user.id}:#{project.id}") }).to be_nil
end end
end end
...@@ -34,15 +39,15 @@ describe Gitlab::Checks::ProjectCreated, :clean_gitlab_redis_shared_state do ...@@ -34,15 +39,15 @@ describe Gitlab::Checks::ProjectCreated, :clean_gitlab_redis_shared_state do
describe '#add_message' do describe '#add_message' do
it 'queues a project created message' do it 'queues a project created message' do
project_created = described_class.new(project, user, 'http') expect(subject.add_message).to eq('OK')
expect(project_created.add_message).to eq('OK')
end end
it 'handles anonymous push' do context 'when user is nil' do
project_created = described_class.new(nil, user, 'http') let(:git_user) { nil }
expect(project_created.add_message).to be_nil it 'handles anonymous push' do
expect(subject.add_message).to be_nil
end
end end
end end
end end
...@@ -3,24 +3,30 @@ ...@@ -3,24 +3,30 @@
require 'spec_helper' require 'spec_helper'
describe Gitlab::Checks::ProjectMoved, :clean_gitlab_redis_shared_state do describe Gitlab::Checks::ProjectMoved, :clean_gitlab_redis_shared_state do
let(:user) { create(:user) } let_it_be(:user) { create(:user) }
let(:project) { create(:project) } let_it_be(:project) { create(:project, :repository, :wiki_repo, namespace: user.namespace) }
let(:repository) { project.repository }
let(:protocol) { 'http' }
let(:git_user) { user }
let(:redirect_path) { 'foo/bar' }
subject { described_class.new(repository, git_user, protocol, redirect_path) }
describe '.fetch_message' do describe '.fetch_message' do
context 'with a redirect message queue' do context 'with a redirect message queue' do
it 'returns the redirect message' do before do
project_moved = described_class.new(project, user, 'http', 'foo/bar') subject.add_message
project_moved.add_message end
expect(described_class.fetch_message(user.id, project.id)).to eq(project_moved.message) it 'returns the redirect message' do
expect(described_class.fetch_message(user.id, project.id)).to eq(subject.message)
end end
it 'deletes the redirect message from redis' do it 'deletes the redirect message from redis' do
project_moved = described_class.new(project, user, 'http', 'foo/bar')
project_moved.add_message
expect(Gitlab::Redis::SharedState.with { |redis| redis.get("redirect_namespace:#{user.id}:#{project.id}") }).not_to be_nil expect(Gitlab::Redis::SharedState.with { |redis| redis.get("redirect_namespace:#{user.id}:#{project.id}") }).not_to be_nil
described_class.fetch_message(user.id, project.id) described_class.fetch_message(user.id, project.id)
expect(Gitlab::Redis::SharedState.with { |redis| redis.get("redirect_namespace:#{user.id}:#{project.id}") }).to be_nil expect(Gitlab::Redis::SharedState.with { |redis| redis.get("redirect_namespace:#{user.id}:#{project.id}") }).to be_nil
end end
end end
...@@ -34,29 +40,82 @@ describe Gitlab::Checks::ProjectMoved, :clean_gitlab_redis_shared_state do ...@@ -34,29 +40,82 @@ describe Gitlab::Checks::ProjectMoved, :clean_gitlab_redis_shared_state do
describe '#add_message' do describe '#add_message' do
it 'queues a redirect message' do it 'queues a redirect message' do
project_moved = described_class.new(project, user, 'http', 'foo/bar') expect(subject.add_message).to eq("OK")
expect(project_moved.add_message).to eq("OK")
end end
it 'handles anonymous clones' do context 'when user is nil' do
project_moved = described_class.new(project, nil, 'http', 'foo/bar') let(:git_user) { nil }
expect(project_moved.add_message).to eq(nil) it 'handles anonymous clones' do
expect(subject.add_message).to be_nil
end
end end
end end
describe '#message' do describe '#message' do
it 'returns a redirect message' do shared_examples 'errors per protocol' do
project_moved = described_class.new(project, user, 'http', 'foo/bar') shared_examples 'returns redirect message' do
message = <<~MSG it do
Project 'foo/bar' was moved to '#{project.full_path}'. message = <<~MSG
Project '#{redirect_path}' was moved to '#{project.full_path}'.
Please update your Git remote:
git remote set-url origin #{url_to_repo}
MSG
expect(subject.message).to eq(message)
end
end
context 'when protocol is http' do
it_behaves_like 'returns redirect message' do
let(:url_to_repo) { http_url_to_repo }
end
end
context 'when protocol is ssh' do
let(:protocol) { 'ssh' }
Please update your Git remote: it_behaves_like 'returns redirect message' do
let(:url_to_repo) { ssh_url_to_repo }
end
end
end
context 'with project' do
it_behaves_like 'errors per protocol' do
let(:http_url_to_repo) { project.http_url_to_repo }
let(:ssh_url_to_repo) { project.ssh_url_to_repo }
end
end
context 'with wiki' do
let(:repository) { project.wiki.repository }
git remote set-url origin #{project.http_url_to_repo} it_behaves_like 'errors per protocol' do
MSG let(:http_url_to_repo) { project.wiki.http_url_to_repo }
let(:ssh_url_to_repo) { project.wiki.ssh_url_to_repo }
end
end
expect(project_moved.message).to eq(message) context 'with project snippet' do
let_it_be(:snippet) { create(:project_snippet, :repository, project: project, author: user) }
let(:repository) { snippet.repository }
it_behaves_like 'errors per protocol' do
let(:http_url_to_repo) { snippet.http_url_to_repo }
let(:ssh_url_to_repo) { snippet.ssh_url_to_repo }
end
end
context 'with personal snippet' do
let_it_be(:snippet) { create(:personal_snippet, :repository, author: user) }
let(:repository) { snippet.repository }
it 'returns nil' do
expect(subject.add_message).to be_nil
end
end end
end end
end end
...@@ -8,7 +8,8 @@ describe ::Gitlab::RepoPath do ...@@ -8,7 +8,8 @@ describe ::Gitlab::RepoPath do
let_it_be(:project) { create(:project, :repository) } let_it_be(:project) { create(:project, :repository) }
let_it_be(:personal_snippet) { create(:personal_snippet) } let_it_be(:personal_snippet) { create(:personal_snippet) }
let_it_be(:project_snippet) { create(:project_snippet, project: project) } let_it_be(:project_snippet) { create(:project_snippet, project: project) }
let_it_be(:redirect) { project.route.create_redirect('foo/bar/baz') } let_it_be(:redirect_route) { 'foo/bar/baz' }
let_it_be(:redirect) { project.route.create_redirect(redirect_route) }
describe '.parse' do describe '.parse' do
context 'a repository storage path' do context 'a repository storage path' do
...@@ -43,22 +44,20 @@ describe ::Gitlab::RepoPath do ...@@ -43,22 +44,20 @@ describe ::Gitlab::RepoPath do
end end
context 'of a redirected project' do context 'of a redirected project' do
let(:redirect) { project.route.create_redirect('foo/bar') }
it 'parses a relative repository path' do it 'parses a relative repository path' do
expect(described_class.parse(redirect.path + '.git')).to eq([project, project, Gitlab::GlRepository::PROJECT, 'foo/bar']) expect(described_class.parse(redirect.path + '.git')).to eq([project, project, Gitlab::GlRepository::PROJECT, redirect_route])
end end
it 'parses a relative wiki path' do it 'parses a relative wiki path' do
expect(described_class.parse(redirect.path + '.wiki.git')).to eq([project, project, Gitlab::GlRepository::WIKI, 'foo/bar.wiki']) expect(described_class.parse(redirect.path + '.wiki.git')).to eq([project, project, Gitlab::GlRepository::WIKI, redirect_route])
end end
it 'parses a relative path starting with /' do it 'parses a relative path starting with /' do
expect(described_class.parse('/' + redirect.path + '.git')).to eq([project, project, Gitlab::GlRepository::PROJECT, 'foo/bar']) expect(described_class.parse('/' + redirect.path + '.git')).to eq([project, project, Gitlab::GlRepository::PROJECT, redirect_route])
end end
it 'parses a redirected project snippet repository path' do it 'parses a redirected project snippet repository path' do
expect(described_class.parse(redirect.path + "/snippets/#{project_snippet.id}.git")).to eq([project_snippet, project, Gitlab::GlRepository::SNIPPET, "foo/bar/snippets/#{project_snippet.id}"]) expect(described_class.parse(redirect.path + "/snippets/#{project_snippet.id}.git")).to eq([project_snippet, project, Gitlab::GlRepository::SNIPPET, redirect_route])
end end
end end
end end
...@@ -71,8 +70,8 @@ describe ::Gitlab::RepoPath do ...@@ -71,8 +70,8 @@ describe ::Gitlab::RepoPath do
describe '.find_project' do describe '.find_project' do
context 'when finding a project by its canonical path' do context 'when finding a project by its canonical path' do
context 'when the cases match' do context 'when the cases match' do
it 'returns the project and false' do it 'returns the project and nil' do
expect(described_class.find_project(project.full_path)).to eq([project, false]) expect(described_class.find_project(project.full_path)).to eq([project, nil])
end end
end end
...@@ -81,45 +80,45 @@ describe ::Gitlab::RepoPath do ...@@ -81,45 +80,45 @@ describe ::Gitlab::RepoPath do
# easy and safe to redirect someone to the correctly-cased URL. For git # easy and safe to redirect someone to the correctly-cased URL. For git
# requests, we should accept wrongly-cased URLs because it is a pain to # requests, we should accept wrongly-cased URLs because it is a pain to
# block people's git operations and force them to update remote URLs. # block people's git operations and force them to update remote URLs.
it 'returns the project and false' do it 'returns the project and nil' do
expect(described_class.find_project(project.full_path.upcase)).to eq([project, false]) expect(described_class.find_project(project.full_path.upcase)).to eq([project, nil])
end end
end end
end end
context 'when finding a project via a redirect' do context 'when finding a project via a redirect' do
it 'returns the project and true' do it 'returns the project and nil' do
expect(described_class.find_project(redirect.path)).to eq([project, true]) expect(described_class.find_project(redirect.path)).to eq([project, redirect.path])
end end
end end
end end
describe '.find_snippet' do describe '.find_snippet' do
it 'extracts path and id from personal snippet route' do it 'extracts path and id from personal snippet route' do
expect(described_class.find_snippet("snippets/#{personal_snippet.id}")).to eq([personal_snippet, false]) expect(described_class.find_snippet("snippets/#{personal_snippet.id}")).to eq([personal_snippet, nil])
end end
it 'extracts path and id from project snippet route' do it 'extracts path and id from project snippet route' do
expect(described_class.find_snippet("#{project.full_path}/snippets/#{project_snippet.id}")).to eq([project_snippet, false]) expect(described_class.find_snippet("#{project.full_path}/snippets/#{project_snippet.id}")).to eq([project_snippet, nil])
end end
it 'returns nil for invalid snippet paths' do it 'returns nil for invalid snippet paths' do
aggregate_failures do aggregate_failures do
expect(described_class.find_snippet("snippets/#{project_snippet.id}")).to eq([nil, false]) expect(described_class.find_snippet("snippets/#{project_snippet.id}")).to eq([nil, nil])
expect(described_class.find_snippet("#{project.full_path}/snippets/#{personal_snippet.id}")).to eq([nil, false]) expect(described_class.find_snippet("#{project.full_path}/snippets/#{personal_snippet.id}")).to eq([nil, nil])
expect(described_class.find_snippet('')).to eq([nil, false]) expect(described_class.find_snippet('')).to eq([nil, nil])
end end
end end
it 'returns nil for snippets not associated with the project' do it 'returns nil for snippets not associated with the project' do
snippet = create(:project_snippet) snippet = create(:project_snippet)
expect(described_class.find_snippet("#{project.full_path}/snippets/#{snippet.id}")).to eq([nil, false]) expect(described_class.find_snippet("#{project.full_path}/snippets/#{snippet.id}")).to eq([nil, nil])
end end
context 'when finding a project snippet via a redirect' do context 'when finding a project snippet via a redirect' do
it 'returns the project and true' do it 'returns the project and true' do
expect(described_class.find_snippet("#{redirect.path}/snippets/#{project_snippet.id}")).to eq([project_snippet, true]) expect(described_class.find_snippet("#{redirect.path}/snippets/#{project_snippet.id}")).to eq([project_snippet, redirect.path])
end end
end end
end end
......
...@@ -697,4 +697,20 @@ describe Snippet do ...@@ -697,4 +697,20 @@ describe Snippet do
it { is_expected.to eq result } it { is_expected.to eq result }
end end
end end
describe '#url_to_repo' do
subject { snippet.url_to_repo }
context 'with personal snippet' do
let(:snippet) { create(:personal_snippet) }
it { is_expected.to eq(Gitlab.config.gitlab_shell.ssh_path_prefix + "snippets/#{snippet.id}.git") }
end
context 'with project snippet' do
let(:snippet) { create(:project_snippet) }
it { is_expected.to eq(Gitlab.config.gitlab_shell.ssh_path_prefix + "#{snippet.project.full_path}/snippets/#{snippet.id}.git") }
end
end
end end
...@@ -234,7 +234,7 @@ describe PostReceiveService do ...@@ -234,7 +234,7 @@ describe PostReceiveService do
context 'with a redirected data' do context 'with a redirected data' do
it 'returns redirected message on the response' do it 'returns redirected message on the response' do
project_moved = Gitlab::Checks::ProjectMoved.new(project, user, 'http', 'foo/baz') project_moved = Gitlab::Checks::ProjectMoved.new(project.repository, user, 'http', 'foo/baz')
project_moved.add_message project_moved.add_message
expect(subject).to include(build_basic_message(project_moved.message)) expect(subject).to include(build_basic_message(project_moved.message))
...@@ -243,7 +243,7 @@ describe PostReceiveService do ...@@ -243,7 +243,7 @@ describe PostReceiveService do
context 'with new project data' do context 'with new project data' do
it 'returns new project message on the response' do it 'returns new project message on the response' do
project_created = Gitlab::Checks::ProjectCreated.new(project, user, 'http') project_created = Gitlab::Checks::ProjectCreated.new(project.repository, user, 'http')
project_created.add_message project_created.add_message
expect(subject).to include(build_basic_message(project_created.message)) expect(subject).to include(build_basic_message(project_created.message))
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
# end # end
# #
RSpec.shared_examples 'an idempotent worker' do RSpec.shared_examples 'an idempotent worker' do
let(:worker_exec_times) { IdempotentWorkerHelper::WORKER_EXEC_TIMES }
# Avoid stubbing calls for a more accurate run. # Avoid stubbing calls for a more accurate run.
subject do subject do
defined?(job_args) ? perform_multiple(job_args) : perform_multiple defined?(job_args) ? perform_multiple(job_args) : perform_multiple
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
require 'spec_helper' require 'spec_helper'
describe ApplicationWorker do describe ApplicationWorker do
let(:worker) do let_it_be(:worker) do
Class.new do Class.new do
def self.name def self.name
'Gitlab::Foo::Bar::DummyWorker' 'Gitlab::Foo::Bar::DummyWorker'
...@@ -13,12 +13,51 @@ describe ApplicationWorker do ...@@ -13,12 +13,51 @@ describe ApplicationWorker do
end end
end end
let(:instance) { worker.new }
describe 'Sidekiq options' do describe 'Sidekiq options' do
it 'sets the queue name based on the class name' do it 'sets the queue name based on the class name' do
expect(worker.sidekiq_options['queue']).to eq('foo_bar_dummy') expect(worker.sidekiq_options['queue']).to eq('foo_bar_dummy')
end end
end end
describe '#structured_payload' do
let(:payload) { {} }
subject(:result) { instance.structured_payload(payload) }
it 'adds worker related payload' do
instance.jid = 'a jid'
expect(result).to include(
'class' => worker.class,
'job_status' => 'running',
'queue' => worker.queue,
'jid' => instance.jid
)
end
it 'adds labkit context' do
user = build_stubbed(:user, username: 'jane-doe')
instance.with_context(user: user) do
expect(result).to include('meta.user' => user.username)
end
end
it 'adds custom payload converting stringified keys' do
payload[:message] = 'some message'
expect(result).to include('message' => payload[:message])
end
it 'does not override predefined context keys with custom payload' do
payload['class'] = 'custom value'
expect(result).to include('class' => worker.class)
end
end
describe '.queue_namespace' do describe '.queue_namespace' do
it 'sets the queue name based on the class name' do it 'sets the queue name based on the class name' do
worker.queue_namespace :some_namespace worker.queue_namespace :some_namespace
......
...@@ -21,12 +21,12 @@ describe ExpireJobCacheWorker do ...@@ -21,12 +21,12 @@ describe ExpireJobCacheWorker do
allow(Gitlab::EtagCaching::Store).to receive(:new) { spy_store } allow(Gitlab::EtagCaching::Store).to receive(:new) { spy_store }
expect(spy_store).to receive(:touch) expect(spy_store).to receive(:touch)
.exactly(IdempotentWorkerHelper::WORKER_EXEC_TIMES).times .exactly(worker_exec_times).times
.with(pipeline_path) .with(pipeline_path)
.and_call_original .and_call_original
expect(spy_store).to receive(:touch) expect(spy_store).to receive(:touch)
.exactly(IdempotentWorkerHelper::WORKER_EXEC_TIMES).times .exactly(worker_exec_times).times
.with(job_path) .with(job_path)
.and_call_original .and_call_original
......
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