Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
25db9c1230
commit
0a5ea888dc
|
@ -1 +1 @@
|
|||
c67f1a2bb56d8fa3403b529fd3bf36dba3a6488c
|
||||
07aa359a7724540bbfa4868407b9a2c9b45bf139
|
||||
|
|
|
@ -7,7 +7,6 @@ import toast from '~/vue_shared/plugins/global_toast';
|
|||
|
||||
import { deprecatedCreateFlash as Flash } from '../flash';
|
||||
|
||||
import BlobCiSyntaxYamlSelector from './template_selectors/ci_syntax_yaml_selector';
|
||||
import BlobCiYamlSelector from './template_selectors/ci_yaml_selector';
|
||||
import DockerfileSelector from './template_selectors/dockerfile_selector';
|
||||
import GitignoreSelector from './template_selectors/gitignore_selector';
|
||||
|
@ -34,7 +33,6 @@ export default class FileTemplateMediator {
|
|||
this.templateSelectors = [
|
||||
GitignoreSelector,
|
||||
BlobCiYamlSelector,
|
||||
BlobCiSyntaxYamlSelector,
|
||||
MetricsDashboardSelector,
|
||||
DockerfileSelector,
|
||||
LicenseSelector,
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
|
||||
import FileTemplateSelector from '../file_template_selector';
|
||||
|
||||
export default class BlobCiSyntaxYamlSelector extends FileTemplateSelector {
|
||||
constructor({ mediator }) {
|
||||
super(mediator);
|
||||
this.config = {
|
||||
key: 'gitlab-ci-yaml',
|
||||
name: '.gitlab-ci.yml',
|
||||
pattern: /(.gitlab-ci.yml)/,
|
||||
type: 'gitlab_ci_syntax_ymls',
|
||||
dropdown: '.js-gitlab-ci-syntax-yml-selector',
|
||||
wrapper: '.js-gitlab-ci-syntax-yml-selector-wrap',
|
||||
};
|
||||
}
|
||||
|
||||
initDropdown() {
|
||||
initDeprecatedJQueryDropdown(this.$dropdown, {
|
||||
data: this.$dropdown.data('data'),
|
||||
filterable: true,
|
||||
selectable: true,
|
||||
search: {
|
||||
fields: ['name'],
|
||||
},
|
||||
clicked: (options) => this.reportSelectionName(options),
|
||||
text: (item) => item.name,
|
||||
});
|
||||
}
|
||||
}
|
|
@ -134,7 +134,6 @@ export default {
|
|||
<ci-lint v-else :is-valid="isValid" :ci-config="ciConfigData" />
|
||||
</editor-tab>
|
||||
<editor-tab
|
||||
v-if="glFeatures.ciConfigMergedTab"
|
||||
class="gl-mb-3"
|
||||
:empty-message="$options.i18n.empty.merge"
|
||||
:keep-component-mounted="false"
|
||||
|
|
|
@ -62,6 +62,7 @@ const projectSelect = () => {
|
|||
with_shared: this.withShared,
|
||||
include_subgroups: this.includeProjectsInSubgroups,
|
||||
order_by: 'similarity',
|
||||
simple: true,
|
||||
},
|
||||
projectsCallback,
|
||||
);
|
||||
|
|
|
@ -164,7 +164,6 @@
|
|||
.license-selector,
|
||||
.gitignore-selector,
|
||||
.gitlab-ci-yml-selector,
|
||||
.gitlab-ci-syntax-yml-selector,
|
||||
.dockerfile-selector,
|
||||
.template-type-selector,
|
||||
.metrics-dashboard-selector {
|
||||
|
|
|
@ -31,7 +31,6 @@ class Projects::BlobController < Projects::ApplicationController
|
|||
before_action :editor_variables, except: [:show, :preview, :diff]
|
||||
before_action :validate_diff_params, only: :diff
|
||||
before_action :set_last_commit_sha, only: [:edit, :update]
|
||||
before_action :record_experiment, only: :new
|
||||
|
||||
track_redis_hll_event :create, :update, name: 'g_edit_by_sfe'
|
||||
|
||||
|
@ -261,10 +260,4 @@ class Projects::BlobController < Projects::ApplicationController
|
|||
def visitor_id
|
||||
current_user&.id
|
||||
end
|
||||
|
||||
def record_experiment
|
||||
return unless params[:file_name] == @project.ci_config_path_or_default && @project.namespace.recent?
|
||||
|
||||
record_experiment_user(:ci_syntax_templates_b, namespace_id: @project.namespace_id)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
class Projects::Ci::PipelineEditorController < Projects::ApplicationController
|
||||
before_action :check_can_collaborate!
|
||||
before_action do
|
||||
push_frontend_feature_flag(:ci_config_merged_tab, @project, default_enabled: :yaml)
|
||||
push_frontend_feature_flag(:pipeline_editor_empty_state_action, @project, default_enabled: :yaml)
|
||||
push_frontend_feature_flag(:pipeline_editor_branch_switcher, @project, default_enabled: :yaml)
|
||||
push_frontend_feature_flag(:pipeline_editor_drawer, @project, default_enabled: :yaml)
|
||||
|
|
|
@ -7,7 +7,6 @@ class TemplateFinder
|
|||
dockerfiles: ::Gitlab::Template::DockerfileTemplate,
|
||||
gitignores: ::Gitlab::Template::GitignoreTemplate,
|
||||
gitlab_ci_ymls: ::Gitlab::Template::GitlabCiYmlTemplate,
|
||||
gitlab_ci_syntax_ymls: ::Gitlab::Template::GitlabCiSyntaxYmlTemplate,
|
||||
metrics_dashboard_ymls: ::Gitlab::Template::MetricsDashboardTemplate,
|
||||
issues: ::Gitlab::Template::IssueTemplate,
|
||||
merge_requests: ::Gitlab::Template::MergeRequestTemplate
|
||||
|
|
|
@ -206,10 +206,6 @@ module BlobHelper
|
|||
@gitlab_ci_ymls ||= TemplateFinder.all_template_names(project, :gitlab_ci_ymls)
|
||||
end
|
||||
|
||||
def gitlab_ci_syntax_ymls(project)
|
||||
@gitlab_ci_syntax_ymls ||= TemplateFinder.all_template_names(project, :gitlab_ci_syntax_ymls)
|
||||
end
|
||||
|
||||
def metrics_dashboard_ymls(project)
|
||||
@metrics_dashboard_ymls ||= TemplateFinder.all_template_names(project, :metrics_dashboard_ymls)
|
||||
end
|
||||
|
|
|
@ -85,7 +85,6 @@ module Ci
|
|||
|
||||
if pipeline.persisted?
|
||||
schedule_head_pipeline_update
|
||||
record_conversion_event
|
||||
create_namespace_onboarding_action
|
||||
end
|
||||
|
||||
|
@ -123,12 +122,6 @@ module Ci
|
|||
end
|
||||
end
|
||||
|
||||
def record_conversion_event
|
||||
return unless project.namespace.recent?
|
||||
|
||||
Experiments::RecordConversionEventWorker.perform_async(:ci_syntax_templates_b, current_user.id)
|
||||
end
|
||||
|
||||
def create_namespace_onboarding_action
|
||||
Namespaces::OnboardingPipelineCreatedWorker.perform_async(project.namespace_id)
|
||||
end
|
||||
|
|
|
@ -253,17 +253,23 @@ module Ci
|
|||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
def builds_for_shared_runner
|
||||
new_builds.
|
||||
relation = new_builds.
|
||||
# don't run projects which have not enabled shared runners and builds
|
||||
joins(:project).where(projects: { shared_runners_enabled: true, pending_delete: false })
|
||||
.joins('LEFT JOIN project_features ON ci_builds.project_id = project_features.project_id')
|
||||
.where('project_features.builds_access_level IS NULL or project_features.builds_access_level > 0').
|
||||
.where('project_features.builds_access_level IS NULL or project_features.builds_access_level > 0')
|
||||
|
||||
# Implement fair scheduling
|
||||
# this returns builds that are ordered by number of running builds
|
||||
# we prefer projects that don't use shared runners at all
|
||||
joins("LEFT JOIN (#{running_builds_for_shared_runners.to_sql}) AS project_builds ON ci_builds.project_id=project_builds.project_id")
|
||||
.order(Arel.sql('COALESCE(project_builds.running_builds, 0) ASC'), 'ci_builds.id ASC')
|
||||
if Feature.enabled?(:ci_queueing_disaster_recovery, runner, type: :ops, default_enabled: :yaml)
|
||||
# if disaster recovery is enabled, we fallback to FIFO scheduling
|
||||
relation.order('ci_builds.id ASC')
|
||||
else
|
||||
# Implement fair scheduling
|
||||
# this returns builds that are ordered by number of running builds
|
||||
# we prefer projects that don't use shared runners at all
|
||||
relation
|
||||
.joins("LEFT JOIN (#{running_builds_for_shared_runners.to_sql}) AS project_builds ON ci_builds.project_id=project_builds.project_id")
|
||||
.order(Arel.sql('COALESCE(project_builds.running_builds, 0) ASC'), 'ci_builds.id ASC')
|
||||
end
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
|
||||
|
|
|
@ -11,8 +11,5 @@
|
|||
= dropdown_tag(_("Apply a template"), options: { toggle_class: 'js-metrics-dashboard-selector qa-metrics-dashboard-dropdown', dropdown_class: 'dropdown-menu-selectable', filter: true, placeholder: "Filter", data: { data: metrics_dashboard_ymls(@project) } } )
|
||||
#gitlab-ci-yml-selector.gitlab-ci-yml-selector.js-gitlab-ci-yml-selector-wrap.js-template-selector-wrap.hidden
|
||||
= dropdown_tag(_("Apply a template"), options: { toggle_class: 'js-gitlab-ci-yml-selector qa-gitlab-ci-yml-dropdown', dropdown_class: 'dropdown-menu-selectable', filter: true, placeholder: "Filter", data: { data: gitlab_ci_ymls(@project), selected: params[:template] } } )
|
||||
- if experiment_enabled?(:ci_syntax_templates_b, subject: current_user) && @project.namespace.recent?
|
||||
.gitlab-ci-syntax-yml-selector.js-gitlab-ci-syntax-yml-selector-wrap.js-template-selector-wrap.hidden
|
||||
= dropdown_tag(_("Learn CI/CD syntax"), options: { toggle_class: 'js-gitlab-ci-syntax-yml-selector qa-gitlab-ci-syntax-yml-dropdown', dropdown_class: 'dropdown-menu-selectable', filter: true, placeholder: "Filter", data: { data: gitlab_ci_syntax_ymls(@project) } } )
|
||||
.dockerfile-selector.js-dockerfile-selector-wrap.js-template-selector-wrap.hidden
|
||||
= dropdown_tag(_("Apply a template"), options: { toggle_class: 'js-dockerfile-selector qa-dockerfile-dropdown', dropdown_class: 'dropdown-menu-selectable', filter: true, placeholder: "Filter", data: { data: dockerfile_names(@project) } } )
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Removed feature flag for Pipeline editor merged YAML tab
|
||||
merge_request: 60659
|
||||
author:
|
||||
type: other
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Remove invalidated CI Syntax Templates Experiment
|
||||
merge_request: 60937
|
||||
author:
|
||||
type: other
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Adds access token endpoints to OpenAPI
|
||||
merge_request: 58620
|
||||
author: jimcser
|
||||
type: added
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Increase load time of project select dropdowns
|
||||
merge_request: 61117
|
||||
author:
|
||||
type: performance
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: ci_config_merged_tab
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53299
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/301103
|
||||
milestone: '13.9'
|
||||
type: development
|
||||
group: group::pipeline authoring
|
||||
default_enabled: true
|
|
@ -1,8 +0,0 @@
|
|||
---
|
||||
name: ci_syntax_templates_b_experiment_percentage
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/53479
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/300993
|
||||
milestone: "13.9"
|
||||
type: experiment
|
||||
group: group::activation
|
||||
default_enabled: false
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: ci_queueing_disaster_recovery
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56658
|
||||
rollout_issue_url:
|
||||
milestone: "13.12"
|
||||
type: ops
|
||||
group: group::continuous integration
|
||||
default_enabled: false
|
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
stage: Enablement
|
||||
group: Distribution
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||
type: reference
|
||||
---
|
||||
|
||||
# Disaster Recovery
|
||||
|
||||
This document describes a feature that allows to easily disable some important but computationally
|
||||
expensive parts of the application, in order to relieve stress on the database in an ongoing downtime.
|
||||
|
||||
## `ci_queueing_disaster_recovery`
|
||||
|
||||
This feature flag, if enabled temporarily disables fair scheduling on shared runners.
|
||||
This can help reduce system resource usage on the `jobs/request` endpoint
|
||||
by significantly reducing computations being performed.
|
||||
|
||||
Side effects:
|
||||
|
||||
- In case of a large backlog of jobs, the jobs will be processed in the order
|
||||
they were put in the system instead of balancing the jobs across many projects
|
||||
- Projects which are out of quota will be run. This affects
|
||||
only jobs that were created during the last hour, as prior jobs are canceled
|
||||
by a periodic background worker (`StuckCiJobsWorker`).
|
|
@ -4,6 +4,8 @@ tags:
|
|||
description: Version
|
||||
- name: access_requests
|
||||
description: Access requests for projects and groups
|
||||
- name: access_tokens
|
||||
description: Access tokens for projects
|
||||
info:
|
||||
description: |
|
||||
An OpenAPI definition for the GitLab REST API.
|
||||
|
@ -16,7 +18,8 @@ info:
|
|||
The feature uses the current [GitLab session cookie](https://docs.gitlab.com/ee/api/README.html#session-cookie),
|
||||
so each request is made using your account.
|
||||
|
||||
Read more at <https://docs.gitlab.com/ee/development/documentation/restful_api_styleguide.html>.
|
||||
Instructions for using this tool can be found in [Interactive API Documentation](openapi_interactive.md).
|
||||
|
||||
version: v4
|
||||
title: GitLab API
|
||||
termsOfService: 'https://about.gitlab.com/terms/'
|
||||
|
@ -57,6 +60,12 @@ paths:
|
|||
/v4/groups/{id}/access_requests/{user_id}/approve:
|
||||
$ref: 'v4/access_requests.yaml#/accessRequestsGroupsApprove'
|
||||
|
||||
/v4/groupss/{id}/access_requests/{user_id}:
|
||||
/v4/groups/{id}/access_requests/{user_id}:
|
||||
$ref: 'v4/access_requests.yaml#/accessRequestsGroupsDeny'
|
||||
|
||||
# ACCESS REQUESTS (PROJECTS)
|
||||
/v4/projects/{id}/access_tokens:
|
||||
$ref: 'v4/access_tokens.yaml#/accessTokens'
|
||||
|
||||
/v4/projects/{id}/access_tokens/{token_id}:
|
||||
$ref: 'v4/access_tokens.yaml#/accessTokensRevoke'
|
|
@ -0,0 +1,170 @@
|
|||
# Markdown documentation: https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/api/resource_access_tokens.md
|
||||
|
||||
#/v4/projects/{id}/access_tokens
|
||||
accessTokens:
|
||||
get:
|
||||
description: Lists access tokens for a project
|
||||
summary: List access tokens for a project
|
||||
operationId: accessTokens_get
|
||||
tags:
|
||||
- access_tokens
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
description: The ID or URL-encoded path of the project
|
||||
required: true
|
||||
schema:
|
||||
oneOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
responses:
|
||||
'404':
|
||||
description: Not Found
|
||||
'401':
|
||||
description: Unauthorized operation
|
||||
'200':
|
||||
description: Successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
title: AccessTokenList
|
||||
type: object
|
||||
properties:
|
||||
user_id:
|
||||
type: integer
|
||||
scopes:
|
||||
type: array
|
||||
name:
|
||||
type: string
|
||||
expires_at:
|
||||
type: date
|
||||
id:
|
||||
type: integer
|
||||
active:
|
||||
type: boolean
|
||||
created_at:
|
||||
type: date
|
||||
revoked:
|
||||
type: boolean
|
||||
example:
|
||||
"user_id": 141
|
||||
"scopes" : ["api"]
|
||||
"name": "token"
|
||||
"expires_at": "2022-01-31"
|
||||
"id": 42
|
||||
"active": true
|
||||
"created_at": "2021-01-20T14:13:35Z"
|
||||
"revoked" : false
|
||||
post:
|
||||
description: Creates an access token for a project
|
||||
summary: Creates an access token for a project
|
||||
operationId: accessTokens_post
|
||||
tags:
|
||||
- access_tokens
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
description: The ID or URL-encoded path of the project
|
||||
required: true
|
||||
schema:
|
||||
oneOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
- name: name
|
||||
in: query
|
||||
description: The name of the project access token
|
||||
required: true
|
||||
schema:
|
||||
type: string
|
||||
- name: scopes
|
||||
in: query
|
||||
description: Defines read and write permissions for the token
|
||||
required: true
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
enum: ["api", "read_api", "read_registry", "write_registry", "read_repository", "write_repository"]
|
||||
- name: expires_at
|
||||
in: query
|
||||
description: Date when the token expires. Time of day is Midnight UTC of that date.
|
||||
required: false
|
||||
schema:
|
||||
type: date
|
||||
responses:
|
||||
'404':
|
||||
description: Not Found
|
||||
'401':
|
||||
description: Unauthorized operation
|
||||
'200':
|
||||
description: Successful operation
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
title: AccessTokenList
|
||||
type: object
|
||||
properties:
|
||||
user_id:
|
||||
type: integer
|
||||
scopes:
|
||||
type: array
|
||||
name:
|
||||
type: string
|
||||
expires_at:
|
||||
type: date
|
||||
id:
|
||||
type: integer
|
||||
active:
|
||||
type: boolean
|
||||
created_at:
|
||||
type: date
|
||||
revoked:
|
||||
type: boolean
|
||||
token:
|
||||
type: string
|
||||
example:
|
||||
"user_id": 166
|
||||
"scopes" : [
|
||||
"api",
|
||||
"read_repository"
|
||||
]
|
||||
"name": "test"
|
||||
"expires_at": "2022-01-31"
|
||||
"id": 58
|
||||
"active": true
|
||||
"created_at": "2021-01-20T14:13:35Z"
|
||||
"revoked" : false
|
||||
"token" : "D4y...Wzr"
|
||||
|
||||
#/v4/projects/{id}/access_tokens/{token_id}
|
||||
accessTokensRevoke:
|
||||
delete:
|
||||
description: Revokes an access token
|
||||
summary: Revokes an access token
|
||||
operationId: accessTokens_delete
|
||||
tags:
|
||||
- access_tokens
|
||||
parameters:
|
||||
- name: id
|
||||
in: path
|
||||
description: The ID or URL-encoded path of the project
|
||||
required: true
|
||||
schema:
|
||||
oneOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
- name: token_id
|
||||
in: path
|
||||
description: The ID of the project access token
|
||||
required: true
|
||||
schema:
|
||||
oneOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
responses:
|
||||
'400':
|
||||
description: Bad Request
|
||||
'404':
|
||||
description: Not Found
|
||||
'204':
|
||||
description: No content if successfully revoked
|
|
@ -55,6 +55,7 @@ POST projects/:id/access_tokens
|
|||
|
||||
| Attribute | Type | required | Description |
|
||||
|-----------|---------|----------|---------------------|
|
||||
| `id` | integer/string | yes | The ID of the project |
|
||||
| `name` | String | yes | The name of the project access token |
|
||||
| `scopes` | Array\[String] | yes | [List of scopes](../user/project/settings/project_access_tokens.md#limiting-scopes-of-a-project-access-token) |
|
||||
| `expires_at` | Date | no | The token expires at midnight UTC on that date |
|
||||
|
|
|
@ -73,8 +73,7 @@ each job depends only on the previous stage being completed successfully.
|
|||
## View expanded configuration
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/246801) in GitLab 13.9.
|
||||
> - It is [deployed behind a feature flag](../../user/feature_flags.md), enabled by default.
|
||||
> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-expanded-configuration). **(FREE SELF)**
|
||||
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/301103) in GitLab 13.12.
|
||||
|
||||
To view the fully expanded CI/CD configuration as one combined file, go to the
|
||||
pipeline editor's **View merged YAML** tab. This tab displays an expanded configuration
|
||||
|
@ -85,25 +84,6 @@ where:
|
|||
[extended configuration merged into the job](../yaml/README.md#merge-details).
|
||||
- YAML anchors are [replaced with the linked configuration](../yaml/README.md#anchors).
|
||||
|
||||
### Enable or disable expanded configuration **(FREE SELF)**
|
||||
|
||||
Expanded CI/CD configuration is under development and not ready for production use.
|
||||
It is deployed behind a feature flag that is **enabled by default**.
|
||||
[GitLab administrators with access to the GitLab Rails console](../../administration/feature_flags.md)
|
||||
can opt to enable it.
|
||||
|
||||
To disable it:
|
||||
|
||||
```ruby
|
||||
Feature.disable(:ci_config_merged_tab)
|
||||
```
|
||||
|
||||
To enable it:
|
||||
|
||||
```ruby
|
||||
Feature.enable(:ci_config_merged_tab)
|
||||
```
|
||||
|
||||
## Commit changes to CI configuration
|
||||
|
||||
The commit form appears at the bottom of each tab in the editor so you can commit
|
||||
|
|
|
@ -4,7 +4,7 @@ module API
|
|||
class ProjectTemplates < ::API::Base
|
||||
include PaginationParams
|
||||
|
||||
TEMPLATE_TYPES = %w[dockerfiles gitignores gitlab_ci_ymls gitlab_ci_syntax_ymls licenses metrics_dashboard_ymls issues merge_requests].freeze
|
||||
TEMPLATE_TYPES = %w[dockerfiles gitignores gitlab_ci_ymls licenses metrics_dashboard_ymls issues merge_requests].freeze
|
||||
# The regex is needed to ensure a period (e.g. agpl-3.0)
|
||||
# isn't confused with a format type. We also need to allow encoded
|
||||
# values (e.g. C%2B%2B for C++), so allow % and + as well.
|
||||
|
@ -16,7 +16,7 @@ module API
|
|||
|
||||
params do
|
||||
requires :id, type: String, desc: 'The ID of a project'
|
||||
requires :type, type: String, values: TEMPLATE_TYPES, desc: 'The type (dockerfiles|gitignores|gitlab_ci_ymls|gitlab_ci_syntax_ymls|licenses|metrics_dashboard_ymls|issues|merge_requests) of the template'
|
||||
requires :type, type: String, values: TEMPLATE_TYPES, desc: 'The type (dockerfiles|gitignores|gitlab_ci_ymls|licenses|metrics_dashboard_ymls|issues|merge_requests) of the template'
|
||||
end
|
||||
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
|
||||
desc 'Get a list of templates available to this project' do
|
||||
|
|
|
@ -13,9 +13,6 @@ module API
|
|||
gitlab_ci_ymls: {
|
||||
gitlab_version: 8.9
|
||||
},
|
||||
gitlab_ci_syntax_ymls: {
|
||||
gitlab_version: 13.8
|
||||
},
|
||||
dockerfiles: {
|
||||
gitlab_version: 8.15
|
||||
}
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
#
|
||||
# You can use artifacts to pass data to jobs in later stages.
|
||||
# For more information, see https://docs.gitlab.com/ee/ci/pipelines/job_artifacts.html
|
||||
#
|
||||
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
- deploy
|
||||
|
||||
build-job:
|
||||
stage: build
|
||||
script:
|
||||
- echo "This job might build an important file, and pass it to later jobs."
|
||||
- echo "This is the content of the important file" > important-file.txt
|
||||
artifacts:
|
||||
paths:
|
||||
- important-file.txt
|
||||
|
||||
test-job-with-artifacts:
|
||||
stage: test
|
||||
script:
|
||||
- echo "This job uses the artifact from the job in the earlier stage."
|
||||
- cat important-file.txt
|
||||
- echo "It creates another file, and adds it to the artifacts."
|
||||
- echo "This is a second important file" > important-file2.txt
|
||||
artifacts:
|
||||
paths:
|
||||
- important-file2.txt
|
||||
|
||||
test-job-with-no-artifacts:
|
||||
stage: test
|
||||
dependencies: [] # Use to skip downloading any artifacts
|
||||
script:
|
||||
- echo "This job does not get the artifacts from other jobs."
|
||||
- cat important-file.txt || exit 0
|
||||
|
||||
deploy-job-with-all-artifacts:
|
||||
stage: deploy
|
||||
script:
|
||||
- echo "By default, jobs download all available artifacts."
|
||||
- cat important-file.txt
|
||||
- cat important-file2.txt
|
||||
|
||||
deploy-job-with-1-artifact:
|
||||
stage: deploy
|
||||
dependencies:
|
||||
- build-job # Download artifacts from only this job
|
||||
script:
|
||||
- echo "You can configure a job to download artifacts from only certain jobs."
|
||||
- cat important-file.txt
|
||||
- cat important-file2.txt || exit 0
|
|
@ -1,36 +0,0 @@
|
|||
#
|
||||
# You can define common tasks and run them before or after the main scripts in jobs.
|
||||
# For more information, see:
|
||||
# - https://docs.gitlab.com/ee/ci/yaml/README.html#before_script
|
||||
# - https://docs.gitlab.com/ee/ci/yaml/README.html#after_script
|
||||
#
|
||||
|
||||
stages:
|
||||
- test
|
||||
|
||||
default:
|
||||
before_script:
|
||||
- echo "This script runs before the main script in every job, unless the job overrides it."
|
||||
- echo "It may set up common dependencies, for example."
|
||||
after_script:
|
||||
- echo "This script runs after the main script in every job, unless the job overrides it."
|
||||
- echo "It may do some common final clean up tasks"
|
||||
|
||||
job-standard:
|
||||
stage: test
|
||||
script:
|
||||
- echo "This job uses both of the globally defined before and after scripts."
|
||||
|
||||
job-override-before:
|
||||
stage: test
|
||||
before_script:
|
||||
- echo "Use a different before_script in this job."
|
||||
script:
|
||||
- echo "This job uses its own before_script, and the global after_script."
|
||||
|
||||
job-override-after:
|
||||
stage: test
|
||||
after_script:
|
||||
- echo "Use a different after_script in this job."
|
||||
script:
|
||||
- echo "This job uses its own after_script, and the global before_script."
|
|
@ -1,53 +0,0 @@
|
|||
#
|
||||
# A manual job is a type of job that is not executed automatically and must be explicitly started by a user.
|
||||
# To make a job manual, add when: manual to its configuration.
|
||||
# For more information, see https://docs.gitlab.com/ee/ci/yaml/README.html#whenmanual
|
||||
#
|
||||
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
- deploy
|
||||
|
||||
build-job:
|
||||
stage: build
|
||||
script:
|
||||
- echo "This job is not a manual job"
|
||||
|
||||
manual-build:
|
||||
stage: build
|
||||
script:
|
||||
- echo "This manual job passes after you trigger it."
|
||||
when: manual
|
||||
|
||||
manual-build-allowed-to-fail:
|
||||
stage: build
|
||||
script:
|
||||
- echo "This manual job fails after you trigger it."
|
||||
- echo "It is allowed to fail, so the pipeline does not fail.
|
||||
when: manual
|
||||
allow_failure: true # Default behavior
|
||||
|
||||
test-job:
|
||||
stage: test
|
||||
script:
|
||||
- echo "This is a normal test job"
|
||||
- echo "It runs when the when the build stage completes."
|
||||
- echo "It does not need to wait for the manual jobs in the build stage to run."
|
||||
|
||||
manual-test-not-allowed-to-fail:
|
||||
stage: test
|
||||
script:
|
||||
- echo "This manual job fails after you trigger it."
|
||||
- echo "It is NOT allowed to fail, so the pipeline is marked as failed
|
||||
- echo "when this job completes."
|
||||
- exit 1
|
||||
when: manual
|
||||
allow_failure: false # Optional behavior
|
||||
|
||||
deploy-job:
|
||||
stage: deploy
|
||||
script:
|
||||
- echo "This is a normal deploy job"
|
||||
- echo "If a manual job that isn't allowed to fail ran in an earlier stage and failed,
|
||||
- echo "this job does not run".
|
|
@ -1,33 +0,0 @@
|
|||
#
|
||||
# A pipeline is composed of independent jobs that run scripts, grouped into stages.
|
||||
# Stages run in sequential order, but jobs within stages run in parallel.
|
||||
# For more information, see: https://docs.gitlab.com/ee/ci/yaml/README.html#stages
|
||||
#
|
||||
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
- deploy
|
||||
|
||||
build-job:
|
||||
stage: build
|
||||
script:
|
||||
- echo "This job runs in the build stage, which runs first."
|
||||
|
||||
test-job1:
|
||||
stage: test
|
||||
script:
|
||||
- echo "This job runs in the test stage."
|
||||
- echo "It only starts when the job in the build stage completes successfully."
|
||||
|
||||
test-job2:
|
||||
stage: test
|
||||
script:
|
||||
- echo "This job also runs in the test stage."
|
||||
- echo "This job can run at the same time as test-job2."
|
||||
|
||||
deploy-job:
|
||||
stage: deploy
|
||||
script:
|
||||
- echo "This job runs in the deploy stage."
|
||||
- echo "It only runs when both jobs in the test stage complete successfully"
|
|
@ -1,47 +0,0 @@
|
|||
#
|
||||
# Variables can be used to for more dynamic behavior in jobs and scripts.
|
||||
# For more information, see https://docs.gitlab.com/ee/ci/variables/README.html
|
||||
#
|
||||
|
||||
stages:
|
||||
- test
|
||||
|
||||
variables:
|
||||
VAR1: "Variable 1 defined globally"
|
||||
|
||||
use-a-variable:
|
||||
stage: test
|
||||
script:
|
||||
- echo "You can use variables in jobs."
|
||||
- echo "The content of 'VAR1' is = $VAR1"
|
||||
|
||||
override-a-variable:
|
||||
stage: test
|
||||
variables:
|
||||
VAR1: "Variable 1 was overriden in in the job."
|
||||
script:
|
||||
- echo "You can override global variables in jobs."
|
||||
- echo "The content of 'VAR1' is = $VAR1"
|
||||
|
||||
define-a-new-variable:
|
||||
stage: test
|
||||
variables:
|
||||
VAR2: "Variable 2 is new and defined in the job only."
|
||||
script:
|
||||
- echo "You can mix global variables with variables defined in jobs."
|
||||
- echo "The content of 'VAR1' is = $VAR1"
|
||||
- echo "The content of 'VAR2' is = $VAR2"
|
||||
|
||||
incorrect-variable-usage:
|
||||
stage: test
|
||||
script:
|
||||
- echo "You can't use variables only defined in other jobs."
|
||||
- echo "The content of 'VAR2' is = $VAR2"
|
||||
|
||||
predefined-variables:
|
||||
stage: test
|
||||
script:
|
||||
- echo "Some variables are predefined by GitLab CI/CD, for example:"
|
||||
- echo "The commit author's username is $GITLAB_USER_LOGIN"
|
||||
- echo "The commit branch is $CI_COMMIT_BRANCH"
|
||||
- echo "The project path is $CI_PROJECT_PATH"
|
|
@ -51,10 +51,6 @@ module Gitlab
|
|||
trial_during_signup: {
|
||||
tracking_category: 'Growth::Conversion::Experiment::TrialDuringSignup'
|
||||
},
|
||||
ci_syntax_templates_b: {
|
||||
tracking_category: 'Growth::Activation::Experiment::CiSyntaxTemplates',
|
||||
rollout_strategy: :user
|
||||
},
|
||||
invite_members_new_dropdown: {
|
||||
tracking_category: 'Growth::Expansion::Experiment::InviteMembersNewDropdown'
|
||||
},
|
||||
|
|
|
@ -39,7 +39,7 @@ module Gitlab
|
|||
private
|
||||
|
||||
def add_instrumentation_keys!(job, output_payload)
|
||||
output_payload.merge!(job[:instrumentation].stringify_keys)
|
||||
output_payload.merge!(job[:instrumentation].stringify_keys) if job[:instrumentation]
|
||||
end
|
||||
|
||||
def add_logging_extras!(job, output_payload)
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module Template
|
||||
class GitlabCiSyntaxYmlTemplate < BaseTemplate
|
||||
class << self
|
||||
def extension
|
||||
'.gitlab-ci.yml'
|
||||
end
|
||||
|
||||
def categories
|
||||
{
|
||||
'General' => ''
|
||||
}
|
||||
end
|
||||
|
||||
def base_dir
|
||||
Rails.root.join('lib/gitlab/ci/syntax_templates')
|
||||
end
|
||||
|
||||
def finder(project = nil)
|
||||
Gitlab::Template::Finders::GlobalTemplateFinder.new(
|
||||
self.base_dir, self.extension, self.categories
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -19052,9 +19052,6 @@ msgstr ""
|
|||
msgid "Lead time"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn CI/CD syntax"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn GitLab"
|
||||
msgstr ""
|
||||
|
||||
|
@ -31085,6 +31082,9 @@ msgstr ""
|
|||
msgid "SuperSonics|Activated on"
|
||||
msgstr ""
|
||||
|
||||
msgid "SuperSonics|An error occurred while activating your subscription."
|
||||
msgstr ""
|
||||
|
||||
msgid "SuperSonics|Expires on"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
"@gitlab/favicon-overlay": "2.0.0",
|
||||
"@gitlab/svgs": "1.192.0",
|
||||
"@gitlab/tributejs": "1.0.0",
|
||||
"@gitlab/ui": "29.14.0",
|
||||
"@gitlab/ui": "29.16.0",
|
||||
"@gitlab/visual-review-tools": "1.6.1",
|
||||
"@rails/actioncable": "^6.0.3-4",
|
||||
"@rails/ujs": "^6.0.3-4",
|
||||
|
|
|
@ -7,96 +7,6 @@ RSpec.describe Projects::BlobController do
|
|||
|
||||
let(:project) { create(:project, :public, :repository) }
|
||||
|
||||
describe "GET new" do
|
||||
context 'with no jobs' do
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:file_name) { '.gitlab-ci.yml' }
|
||||
|
||||
def request
|
||||
get(:new, params: { namespace_id: project.namespace, project_id: project, id: 'master', file_name: file_name } )
|
||||
end
|
||||
|
||||
before do
|
||||
project.add_maintainer(user)
|
||||
sign_in(user)
|
||||
|
||||
stub_experiment(ci_syntax_templates_b: experiment_active)
|
||||
stub_experiment_for_subject(ci_syntax_templates_b: in_experiment_group)
|
||||
end
|
||||
|
||||
context 'when the experiment is not active' do
|
||||
let(:experiment_active) { false }
|
||||
let(:in_experiment_group) { false }
|
||||
|
||||
it 'does not record the experiment user' do
|
||||
expect(Experiment).not_to receive(:add_user)
|
||||
|
||||
request
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the experiment is active' do
|
||||
let(:experiment_active) { true }
|
||||
|
||||
context 'when the user is in the control group' do
|
||||
let(:in_experiment_group) { false }
|
||||
|
||||
it 'records the experiment user in the control group' do
|
||||
expect(Experiment).to receive(:add_user)
|
||||
.with(:ci_syntax_templates_b, :control, user, namespace_id: project.namespace_id)
|
||||
|
||||
request
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user is in the experimental group' do
|
||||
let(:in_experiment_group) { true }
|
||||
|
||||
it 'records the experiment user in the experimental group' do
|
||||
expect(Experiment).to receive(:add_user)
|
||||
.with(:ci_syntax_templates_b, :experimental, user, namespace_id: project.namespace_id)
|
||||
|
||||
request
|
||||
end
|
||||
|
||||
context 'when requesting a non default config file type' do
|
||||
let(:file_name) { '.non_default_ci_config' }
|
||||
let(:project) { create(:project, :public, :repository, ci_config_path: file_name) }
|
||||
|
||||
it 'records the experiment user in the experimental group' do
|
||||
expect(Experiment).to receive(:add_user)
|
||||
.with(:ci_syntax_templates_b, :experimental, user, namespace_id: project.namespace_id)
|
||||
|
||||
request
|
||||
end
|
||||
end
|
||||
|
||||
context 'when requesting a different file type' do
|
||||
let(:file_name) { '.gitignore' }
|
||||
|
||||
it 'does not record the experiment user' do
|
||||
expect(Experiment).not_to receive(:add_user)
|
||||
|
||||
request
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the group is created longer than 90 days ago' do
|
||||
before do
|
||||
project.namespace.update_attribute(:created_at, 91.days.ago)
|
||||
end
|
||||
|
||||
it 'does not record the experiment user' do
|
||||
expect(Experiment).not_to receive(:add_user)
|
||||
|
||||
request
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET show" do
|
||||
def request
|
||||
get(:show, params: { namespace_id: project.namespace, project_id: project, id: id })
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe 'Projects > Files > User wants to add a .gitlab-ci.yml file' do
|
||||
include Spec::Support::Helpers::Features::EditorLiteSpecHelpers
|
||||
|
||||
let_it_be(:namespace) { create(:namespace) }
|
||||
|
||||
let(:project) { create(:project, :repository, namespace: namespace) }
|
||||
|
||||
before do
|
||||
sign_in project.owner
|
||||
stub_experiment(ci_syntax_templates_b: experiment_active)
|
||||
stub_experiment_for_subject(ci_syntax_templates_b: in_experiment_group)
|
||||
|
||||
visit project_new_blob_path(project, 'master', file_name: '.gitlab-ci.yml')
|
||||
end
|
||||
|
||||
context 'when experiment is not active' do
|
||||
let(:experiment_active) { false }
|
||||
let(:in_experiment_group) { false }
|
||||
|
||||
it 'does not show the "Learn CI/CD syntax" template dropdown' do
|
||||
expect(page).not_to have_css('.gitlab-ci-syntax-yml-selector')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when experiment is active' do
|
||||
let(:experiment_active) { true }
|
||||
|
||||
context 'when the user is in the control group' do
|
||||
let(:in_experiment_group) { false }
|
||||
|
||||
it 'does not show the "Learn CI/CD syntax" template dropdown' do
|
||||
expect(page).not_to have_css('.gitlab-ci-syntax-yml-selector')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the user is in the experimental group' do
|
||||
let(:in_experiment_group) { true }
|
||||
|
||||
it 'allows the user to pick a "Learn CI/CD syntax" template from the dropdown', :js do
|
||||
expect(page).to have_css('.gitlab-ci-syntax-yml-selector')
|
||||
|
||||
find('.js-gitlab-ci-syntax-yml-selector').click
|
||||
|
||||
wait_for_requests
|
||||
|
||||
within '.gitlab-ci-syntax-yml-selector' do
|
||||
find('.dropdown-input-field').set('Artifacts example')
|
||||
find('.dropdown-content .is-focused', text: 'Artifacts example').click
|
||||
end
|
||||
|
||||
wait_for_requests
|
||||
|
||||
expect(page).to have_css('.gitlab-ci-syntax-yml-selector .dropdown-toggle-text', text: 'Learn CI/CD syntax')
|
||||
expect(editor_get_value).to have_content('You can use artifacts to pass data to jobs in later stages.')
|
||||
end
|
||||
|
||||
context 'when the group is created longer than 90 days ago' do
|
||||
let(:namespace) { create(:namespace, created_at: 91.days.ago) }
|
||||
|
||||
it 'does not show the "Learn CI/CD syntax" template dropdown' do
|
||||
expect(page).not_to have_css('.gitlab-ci-syntax-yml-selector')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -21,7 +21,6 @@ RSpec.describe TemplateFinder do
|
|||
:gitignores | 'Actionscript'
|
||||
:gitlab_ci_ymls | 'Android'
|
||||
:metrics_dashboard_ymls | 'Default'
|
||||
:gitlab_ci_syntax_ymls | 'Artifacts example'
|
||||
end
|
||||
|
||||
with_them do
|
||||
|
@ -110,7 +109,6 @@ RSpec.describe TemplateFinder do
|
|||
:gitlab_ci_ymls | described_class
|
||||
:licenses | ::LicenseTemplateFinder
|
||||
:metrics_dashboard_ymls | described_class
|
||||
:gitlab_ci_syntax_ymls | described_class
|
||||
:issues | described_class
|
||||
:merge_requests | described_class
|
||||
end
|
||||
|
@ -160,7 +158,6 @@ RSpec.describe TemplateFinder do
|
|||
:gitignores | 'Actionscript'
|
||||
:gitlab_ci_ymls | 'Android'
|
||||
:metrics_dashboard_ymls | 'Default'
|
||||
:gitlab_ci_syntax_ymls | 'Artifacts example'
|
||||
end
|
||||
|
||||
with_them do
|
||||
|
|
|
@ -20,11 +20,6 @@ describe('Pipeline editor tabs component', () => {
|
|||
const MockTextEditor = {
|
||||
template: '<div />',
|
||||
};
|
||||
const mockProvide = {
|
||||
glFeatures: {
|
||||
ciConfigMergedTab: true,
|
||||
},
|
||||
};
|
||||
|
||||
const createComponent = ({
|
||||
props = {},
|
||||
|
@ -43,7 +38,7 @@ describe('Pipeline editor tabs component', () => {
|
|||
appStatus,
|
||||
};
|
||||
},
|
||||
provide: { ...mockProvide, ...provide },
|
||||
provide: { ...provide },
|
||||
stubs: {
|
||||
TextEditor: MockTextEditor,
|
||||
EditorTab,
|
||||
|
@ -81,26 +76,24 @@ describe('Pipeline editor tabs component', () => {
|
|||
});
|
||||
|
||||
describe('visualization tab', () => {
|
||||
describe('with feature flag on', () => {
|
||||
describe('while loading', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({ appStatus: EDITOR_APP_STATUS_LOADING });
|
||||
});
|
||||
|
||||
it('displays a loading icon if the lint query is loading', () => {
|
||||
expect(findLoadingIcon().exists()).toBe(true);
|
||||
expect(findPipelineGraph().exists()).toBe(false);
|
||||
});
|
||||
describe('while loading', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({ appStatus: EDITOR_APP_STATUS_LOADING });
|
||||
});
|
||||
describe('after loading', () => {
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
});
|
||||
|
||||
it('display the tab and visualization', () => {
|
||||
expect(findVisualizationTab().exists()).toBe(true);
|
||||
expect(findPipelineGraph().exists()).toBe(true);
|
||||
});
|
||||
it('displays a loading icon if the lint query is loading', () => {
|
||||
expect(findLoadingIcon().exists()).toBe(true);
|
||||
expect(findPipelineGraph().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
describe('after loading', () => {
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
});
|
||||
|
||||
it('display the tab and visualization', () => {
|
||||
expect(findVisualizationTab().exists()).toBe(true);
|
||||
expect(findPipelineGraph().exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -132,53 +125,41 @@ describe('Pipeline editor tabs component', () => {
|
|||
});
|
||||
|
||||
describe('merged tab', () => {
|
||||
describe('with feature flag on', () => {
|
||||
describe('while loading', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({ appStatus: EDITOR_APP_STATUS_LOADING });
|
||||
});
|
||||
|
||||
it('displays a loading icon if the lint query is loading', () => {
|
||||
expect(findLoadingIcon().exists()).toBe(true);
|
||||
});
|
||||
describe('while loading', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({ appStatus: EDITOR_APP_STATUS_LOADING });
|
||||
});
|
||||
|
||||
describe('when there is a fetch error', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({ appStatus: EDITOR_APP_STATUS_ERROR });
|
||||
});
|
||||
|
||||
it('show an error message', () => {
|
||||
expect(findAlert().exists()).toBe(true);
|
||||
expect(findAlert().text()).toBe(wrapper.vm.$options.errorTexts.loadMergedYaml);
|
||||
});
|
||||
|
||||
it('does not render the `meged_preview` component', () => {
|
||||
expect(findMergedPreview().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('after loading', () => {
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
});
|
||||
|
||||
it('display the tab and the merged preview component', () => {
|
||||
expect(findMergedTab().exists()).toBe(true);
|
||||
expect(findMergedPreview().exists()).toBe(true);
|
||||
});
|
||||
it('displays a loading icon if the lint query is loading', () => {
|
||||
expect(findLoadingIcon().exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
describe('with feature flag off', () => {
|
||||
|
||||
describe('when there is a fetch error', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({ provide: { glFeatures: { ciConfigMergedTab: false } } });
|
||||
createComponent({ appStatus: EDITOR_APP_STATUS_ERROR });
|
||||
});
|
||||
|
||||
it('does not display the merged tab', () => {
|
||||
expect(findMergedTab().exists()).toBe(false);
|
||||
it('show an error message', () => {
|
||||
expect(findAlert().exists()).toBe(true);
|
||||
expect(findAlert().text()).toBe(wrapper.vm.$options.errorTexts.loadMergedYaml);
|
||||
});
|
||||
|
||||
it('does not render the `merged_preview` component', () => {
|
||||
expect(findMergedPreview().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('after loading', () => {
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
});
|
||||
|
||||
it('display the tab and the merged preview component', () => {
|
||||
expect(findMergedTab().exists()).toBe(true);
|
||||
expect(findMergedPreview().exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('show tab content based on status', () => {
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe 'ci/syntax_templates' do
|
||||
let_it_be(:project) { create(:project, :repository) }
|
||||
let_it_be(:user) { create(:user) }
|
||||
|
||||
let(:lint) { Gitlab::Ci::Lint.new(project: project, current_user: user) }
|
||||
|
||||
before do
|
||||
project.add_developer(user)
|
||||
end
|
||||
|
||||
subject(:lint_result) { lint.validate(content) }
|
||||
|
||||
Dir.glob('lib/gitlab/ci/syntax_templates/**/*.yml').each do |template|
|
||||
describe template do
|
||||
let(:content) { File.read(template) }
|
||||
|
||||
it 'validates the template' do
|
||||
expect(lint_result).to be_valid, "got errors: #{lint_result.errors.join(', ')}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -293,6 +293,16 @@ RSpec.describe Gitlab::SidekiqLogging::StructuredLogger do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when instrumentation data is not loaded' do
|
||||
before do
|
||||
allow(logger).to receive(:info)
|
||||
end
|
||||
|
||||
it 'does not raise exception' do
|
||||
expect { subject.call(job.dup, 'test_queue') {} }.not_to raise_error
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#add_time_keys!' do
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Template::GitlabCiSyntaxYmlTemplate do
|
||||
subject { described_class }
|
||||
|
||||
describe '#content' do
|
||||
it 'loads the full file' do
|
||||
template = subject.new(Rails.root.join('lib/gitlab/ci/syntax_templates/Artifacts example.gitlab-ci.yml'))
|
||||
|
||||
expect(template.content).to start_with('#')
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'file template shared examples', 'Artifacts example', '.gitlab-ci.yml'
|
||||
end
|
|
@ -53,15 +53,6 @@ RSpec.describe API::ProjectTemplates do
|
|||
expect(json_response).to satisfy_one { |template| template['key'] == 'Android' }
|
||||
end
|
||||
|
||||
it 'returns gitlab_ci_syntax_ymls' do
|
||||
get api("/projects/#{public_project.id}/templates/gitlab_ci_syntax_ymls")
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response).to include_pagination_headers
|
||||
expect(response).to match_response_schema('public_api/v4/template_list')
|
||||
expect(json_response).to satisfy_one { |template| template['key'] == 'Artifacts example' }
|
||||
end
|
||||
|
||||
it 'returns licenses' do
|
||||
get api("/projects/#{public_project.id}/templates/licenses")
|
||||
|
||||
|
@ -172,14 +163,6 @@ RSpec.describe API::ProjectTemplates do
|
|||
expect(json_response['name']).to eq('Android')
|
||||
end
|
||||
|
||||
it 'returns a specific gitlab_ci_syntax_yml' do
|
||||
get api("/projects/#{public_project.id}/templates/gitlab_ci_syntax_ymls/Artifacts%20example")
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response).to match_response_schema('public_api/v4/template')
|
||||
expect(json_response['name']).to eq('Artifacts example')
|
||||
end
|
||||
|
||||
it 'returns a specific metrics_dashboard_yml' do
|
||||
get api("/projects/#{public_project.id}/templates/metrics_dashboard_ymls/Default")
|
||||
|
||||
|
|
|
@ -102,14 +102,6 @@ RSpec.describe Ci::CreatePipelineService do
|
|||
execute_service
|
||||
end
|
||||
|
||||
describe 'recording a conversion event' do
|
||||
it 'schedules a record conversion event worker' do
|
||||
expect(Experiments::RecordConversionEventWorker).to receive(:perform_async).with(:ci_syntax_templates_b, user.id)
|
||||
|
||||
pipeline
|
||||
end
|
||||
end
|
||||
|
||||
context 'when merge requests already exist for this source branch' do
|
||||
let(:merge_request_1) do
|
||||
create(:merge_request, source_branch: 'feature', target_branch: "master", source_project: project)
|
||||
|
|
|
@ -82,31 +82,69 @@ module Ci
|
|||
let!(:build2_project2) { FactoryBot.create :ci_build, pipeline: pipeline2 }
|
||||
let!(:build1_project3) { FactoryBot.create :ci_build, pipeline: pipeline3 }
|
||||
|
||||
it 'prefers projects without builds first' do
|
||||
# it gets for one build from each of the projects
|
||||
expect(execute(shared_runner)).to eq(build1_project1)
|
||||
expect(execute(shared_runner)).to eq(build1_project2)
|
||||
expect(execute(shared_runner)).to eq(build1_project3)
|
||||
context 'when using fair scheduling' do
|
||||
context 'when all builds are pending' do
|
||||
it 'prefers projects without builds first' do
|
||||
# it gets for one build from each of the projects
|
||||
expect(execute(shared_runner)).to eq(build1_project1)
|
||||
expect(execute(shared_runner)).to eq(build1_project2)
|
||||
expect(execute(shared_runner)).to eq(build1_project3)
|
||||
|
||||
# then it gets a second build from each of the projects
|
||||
expect(execute(shared_runner)).to eq(build2_project1)
|
||||
expect(execute(shared_runner)).to eq(build2_project2)
|
||||
# then it gets a second build from each of the projects
|
||||
expect(execute(shared_runner)).to eq(build2_project1)
|
||||
expect(execute(shared_runner)).to eq(build2_project2)
|
||||
|
||||
# in the end the third build
|
||||
expect(execute(shared_runner)).to eq(build3_project1)
|
||||
# in the end the third build
|
||||
expect(execute(shared_runner)).to eq(build3_project1)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when some builds transition to success' do
|
||||
it 'equalises number of running builds' do
|
||||
# after finishing the first build for project 1, get a second build from the same project
|
||||
expect(execute(shared_runner)).to eq(build1_project1)
|
||||
build1_project1.reload.success
|
||||
expect(execute(shared_runner)).to eq(build2_project1)
|
||||
|
||||
expect(execute(shared_runner)).to eq(build1_project2)
|
||||
build1_project2.reload.success
|
||||
expect(execute(shared_runner)).to eq(build2_project2)
|
||||
expect(execute(shared_runner)).to eq(build1_project3)
|
||||
expect(execute(shared_runner)).to eq(build3_project1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it 'equalises number of running builds' do
|
||||
# after finishing the first build for project 1, get a second build from the same project
|
||||
expect(execute(shared_runner)).to eq(build1_project1)
|
||||
build1_project1.reload.success
|
||||
expect(execute(shared_runner)).to eq(build2_project1)
|
||||
context 'when using DEFCON mode that disables fair scheduling' do
|
||||
before do
|
||||
stub_feature_flags(ci_queueing_disaster_recovery: true)
|
||||
end
|
||||
|
||||
expect(execute(shared_runner)).to eq(build1_project2)
|
||||
build1_project2.reload.success
|
||||
expect(execute(shared_runner)).to eq(build2_project2)
|
||||
expect(execute(shared_runner)).to eq(build1_project3)
|
||||
expect(execute(shared_runner)).to eq(build3_project1)
|
||||
context 'when all builds are pending' do
|
||||
it 'returns builds in order of creation (FIFO)' do
|
||||
# it gets for one build from each of the projects
|
||||
expect(execute(shared_runner)).to eq(build1_project1)
|
||||
expect(execute(shared_runner)).to eq(build2_project1)
|
||||
expect(execute(shared_runner)).to eq(build3_project1)
|
||||
expect(execute(shared_runner)).to eq(build1_project2)
|
||||
expect(execute(shared_runner)).to eq(build2_project2)
|
||||
expect(execute(shared_runner)).to eq(build1_project3)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when some builds transition to success' do
|
||||
it 'returns builds in order of creation (FIFO)' do
|
||||
expect(execute(shared_runner)).to eq(build1_project1)
|
||||
build1_project1.reload.success
|
||||
expect(execute(shared_runner)).to eq(build2_project1)
|
||||
|
||||
expect(execute(shared_runner)).to eq(build3_project1)
|
||||
build2_project1.reload.success
|
||||
expect(execute(shared_runner)).to eq(build1_project2)
|
||||
expect(execute(shared_runner)).to eq(build2_project2)
|
||||
expect(execute(shared_runner)).to eq(build1_project3)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -253,6 +253,9 @@ RSpec.configure do |config|
|
|||
# tests, until we introduce it in user settings
|
||||
stub_feature_flags(forti_token_cloud: false)
|
||||
|
||||
# This feature flag is by default disabled and used in disaster recovery mode
|
||||
stub_feature_flags(ci_queueing_disaster_recovery: false)
|
||||
|
||||
enable_rugged = example.metadata[:enable_rugged].present?
|
||||
|
||||
# Disable Rugged features by default
|
||||
|
|
|
@ -907,10 +907,10 @@
|
|||
resolved "https://registry.yarnpkg.com/@gitlab/tributejs/-/tributejs-1.0.0.tgz#672befa222aeffc83e7d799b0500a7a4418e59b8"
|
||||
integrity sha512-nmKw1+hB6MHvlmPz63yPwVs1qQkycHwsKgxpEbzmky16Y6mL4EJMk3w1b8QlOAF/AIAzjCERPhe/R4MJiohbZw==
|
||||
|
||||
"@gitlab/ui@29.14.0":
|
||||
version "29.14.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-29.14.0.tgz#0b5dc564fa26194ddbea6fe78418dc46c0e557ac"
|
||||
integrity sha512-SYRokscvZD/F0TFa2gc0CgBtLeBlv4mPDhGPQUvh6uaX68NgMx9CstfYb286j5dKlvqBw+7r83fMiAHEzpberw==
|
||||
"@gitlab/ui@29.16.0":
|
||||
version "29.16.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-29.16.0.tgz#80e16c6e046bae1c98774dddfdd6b829f299df5e"
|
||||
integrity sha512-Pq6Ycguq2AruJGfDQvJ8xy7J5Ldz8fgx5Z/Bq0Dq0fiCvuLiHDu0nQMjuFTGXMM/fDSFcBzPxE0+7LsNS37v5g==
|
||||
dependencies:
|
||||
"@babel/standalone" "^7.0.0"
|
||||
"@gitlab/vue-toasted" "^1.3.0"
|
||||
|
|
Loading…
Reference in New Issue