Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
fc1df8c830
commit
8ae26d705a
31 changed files with 439 additions and 115 deletions
|
@ -283,6 +283,10 @@ class Snippet < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
def url_to_repo
|
||||
Gitlab::Shell.url_to_repo(full_path.delete('@'))
|
||||
end
|
||||
|
||||
def repository_storage
|
||||
snippet_repository&.shard_name ||
|
||||
Gitlab::CurrentSettings.pick_repository_storage
|
||||
|
|
|
@ -159,6 +159,8 @@
|
|||
%span.badge.badge-pill.count.merge_counter.js-merge-counter.fly-out-badge
|
||||
= number_with_delimiter(@project.open_merge_requests_count)
|
||||
|
||||
= render_if_exists "layouts/nav/requirements_link", project: @project
|
||||
|
||||
- if project_nav_tab? :pipelines
|
||||
= 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
|
||||
|
|
|
@ -13,6 +13,17 @@ module ApplicationWorker
|
|||
|
||||
included do
|
||||
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
|
||||
|
||||
class_methods do
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix project moved message after git operation
|
||||
merge_request: 27341
|
||||
author:
|
||||
type: fixed
|
5
changelogs/unreleased/fj-fix-snippet-url-to-repo.yml
Normal file
5
changelogs/unreleased/fj-fix-snippet-url-to-repo.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix remove special chars from snippet url_to_repo
|
||||
merge_request: 27390
|
||||
author:
|
||||
type: fixed
|
|
@ -232,6 +232,8 @@
|
|||
- 2
|
||||
- - service_desk_email_receiver
|
||||
- 1
|
||||
- - status_page_publish_incident
|
||||
- 1
|
||||
- - sync_seat_link_request
|
||||
- 1
|
||||
- - system_hook_push
|
||||
|
|
|
@ -182,7 +182,7 @@ Unicorn specific metrics, when Unicorn is used.
|
|||
| `unicorn_queued_connections` | Gauge | 11.0 | The number of queued Unicorn connections |
|
||||
| `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:
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
## Puma
|
||||
|
||||
GitLab plans to use [Puma](https://github.com/puma/puma) to replace
|
||||
[Unicorn](https://bogomips.org/unicorn/).
|
||||
As of GitLab 12.9, [Puma](https://github.com/puma/puma) has replaced [Unicorn](https://bogomips.org/unicorn/).
|
||||
as the default web server.
|
||||
|
||||
## Why switch to Puma?
|
||||
|
||||
|
|
|
@ -11,9 +11,8 @@ dependency proxies, see the [user guide](../../user/group/dependency_proxy/index
|
|||
|
||||
NOTE: **Note:**
|
||||
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**
|
||||
|
||||
|
@ -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. 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
|
||||
|
||||
|
|
|
@ -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
|
||||
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
|
||||
[ce-14605]: https://gitlab.com/gitlab-org/gitlab-foss/issues/14605
|
||||
[ee-80]: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/80
|
||||
|
|
|
@ -163,6 +163,7 @@ Complementary reads:
|
|||
|
||||
- [Jira Connect app](integrations/jira_connect.md)
|
||||
- [Security Scanners](integrations/secure.md)
|
||||
- [Secure Partner Integration](integrations/secure_partner_integration.md)
|
||||
|
||||
## Testing guides
|
||||
|
||||
|
|
103
doc/development/integrations/secure_partner_integration.md
Normal file
103
doc/development/integrations/secure_partner_integration.md
Normal file
|
@ -0,0 +1,103 @@
|
|||
# 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/
|
|||
# Change the permissions of the directory where GitLab Pages are stored
|
||||
sudo chmod -R ug+rwX shared/pages/
|
||||
|
||||
# Copy the example Unicorn config
|
||||
sudo -u git -H cp config/unicorn.rb.example config/unicorn.rb
|
||||
# Copy the example Puma config
|
||||
sudo -u git -H cp config/puma.rb.example config/puma.rb
|
||||
|
||||
# Find number of cores
|
||||
nproc
|
||||
|
||||
# Enable cluster mode if you expect to have a high load instance
|
||||
# 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
|
||||
# Refer to https://github.com/puma/puma#configuration for more information.
|
||||
# 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.
|
||||
sudo -u git -H editor config/puma.rb
|
||||
|
||||
# Copy the example Rack attack config
|
||||
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
|
|||
```
|
||||
|
||||
CAUTION: **Caution:**
|
||||
Make sure to edit both `gitlab.yml` and `unicorn.rb` to match your setup.
|
||||
If you want to use Puma web server, see [Using Puma](#using-puma) for the additional steps.
|
||||
Make sure to edit both `gitlab.yml` and `puma.rb` to match your setup.
|
||||
If you want to use the Unicorn web server, see [Using Unicorn](#using-unicorn) for the additional steps.
|
||||
|
||||
NOTE: **Note:**
|
||||
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`,
|
|||
|
||||
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.
|
||||
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:
|
||||
|
||||
To use GitLab with Puma:
|
||||
|
||||
1. Finish GitLab setup so you have it up and running.
|
||||
1. Copy the supplied example Puma config file into place:
|
||||
1. Finish the GitLab setup so you have it up and running.
|
||||
1. Copy the supplied example Unicorn config file into place:
|
||||
|
||||
```shell
|
||||
cd /home/git/gitlab
|
||||
|
||||
# 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.
|
||||
|
||||
## Troubleshooting
|
||||
|
|
|
@ -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.
|
||||
|
||||
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)
|
||||
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
module Gitlab
|
||||
module Checks
|
||||
class PostPushMessage
|
||||
def initialize(project, user, protocol)
|
||||
@project = project
|
||||
def initialize(repository, user, protocol)
|
||||
@repository = repository
|
||||
@user = user
|
||||
@protocol = protocol
|
||||
end
|
||||
|
@ -34,14 +34,21 @@ module Gitlab
|
|||
|
||||
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)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
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
|
||||
|
|
|
@ -5,10 +5,10 @@ module Gitlab
|
|||
class ProjectMoved < PostPushMessage
|
||||
REDIRECT_NAMESPACE = "redirect_namespace"
|
||||
|
||||
def initialize(project, user, protocol, redirected_path)
|
||||
def initialize(repository, user, protocol, redirected_path)
|
||||
@redirected_path = redirected_path
|
||||
|
||||
super(project, user, protocol)
|
||||
super(repository, user, protocol)
|
||||
end
|
||||
|
||||
def message
|
||||
|
|
|
@ -188,7 +188,7 @@ module Gitlab
|
|||
def add_project_moved_message!
|
||||
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
|
||||
end
|
||||
|
@ -250,7 +250,7 @@ module Gitlab
|
|||
@project = project
|
||||
user_access.project = @project
|
||||
|
||||
Checks::ProjectCreated.new(project, user, protocol).add_message
|
||||
Checks::ProjectCreated.new(repository, user, protocol).add_message
|
||||
end
|
||||
|
||||
def check_repository_existence!
|
||||
|
|
|
@ -39,11 +39,11 @@ module Gitlab
|
|||
|
||||
override :check_project!
|
||||
def check_project!(cmd, changes)
|
||||
if snippet.is_a?(ProjectSnippet)
|
||||
check_namespace!
|
||||
check_project_accessibility!
|
||||
# TODO add add_project_moved_message! to handle non-project repo https://gitlab.com/gitlab-org/gitlab/issues/205646
|
||||
end
|
||||
return unless snippet.is_a?(ProjectSnippet)
|
||||
|
||||
check_namespace!
|
||||
check_project_accessibility!
|
||||
add_project_moved_message!
|
||||
end
|
||||
|
||||
override :check_push_access!
|
||||
|
|
|
@ -19,8 +19,7 @@ module Gitlab
|
|||
|
||||
# Removing the suffix (.wiki, .design, ...) from the project path
|
||||
full_path = repo_path.chomp(type.path_suffix)
|
||||
container, project, was_redirected = find_container(type, full_path)
|
||||
redirected_path = repo_path if was_redirected
|
||||
container, project, redirected_path = find_container(type, full_path)
|
||||
|
||||
return [container, project, type, redirected_path] if container
|
||||
end
|
||||
|
@ -33,22 +32,23 @@ module Gitlab
|
|||
|
||||
def self.find_container(type, full_path)
|
||||
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
|
||||
project, was_redirected = find_project(full_path)
|
||||
project, redirected_path = find_project(full_path)
|
||||
|
||||
[project, project, was_redirected]
|
||||
[project, project, redirected_path]
|
||||
end
|
||||
end
|
||||
|
||||
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)
|
||||
redirected_path = redirected?(project, project_path) ? project_path : nil
|
||||
|
||||
[project, redirected?(project, project_path)]
|
||||
[project, redirected_path]
|
||||
end
|
||||
|
||||
def self.redirected?(project, project_path)
|
||||
|
@ -59,12 +59,12 @@ module Gitlab
|
|||
# - snippets/1
|
||||
# - h5bp/html5-boilerplate/snippets/53
|
||||
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)
|
||||
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
|
||||
|
||||
def self.extract_snippet_info(snippet_path)
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
### Environment variables
|
||||
RAILS_ENV="production"
|
||||
EXPERIMENTAL_PUMA=""
|
||||
USE_UNICORN=""
|
||||
|
||||
# Script variable names should be lower-case not to conflict with
|
||||
# internal /bin/sh variables such as PATH, EDITOR or SHELL.
|
||||
|
@ -68,10 +68,10 @@ if ! cd "$app_root" ; then
|
|||
fi
|
||||
|
||||
# Select the web server to use
|
||||
if [ -z "$EXPERIMENTAL_PUMA" ]; then
|
||||
use_web_server="unicorn"
|
||||
else
|
||||
if [ -z "$USE_UNICORN" ]; then
|
||||
use_web_server="puma"
|
||||
else
|
||||
use_web_server="unicorn"
|
||||
fi
|
||||
|
||||
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
# Normal values are "production", "test" and "development".
|
||||
RAILS_ENV="production"
|
||||
|
||||
# Uncomment the line below to enable Puma web server instead of Unicorn.
|
||||
# EXPERIMENTAL_PUMA=1
|
||||
# Uncomment the line below to enable the Unicorn web server instead of Puma.
|
||||
# USE_UNICORN=1
|
||||
|
||||
# app_user defines the user that GitLab is run as.
|
||||
# The default is "git".
|
||||
|
|
|
@ -16775,6 +16775,9 @@ msgstr ""
|
|||
msgid "Require users to prove ownership of custom domains"
|
||||
msgstr ""
|
||||
|
||||
msgid "Requirements"
|
||||
msgstr ""
|
||||
|
||||
msgid "Requires approval from %{names}."
|
||||
msgid_plural "Requires %{count} more approvals from %{names}."
|
||||
msgstr[0] ""
|
||||
|
|
|
@ -18,6 +18,13 @@ describe 'Project navbar' do
|
|||
}
|
||||
end
|
||||
|
||||
let(:requirements_nav_item) do
|
||||
{
|
||||
nav_item: _('Requirements'),
|
||||
nav_sub_items: [_('List')]
|
||||
}
|
||||
end
|
||||
|
||||
let(:structure) do
|
||||
[
|
||||
{
|
||||
|
@ -54,6 +61,7 @@ describe 'Project navbar' do
|
|||
nav_item: _('Merge Requests'),
|
||||
nav_sub_items: []
|
||||
},
|
||||
(requirements_nav_item if Gitlab.ee?),
|
||||
{
|
||||
nav_item: _('CI / CD'),
|
||||
nav_sub_items: [
|
||||
|
@ -100,6 +108,7 @@ describe 'Project navbar' do
|
|||
end
|
||||
|
||||
before do
|
||||
stub_licensed_features(requirements: false)
|
||||
project.add_maintainer(user)
|
||||
sign_in(user)
|
||||
end
|
||||
|
@ -123,5 +132,15 @@ describe 'Project navbar' do
|
|||
|
||||
it_behaves_like 'verified navigation bar'
|
||||
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
|
||||
|
|
|
@ -3,24 +3,29 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Gitlab::Checks::ProjectCreated, :clean_gitlab_redis_shared_state do
|
||||
let(:user) { create(:user) }
|
||||
let(:project) { create(:project) }
|
||||
let_it_be(:user) { create(:user) }
|
||||
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
|
||||
context 'with a project created message queue' do
|
||||
let(:project_created) { described_class.new(project, user, 'http') }
|
||||
|
||||
before do
|
||||
project_created.add_message
|
||||
subject.add_message
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
end
|
||||
end
|
||||
|
@ -34,15 +39,15 @@ describe Gitlab::Checks::ProjectCreated, :clean_gitlab_redis_shared_state do
|
|||
|
||||
describe '#add_message' do
|
||||
it 'queues a project created message' do
|
||||
project_created = described_class.new(project, user, 'http')
|
||||
|
||||
expect(project_created.add_message).to eq('OK')
|
||||
expect(subject.add_message).to eq('OK')
|
||||
end
|
||||
|
||||
it 'handles anonymous push' do
|
||||
project_created = described_class.new(nil, user, 'http')
|
||||
context 'when user is nil' do
|
||||
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
|
||||
|
|
|
@ -3,24 +3,30 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Gitlab::Checks::ProjectMoved, :clean_gitlab_redis_shared_state do
|
||||
let(:user) { create(:user) }
|
||||
let(:project) { create(:project) }
|
||||
let_it_be(:user) { create(:user) }
|
||||
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
|
||||
context 'with a redirect message queue' do
|
||||
it 'returns the redirect message' do
|
||||
project_moved = described_class.new(project, user, 'http', 'foo/bar')
|
||||
project_moved.add_message
|
||||
before do
|
||||
subject.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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
end
|
||||
end
|
||||
|
@ -34,29 +40,82 @@ describe Gitlab::Checks::ProjectMoved, :clean_gitlab_redis_shared_state do
|
|||
|
||||
describe '#add_message' do
|
||||
it 'queues a redirect message' do
|
||||
project_moved = described_class.new(project, user, 'http', 'foo/bar')
|
||||
expect(project_moved.add_message).to eq("OK")
|
||||
expect(subject.add_message).to eq("OK")
|
||||
end
|
||||
|
||||
it 'handles anonymous clones' do
|
||||
project_moved = described_class.new(project, nil, 'http', 'foo/bar')
|
||||
context 'when user is nil' do
|
||||
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
|
||||
|
||||
describe '#message' do
|
||||
it 'returns a redirect message' do
|
||||
project_moved = described_class.new(project, user, 'http', 'foo/bar')
|
||||
message = <<~MSG
|
||||
Project 'foo/bar' was moved to '#{project.full_path}'.
|
||||
shared_examples 'errors per protocol' do
|
||||
shared_examples 'returns redirect message' do
|
||||
it do
|
||||
message = <<~MSG
|
||||
Project '#{redirect_path}' was moved to '#{project.full_path}'.
|
||||
|
||||
Please update your Git remote:
|
||||
Please update your Git remote:
|
||||
|
||||
git remote set-url origin #{project.http_url_to_repo}
|
||||
MSG
|
||||
git remote set-url origin #{url_to_repo}
|
||||
MSG
|
||||
|
||||
expect(project_moved.message).to eq(message)
|
||||
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' }
|
||||
|
||||
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 }
|
||||
|
||||
it_behaves_like 'errors per protocol' do
|
||||
let(:http_url_to_repo) { project.wiki.http_url_to_repo }
|
||||
let(:ssh_url_to_repo) { project.wiki.ssh_url_to_repo }
|
||||
end
|
||||
end
|
||||
|
||||
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
|
||||
|
|
|
@ -8,7 +8,8 @@ describe ::Gitlab::RepoPath do
|
|||
let_it_be(:project) { create(:project, :repository) }
|
||||
let_it_be(:personal_snippet) { create(:personal_snippet) }
|
||||
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
|
||||
context 'a repository storage path' do
|
||||
|
@ -43,22 +44,20 @@ describe ::Gitlab::RepoPath do
|
|||
end
|
||||
|
||||
context 'of a redirected project' do
|
||||
let(:redirect) { project.route.create_redirect('foo/bar') }
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
|
@ -71,8 +70,8 @@ describe ::Gitlab::RepoPath do
|
|||
describe '.find_project' do
|
||||
context 'when finding a project by its canonical path' do
|
||||
context 'when the cases match' do
|
||||
it 'returns the project and false' do
|
||||
expect(described_class.find_project(project.full_path)).to eq([project, false])
|
||||
it 'returns the project and nil' do
|
||||
expect(described_class.find_project(project.full_path)).to eq([project, nil])
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -81,45 +80,45 @@ describe ::Gitlab::RepoPath do
|
|||
# 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
|
||||
# block people's git operations and force them to update remote URLs.
|
||||
it 'returns the project and false' do
|
||||
expect(described_class.find_project(project.full_path.upcase)).to eq([project, false])
|
||||
it 'returns the project and nil' do
|
||||
expect(described_class.find_project(project.full_path.upcase)).to eq([project, nil])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when finding a project via a redirect' do
|
||||
it 'returns the project and true' do
|
||||
expect(described_class.find_project(redirect.path)).to eq([project, true])
|
||||
it 'returns the project and nil' do
|
||||
expect(described_class.find_project(redirect.path)).to eq([project, redirect.path])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.find_snippet' 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
|
||||
|
||||
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
|
||||
|
||||
it 'returns nil for invalid snippet paths' do
|
||||
aggregate_failures do
|
||||
expect(described_class.find_snippet("snippets/#{project_snippet.id}")).to eq([nil, false])
|
||||
expect(described_class.find_snippet("#{project.full_path}/snippets/#{personal_snippet.id}")).to eq([nil, false])
|
||||
expect(described_class.find_snippet('')).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, nil])
|
||||
expect(described_class.find_snippet('')).to eq([nil, nil])
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns nil for snippets not associated with the project' do
|
||||
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
|
||||
|
||||
context 'when finding a project snippet via a redirect' 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
|
||||
|
|
|
@ -697,4 +697,20 @@ describe Snippet do
|
|||
it { is_expected.to eq result }
|
||||
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
|
||||
|
|
|
@ -234,7 +234,7 @@ describe PostReceiveService do
|
|||
|
||||
context 'with a redirected data' 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
|
||||
|
||||
expect(subject).to include(build_basic_message(project_moved.message))
|
||||
|
@ -243,7 +243,7 @@ describe PostReceiveService do
|
|||
|
||||
context 'with new project data' 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
|
||||
|
||||
expect(subject).to include(build_basic_message(project_created.message))
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
# end
|
||||
#
|
||||
RSpec.shared_examples 'an idempotent worker' do
|
||||
let(:worker_exec_times) { IdempotentWorkerHelper::WORKER_EXEC_TIMES }
|
||||
|
||||
# Avoid stubbing calls for a more accurate run.
|
||||
subject do
|
||||
defined?(job_args) ? perform_multiple(job_args) : perform_multiple
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe ApplicationWorker do
|
||||
let(:worker) do
|
||||
let_it_be(:worker) do
|
||||
Class.new do
|
||||
def self.name
|
||||
'Gitlab::Foo::Bar::DummyWorker'
|
||||
|
@ -13,12 +13,51 @@ describe ApplicationWorker do
|
|||
end
|
||||
end
|
||||
|
||||
let(:instance) { worker.new }
|
||||
|
||||
describe 'Sidekiq options' do
|
||||
it 'sets the queue name based on the class name' do
|
||||
expect(worker.sidekiq_options['queue']).to eq('foo_bar_dummy')
|
||||
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
|
||||
it 'sets the queue name based on the class name' do
|
||||
worker.queue_namespace :some_namespace
|
||||
|
|
|
@ -21,12 +21,12 @@ describe ExpireJobCacheWorker do
|
|||
allow(Gitlab::EtagCaching::Store).to receive(:new) { spy_store }
|
||||
|
||||
expect(spy_store).to receive(:touch)
|
||||
.exactly(IdempotentWorkerHelper::WORKER_EXEC_TIMES).times
|
||||
.exactly(worker_exec_times).times
|
||||
.with(pipeline_path)
|
||||
.and_call_original
|
||||
|
||||
expect(spy_store).to receive(:touch)
|
||||
.exactly(IdempotentWorkerHelper::WORKER_EXEC_TIMES).times
|
||||
.exactly(worker_exec_times).times
|
||||
.with(job_path)
|
||||
.and_call_original
|
||||
|
||||
|
|
Loading…
Reference in a new issue