diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-05-06 18:10:17 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-05-06 18:10:17 +0300 |
commit | 0a5ea888dca19dec6ce473a88c35a4ef95f61a9c (patch) | |
tree | 6507f8bd191ebe9f1e73e0d76c36b226f18c595f | |
parent | 25db9c1230f7b54a7337b3d2dfe714478a7d54f0 (diff) |
Add latest changes from gitlab-org/gitlab@master
49 files changed, 379 insertions, 687 deletions
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index e70d1d0105b..8c25be0f02f 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -c67f1a2bb56d8fa3403b529fd3bf36dba3a6488c +07aa359a7724540bbfa4868407b9a2c9b45bf139 diff --git a/app/assets/javascripts/blob/file_template_mediator.js b/app/assets/javascripts/blob/file_template_mediator.js index 77910850908..59ab84bf208 100644 --- a/app/assets/javascripts/blob/file_template_mediator.js +++ b/app/assets/javascripts/blob/file_template_mediator.js @@ -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, diff --git a/app/assets/javascripts/blob/template_selectors/ci_syntax_yaml_selector.js b/app/assets/javascripts/blob/template_selectors/ci_syntax_yaml_selector.js deleted file mode 100644 index c30ff4f1290..00000000000 --- a/app/assets/javascripts/blob/template_selectors/ci_syntax_yaml_selector.js +++ /dev/null @@ -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, - }); - } -} diff --git a/app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue b/app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue index 7280315fb48..4e2f26af51d 100644 --- a/app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue +++ b/app/assets/javascripts/pipeline_editor/components/pipeline_editor_tabs.vue @@ -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" diff --git a/app/assets/javascripts/project_select.js b/app/assets/javascripts/project_select.js index e1e04d63576..7222c2bd908 100644 --- a/app/assets/javascripts/project_select.js +++ b/app/assets/javascripts/project_select.js @@ -62,6 +62,7 @@ const projectSelect = () => { with_shared: this.withShared, include_subgroups: this.includeProjectsInSubgroups, order_by: 'similarity', + simple: true, }, projectsCallback, ); diff --git a/app/assets/stylesheets/pages/editor.scss b/app/assets/stylesheets/pages/editor.scss index 141dc6a8aad..c177d0b74a2 100644 --- a/app/assets/stylesheets/pages/editor.scss +++ b/app/assets/stylesheets/pages/editor.scss @@ -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 { diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index 2b2b4bfb65a..65b7a78cb58 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -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 diff --git a/app/controllers/projects/ci/pipeline_editor_controller.rb b/app/controllers/projects/ci/pipeline_editor_controller.rb index 13c22356b60..6e31816bc99 100644 --- a/app/controllers/projects/ci/pipeline_editor_controller.rb +++ b/app/controllers/projects/ci/pipeline_editor_controller.rb @@ -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) diff --git a/app/finders/template_finder.rb b/app/finders/template_finder.rb index 739beee236c..2d3fc9db1f0 100644 --- a/app/finders/template_finder.rb +++ b/app/finders/template_finder.rb @@ -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 diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb index 3144686bba9..dfd6de3f1d5 100644 --- a/app/helpers/blob_helper.rb +++ b/app/helpers/blob_helper.rb @@ -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 diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb index b9891172c6c..bdbef9117e6 100644 --- a/app/services/ci/create_pipeline_service.rb +++ b/app/services/ci/create_pipeline_service.rb @@ -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 diff --git a/app/services/ci/register_job_service.rb b/app/services/ci/register_job_service.rb index ab5aac55515..bb82f9eed22 100644 --- a/app/services/ci/register_job_service.rb +++ b/app/services/ci/register_job_service.rb @@ -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 diff --git a/app/views/projects/blob/_template_selectors.html.haml b/app/views/projects/blob/_template_selectors.html.haml index 24a4db010c8..a76e61bc3dd 100644 --- a/app/views/projects/blob/_template_selectors.html.haml +++ b/app/views/projects/blob/_template_selectors.html.haml @@ -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) } } ) diff --git a/changelogs/unreleased/301103-feature-flag-rollout-merged-yaml-tab-in-pa-home.yml b/changelogs/unreleased/301103-feature-flag-rollout-merged-yaml-tab-in-pa-home.yml new file mode 100644 index 00000000000..ddb1b73ceaa --- /dev/null +++ b/changelogs/unreleased/301103-feature-flag-rollout-merged-yaml-tab-in-pa-home.yml @@ -0,0 +1,5 @@ +--- +title: Removed feature flag for Pipeline editor merged YAML tab +merge_request: 60659 +author: +type: other diff --git a/changelogs/unreleased/327877-experiment-clean-up-ci_syntax_templates_b-empty-versatile-template.yml b/changelogs/unreleased/327877-experiment-clean-up-ci_syntax_templates_b-empty-versatile-template.yml new file mode 100644 index 00000000000..4317e01c6b0 --- /dev/null +++ b/changelogs/unreleased/327877-experiment-clean-up-ci_syntax_templates_b-empty-versatile-template.yml @@ -0,0 +1,5 @@ +--- +title: Remove invalidated CI Syntax Templates Experiment +merge_request: 60937 +author: +type: other diff --git a/changelogs/unreleased/jimcser-add-access-token.yml b/changelogs/unreleased/jimcser-add-access-token.yml new file mode 100644 index 00000000000..dde365316a8 --- /dev/null +++ b/changelogs/unreleased/jimcser-add-access-token.yml @@ -0,0 +1,5 @@ +--- +title: Adds access token endpoints to OpenAPI +merge_request: 58620 +author: jimcser +type: added diff --git a/changelogs/unreleased/ph-groupCreateMergeRequestPerformanceImprovement.yml b/changelogs/unreleased/ph-groupCreateMergeRequestPerformanceImprovement.yml new file mode 100644 index 00000000000..0b651e4a4c4 --- /dev/null +++ b/changelogs/unreleased/ph-groupCreateMergeRequestPerformanceImprovement.yml @@ -0,0 +1,5 @@ +--- +title: Increase load time of project select dropdowns +merge_request: 61117 +author: +type: performance diff --git a/config/feature_flags/development/ci_config_merged_tab.yml b/config/feature_flags/development/ci_config_merged_tab.yml deleted file mode 100644 index 8ccdf105951..00000000000 --- a/config/feature_flags/development/ci_config_merged_tab.yml +++ /dev/null @@ -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 diff --git a/config/feature_flags/experiment/ci_syntax_templates_b_experiment_percentage.yml b/config/feature_flags/experiment/ci_syntax_templates_b_experiment_percentage.yml deleted file mode 100644 index 0bad0bbb1c0..00000000000 --- a/config/feature_flags/experiment/ci_syntax_templates_b_experiment_percentage.yml +++ /dev/null @@ -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 diff --git a/config/feature_flags/ops/ci_queueing_disaster_recovery.yml b/config/feature_flags/ops/ci_queueing_disaster_recovery.yml new file mode 100644 index 00000000000..8c87df59e08 --- /dev/null +++ b/config/feature_flags/ops/ci_queueing_disaster_recovery.yml @@ -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 diff --git a/doc/administration/troubleshooting/defcon.md b/doc/administration/troubleshooting/defcon.md new file mode 100644 index 00000000000..09e11553d97 --- /dev/null +++ b/doc/administration/troubleshooting/defcon.md @@ -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`). diff --git a/doc/api/openapi/openapi.yaml b/doc/api/openapi/openapi.yaml index 1a80daf304c..46267129b32 100644 --- a/doc/api/openapi/openapi.yaml +++ b/doc/api/openapi/openapi.yaml @@ -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'
\ No newline at end of file diff --git a/doc/api/openapi/v4/access_tokens.yaml b/doc/api/openapi/v4/access_tokens.yaml new file mode 100644 index 00000000000..9a1a6960eea --- /dev/null +++ b/doc/api/openapi/v4/access_tokens.yaml @@ -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 diff --git a/doc/api/resource_access_tokens.md b/doc/api/resource_access_tokens.md index 2b6400a6f0d..ecc5b3bf172 100644 --- a/doc/api/resource_access_tokens.md +++ b/doc/api/resource_access_tokens.md @@ -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 | diff --git a/doc/ci/pipeline_editor/index.md b/doc/ci/pipeline_editor/index.md index b7df28729ef..130e21502ed 100644 --- a/doc/ci/pipeline_editor/index.md +++ b/doc/ci/pipeline_editor/index.md @@ -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 diff --git a/lib/api/project_templates.rb b/lib/api/project_templates.rb index fdfdc244cbe..5d6f67ccbae 100644 --- a/lib/api/project_templates.rb +++ b/lib/api/project_templates.rb @@ -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 diff --git a/lib/api/templates.rb b/lib/api/templates.rb index bc1e427bcaa..b7fb35eac03 100644 --- a/lib/api/templates.rb +++ b/lib/api/templates.rb @@ -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 } diff --git a/lib/gitlab/ci/syntax_templates/Artifacts example.gitlab-ci.yml b/lib/gitlab/ci/syntax_templates/Artifacts example.gitlab-ci.yml deleted file mode 100644 index 7182b96594d..00000000000 --- a/lib/gitlab/ci/syntax_templates/Artifacts example.gitlab-ci.yml +++ /dev/null @@ -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 diff --git a/lib/gitlab/ci/syntax_templates/Before_script and after_script example.gitlab-ci.yml b/lib/gitlab/ci/syntax_templates/Before_script and after_script example.gitlab-ci.yml deleted file mode 100644 index 382bac09ed7..00000000000 --- a/lib/gitlab/ci/syntax_templates/Before_script and after_script example.gitlab-ci.yml +++ /dev/null @@ -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." diff --git a/lib/gitlab/ci/syntax_templates/Manual jobs example.gitlab-ci.yml b/lib/gitlab/ci/syntax_templates/Manual jobs example.gitlab-ci.yml deleted file mode 100644 index 5f27def74c9..00000000000 --- a/lib/gitlab/ci/syntax_templates/Manual jobs example.gitlab-ci.yml +++ /dev/null @@ -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". diff --git a/lib/gitlab/ci/syntax_templates/Multi-stage pipeline example.gitlab-ci.yml b/lib/gitlab/ci/syntax_templates/Multi-stage pipeline example.gitlab-ci.yml deleted file mode 100644 index aced628aacb..00000000000 --- a/lib/gitlab/ci/syntax_templates/Multi-stage pipeline example.gitlab-ci.yml +++ /dev/null @@ -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" diff --git a/lib/gitlab/ci/syntax_templates/Variables example.gitlab-ci.yml b/lib/gitlab/ci/syntax_templates/Variables example.gitlab-ci.yml deleted file mode 100644 index 2b8cf7bab44..00000000000 --- a/lib/gitlab/ci/syntax_templates/Variables example.gitlab-ci.yml +++ /dev/null @@ -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" diff --git a/lib/gitlab/experimentation.rb b/lib/gitlab/experimentation.rb index 1b838b45122..e4233b8a935 100644 --- a/lib/gitlab/experimentation.rb +++ b/lib/gitlab/experimentation.rb @@ -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' }, diff --git a/lib/gitlab/sidekiq_logging/structured_logger.rb b/lib/gitlab/sidekiq_logging/structured_logger.rb index 98f8e1abe35..87fb36d04e9 100644 --- a/lib/gitlab/sidekiq_logging/structured_logger.rb +++ b/lib/gitlab/sidekiq_logging/structured_logger.rb @@ -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) diff --git a/lib/gitlab/template/gitlab_ci_syntax_yml_template.rb b/lib/gitlab/template/gitlab_ci_syntax_yml_template.rb deleted file mode 100644 index 3bf3a28d3c5..00000000000 --- a/lib/gitlab/template/gitlab_ci_syntax_yml_template.rb +++ /dev/null @@ -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 diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 70cba0de49f..ced2e339114 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -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 "" diff --git a/package.json b/package.json index c677eb4ee26..d2a99debada 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/spec/controllers/projects/blob_controller_spec.rb b/spec/controllers/projects/blob_controller_spec.rb index c9a76049e19..4bc2a235eec 100644 --- a/spec/controllers/projects/blob_controller_spec.rb +++ b/spec/controllers/projects/blob_controller_spec.rb @@ -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 }) diff --git a/spec/features/projects/files/gitlab_ci_syntax_yml_dropdown_spec.rb b/spec/features/projects/files/gitlab_ci_syntax_yml_dropdown_spec.rb deleted file mode 100644 index 10041825f0d..00000000000 --- a/spec/features/projects/files/gitlab_ci_syntax_yml_dropdown_spec.rb +++ /dev/null @@ -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 diff --git a/spec/finders/template_finder_spec.rb b/spec/finders/template_finder_spec.rb index 164975fdfb6..b7339288c51 100644 --- a/spec/finders/template_finder_spec.rb +++ b/spec/finders/template_finder_spec.rb @@ -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 diff --git a/spec/frontend/pipeline_editor/components/pipeline_editor_tabs_spec.js b/spec/frontend/pipeline_editor/components/pipeline_editor_tabs_spec.js index d4f467cc9e6..5cf8d47bc23 100644 --- a/spec/frontend/pipeline_editor/components/pipeline_editor_tabs_spec.js +++ b/spec/frontend/pipeline_editor/components/pipeline_editor_tabs_spec.js @@ -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('after loading', () => { - beforeEach(() => { - createComponent(); - }); - - it('display the tab and visualization', () => { - expect(findVisualizationTab().exists()).toBe(true); - expect(findPipelineGraph().exists()).toBe(true); - }); + 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('after loading', () => { + beforeEach(() => { + createComponent(); + }); + + it('display the tab and visualization', () => { + expect(findVisualizationTab().exists()).toBe(true); + expect(findPipelineGraph().exists()).toBe(true); }); }); }); @@ -132,51 +125,39 @@ 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('displays a loading icon if the lint query is loading', () => { + expect(findLoadingIcon().exists()).toBe(true); + }); + }); - it('does not render the `meged_preview` component', () => { - expect(findMergedPreview().exists()).toBe(false); - }); + describe('when there is a fetch error', () => { + beforeEach(() => { + createComponent({ appStatus: EDITOR_APP_STATUS_ERROR }); }); - describe('after loading', () => { - beforeEach(() => { - createComponent(); - }); + it('show an error message', () => { + expect(findAlert().exists()).toBe(true); + expect(findAlert().text()).toBe(wrapper.vm.$options.errorTexts.loadMergedYaml); + }); - it('display the tab and the merged preview component', () => { - expect(findMergedTab().exists()).toBe(true); - expect(findMergedPreview().exists()).toBe(true); - }); + it('does not render the `merged_preview` component', () => { + expect(findMergedPreview().exists()).toBe(false); }); }); - describe('with feature flag off', () => { + + describe('after loading', () => { beforeEach(() => { - createComponent({ provide: { glFeatures: { ciConfigMergedTab: false } } }); + createComponent(); }); - it('does not display the merged tab', () => { - expect(findMergedTab().exists()).toBe(false); - expect(findMergedPreview().exists()).toBe(false); + it('display the tab and the merged preview component', () => { + expect(findMergedTab().exists()).toBe(true); + expect(findMergedPreview().exists()).toBe(true); }); }); }); diff --git a/spec/lib/gitlab/ci/syntax_templates_spec.rb b/spec/lib/gitlab/ci/syntax_templates_spec.rb deleted file mode 100644 index 29a0ffe2f02..00000000000 --- a/spec/lib/gitlab/ci/syntax_templates_spec.rb +++ /dev/null @@ -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 diff --git a/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb b/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb index 43df16c710f..731c509e221 100644 --- a/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb +++ b/spec/lib/gitlab/sidekiq_logging/structured_logger_spec.rb @@ -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 diff --git a/spec/lib/gitlab/template/gitlab_ci_syntax_yml_template_spec.rb b/spec/lib/gitlab/template/gitlab_ci_syntax_yml_template_spec.rb deleted file mode 100644 index d1024019a9f..00000000000 --- a/spec/lib/gitlab/template/gitlab_ci_syntax_yml_template_spec.rb +++ /dev/null @@ -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 diff --git a/spec/requests/api/project_templates_spec.rb b/spec/requests/api/project_templates_spec.rb index a424bc62014..070fd6db3dc 100644 --- a/spec/requests/api/project_templates_spec.rb +++ b/spec/requests/api/project_templates_spec.rb @@ -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") diff --git a/spec/services/ci/create_pipeline_service_spec.rb b/spec/services/ci/create_pipeline_service_spec.rb index 4e4ece0d0f9..3ae4dc9f988 100644 --- a/spec/services/ci/create_pipeline_service_spec.rb +++ b/spec/services/ci/create_pipeline_service_spec.rb @@ -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) diff --git a/spec/services/ci/register_job_service_spec.rb b/spec/services/ci/register_job_service_spec.rb index fb2474ef63b..65211632e3a 100644 --- a/spec/services/ci/register_job_service_spec.rb +++ b/spec/services/ci/register_job_service_spec.rb @@ -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) - - # 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) - 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) - - 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 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) + + # 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 + + context 'when using DEFCON mode that disables fair scheduling' do + before do + stub_feature_flags(ci_queueing_disaster_recovery: true) + end + + 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 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 4a3227cc9f5..34f9d189d71 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -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 diff --git a/yarn.lock b/yarn.lock index ef5ed4520e8..1dfb291c1a7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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" |