Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
8a0ba60290
commit
9b124bc39e
40 changed files with 1458 additions and 391 deletions
|
@ -17,10 +17,10 @@ $new-namespace-panel-height: 240px;
|
|||
|
||||
.new-namespace-panel {
|
||||
&:hover {
|
||||
background-color: $gray-10;
|
||||
background-color: var(--gray-50, $gray-10);
|
||||
}
|
||||
|
||||
color: $purple-700;
|
||||
color: var(--purple-700, $purple-700);
|
||||
min-height: $new-namespace-panel-height;
|
||||
text-align: center;
|
||||
@include media-breakpoint-up(lg) {
|
||||
|
|
|
@ -11,6 +11,7 @@ body.gl-dark {
|
|||
--green-700: #91d4a8;
|
||||
--blue-400: #1f75cb;
|
||||
--orange-400: #ab6100;
|
||||
--purple-100: #2f2a6b;
|
||||
--gl-text-color: #fafafa;
|
||||
--border-color: #4f4f4f;
|
||||
--black: #fff;
|
||||
|
@ -1524,7 +1525,7 @@ svg.s16 {
|
|||
background-color: #660e00;
|
||||
}
|
||||
.identicon.bg2 {
|
||||
background-color: #f4f0ff;
|
||||
background-color: #232150;
|
||||
}
|
||||
.identicon.bg3 {
|
||||
background-color: #f1f1ff;
|
||||
|
@ -1651,7 +1652,7 @@ body.gl-dark .nav-sidebar li.active > a {
|
|||
body.gl-dark .nav-sidebar .fly-out-top-item a,
|
||||
body.gl-dark .nav-sidebar .fly-out-top-item.active a,
|
||||
body.gl-dark .nav-sidebar .fly-out-top-item .fly-out-top-item-container {
|
||||
background-color: #2f2a6b;
|
||||
background-color: var(--purple-100, #e1d8f9);
|
||||
color: var(--black, #333);
|
||||
}
|
||||
body.gl-dark .logo-text svg {
|
||||
|
@ -1746,6 +1747,17 @@ body.gl-dark {
|
|||
--indigo-900: #ebebfa;
|
||||
--indigo-950: #f7f7ff;
|
||||
--indigo-900-alpha-008: rgba(235, 235, 250, 0.08);
|
||||
--purple-50: #232150;
|
||||
--purple-100: #2f2a6b;
|
||||
--purple-200: #453894;
|
||||
--purple-300: #5943b6;
|
||||
--purple-400: #694cc0;
|
||||
--purple-500: #7b58cf;
|
||||
--purple-600: #9475db;
|
||||
--purple-700: #ac93e6;
|
||||
--purple-800: #cbbbf2;
|
||||
--purple-900: #e1d8f9;
|
||||
--purple-950: #f4f0ff;
|
||||
--gl-text-color: #fafafa;
|
||||
--border-color: #4f4f4f;
|
||||
--white: #333;
|
||||
|
|
|
@ -72,6 +72,18 @@ $indigo-900: #ebebfa;
|
|||
$indigo-950: #f7f7ff;
|
||||
$indigo-900-alpha-008: rgba($indigo-900, 0.08);
|
||||
|
||||
$purple-50: #232150;
|
||||
$purple-100: #2f2a6b;
|
||||
$purple-200: #453894;
|
||||
$purple-300: #5943b6;
|
||||
$purple-400: #694cc0;
|
||||
$purple-500: #7b58cf;
|
||||
$purple-600: #9475db;
|
||||
$purple-700: #ac93e6;
|
||||
$purple-800: #cbbbf2;
|
||||
$purple-900: #e1d8f9;
|
||||
$purple-950: #f4f0ff;
|
||||
|
||||
$gray-lightest: #222;
|
||||
$gray-light: $gray-50;
|
||||
$gray-lighter: #303030;
|
||||
|
@ -163,6 +175,18 @@ body.gl-dark {
|
|||
--indigo-950: #{$indigo-950};
|
||||
--indigo-900-alpha-008: #{$indigo-900-alpha-008};
|
||||
|
||||
--purple-50: #{$purple-50};
|
||||
--purple-100: #{$purple-100};
|
||||
--purple-200: #{$purple-200};
|
||||
--purple-300: #{$purple-300};
|
||||
--purple-400: #{$purple-400};
|
||||
--purple-500: #{$purple-500};
|
||||
--purple-600: #{$purple-600};
|
||||
--purple-700: #{$purple-700};
|
||||
--purple-800: #{$purple-800};
|
||||
--purple-900: #{$purple-900};
|
||||
--purple-950: #{$purple-950};
|
||||
|
||||
--gl-text-color: #{$gray-900};
|
||||
--border-color: #{$border-color};
|
||||
|
||||
|
|
|
@ -184,7 +184,7 @@
|
|||
a:hover,
|
||||
&.active a,
|
||||
.fly-out-top-item-container {
|
||||
background-color: $purple-900;
|
||||
background-color: var(--purple-100, $purple-900);
|
||||
color: var(--black, $white);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,16 @@ class Compare
|
|||
@straight = straight
|
||||
end
|
||||
|
||||
# Return a Hash of parameters for passing to a URL helper
|
||||
#
|
||||
# See `namespace_project_compare_url`
|
||||
def to_param
|
||||
{
|
||||
from: @straight ? start_commit_sha : base_commit_sha,
|
||||
to: head_commit_sha
|
||||
}
|
||||
end
|
||||
|
||||
def cache_key
|
||||
[@project, :compare, diff_refs.hash]
|
||||
end
|
||||
|
|
|
@ -16,8 +16,14 @@ module Ci
|
|||
private
|
||||
|
||||
def create_pipeline_for(pull_request)
|
||||
Ci::CreatePipelineService.new(project, current_user, create_params(pull_request))
|
||||
.execute(:external_pull_request_event, external_pull_request: pull_request)
|
||||
if ::Feature.enabled?(:ci_create_external_pr_pipeline_async, project, default_enabled: :yaml)
|
||||
Ci::ExternalPullRequests::CreatePipelineWorker.perform_async(
|
||||
project.id, current_user.id, pull_request.id
|
||||
)
|
||||
else
|
||||
Ci::CreatePipelineService.new(project, current_user, create_params(pull_request))
|
||||
.execute(:external_pull_request_event, external_pull_request: pull_request)
|
||||
end
|
||||
end
|
||||
|
||||
def create_params(pull_request)
|
||||
|
|
|
@ -1470,6 +1470,15 @@
|
|||
:weight: 3
|
||||
:idempotent:
|
||||
:tags: []
|
||||
- :name: pipeline_creation:ci_external_pull_requests_create_pipeline
|
||||
:worker_name: Ci::ExternalPullRequests::CreatePipelineWorker
|
||||
:feature_category: :pipeline_authoring
|
||||
:has_external_dependencies:
|
||||
:urgency: :high
|
||||
:resource_boundary: :cpu
|
||||
:weight: 4
|
||||
:idempotent:
|
||||
:tags: []
|
||||
- :name: pipeline_creation:create_pipeline
|
||||
:worker_name: CreatePipelineWorker
|
||||
:feature_category: :continuous_integration
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Ci
|
||||
module ExternalPullRequests
|
||||
class CreatePipelineWorker # rubocop:disable Scalability/IdempotentWorker
|
||||
include ApplicationWorker
|
||||
|
||||
data_consistency :always
|
||||
queue_namespace :pipeline_creation
|
||||
feature_category :pipeline_authoring
|
||||
urgency :high
|
||||
worker_resource_boundary :cpu
|
||||
|
||||
def perform(project_id, user_id, external_pull_request_id)
|
||||
user = User.find_by_id(user_id)
|
||||
return unless user
|
||||
|
||||
project = Project.find_by_id(project_id)
|
||||
return unless project
|
||||
|
||||
external_pull_request = project.external_pull_requests.find_by_id(external_pull_request_id)
|
||||
return unless external_pull_request
|
||||
|
||||
::Ci::CreatePipelineService
|
||||
.new(project, user, execute_params(external_pull_request))
|
||||
.execute(:external_pull_request_event, external_pull_request: external_pull_request)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def execute_params(pull_request)
|
||||
{
|
||||
ref: pull_request.source_ref,
|
||||
source_sha: pull_request.source_sha,
|
||||
target_sha: pull_request.target_sha
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: ci_create_external_pr_pipeline_async
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68567
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338908
|
||||
milestone: '14.3'
|
||||
type: development
|
||||
group: group::pipeline authoring
|
||||
default_enabled: false
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: usage_data_i_testing_web_performance_widget_total
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46746
|
||||
rollout_issue_url:
|
||||
milestone: '13.8'
|
||||
type: development
|
||||
group: group::testing
|
||||
default_enabled: true
|
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class SetDefaultJobTokenScopeTrue < ActiveRecord::Migration[6.1]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
def up
|
||||
with_lock_retries do
|
||||
change_column_default :project_ci_cd_settings, :job_token_scope_enabled, from: false, to: true
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
with_lock_retries do
|
||||
change_column_default :project_ci_cd_settings, :job_token_scope_enabled, from: true, to: false
|
||||
end
|
||||
end
|
||||
end
|
1
db/schema_migrations/20210819153805
Normal file
1
db/schema_migrations/20210819153805
Normal file
|
@ -0,0 +1 @@
|
|||
195d2444bf9d5113ee589b1accdbf04efbc7fb84c2ead4deed3985b254345e07
|
|
@ -16996,7 +16996,7 @@ CREATE TABLE project_ci_cd_settings (
|
|||
auto_rollback_enabled boolean DEFAULT false NOT NULL,
|
||||
keep_latest_artifact boolean DEFAULT true NOT NULL,
|
||||
restrict_user_defined_variables boolean DEFAULT false NOT NULL,
|
||||
job_token_scope_enabled boolean DEFAULT false NOT NULL
|
||||
job_token_scope_enabled boolean DEFAULT true NOT NULL
|
||||
);
|
||||
|
||||
CREATE SEQUENCE project_ci_cd_settings_id_seq
|
||||
|
|
|
@ -200,7 +200,8 @@ Example response:
|
|||
"deleted_file": false
|
||||
}],
|
||||
"compare_timeout": false,
|
||||
"compare_same_ref": false
|
||||
"compare_same_ref": false,
|
||||
"web_url": "https://gitlab.example.com/thedude/gitlab-foss/-/compare/ae73cb07c9eeaf35924a10f713b364d32b2dd34f...0b4bc9a49b562e85de7cc9e834518ea6828729b9"
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -290,6 +290,35 @@ You can use the `$` character for both variables and paths. For example, if the
|
|||
`$DOCKERFILES_DIR` variable exists, its value is used. If it does not exist, the
|
||||
`$` is interpreted as being part of a path.
|
||||
|
||||
## Reuse rules in different jobs
|
||||
|
||||
> [Introduced in](https://gitlab.com/gitlab-org/gitlab/-/issues/322992) GitLab 14.3.
|
||||
|
||||
Use [`!reference` tags](../yaml/index.md#reference-tags) to reuse rules in different
|
||||
jobs. You can combine `!reference` rules with regular job-defined rules:
|
||||
|
||||
```yaml
|
||||
.default_rules:
|
||||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == "schedule"
|
||||
when: never
|
||||
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||
|
||||
job1:
|
||||
rules:
|
||||
- !reference [.default_rules, rules]
|
||||
script:
|
||||
- echo "This job runs for the default branch, but not schedules."
|
||||
|
||||
job2:
|
||||
rules:
|
||||
- !reference [.default_rules, rules]
|
||||
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
|
||||
script:
|
||||
- echo "This job runs for the default branch, but not schedules."
|
||||
- echo "It also runs for merge requests."
|
||||
```
|
||||
|
||||
## Specify when jobs run with `only` and `except`
|
||||
|
||||
You can use [`only`](../yaml/index.md#only--except) and [`except`](../yaml/index.md#only--except)
|
||||
|
|
|
@ -1141,6 +1141,9 @@ The job is not added to the pipeline:
|
|||
- If no rules match.
|
||||
- If a rule matches and has `when: never`.
|
||||
|
||||
You can use [`!reference` tags](#reference-tags) to [reuse `rules` configuration](../jobs/job_control.md#reuse-rules-in-different-jobs)
|
||||
in different jobs.
|
||||
|
||||
#### `rules:if`
|
||||
|
||||
Use `rules:if` clauses to specify when to add a job to a pipeline:
|
||||
|
@ -4765,6 +4768,7 @@ into templates.
|
|||
### `!reference` tags
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/266173) in GitLab 13.9.
|
||||
> - `rules` keyword support [introduced in](https://gitlab.com/gitlab-org/gitlab/-/issues/322992) GitLab 14.3.
|
||||
|
||||
Use the `!reference` custom YAML tag to select keyword configuration from other job
|
||||
sections and reuse it in the current section. Unlike [YAML anchors](#anchors), you can
|
||||
|
|
|
@ -444,6 +444,10 @@ the system saves only the first 20 of them. Note that vulnerabilities in the [Pi
|
|||
Security](../../user/application_security/security_dashboard/#pipeline-security)
|
||||
tab do not enforce this limit and all identifiers present in the report artifact are displayed.
|
||||
|
||||
### Details
|
||||
|
||||
The `details` field is an object that supports many different content elements that are displayed when viewing vulnerability information. An example of the various data elements can be seen in the [security-reports repository](https://gitlab.com/gitlab-examples/security/security-reports/-/tree/master/samples/details-example).
|
||||
|
||||
### Location
|
||||
|
||||
The `location` indicates where the vulnerability has been detected.
|
||||
|
@ -454,10 +458,6 @@ which is used to track vulnerabilities
|
|||
as new commits are pushed to the repository.
|
||||
The attributes used to generate the location fingerprint also depend on the type of scanning.
|
||||
|
||||
### Details
|
||||
|
||||
The `details` field is an object that supports many different content elements that are displayed when viewing vulnerability information. An example of the various data elements can be seen in the [security-reports repository](https://gitlab.com/gitlab-examples/security/security-reports/-/tree/master/samples/details-example).
|
||||
|
||||
#### Dependency Scanning
|
||||
|
||||
The `location` of a Dependency Scanning vulnerability is composed of a `dependency` and a `file`.
|
||||
|
|
|
@ -337,6 +337,16 @@ For more details about which findings or vulnerabilities you can view in each of
|
|||
|
||||
## Troubleshooting
|
||||
|
||||
### Secure job failing with exit code 1
|
||||
|
||||
If a Secure job is failing and it's unclear why, add `SECURE_LOG_LEVEL: "debug"` as a global CI/CD variable for
|
||||
more verbose output that is helpful for troubleshooting.
|
||||
|
||||
```yaml
|
||||
variables:
|
||||
SECURE_LOG_LEVEL: "debug"
|
||||
```
|
||||
|
||||
### Outdated security reports
|
||||
|
||||
When a security report generated for a merge request becomes outdated, the merge request shows a warning
|
||||
|
|
|
@ -10,27 +10,27 @@ The Slack notifications service enables your GitLab project to send events
|
|||
(such as issue creation) to your existing Slack team as notifications. Setting up
|
||||
Slack notifications requires configuration changes for both Slack and GitLab.
|
||||
|
||||
You can also use Slack slash commands to control GitLab inside Slack. This is the
|
||||
separately configured [Slack slash commands](slack_slash_commands.md).
|
||||
You can also use [Slack slash commands](slack_slash_commands.md)
|
||||
to control GitLab from Slack. Slash commands are configured separately.
|
||||
|
||||
## Slack configuration
|
||||
## Configure Slack
|
||||
|
||||
1. Sign in to your Slack team and [start a new Incoming WebHooks configuration](https://my.slack.com/services/new/incoming-webhook).
|
||||
1. Identify the Slack channel where notifications should be sent to by default.
|
||||
Select **Add Incoming WebHooks integration** to add the configuration.
|
||||
1. Copy the **Webhook URL**, which is used later in the GitLab configuration.
|
||||
1. Copy the **Webhook URL** to use later when you configure GitLab.
|
||||
|
||||
## GitLab configuration
|
||||
## Configure GitLab
|
||||
|
||||
1. On the top bar, select **Menu > Projects** and find your project.
|
||||
1. On the left sidebar, select **Settings > Integrations**.
|
||||
1. Select the **Slack notifications** integration to configure it.
|
||||
1. Select **Slack notifications**.
|
||||
1. In the **Enable integration** section, select the **Active** checkbox.
|
||||
1. In the **Trigger** section, select the checkboxes for each type of GitLab
|
||||
event to send to Slack as a notification. For a full list, see
|
||||
[Triggers available for Slack notifications](#triggers-available-for-slack-notifications).
|
||||
[Triggers for Slack notifications](#triggers-for-slack-notifications).
|
||||
By default, messages are sent to the channel you configured during
|
||||
[Slack integration](#slack-configuration).
|
||||
[Slack configuration](#configure-slack).
|
||||
1. (Optional) To send messages to a different channel, multiple channels, or as
|
||||
a direct message:
|
||||
- *To send messages to channels,* enter the Slack channel names, separated by
|
||||
|
@ -40,38 +40,38 @@ separately configured [Slack slash commands](slack_slash_commands.md).
|
|||
NOTE:
|
||||
Usernames and private channels are not supported.
|
||||
|
||||
1. In **Webhook**, enter the webhook URL you copied from the previous
|
||||
[Slack integration](#slack-configuration) step.
|
||||
1. In **Webhook**, enter the webhook URL you copied in the
|
||||
[Slack configuration](#configure-slack) step.
|
||||
1. (Optional) In **Username**, enter the username of the Slack bot that sends
|
||||
the notifications.
|
||||
1. Select the **Notify only broken pipelines** checkbox to notify only on failures.
|
||||
1. In the **Branches to be notified** dropdown, select which types of branches
|
||||
to send notifications for.
|
||||
1. Leave the **Labels to be notified** field blank to get all notifications or
|
||||
add labels that the issue or merge request must have in order to trigger a
|
||||
1. Leave the **Labels to be notified** field blank to get all notifications, or
|
||||
add labels that the issue or merge request must have to trigger a
|
||||
notification.
|
||||
1. Select **Test settings** to verify your information, and then select
|
||||
**Save changes**.
|
||||
|
||||
Your Slack team now starts receiving GitLab event notifications as configured.
|
||||
|
||||
### Triggers available for Slack notifications
|
||||
## Triggers for Slack notifications
|
||||
|
||||
The following triggers are available for Slack notifications:
|
||||
|
||||
| Trigger | Description |
|
||||
|------------------------|-------------|
|
||||
| **Push** | Triggered by a push to the repository. |
|
||||
| **Issue** | Triggered when an issue is created, updated, or closed. |
|
||||
| **Confidential issue** | Triggered when a confidential issue is created, updated, or closed. |
|
||||
| **Merge request** | Triggered when a merge request is created, updated, or merged. |
|
||||
| **Note** | Triggered when someone adds a comment. |
|
||||
| **Confidential note** | Triggered when someone adds a confidential note. |
|
||||
| **Tag push** | Triggered when a new tag is pushed to the repository. |
|
||||
| **Pipeline** | Triggered when a pipeline status changes. |
|
||||
| **Wiki page** | Triggered when a wiki page is created or updated. |
|
||||
| **Deployment** | Triggered when a deployment starts or finishes. |
|
||||
| **Alert** | Triggered when a new, unique alert is recorded. |
|
||||
| Trigger name | Trigger event |
|
||||
|------------------------|------------------------------------------------------|
|
||||
| **Push** | A push to the repository. |
|
||||
| **Issue** | An issue is created, updated, or closed. |
|
||||
| **Confidential issue** | A confidential issue is created, updated, or closed. |
|
||||
| **Merge request** | A merge request is created, updated, or merged. |
|
||||
| **Note** | A comment is added. |
|
||||
| **Confidential note** | A confidential note is added. |
|
||||
| **Tag push** | A new tag is pushed to the repository. |
|
||||
| **Pipeline** | A pipeline status changed. |
|
||||
| **Wiki page** | A wiki page is created or updated. |
|
||||
| **Deployment** | A deployment starts or finishes. |
|
||||
| **Alert** | A new, unique alert is recorded. |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
|
@ -81,45 +81,48 @@ for errors relating to your Slack service.
|
|||
|
||||
### Something went wrong on our end
|
||||
|
||||
This is a generic error shown in the GitLab UI and does not mean much by itself.
|
||||
You might get this generic error message in the GitLab UI.
|
||||
Review [the logs](../../../administration/logs.md#productionlog) to find
|
||||
an error message and keep troubleshooting from there.
|
||||
the error message and keep troubleshooting from there.
|
||||
|
||||
### `certificate verify failed`
|
||||
|
||||
You may see an entry similar to the following in your Sidekiq log:
|
||||
You might see an entry like the following in your Sidekiq log:
|
||||
|
||||
```plaintext
|
||||
2019-01-10_13:22:08.42572 2019-01-10T13:22:08.425Z 6877 TID-abcdefg ProjectServiceWorker JID-3bade5fb3dd47a85db6d78c5 ERROR: {:class=>"ProjectServiceWorker", :service_class=>"SlackService", :message=>"SSL_connect returned=1 errno=0 state=error: certificate verify failed"}
|
||||
```
|
||||
|
||||
This is probably a problem either with GitLab communicating with Slack, or GitLab
|
||||
communicating with itself. The former is less likely, as Slack's security certificates
|
||||
should _hopefully_ always be trusted. We can establish which we're dealing with by using
|
||||
the below rails console script.
|
||||
This issue occurs when there is a problem with GitLab communicating with Slack,
|
||||
or GitLab communicating with itself.
|
||||
The former is less likely, as Slack security certificates should always be trusted.
|
||||
|
||||
```shell
|
||||
# start a rails console:
|
||||
sudo gitlab-rails console -e production
|
||||
To view which of these problems is the cause of the issue:
|
||||
|
||||
# or for source installs:
|
||||
bundle exec rails console -e production
|
||||
```
|
||||
1. Start a Rails console:
|
||||
|
||||
```ruby
|
||||
# run this in the Rails console
|
||||
# replace <SLACK URL> with your actual Slack URL
|
||||
result = Net::HTTP.get(URI('https://<SLACK URL>'));0
|
||||
```shell
|
||||
sudo gitlab-rails console -e production
|
||||
|
||||
# replace <GITLAB URL> with your actual GitLab URL
|
||||
result = Net::HTTP.get(URI('https://<GITLAB URL>'));0
|
||||
```
|
||||
# for source installs:
|
||||
bundle exec rails console -e production
|
||||
```
|
||||
|
||||
If GitLab is not trusting HTTPS connections to itself, then you may
|
||||
need to [add your certificate to the GitLab trusted certificates](https://docs.gitlab.com/omnibus/settings/ssl.html#install-custom-public-certificates).
|
||||
1. Run the following commands:
|
||||
|
||||
If GitLab is not trusting connections to Slack, then the GitLab
|
||||
OpenSSL trust store is incorrect. Some typical causes:
|
||||
```ruby
|
||||
# replace <SLACK URL> with your actual Slack URL
|
||||
result = Net::HTTP.get(URI('https://<SLACK URL>'));0
|
||||
|
||||
# replace <GITLAB URL> with your actual GitLab URL
|
||||
result = Net::HTTP.get(URI('https://<GITLAB URL>'));0
|
||||
```
|
||||
|
||||
If GitLab does not trust HTTPS connections to itself,
|
||||
[add your certificate to the GitLab trusted certificates](https://docs.gitlab.com/omnibus/settings/ssl.html#install-custom-public-certificates).
|
||||
|
||||
If GitLab does not trust connections to Slack,
|
||||
the GitLab OpenSSL trust store is incorrect. Typical causes are:
|
||||
|
||||
- Overriding the trust store with `gitlab_rails['env'] = {"SSL_CERT_FILE" => "/path/to/file.pem"}`.
|
||||
- Accidentally modifying the default CA bundle `/opt/gitlab/embedded/ssl/certs/cacert.pem`.
|
||||
|
|
|
@ -20,6 +20,10 @@ module API
|
|||
end
|
||||
|
||||
expose :same, as: :compare_same_ref
|
||||
|
||||
expose :web_url do |compare, _|
|
||||
Gitlab::UrlBuilder.build(compare)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -24,6 +24,8 @@ module Gitlab
|
|||
instance.project_job_url(object.project, object, **options)
|
||||
when Commit
|
||||
commit_url(object, **options)
|
||||
when Compare
|
||||
compare_url(object, **options)
|
||||
when Group
|
||||
instance.group_canonical_url(object, **options)
|
||||
when Issue
|
||||
|
@ -68,6 +70,12 @@ module Gitlab
|
|||
instance.commit_url(commit, **options)
|
||||
end
|
||||
|
||||
def compare_url(compare, **options)
|
||||
return '' unless compare.project
|
||||
|
||||
instance.project_compare_url(compare.project, **options.merge(compare.to_param))
|
||||
end
|
||||
|
||||
def note_url(note, **options)
|
||||
if note.for_commit?
|
||||
return '' unless note.project
|
||||
|
|
|
@ -168,7 +168,6 @@
|
|||
category: testing
|
||||
redis_slot: testing
|
||||
aggregation: weekly
|
||||
feature_flag: usage_data_i_testing_web_performance_widget_total
|
||||
- name: i_testing_group_code_coverage_project_click_total
|
||||
category: testing
|
||||
redis_slot: testing
|
||||
|
|
47
package.json
47
package.json
|
@ -66,34 +66,34 @@
|
|||
"@sentry/browser": "5.26.0",
|
||||
"@sourcegraph/code-host-integration": "0.0.59",
|
||||
"@tiptap/core": "^2.0.0-beta.86",
|
||||
"@tiptap/extension-blockquote": "^2.0.0-beta.14",
|
||||
"@tiptap/extension-bold": "^2.0.0-beta.14",
|
||||
"@tiptap/extension-bullet-list": "^2.0.0-beta.14",
|
||||
"@tiptap/extension-code": "^2.0.0-beta.14",
|
||||
"@tiptap/extension-blockquote": "^2.0.0-beta.15",
|
||||
"@tiptap/extension-bold": "^2.0.0-beta.15",
|
||||
"@tiptap/extension-bullet-list": "^2.0.0-beta.15",
|
||||
"@tiptap/extension-code": "^2.0.0-beta.16",
|
||||
"@tiptap/extension-code-block-lowlight": "2.0.0-beta.32",
|
||||
"@tiptap/extension-document": "^2.0.0-beta.12",
|
||||
"@tiptap/extension-dropcursor": "^2.0.0-beta.17",
|
||||
"@tiptap/extension-gapcursor": "^2.0.0-beta.18",
|
||||
"@tiptap/extension-document": "^2.0.0-beta.13",
|
||||
"@tiptap/extension-dropcursor": "^2.0.0-beta.18",
|
||||
"@tiptap/extension-gapcursor": "^2.0.0-beta.19",
|
||||
"@tiptap/extension-hard-break": "^2.0.0-beta.14",
|
||||
"@tiptap/extension-heading": "^2.0.0-beta.14",
|
||||
"@tiptap/extension-history": "^2.0.0-beta.14",
|
||||
"@tiptap/extension-horizontal-rule": "^2.0.0-beta.17",
|
||||
"@tiptap/extension-image": "^2.0.0-beta.14",
|
||||
"@tiptap/extension-italic": "^2.0.0-beta.14",
|
||||
"@tiptap/extension-link": "^2.0.0-beta.18",
|
||||
"@tiptap/extension-list-item": "^2.0.0-beta.13",
|
||||
"@tiptap/extension-ordered-list": "^2.0.0-beta.14",
|
||||
"@tiptap/extension-paragraph": "^2.0.0-beta.15",
|
||||
"@tiptap/extension-strike": "^2.0.0-beta.16",
|
||||
"@tiptap/extension-heading": "^2.0.0-beta.15",
|
||||
"@tiptap/extension-history": "^2.0.0-beta.16",
|
||||
"@tiptap/extension-horizontal-rule": "^2.0.0-beta.19",
|
||||
"@tiptap/extension-image": "^2.0.0-beta.15",
|
||||
"@tiptap/extension-italic": "^2.0.0-beta.15",
|
||||
"@tiptap/extension-link": "^2.0.0-beta.19",
|
||||
"@tiptap/extension-list-item": "^2.0.0-beta.14",
|
||||
"@tiptap/extension-ordered-list": "^2.0.0-beta.15",
|
||||
"@tiptap/extension-paragraph": "^2.0.0-beta.17",
|
||||
"@tiptap/extension-strike": "^2.0.0-beta.17",
|
||||
"@tiptap/extension-subscript": "^2.0.0-beta.4",
|
||||
"@tiptap/extension-superscript": "^2.0.0-beta.4",
|
||||
"@tiptap/extension-table": "^2.0.0-beta.25",
|
||||
"@tiptap/extension-table-cell": "^2.0.0-beta.13",
|
||||
"@tiptap/extension-table-header": "^2.0.0-beta.15",
|
||||
"@tiptap/extension-table-row": "^2.0.0-beta.13",
|
||||
"@tiptap/extension-table": "^2.0.0-beta.29",
|
||||
"@tiptap/extension-table-cell": "^2.0.0-beta.14",
|
||||
"@tiptap/extension-table-header": "^2.0.0-beta.16",
|
||||
"@tiptap/extension-table-row": "^2.0.0-beta.14",
|
||||
"@tiptap/extension-task-item": "^2.0.0-beta.17",
|
||||
"@tiptap/extension-task-list": "^2.0.0-beta.17",
|
||||
"@tiptap/extension-text": "^2.0.0-beta.12",
|
||||
"@tiptap/extension-text": "^2.0.0-beta.13",
|
||||
"@tiptap/vue-2": "^2.0.0-beta.39",
|
||||
"@toast-ui/editor": "^2.5.2",
|
||||
"@toast-ui/vue-editor": "^2.5.2",
|
||||
|
@ -150,7 +150,7 @@
|
|||
"lowlight": "^1.20.0",
|
||||
"marked": "^0.3.12",
|
||||
"mathjax": "3",
|
||||
"mermaid": "^8.10.2",
|
||||
"mermaid": "^8.11.5",
|
||||
"minimatch": "^3.0.4",
|
||||
"monaco-editor": "^0.25.2",
|
||||
"monaco-editor-webpack-plugin": "^4.0.0",
|
||||
|
@ -259,6 +259,7 @@
|
|||
"postcss": "^7.0.14",
|
||||
"prettier": "2.2.1",
|
||||
"prosemirror-schema-basic": "^1.1.2",
|
||||
"prosemirror-schema-list": "^1.1.5",
|
||||
"prosemirror-test-builder": "^1.0.4",
|
||||
"purgecss": "^4.0.3",
|
||||
"purgecss-from-html": "^4.0.3",
|
||||
|
|
22
spec/factories/compares.rb
Normal file
22
spec/factories/compares.rb
Normal file
|
@ -0,0 +1,22 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
FactoryBot.define do
|
||||
factory :compare do
|
||||
skip_create # No persistence
|
||||
|
||||
start_project { association(:project, :repository) }
|
||||
target_project { start_project }
|
||||
|
||||
start_ref { 'master' }
|
||||
target_ref { 'feature' }
|
||||
|
||||
base_sha { nil }
|
||||
straight { false }
|
||||
|
||||
initialize_with do
|
||||
CompareService
|
||||
.new(start_project, start_ref)
|
||||
.execute(target_project, target_ref, base_sha: base_sha, straight: straight)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -69,6 +69,27 @@ RSpec.describe Gitlab::UrlBuilder do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when passing a compare' do
|
||||
# NOTE: The Compare requires an actual repository, which isn't available
|
||||
# with the `build_stubbed` strategy used by the table tests above
|
||||
let_it_be(:compare) { create(:compare) }
|
||||
let_it_be(:project) { compare.project }
|
||||
|
||||
it 'returns the full URL' do
|
||||
expect(subject.build(compare)).to eq("#{Gitlab.config.gitlab.url}/#{project.full_path}/-/compare/#{compare.base_commit_sha}...#{compare.head_commit_sha}")
|
||||
end
|
||||
|
||||
it 'returns only the path if only_path is given' do
|
||||
expect(subject.build(compare, only_path: true)).to eq("/#{project.full_path}/-/compare/#{compare.base_commit_sha}...#{compare.head_commit_sha}")
|
||||
end
|
||||
|
||||
it 'returns an empty string for missing project' do
|
||||
expect(compare).to receive(:project).and_return(nil)
|
||||
|
||||
expect(subject.build(compare)).to eq('')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when passing a commit without a project' do
|
||||
let(:commit) { build_stubbed(:commit) }
|
||||
|
||||
|
|
33
spec/migrations/set_default_job_token_scope_true_spec.rb
Normal file
33
spec/migrations/set_default_job_token_scope_true_spec.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require_migration!
|
||||
|
||||
RSpec.describe SetDefaultJobTokenScopeTrue, schema: 20210819153805 do
|
||||
let(:ci_cd_settings) { table(:project_ci_cd_settings) }
|
||||
let(:namespaces) { table(:namespaces) }
|
||||
let(:projects) { table(:projects) }
|
||||
|
||||
let(:namespace) { namespaces.create!(name: 'test', path: 'path', type: 'Group') }
|
||||
let(:project) { projects.create!(namespace_id: namespace.id) }
|
||||
|
||||
describe '#up' do
|
||||
it 'sets the job_token_scope_enabled default to true' do
|
||||
described_class.new.up
|
||||
|
||||
settings = ci_cd_settings.create!(project_id: project.id)
|
||||
|
||||
expect(settings.job_token_scope_enabled).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
describe '#down' do
|
||||
it 'sets the job_token_scope_enabled default to false' do
|
||||
described_class.new.down
|
||||
|
||||
settings = ci_cd_settings.create!(project_id: project.id)
|
||||
|
||||
expect(settings.job_token_scope_enabled).to be_falsey
|
||||
end
|
||||
end
|
||||
end
|
|
@ -21,12 +21,6 @@ RSpec.describe ProjectCiCdSetting do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#job_token_scope_enabled' do
|
||||
it 'is false by default' do
|
||||
expect(described_class.new.job_token_scope_enabled).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
describe '#default_git_depth' do
|
||||
let(:default_value) { described_class::DEFAULT_GIT_DEPTH }
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ RSpec.describe API::GenericPackages do
|
|||
let_it_be(:project_deploy_token_wo) { create(:project_deploy_token, deploy_token: deploy_token_wo, project: project) }
|
||||
|
||||
let(:user) { personal_access_token.user }
|
||||
let(:ci_build) { create(:ci_build, :running, user: user) }
|
||||
let(:ci_build) { create(:ci_build, :running, user: user, project: project) }
|
||||
let(:snowplow_standard_context_params) { { user: user, project: project, namespace: project.namespace } }
|
||||
|
||||
def auth_header
|
||||
|
|
|
@ -11,7 +11,7 @@ RSpec.describe API::GoProxy do
|
|||
let_it_be(:base) { "#{Settings.build_gitlab_go_url}/#{project.full_path}" }
|
||||
|
||||
let_it_be(:oauth) { create :oauth_access_token, scopes: 'api', resource_owner: user }
|
||||
let_it_be(:job) { create :ci_build, user: user, status: :running }
|
||||
let_it_be(:job) { create :ci_build, user: user, status: :running, project: project }
|
||||
let_it_be(:pa_token) { create :personal_access_token, user: user }
|
||||
|
||||
let_it_be(:modules) do
|
||||
|
|
|
@ -15,7 +15,7 @@ RSpec.describe API::MavenPackages do
|
|||
let_it_be(:package_file) { package.package_files.with_file_name_like('%.xml').first }
|
||||
let_it_be(:jar_file) { package.package_files.with_file_name_like('%.jar').first }
|
||||
let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
|
||||
let_it_be(:job, reload: true) { create(:ci_build, user: user, status: :running) }
|
||||
let_it_be(:job, reload: true) { create(:ci_build, user: user, status: :running, project: project) }
|
||||
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
|
||||
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
|
||||
let_it_be(:deploy_token_for_group) { create(:deploy_token, :group, read_package_registry: true, write_package_registry: true) }
|
||||
|
|
|
@ -13,7 +13,7 @@ RSpec.describe API::PypiPackages do
|
|||
let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
|
||||
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
|
||||
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
|
||||
let_it_be(:job) { create(:ci_build, :running, user: user) }
|
||||
let_it_be(:job) { create(:ci_build, :running, user: user, project: project) }
|
||||
|
||||
let(:headers) { {} }
|
||||
|
||||
|
|
|
@ -839,7 +839,7 @@ RSpec.describe API::Releases do
|
|||
|
||||
context 'when a valid token is provided' do
|
||||
it 'creates the release for a running job' do
|
||||
job.update!(status: :running)
|
||||
job.update!(status: :running, project: project)
|
||||
post api("/projects/#{project.id}/releases"), params: params.merge(job_token: job.token)
|
||||
|
||||
expect(response).to have_gitlab_http_status(:created)
|
||||
|
|
|
@ -354,6 +354,7 @@ RSpec.describe API::Repositories do
|
|||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(json_response['commits']).to be_present
|
||||
expect(json_response['diffs']).to be_present
|
||||
expect(json_response['web_url']).to be_present
|
||||
end
|
||||
|
||||
it "compares branches with explicit merge-base mode" do
|
||||
|
@ -365,6 +366,7 @@ RSpec.describe API::Repositories do
|
|||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(json_response['commits']).to be_present
|
||||
expect(json_response['diffs']).to be_present
|
||||
expect(json_response['web_url']).to be_present
|
||||
end
|
||||
|
||||
it "compares branches with explicit straight mode" do
|
||||
|
@ -376,6 +378,7 @@ RSpec.describe API::Repositories do
|
|||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(json_response['commits']).to be_present
|
||||
expect(json_response['diffs']).to be_present
|
||||
expect(json_response['web_url']).to be_present
|
||||
end
|
||||
|
||||
it "compares tags" do
|
||||
|
@ -384,6 +387,7 @@ RSpec.describe API::Repositories do
|
|||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(json_response['commits']).to be_present
|
||||
expect(json_response['diffs']).to be_present
|
||||
expect(json_response['web_url']).to be_present
|
||||
end
|
||||
|
||||
it "compares commits" do
|
||||
|
@ -393,6 +397,7 @@ RSpec.describe API::Repositories do
|
|||
expect(json_response['commits']).to be_empty
|
||||
expect(json_response['diffs']).to be_empty
|
||||
expect(json_response['compare_same_ref']).to be_falsey
|
||||
expect(json_response['web_url']).to be_present
|
||||
end
|
||||
|
||||
it "compares commits in reverse order" do
|
||||
|
@ -401,6 +406,7 @@ RSpec.describe API::Repositories do
|
|||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(json_response['commits']).to be_present
|
||||
expect(json_response['diffs']).to be_present
|
||||
expect(json_response['web_url']).to be_present
|
||||
end
|
||||
|
||||
it "compare commits between different projects with non-forked relation" do
|
||||
|
|
|
@ -10,7 +10,7 @@ RSpec.describe API::RubygemPackages do
|
|||
let_it_be_with_reload(:project) { create(:project) }
|
||||
let_it_be(:personal_access_token) { create(:personal_access_token) }
|
||||
let_it_be(:user) { personal_access_token.user }
|
||||
let_it_be(:job) { create(:ci_build, :running, user: user) }
|
||||
let_it_be(:job) { create(:ci_build, :running, user: user, project: project) }
|
||||
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
|
||||
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
|
||||
let_it_be(:headers) { {} }
|
||||
|
|
|
@ -12,7 +12,7 @@ RSpec.describe API::Terraform::Modules::V1::Packages do
|
|||
let_it_be(:package) { create(:terraform_module_package, project: project) }
|
||||
let_it_be(:personal_access_token) { create(:personal_access_token) }
|
||||
let_it_be(:user) { personal_access_token.user }
|
||||
let_it_be(:job) { create(:ci_build, :running, user: user) }
|
||||
let_it_be(:job) { create(:ci_build, :running, user: user, project: project) }
|
||||
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
|
||||
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
|
||||
|
||||
|
|
|
@ -882,6 +882,10 @@ RSpec.describe 'Git HTTP requests' do
|
|||
before do
|
||||
build.update!(user: user)
|
||||
project.add_reporter(user)
|
||||
create(:ci_job_token_project_scope_link,
|
||||
source_project: project,
|
||||
target_project: other_project,
|
||||
added_by: user)
|
||||
end
|
||||
|
||||
shared_examples 'can download code only' do
|
||||
|
@ -1447,6 +1451,10 @@ RSpec.describe 'Git HTTP requests' do
|
|||
|
||||
before do
|
||||
build.update!(project: project) # can't associate it on factory create
|
||||
create(:ci_job_token_project_scope_link,
|
||||
source_project: project,
|
||||
target_project: other_project,
|
||||
added_by: user)
|
||||
end
|
||||
|
||||
context 'when build created by system is authenticated' do
|
||||
|
|
|
@ -12,7 +12,7 @@ RSpec.describe Ci::ExternalPullRequests::CreatePipelineService do
|
|||
project.add_maintainer(user)
|
||||
end
|
||||
|
||||
subject(:response) { described_class.new(project, user).execute(pull_request) }
|
||||
subject(:execute) { described_class.new(project, user).execute(pull_request) }
|
||||
|
||||
context 'when pull request is open' do
|
||||
before do
|
||||
|
@ -21,26 +21,43 @@ RSpec.describe Ci::ExternalPullRequests::CreatePipelineService do
|
|||
|
||||
context 'when source sha is the head of the source branch' do
|
||||
let(:source_branch) { project.repository.branches.last }
|
||||
let(:create_pipeline_service) { instance_double(Ci::CreatePipelineService) }
|
||||
|
||||
before do
|
||||
pull_request.update!(source_branch: source_branch.name, source_sha: source_branch.target)
|
||||
end
|
||||
|
||||
it 'creates a pipeline for external pull request', :aggregate_failures do
|
||||
pipeline = response.payload
|
||||
context 'when the FF ci_create_external_pr_pipeline_async is disabled' do
|
||||
before do
|
||||
stub_feature_flags(ci_create_external_pr_pipeline_async: false)
|
||||
end
|
||||
|
||||
expect(response).to be_success
|
||||
expect(pipeline).to be_valid
|
||||
expect(pipeline).to be_persisted
|
||||
expect(pipeline).to be_external_pull_request_event
|
||||
expect(pipeline).to eq(project.ci_pipelines.last)
|
||||
expect(pipeline.external_pull_request).to eq(pull_request)
|
||||
expect(pipeline.user).to eq(user)
|
||||
expect(pipeline.status).to eq('created')
|
||||
expect(pipeline.ref).to eq(pull_request.source_branch)
|
||||
expect(pipeline.sha).to eq(pull_request.source_sha)
|
||||
expect(pipeline.source_sha).to eq(pull_request.source_sha)
|
||||
it 'creates a pipeline for external pull request', :aggregate_failures do
|
||||
pipeline = execute.payload
|
||||
|
||||
expect(execute).to be_success
|
||||
expect(pipeline).to be_valid
|
||||
expect(pipeline).to be_persisted
|
||||
expect(pipeline).to be_external_pull_request_event
|
||||
expect(pipeline).to eq(project.ci_pipelines.last)
|
||||
expect(pipeline.external_pull_request).to eq(pull_request)
|
||||
expect(pipeline.user).to eq(user)
|
||||
expect(pipeline.status).to eq('created')
|
||||
expect(pipeline.ref).to eq(pull_request.source_branch)
|
||||
expect(pipeline.sha).to eq(pull_request.source_sha)
|
||||
expect(pipeline.source_sha).to eq(pull_request.source_sha)
|
||||
end
|
||||
end
|
||||
|
||||
it 'enqueues Ci::ExternalPullRequests::CreatePipelineWorker' do
|
||||
expect { execute }
|
||||
.to change { ::Ci::ExternalPullRequests::CreatePipelineWorker.jobs.count }
|
||||
.by(1)
|
||||
|
||||
args = ::Ci::ExternalPullRequests::CreatePipelineWorker.jobs.last['args']
|
||||
|
||||
expect(args[0]).to eq(project.id)
|
||||
expect(args[1]).to eq(user.id)
|
||||
expect(args[2]).to eq(pull_request.id)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -53,11 +70,12 @@ RSpec.describe Ci::ExternalPullRequests::CreatePipelineService do
|
|||
end
|
||||
|
||||
it 'does nothing', :aggregate_failures do
|
||||
expect(Ci::CreatePipelineService).not_to receive(:new)
|
||||
expect { execute }
|
||||
.not_to change { ::Ci::ExternalPullRequests::CreatePipelineWorker.jobs.count }
|
||||
|
||||
expect(response).to be_error
|
||||
expect(response.message).to eq('The source sha is not the head of the source branch')
|
||||
expect(response.payload).to be_nil
|
||||
expect(execute).to be_error
|
||||
expect(execute.message).to eq('The source sha is not the head of the source branch')
|
||||
expect(execute.payload).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -68,11 +86,12 @@ RSpec.describe Ci::ExternalPullRequests::CreatePipelineService do
|
|||
end
|
||||
|
||||
it 'does nothing', :aggregate_failures do
|
||||
expect(Ci::CreatePipelineService).not_to receive(:new)
|
||||
expect { execute }
|
||||
.not_to change { ::Ci::ExternalPullRequests::CreatePipelineWorker.jobs.count }
|
||||
|
||||
expect(response).to be_error
|
||||
expect(response.message).to eq('The pull request is not opened')
|
||||
expect(response.payload).to be_nil
|
||||
expect(execute).to be_error
|
||||
expect(execute.message).to eq('The pull request is not opened')
|
||||
expect(execute.payload).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,7 +11,7 @@ RSpec.shared_context 'npm api setup' do
|
|||
let_it_be(:package, reload: true) { create(:npm_package, project: project, name: "@#{group.path}/scoped_package") }
|
||||
let_it_be(:token) { create(:oauth_access_token, scopes: 'api', resource_owner: user) }
|
||||
let_it_be(:personal_access_token) { create(:personal_access_token, user: user) }
|
||||
let_it_be(:job, reload: true) { create(:ci_build, user: user, status: :running) }
|
||||
let_it_be(:job, reload: true) { create(:ci_build, user: user, status: :running, project: project) }
|
||||
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
|
||||
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
|
||||
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Ci::ExternalPullRequests::CreatePipelineWorker do
|
||||
let_it_be(:project) { create(:project, :auto_devops, :repository) }
|
||||
let_it_be(:user) { project.owner }
|
||||
let_it_be(:external_pull_request) do
|
||||
branch = project.repository.branches.last
|
||||
create(:external_pull_request, project: project, source_branch: branch.name, source_sha: branch.target)
|
||||
end
|
||||
|
||||
let(:worker) { described_class.new }
|
||||
|
||||
describe '#perform' do
|
||||
let(:project_id) { project.id }
|
||||
let(:user_id) { user.id }
|
||||
let(:external_pull_request_id) { external_pull_request.id }
|
||||
|
||||
subject(:perform) { worker.perform(project_id, user_id, external_pull_request_id) }
|
||||
|
||||
it 'creates the pipeline' do
|
||||
pipeline = perform.payload
|
||||
|
||||
expect(pipeline).to be_valid
|
||||
expect(pipeline).to be_persisted
|
||||
expect(pipeline).to be_external_pull_request_event
|
||||
expect(pipeline.project).to eq(project)
|
||||
expect(pipeline.user).to eq(user)
|
||||
expect(pipeline.external_pull_request).to eq(external_pull_request)
|
||||
expect(pipeline.status).to eq('created')
|
||||
expect(pipeline.ref).to eq(external_pull_request.source_branch)
|
||||
expect(pipeline.sha).to eq(external_pull_request.source_sha)
|
||||
expect(pipeline.source_sha).to eq(external_pull_request.source_sha)
|
||||
expect(pipeline.target_sha).to eq(external_pull_request.target_sha)
|
||||
end
|
||||
|
||||
shared_examples_for 'not calling service' do
|
||||
it 'does not call the service' do
|
||||
expect(Ci::CreatePipelineService).not_to receive(:new)
|
||||
perform
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the project not found' do
|
||||
let(:project_id) { non_existing_record_id }
|
||||
|
||||
it_behaves_like 'not calling service'
|
||||
end
|
||||
|
||||
context 'when the user not found' do
|
||||
let(:user_id) { non_existing_record_id }
|
||||
|
||||
it_behaves_like 'not calling service'
|
||||
end
|
||||
|
||||
context 'when the pull request not found' do
|
||||
let(:external_pull_request_id) { non_existing_record_id }
|
||||
|
||||
it_behaves_like 'not calling service'
|
||||
end
|
||||
|
||||
context 'when the pull request does not belong to the project' do
|
||||
let(:external_pull_request_id) { create(:external_pull_request).id }
|
||||
|
||||
it_behaves_like 'not calling service'
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue