diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index dc6249100bd..edb3921609d 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -666,12 +666,6 @@ Style/RedundantFreeze: Style/RedundantInterpolation: Enabled: false -# Offense count: 33 -# Cop supports --auto-correct. -# Configuration parameters: AllowMultipleReturnValues. -Style/RedundantReturn: - Enabled: false - # Offense count: 801 # Cop supports --auto-correct. Style/RedundantSelf: diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 789213a5fc6..2595b646964 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -306,7 +306,7 @@ class ApplicationController < ActionController::Base return if session[:impersonator_id] || !current_user&.allow_password_authentication? if current_user&.password_expired? - return redirect_to new_profile_password_path + redirect_to new_profile_password_path end end @@ -364,7 +364,7 @@ class ApplicationController < ActionController::Base def require_email if current_user && current_user.temp_oauth_email? && session[:impersonator_id].nil? - return redirect_to profile_path, notice: _('Please complete your profile with email address') + redirect_to profile_path, notice: _('Please complete your profile with email address') end end diff --git a/app/controllers/chaos_controller.rb b/app/controllers/chaos_controller.rb index ac008165c16..e0d1f313fc7 100644 --- a/app/controllers/chaos_controller.rb +++ b/app/controllers/chaos_controller.rb @@ -45,7 +45,6 @@ class ChaosController < ActionController::Base unless Devise.secure_compare(chaos_secret_configured, chaos_secret_request) render plain: "To experience chaos, please set a valid `X-Chaos-Secret` header or `token` param", status: :unauthorized - return end end diff --git a/app/controllers/concerns/issuable_actions.rb b/app/controllers/concerns/issuable_actions.rb index 068b7bdae2a..c4dbce00593 100644 --- a/app/controllers/concerns/issuable_actions.rb +++ b/app/controllers/concerns/issuable_actions.rb @@ -197,13 +197,13 @@ module IssuableActions def authorize_destroy_issuable! unless can?(current_user, :"destroy_#{issuable.to_ability_name}", issuable) - return access_denied! + access_denied! end end def authorize_admin_issuable! unless can?(current_user, :"admin_#{resource_name}", parent) - return access_denied! + access_denied! end end diff --git a/app/controllers/groups/application_controller.rb b/app/controllers/groups/application_controller.rb index 84c8d7ada43..9c2e361e92f 100644 --- a/app/controllers/groups/application_controller.rb +++ b/app/controllers/groups/application_controller.rb @@ -30,25 +30,25 @@ class Groups::ApplicationController < ApplicationController def authorize_admin_group! unless can?(current_user, :admin_group, group) - return render_404 + render_404 end end def authorize_create_deploy_token! unless can?(current_user, :create_deploy_token, group) - return render_404 + render_404 end end def authorize_destroy_deploy_token! unless can?(current_user, :destroy_deploy_token, group) - return render_404 + render_404 end end def authorize_admin_group_member! unless can?(current_user, :admin_group_member, group) - return render_403 + render_403 end end diff --git a/app/controllers/omniauth_callbacks_controller.rb b/app/controllers/omniauth_callbacks_controller.rb index 4c595313cb6..706a4843117 100644 --- a/app/controllers/omniauth_callbacks_controller.rb +++ b/app/controllers/omniauth_callbacks_controller.rb @@ -200,7 +200,7 @@ class OmniauthCallbacksController < Devise::OmniauthCallbacksController def fail_login(user) error_message = user.errors.full_messages.to_sentence - return redirect_to omniauth_error_path(oauth['provider'], error: error_message) + redirect_to omniauth_error_path(oauth['provider'], error: error_message) end def fail_auth0_login diff --git a/app/controllers/projects/application_controller.rb b/app/controllers/projects/application_controller.rb index 82f98a9e411..d78a9bf0666 100644 --- a/app/controllers/projects/application_controller.rb +++ b/app/controllers/projects/application_controller.rb @@ -42,7 +42,7 @@ class Projects::ApplicationController < ApplicationController def authorize_action!(action) unless can?(current_user, action, project) - return access_denied! + access_denied! end end diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb index 80c5fb470dd..49f658d9ffc 100644 --- a/app/controllers/projects/blob_controller.rb +++ b/app/controllers/projects/blob_controller.rb @@ -129,7 +129,7 @@ class Projects::BlobController < Projects::ApplicationController end end - return redirect_to_tree_root_for_missing_path(@project, @ref, @path) + redirect_to_tree_root_for_missing_path(@project, @ref, @path) end end diff --git a/app/controllers/projects/releases_controller.rb b/app/controllers/projects/releases_controller.rb index 3d48fb9c803..d58755c2655 100644 --- a/app/controllers/projects/releases_controller.rb +++ b/app/controllers/projects/releases_controller.rb @@ -30,7 +30,7 @@ class Projects::ReleasesController < Projects::ApplicationController def new unless Feature.enabled?(:new_release_page, project) - return redirect_to(new_project_tag_path(@project)) + redirect_to(new_project_tag_path(@project)) end end diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb index aadc766313d..638e1a05c18 100644 --- a/app/controllers/projects/tree_controller.rb +++ b/app/controllers/projects/tree_controller.rb @@ -20,9 +20,9 @@ class Projects::TreeController < Projects::ApplicationController if tree.entries.empty? if @repository.blob_at(@commit.id, @path) - return redirect_to project_blob_path(@project, File.join(@ref, @path)) + redirect_to project_blob_path(@project, File.join(@ref, @path)) elsif @path.present? - return redirect_to_tree_root_for_missing_path(@project, @ref, @path) + redirect_to_tree_root_for_missing_path(@project, @ref, @path) end end end diff --git a/app/graphql/resolvers/projects/jira_projects_resolver.rb b/app/graphql/resolvers/projects/jira_projects_resolver.rb index 3b6e5c4fd42..2dc712128cc 100644 --- a/app/graphql/resolvers/projects/jira_projects_resolver.rb +++ b/app/graphql/resolvers/projects/jira_projects_resolver.rb @@ -37,7 +37,7 @@ module Resolvers def jira_projects(name:) args = { query: name }.compact - return Jira::Requests::Projects::ListService.new(project.jira_service, args).execute + Jira::Requests::Projects::ListService.new(project.jira_service, args).execute end end end diff --git a/app/services/access_token_validation_service.rb b/app/services/access_token_validation_service.rb index 851d862c0cf..eb2e66a9285 100644 --- a/app/services/access_token_validation_service.rb +++ b/app/services/access_token_validation_service.rb @@ -17,21 +17,21 @@ class AccessTokenValidationService def validate(scopes: []) if token.expired? - return EXPIRED + EXPIRED elsif token.revoked? - return REVOKED + REVOKED elsif !self.include_any_scope?(scopes) - return INSUFFICIENT_SCOPE + INSUFFICIENT_SCOPE elsif token.respond_to?(:impersonation) && token.impersonation && !Gitlab.config.gitlab.impersonation_enabled - return IMPERSONATION_DISABLED + IMPERSONATION_DISABLED else - return VALID + VALID end end diff --git a/app/services/spam/spam_verdict_service.rb b/app/services/spam/spam_verdict_service.rb index be156a0ebeb..ba1c583c7af 100644 --- a/app/services/spam/spam_verdict_service.rb +++ b/app/services/spam/spam_verdict_service.rb @@ -57,7 +57,7 @@ module Spam rescue *Gitlab::HTTP::HTTP_ERRORS => e # @TODO: log error via try_post https://gitlab.com/gitlab-org/gitlab/-/issues/219223 Gitlab::ErrorTracking.log_exception(e) - return + nil rescue # @TODO log ALLOW diff --git a/app/workers/delete_merged_branches_worker.rb b/app/workers/delete_merged_branches_worker.rb index ab3d42e5384..8d7026e2d1e 100644 --- a/app/workers/delete_merged_branches_worker.rb +++ b/app/workers/delete_merged_branches_worker.rb @@ -17,7 +17,6 @@ class DeleteMergedBranchesWorker # rubocop:disable Scalability/IdempotentWorker begin ::Branches::DeleteMergedService.new(project, user).execute rescue Gitlab::Access::AccessDeniedError - return end end end diff --git a/doc/operations/metrics/dashboards/templating_variables.md b/doc/operations/metrics/dashboards/templating_variables.md new file mode 100644 index 00000000000..a515742ea92 --- /dev/null +++ b/doc/operations/metrics/dashboards/templating_variables.md @@ -0,0 +1,128 @@ +--- +stage: Monitor +group: APM +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/#designated-technical-writers +--- + +# Templating variables for metrics dashboards + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214539) in GitLab 13.0. + +Templating variables can be used to make your metrics dashboard more versatile. + +`templating` is a top-level key in the +[dashboard YAML](yaml.md#dashboard-top-level-properties). +Define your variables in the `variables` key, under `templating`. The value of +the `variables` key should be a hash, and each key under `variables` +defines a templating variable on the dashboard, and may contain alphanumeric and underscore characters. + +A variable can be used in a Prometheus query in the same dashboard using the syntax +described [in Using Variables](variables.md). + +## `text` variable type + +CAUTION: **Warning:** +This variable type is an _alpha_ feature, and is subject to change at any time +without prior notice! + +For each `text` variable defined in the dashboard YAML, there will be a free text +box on the dashboard UI, allowing you to enter a value for each variable. + +The `text` variable type supports a simple and a full syntax. + +### Simple syntax + +This example creates a variable called `variable1`, with a default value +of `default value`: + +```yaml +templating: + variables: + variable1: 'default value' # `text` type variable with `default value` as its default. +``` + +### Full syntax + +This example creates a variable called `variable1`, with a default value of `default`. +The label for the text box on the UI will be the value of the `label` key: + +```yaml +templating: + variables: + variable1: # The variable name that can be used in queries. + label: 'Variable 1' # (Optional) label that will appear in the UI for this text box. + type: text + options: + default_value: 'default' # (Optional) default value. +``` + +## `custom` variable type + +CAUTION: **Warning:** +This variable type is an _alpha_ feature, and is subject to change at any time +without prior notice! + +Each `custom` variable defined in the dashboard YAML creates a dropdown +selector on the dashboard UI, allowing you to select a value for each variable. + +The `custom` variable type supports a simple and a full syntax. + +### Simple syntax + +This example creates a variable called `variable1`, with a default value of `value1`. +The dashboard UI will display a dropdown with `value1`, `value2` and `value3` +as the choices. + +```yaml +templating: + variables: + variable1: ['value1', 'value2', 'value3'] +``` + +### Full syntax + +This example creates a variable called `variable1`, with a default value of `value_option_2`. +The label for the text box on the UI will be the value of the `label` key. +The dashboard UI will display a dropdown with `Option 1` and `Option 2` +as the choices. + +If you select `Option 1` from the dropdown, the variable will be replaced with `value option 1`. +Similarly, if you select `Option 2`, the variable will be replaced with `value_option_2`: + +```yaml +templating: + variables: + variable1: # The variable name that can be used in queries. + label: 'Variable 1' # (Optional) label that will appear in the UI for this dropdown. + type: custom + options: + values: + - value: 'value option 1' # The value that will replace the variable in queries. + text: 'Option 1' # (Optional) Text that will appear in the UI dropdown. + - value: 'value_option_2' + text: 'Option 2' + default: true # (Optional) This option should be the default value of this variable. +``` + +## `metric_label_values` variable type + +CAUTION: **Warning:** +This variable type is an _alpha_ feature, and is subject to change at any time +without prior notice! + +### Full syntax + +This example creates a variable called `variable2`. The values of the dropdown will +be all the different values of the `backend` label in the Prometheus series described by +`up{env="production"}`. + +```yaml +templating: + variables: + variable2: # The variable name that can be interpolated in queries. + label: 'Variable 2' # (Optional) label that will appear in the UI for this dropdown. + type: metric_label_values + options: + series_selector: 'up{env="production"}' + label: 'backend' +``` diff --git a/doc/operations/metrics/dashboards/variables.md b/doc/operations/metrics/dashboards/variables.md new file mode 100644 index 00000000000..19b77a1ed87 --- /dev/null +++ b/doc/operations/metrics/dashboards/variables.md @@ -0,0 +1,59 @@ +--- +stage: Monitor +group: APM +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/#designated-technical-writers +--- + +# Using Variables + +## Query Variables + +Variables can be specified using double curly braces, such as `"{{ci_environment_slug}}"` ([added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20793) in GitLab 12.7). + +Support for the `"%{ci_environment_slug}"` format was +[removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31581) in GitLab 13.0. +Queries that continue to use the old format will show no data. + +## Predefined variables + +GitLab supports a limited set of [CI variables](../../../ci/variables/README.md) in the Prometheus query. This is particularly useful for identifying a specific environment, for example with `ci_environment_slug`. The supported variables are: + +- `ci_environment_slug` +- `kube_namespace` +- `ci_project_name` +- `ci_project_namespace` +- `ci_project_path` +- `ci_environment_name` +- `__range` + +NOTE: **Note:** +Variables for Prometheus queries must be lowercase. + +### __range + +The `__range` variable is useful in Prometheus +[range vector selectors](https://prometheus.io/docs/prometheus/latest/querying/basics/#range-vector-selectors). +Its value is the total number of seconds in the dashboard's time range. +For example, if the dashboard time range is set to 8 hours, the value of +`__range` is `28800s`. + +## User-defined variables + +[Variables can be defined](../../../operations/metrics/dashboards/yaml.md#templating-templating-properties) in a custom dashboard YAML file. + +## Query Variables from URL + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214500) in GitLab 13.0. + +GitLab supports setting custom variables through URL parameters. Surround the variable +name with double curly braces (`{{example}}`) to interpolate the variable in a query: + +```plaintext +avg(sum(container_memory_usage_bytes{container_name!="{{pod}}"}) by (job)) without (job) /1024/1024/1024' +``` + +The URL for this query would be: + +```plaintext +http://gitlab.com///-/environments//metrics?dashboard=.gitlab%2Fdashboards%2Fcustom.yml&pod=POD +``` diff --git a/doc/operations/metrics/dashboards/yaml.md b/doc/operations/metrics/dashboards/yaml.md index 501bfd29eb5..78d05b79492 100644 --- a/doc/operations/metrics/dashboards/yaml.md +++ b/doc/operations/metrics/dashboards/yaml.md @@ -29,7 +29,7 @@ The following tables outline the details of expected properties. | -------- | ---- | -------- | ----------- | | `variables` | hash | yes | Variables can be defined here. | -Read the documentation on [templating](../../../user/project/integrations/prometheus.md#templating-variables-for-metrics-dashboards). +Read the documentation on [templating](templating_variables.md). ## **Links (`links`) properties** diff --git a/doc/user/admin_area/merge_requests_approvals.md b/doc/user/admin_area/merge_requests_approvals.md index f380ff7b211..ac5ac98c54d 100644 --- a/doc/user/admin_area/merge_requests_approvals.md +++ b/doc/user/admin_area/merge_requests_approvals.md @@ -58,13 +58,13 @@ Maintainer role and above can modify these. This feature comes with two feature flags which are disabled by default. -- The configuration in Admin area is controlled via `admin_merge_request_approval_settings` -- The application of these rules is controlled via `project_merge_request_approval_settings` +- The configuration in Admin area is controlled via `admin_compliance_merge_request_approval_settings`. +- The application of these rules is controlled via `project_compliance_merge_request_approval_settings`. These feature flags can be managed by feature flag [API endpoint](../../api/features.md#set-or-create-a-feature) or by [GitLab administrators with access to the GitLab Rails console](../../administration/feature_flags.md) with the following commands: ```ruby -Feature.enable(:admin_merge_request_approval_settings) -Feature.enable(:project_merge_request_approval_settings) +Feature.enable(:admin_compliance_merge_request_approval_settings) +Feature.enable(:project_compliance_merge_request_approval_settings) ``` diff --git a/doc/user/project/clusters/add_remove_clusters.md b/doc/user/project/clusters/add_remove_clusters.md index 7deab9aae85..f581383022e 100644 --- a/doc/user/project/clusters/add_remove_clusters.md +++ b/doc/user/project/clusters/add_remove_clusters.md @@ -153,11 +153,6 @@ Amazon Elastic Kubernetes Service (EKS) at the project, group, or instance level If you have an existing Kubernetes cluster, you can add it to a project, group, or instance. -For more information, see information for adding an: - -- [Existing Kubernetes cluster](#existing-kubernetes-cluster), including GKE clusters. -- [Existing EKS cluster](add_eks_clusters.md#existing-eks-cluster). - NOTE: **Note:** Kubernetes integration is not supported for arm64 clusters. See the issue [Helm Tiller fails to install on arm64 cluster](https://gitlab.com/gitlab-org/gitlab/-/issues/29838) for details. diff --git a/doc/user/project/integrations/prometheus.md b/doc/user/project/integrations/prometheus.md index 445516b29cc..f038aa4a7de 100644 --- a/doc/user/project/integrations/prometheus.md +++ b/doc/user/project/integrations/prometheus.md @@ -168,60 +168,6 @@ A few fields are required: Multiple metrics can be displayed on the same chart if the fields **Name**, **Type**, and **Y-axis label** match between metrics. For example, a metric with **Name** `Requests Rate`, **Type** `Business`, and **Y-axis label** `rec / sec` would display on the same chart as a second metric with the same values. A **Legend label** is suggested if this feature is used. -#### Query Variables - -##### Predefined variables - -GitLab supports a limited set of [CI variables](../../../ci/variables/README.md) in the Prometheus query. This is particularly useful for identifying a specific environment, for example with `ci_environment_slug`. The supported variables are: - -- `ci_environment_slug` -- `kube_namespace` -- `ci_project_name` -- `ci_project_namespace` -- `ci_project_path` -- `ci_environment_name` -- `__range` - -NOTE: **Note:** -Variables for Prometheus queries must be lowercase. - -###### __range - -The `__range` variable is useful in Prometheus -[range vector selectors](https://prometheus.io/docs/prometheus/latest/querying/basics/#range-vector-selectors). -Its value is the total number of seconds in the dashboard's time range. -For example, if the dashboard time range is set to 8 hours, the value of -`__range` is `28800s`. - -##### User-defined variables - -[Variables can be defined](../../../operations/metrics/dashboards/yaml.md#templating-templating-properties) in a custom dashboard YAML file. - -##### Using variables - -Variables can be specified using double curly braces, such as `"{{ci_environment_slug}}"` ([added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20793) in GitLab 12.7). - -Support for the `"%{ci_environment_slug}"` format was -[removed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31581) in GitLab 13.0. -Queries that continue to use the old format will show no data. - -#### Query Variables from URL - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214500) in GitLab 13.0. - -GitLab supports setting custom variables through URL parameters. Surround the variable -name with double curly braces (`{{example}}`) to interpolate the variable in a query: - -```plaintext -avg(sum(container_memory_usage_bytes{container_name!="{{pod}}"}) by (job)) without (job) /1024/1024/1024' -``` - -The URL for this query would be: - -```plaintext -http://gitlab.com///-/environments//metrics?dashboard=.gitlab%2Fdashboards%2Fcustom.yml&pod=POD -``` - #### Editing additional metrics from the dashboard > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/208976) in GitLab 12.9. @@ -353,131 +299,6 @@ When **Metrics Dashboard YAML definition is invalid** at least one of the follow Metrics Dashboard YAML definition validation information is also available as a [GraphQL API field](../../../api/graphql/reference/index.md#metricsdashboard) -### Templating variables for metrics dashboards - -> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/214539) in GitLab 13.0. - -Templating variables can be used to make your metrics dashboard more versatile. - -#### Templating variable types - -`templating` is a top-level key in the -[dashboard YAML](../../../operations/metrics/dashboards/yaml.md#dashboard-top-level-properties). -Define your variables in the `variables` key, under `templating`. The value of -the `variables` key should be a hash, and each key under `variables` -defines a templating variable on the dashboard, and may contain alphanumeric and underscore characters. - -A variable can be used in a Prometheus query in the same dashboard using the syntax -described [here](#using-variables). - -##### `text` variable type - -CAUTION: **Warning:** -This variable type is an _alpha_ feature, and is subject to change at any time -without prior notice! - -For each `text` variable defined in the dashboard YAML, there will be a free text -box on the dashboard UI, allowing you to enter a value for each variable. - -The `text` variable type supports a simple and a full syntax. - -###### Simple syntax - -This example creates a variable called `variable1`, with a default value -of `default value`: - -```yaml -templating: - variables: - variable1: 'default value' # `text` type variable with `default value` as its default. -``` - -###### Full syntax - -This example creates a variable called `variable1`, with a default value of `default`. -The label for the text box on the UI will be the value of the `label` key: - -```yaml -templating: - variables: - variable1: # The variable name that can be used in queries. - label: 'Variable 1' # (Optional) label that will appear in the UI for this text box. - type: text - options: - default_value: 'default' # (Optional) default value. -``` - -##### `custom` variable type - -CAUTION: **Warning:** -This variable type is an _alpha_ feature, and is subject to change at any time -without prior notice! - -Each `custom` variable defined in the dashboard YAML creates a dropdown -selector on the dashboard UI, allowing you to select a value for each variable. - -The `custom` variable type supports a simple and a full syntax. - -###### Simple syntax - -This example creates a variable called `variable1`, with a default value of `value1`. -The dashboard UI will display a dropdown with `value1`, `value2` and `value3` -as the choices. - -```yaml -templating: - variables: - variable1: ['value1', 'value2', 'value3'] -``` - -###### Full syntax - -This example creates a variable called `variable1`, with a default value of `value_option_2`. -The label for the text box on the UI will be the value of the `label` key. -The dashboard UI will display a dropdown with `Option 1` and `Option 2` -as the choices. - -If you select `Option 1` from the dropdown, the variable will be replaced with `value option 1`. -Similarly, if you select `Option 2`, the variable will be replaced with `value_option_2`: - -```yaml -templating: - variables: - variable1: # The variable name that can be used in queries. - label: 'Variable 1' # (Optional) label that will appear in the UI for this dropdown. - type: custom - options: - values: - - value: 'value option 1' # The value that will replace the variable in queries. - text: 'Option 1' # (Optional) Text that will appear in the UI dropdown. - - value: 'value_option_2' - text: 'Option 2' - default: true # (Optional) This option should be the default value of this variable. -``` - -##### `metric_label_values` variable type - -CAUTION: **Warning:** -This variable type is an _alpha_ feature, and is subject to change at any time -without prior notice! - -###### Full syntax - -This example creates a variable called `variable2`. The values of the dropdown will -be all the different values of the `backend` label in the Prometheus series described by -`up{env="production"}`. - -```yaml -templating: - variables: - variable2: # The variable name that can be interpolated in queries. - label: 'Variable 2' # (Optional) label that will appear in the UI for this dropdown. - type: metric_label_values - options: - series_selector: 'up{env="production"}' - label: 'backend' -``` - ### Add related links to custom dashboards > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/216385) in GitLab 13.1. diff --git a/lib/api/api.rb b/lib/api/api.rb index 73e6bc4d767..bf685706bed 100644 --- a/lib/api/api.rb +++ b/lib/api/api.rb @@ -133,6 +133,8 @@ module API mount ::API::Boards mount ::API::Branches mount ::API::BroadcastMessages + mount ::API::Ci::Pipelines + mount ::API::Ci::PipelineSchedules mount ::API::Ci::Runner mount ::API::Ci::Runners mount ::API::Commits @@ -179,8 +181,6 @@ module API mount ::API::NotificationSettings mount ::API::Pages mount ::API::PagesDomains - mount ::API::Pipelines - mount ::API::PipelineSchedules mount ::API::ProjectClusters mount ::API::ProjectContainerRepositories mount ::API::ProjectEvents diff --git a/lib/api/ci/pipeline_schedules.rb b/lib/api/ci/pipeline_schedules.rb new file mode 100644 index 00000000000..80ad8aa04dd --- /dev/null +++ b/lib/api/ci/pipeline_schedules.rb @@ -0,0 +1,217 @@ +# frozen_string_literal: true + +module API + module Ci + class PipelineSchedules < Grape::API::Instance + include PaginationParams + + before { authenticate! } + + params do + requires :id, type: String, desc: 'The ID of a project' + end + resource :projects, requirements: ::API::API::NAMESPACE_OR_PROJECT_REQUIREMENTS do + desc 'Get all pipeline schedules' do + success Entities::PipelineSchedule + end + params do + use :pagination + optional :scope, type: String, values: %w[active inactive], + desc: 'The scope of pipeline schedules' + end + # rubocop: disable CodeReuse/ActiveRecord + get ':id/pipeline_schedules' do + authorize! :read_pipeline_schedule, user_project + + schedules = ::Ci::PipelineSchedulesFinder.new(user_project).execute(scope: params[:scope]) + .preload([:owner, :last_pipeline]) + present paginate(schedules), with: Entities::PipelineSchedule + end + # rubocop: enable CodeReuse/ActiveRecord + + desc 'Get a single pipeline schedule' do + success Entities::PipelineScheduleDetails + end + params do + requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' + end + get ':id/pipeline_schedules/:pipeline_schedule_id' do + present pipeline_schedule, with: Entities::PipelineScheduleDetails + end + + desc 'Create a new pipeline schedule' do + success Entities::PipelineScheduleDetails + end + params do + requires :description, type: String, desc: 'The description of pipeline schedule' + requires :ref, type: String, desc: 'The branch/tag name will be triggered', allow_blank: false + requires :cron, type: String, desc: 'The cron' + optional :cron_timezone, type: String, default: 'UTC', desc: 'The timezone' + optional :active, type: Boolean, default: true, desc: 'The activation of pipeline schedule' + end + post ':id/pipeline_schedules' do + authorize! :create_pipeline_schedule, user_project + + pipeline_schedule = ::Ci::CreatePipelineScheduleService + .new(user_project, current_user, declared_params(include_missing: false)) + .execute + + if pipeline_schedule.persisted? + present pipeline_schedule, with: Entities::PipelineScheduleDetails + else + render_validation_error!(pipeline_schedule) + end + end + + desc 'Edit a pipeline schedule' do + success Entities::PipelineScheduleDetails + end + params do + requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' + optional :description, type: String, desc: 'The description of pipeline schedule' + optional :ref, type: String, desc: 'The branch/tag name will be triggered' + optional :cron, type: String, desc: 'The cron' + optional :cron_timezone, type: String, desc: 'The timezone' + optional :active, type: Boolean, desc: 'The activation of pipeline schedule' + end + put ':id/pipeline_schedules/:pipeline_schedule_id' do + authorize! :update_pipeline_schedule, pipeline_schedule + + if pipeline_schedule.update(declared_params(include_missing: false)) + present pipeline_schedule, with: Entities::PipelineScheduleDetails + else + render_validation_error!(pipeline_schedule) + end + end + + desc 'Take ownership of a pipeline schedule' do + success Entities::PipelineScheduleDetails + end + params do + requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' + end + post ':id/pipeline_schedules/:pipeline_schedule_id/take_ownership' do + authorize! :update_pipeline_schedule, pipeline_schedule + + if pipeline_schedule.own!(current_user) + present pipeline_schedule, with: Entities::PipelineScheduleDetails + else + render_validation_error!(pipeline_schedule) + end + end + + desc 'Delete a pipeline schedule' do + success Entities::PipelineScheduleDetails + end + params do + requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' + end + delete ':id/pipeline_schedules/:pipeline_schedule_id' do + authorize! :admin_pipeline_schedule, pipeline_schedule + + destroy_conditionally!(pipeline_schedule) + end + + desc 'Play a scheduled pipeline immediately' do + detail 'This feature was added in GitLab 12.8' + end + params do + requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' + end + post ':id/pipeline_schedules/:pipeline_schedule_id/play' do + authorize! :play_pipeline_schedule, pipeline_schedule + + job_id = RunPipelineScheduleWorker # rubocop:disable CodeReuse/Worker + .perform_async(pipeline_schedule.id, current_user.id) + + if job_id + created! + else + render_api_error!('Unable to schedule pipeline run immediately', 500) + end + end + + desc 'Create a new pipeline schedule variable' do + success Entities::Variable + end + params do + requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' + requires :key, type: String, desc: 'The key of the variable' + requires :value, type: String, desc: 'The value of the variable' + optional :variable_type, type: String, values: ::Ci::PipelineScheduleVariable.variable_types.keys, desc: 'The type of variable, must be one of env_var or file. Defaults to env_var' + end + post ':id/pipeline_schedules/:pipeline_schedule_id/variables' do + authorize! :update_pipeline_schedule, pipeline_schedule + + variable_params = declared_params(include_missing: false) + variable = pipeline_schedule.variables.create(variable_params) + if variable.persisted? + present variable, with: Entities::Variable + else + render_validation_error!(variable) + end + end + + desc 'Edit a pipeline schedule variable' do + success Entities::Variable + end + params do + requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' + requires :key, type: String, desc: 'The key of the variable' + optional :value, type: String, desc: 'The value of the variable' + optional :variable_type, type: String, values: ::Ci::PipelineScheduleVariable.variable_types.keys, desc: 'The type of variable, must be one of env_var or file' + end + put ':id/pipeline_schedules/:pipeline_schedule_id/variables/:key' do + authorize! :update_pipeline_schedule, pipeline_schedule + + if pipeline_schedule_variable.update(declared_params(include_missing: false)) + present pipeline_schedule_variable, with: Entities::Variable + else + render_validation_error!(pipeline_schedule_variable) + end + end + + desc 'Delete a pipeline schedule variable' do + success Entities::Variable + end + params do + requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' + requires :key, type: String, desc: 'The key of the variable' + end + delete ':id/pipeline_schedules/:pipeline_schedule_id/variables/:key' do + authorize! :admin_pipeline_schedule, pipeline_schedule + + status :accepted + present pipeline_schedule_variable.destroy, with: Entities::Variable + end + end + + helpers do + # rubocop: disable CodeReuse/ActiveRecord + def pipeline_schedule + @pipeline_schedule ||= + user_project + .pipeline_schedules + .preload(:owner, :last_pipeline) + .find_by(id: params.delete(:pipeline_schedule_id)).tap do |pipeline_schedule| + unless can?(current_user, :read_pipeline_schedule, pipeline_schedule) + not_found!('Pipeline Schedule') + end + end + end + # rubocop: enable CodeReuse/ActiveRecord + + # rubocop: disable CodeReuse/ActiveRecord + def pipeline_schedule_variable + @pipeline_schedule_variable ||= + pipeline_schedule.variables.find_by(key: params[:key]).tap do |pipeline_schedule_variable| + unless pipeline_schedule_variable + not_found!('Pipeline Schedule Variable') + end + end + end + # rubocop: enable CodeReuse/ActiveRecord + end + end + end +end diff --git a/lib/api/ci/pipelines.rb b/lib/api/ci/pipelines.rb new file mode 100644 index 00000000000..33bb8b38d92 --- /dev/null +++ b/lib/api/ci/pipelines.rb @@ -0,0 +1,189 @@ +# frozen_string_literal: true + +module API + module Ci + class Pipelines < Grape::API::Instance + include PaginationParams + + before { authenticate_non_get! } + + params do + requires :id, type: String, desc: 'The project ID' + end + resource :projects, requirements: ::API::API::NAMESPACE_OR_PROJECT_REQUIREMENTS do + desc 'Get all Pipelines of the project' do + detail 'This feature was introduced in GitLab 8.11.' + success Entities::PipelineBasic + end + params do + use :pagination + optional :scope, type: String, values: %w[running pending finished branches tags], + desc: 'The scope of pipelines' + optional :status, type: String, values: ::Ci::HasStatus::AVAILABLE_STATUSES, + desc: 'The status of pipelines' + optional :ref, type: String, desc: 'The ref of pipelines' + optional :sha, type: String, desc: 'The sha of pipelines' + optional :yaml_errors, type: Boolean, desc: 'Returns pipelines with invalid configurations' + optional :name, type: String, desc: 'The name of the user who triggered pipelines' + optional :username, type: String, desc: 'The username of the user who triggered pipelines' + optional :updated_before, type: DateTime, desc: 'Return pipelines updated before the specified datetime. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ' + optional :updated_after, type: DateTime, desc: 'Return pipelines updated after the specified datetime. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ' + optional :order_by, type: String, values: ::Ci::PipelinesFinder::ALLOWED_INDEXED_COLUMNS, default: 'id', + desc: 'Order pipelines' + optional :sort, type: String, values: %w[asc desc], default: 'desc', + desc: 'Sort pipelines' + end + get ':id/pipelines' do + authorize! :read_pipeline, user_project + authorize! :read_build, user_project + + pipelines = ::Ci::PipelinesFinder.new(user_project, current_user, params).execute + present paginate(pipelines), with: Entities::PipelineBasic + end + + desc 'Create a new pipeline' do + detail 'This feature was introduced in GitLab 8.14' + success Entities::Pipeline + end + params do + requires :ref, type: String, desc: 'Reference' + optional :variables, Array, desc: 'Array of variables available in the pipeline' + end + post ':id/pipeline' do + Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42124') + + authorize! :create_pipeline, user_project + + pipeline_params = declared_params(include_missing: false) + .merge(variables_attributes: params[:variables]) + .except(:variables) + + new_pipeline = ::Ci::CreatePipelineService.new(user_project, + current_user, + pipeline_params) + .execute(:api, ignore_skip_ci: true, save_on_errors: false) + + if new_pipeline.persisted? + present new_pipeline, with: Entities::Pipeline + else + render_validation_error!(new_pipeline) + end + end + + desc 'Gets a the latest pipeline for the project branch' do + detail 'This feature was introduced in GitLab 12.3' + success Entities::Pipeline + end + params do + optional :ref, type: String, desc: 'branch ref of pipeline' + end + get ':id/pipelines/latest' do + authorize! :read_pipeline, latest_pipeline + + present latest_pipeline, with: Entities::Pipeline + end + + desc 'Gets a specific pipeline for the project' do + detail 'This feature was introduced in GitLab 8.11' + success Entities::Pipeline + end + params do + requires :pipeline_id, type: Integer, desc: 'The pipeline ID' + end + get ':id/pipelines/:pipeline_id' do + authorize! :read_pipeline, pipeline + + present pipeline, with: Entities::Pipeline + end + + desc 'Gets the variables for a given pipeline' do + detail 'This feature was introduced in GitLab 11.11' + success Entities::Variable + end + params do + requires :pipeline_id, type: Integer, desc: 'The pipeline ID' + end + get ':id/pipelines/:pipeline_id/variables' do + authorize! :read_pipeline_variable, pipeline + + present pipeline.variables, with: Entities::Variable + end + + desc 'Gets the test report for a given pipeline' do + detail 'This feature was introduced in GitLab 13.0. Disabled by default behind feature flag `junit_pipeline_view`' + success TestReportEntity + end + params do + requires :pipeline_id, type: Integer, desc: 'The pipeline ID' + end + get ':id/pipelines/:pipeline_id/test_report' do + not_found! unless Feature.enabled?(:junit_pipeline_view, user_project) + + authorize! :read_build, pipeline + + present pipeline.test_reports, with: TestReportEntity, details: true + end + + desc 'Deletes a pipeline' do + detail 'This feature was introduced in GitLab 11.6' + http_codes [[204, 'Pipeline was deleted'], [403, 'Forbidden']] + end + params do + requires :pipeline_id, type: Integer, desc: 'The pipeline ID' + end + delete ':id/pipelines/:pipeline_id' do + authorize! :destroy_pipeline, pipeline + + destroy_conditionally!(pipeline) do + ::Ci::DestroyPipelineService.new(user_project, current_user).execute(pipeline) + end + end + + desc 'Retry builds in the pipeline' do + detail 'This feature was introduced in GitLab 8.11.' + success Entities::Pipeline + end + params do + requires :pipeline_id, type: Integer, desc: 'The pipeline ID' + end + post ':id/pipelines/:pipeline_id/retry' do + authorize! :update_pipeline, pipeline + + pipeline.retry_failed(current_user) + + present pipeline, with: Entities::Pipeline + end + + desc 'Cancel all builds in the pipeline' do + detail 'This feature was introduced in GitLab 8.11.' + success Entities::Pipeline + end + params do + requires :pipeline_id, type: Integer, desc: 'The pipeline ID' + end + post ':id/pipelines/:pipeline_id/cancel' do + authorize! :update_pipeline, pipeline + + pipeline.cancel_running + + status 200 + present pipeline.reset, with: Entities::Pipeline + end + end + + helpers do + def pipeline + strong_memoize(:pipeline) do + user_project.ci_pipelines.find(params[:pipeline_id]) + end + end + + def latest_pipeline + strong_memoize(:latest_pipeline) do + user_project.latest_pipeline_for_ref(params[:ref]) + end + end + end + end + end +end diff --git a/lib/api/pipeline_schedules.rb b/lib/api/pipeline_schedules.rb deleted file mode 100644 index 9af16f61967..00000000000 --- a/lib/api/pipeline_schedules.rb +++ /dev/null @@ -1,215 +0,0 @@ -# frozen_string_literal: true - -module API - class PipelineSchedules < Grape::API::Instance - include PaginationParams - - before { authenticate! } - - params do - requires :id, type: String, desc: 'The ID of a project' - end - resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do - desc 'Get all pipeline schedules' do - success Entities::PipelineSchedule - end - params do - use :pagination - optional :scope, type: String, values: %w[active inactive], - desc: 'The scope of pipeline schedules' - end - # rubocop: disable CodeReuse/ActiveRecord - get ':id/pipeline_schedules' do - authorize! :read_pipeline_schedule, user_project - - schedules = ::Ci::PipelineSchedulesFinder.new(user_project).execute(scope: params[:scope]) - .preload([:owner, :last_pipeline]) - present paginate(schedules), with: Entities::PipelineSchedule - end - # rubocop: enable CodeReuse/ActiveRecord - - desc 'Get a single pipeline schedule' do - success Entities::PipelineScheduleDetails - end - params do - requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' - end - get ':id/pipeline_schedules/:pipeline_schedule_id' do - present pipeline_schedule, with: Entities::PipelineScheduleDetails - end - - desc 'Create a new pipeline schedule' do - success Entities::PipelineScheduleDetails - end - params do - requires :description, type: String, desc: 'The description of pipeline schedule' - requires :ref, type: String, desc: 'The branch/tag name will be triggered', allow_blank: false - requires :cron, type: String, desc: 'The cron' - optional :cron_timezone, type: String, default: 'UTC', desc: 'The timezone' - optional :active, type: Boolean, default: true, desc: 'The activation of pipeline schedule' - end - post ':id/pipeline_schedules' do - authorize! :create_pipeline_schedule, user_project - - pipeline_schedule = ::Ci::CreatePipelineScheduleService - .new(user_project, current_user, declared_params(include_missing: false)) - .execute - - if pipeline_schedule.persisted? - present pipeline_schedule, with: Entities::PipelineScheduleDetails - else - render_validation_error!(pipeline_schedule) - end - end - - desc 'Edit a pipeline schedule' do - success Entities::PipelineScheduleDetails - end - params do - requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' - optional :description, type: String, desc: 'The description of pipeline schedule' - optional :ref, type: String, desc: 'The branch/tag name will be triggered' - optional :cron, type: String, desc: 'The cron' - optional :cron_timezone, type: String, desc: 'The timezone' - optional :active, type: Boolean, desc: 'The activation of pipeline schedule' - end - put ':id/pipeline_schedules/:pipeline_schedule_id' do - authorize! :update_pipeline_schedule, pipeline_schedule - - if pipeline_schedule.update(declared_params(include_missing: false)) - present pipeline_schedule, with: Entities::PipelineScheduleDetails - else - render_validation_error!(pipeline_schedule) - end - end - - desc 'Take ownership of a pipeline schedule' do - success Entities::PipelineScheduleDetails - end - params do - requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' - end - post ':id/pipeline_schedules/:pipeline_schedule_id/take_ownership' do - authorize! :update_pipeline_schedule, pipeline_schedule - - if pipeline_schedule.own!(current_user) - present pipeline_schedule, with: Entities::PipelineScheduleDetails - else - render_validation_error!(pipeline_schedule) - end - end - - desc 'Delete a pipeline schedule' do - success Entities::PipelineScheduleDetails - end - params do - requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' - end - delete ':id/pipeline_schedules/:pipeline_schedule_id' do - authorize! :admin_pipeline_schedule, pipeline_schedule - - destroy_conditionally!(pipeline_schedule) - end - - desc 'Play a scheduled pipeline immediately' do - detail 'This feature was added in GitLab 12.8' - end - params do - requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' - end - post ':id/pipeline_schedules/:pipeline_schedule_id/play' do - authorize! :play_pipeline_schedule, pipeline_schedule - - job_id = RunPipelineScheduleWorker # rubocop:disable CodeReuse/Worker - .perform_async(pipeline_schedule.id, current_user.id) - - if job_id - created! - else - render_api_error!('Unable to schedule pipeline run immediately', 500) - end - end - - desc 'Create a new pipeline schedule variable' do - success Entities::Variable - end - params do - requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' - requires :key, type: String, desc: 'The key of the variable' - requires :value, type: String, desc: 'The value of the variable' - optional :variable_type, type: String, values: ::Ci::PipelineScheduleVariable.variable_types.keys, desc: 'The type of variable, must be one of env_var or file. Defaults to env_var' - end - post ':id/pipeline_schedules/:pipeline_schedule_id/variables' do - authorize! :update_pipeline_schedule, pipeline_schedule - - variable_params = declared_params(include_missing: false) - variable = pipeline_schedule.variables.create(variable_params) - if variable.persisted? - present variable, with: Entities::Variable - else - render_validation_error!(variable) - end - end - - desc 'Edit a pipeline schedule variable' do - success Entities::Variable - end - params do - requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' - requires :key, type: String, desc: 'The key of the variable' - optional :value, type: String, desc: 'The value of the variable' - optional :variable_type, type: String, values: ::Ci::PipelineScheduleVariable.variable_types.keys, desc: 'The type of variable, must be one of env_var or file' - end - put ':id/pipeline_schedules/:pipeline_schedule_id/variables/:key' do - authorize! :update_pipeline_schedule, pipeline_schedule - - if pipeline_schedule_variable.update(declared_params(include_missing: false)) - present pipeline_schedule_variable, with: Entities::Variable - else - render_validation_error!(pipeline_schedule_variable) - end - end - - desc 'Delete a pipeline schedule variable' do - success Entities::Variable - end - params do - requires :pipeline_schedule_id, type: Integer, desc: 'The pipeline schedule id' - requires :key, type: String, desc: 'The key of the variable' - end - delete ':id/pipeline_schedules/:pipeline_schedule_id/variables/:key' do - authorize! :admin_pipeline_schedule, pipeline_schedule - - status :accepted - present pipeline_schedule_variable.destroy, with: Entities::Variable - end - end - - helpers do - # rubocop: disable CodeReuse/ActiveRecord - def pipeline_schedule - @pipeline_schedule ||= - user_project - .pipeline_schedules - .preload(:owner, :last_pipeline) - .find_by(id: params.delete(:pipeline_schedule_id)).tap do |pipeline_schedule| - unless can?(current_user, :read_pipeline_schedule, pipeline_schedule) - not_found!('Pipeline Schedule') - end - end - end - # rubocop: enable CodeReuse/ActiveRecord - - # rubocop: disable CodeReuse/ActiveRecord - def pipeline_schedule_variable - @pipeline_schedule_variable ||= - pipeline_schedule.variables.find_by(key: params[:key]).tap do |pipeline_schedule_variable| - unless pipeline_schedule_variable - not_found!('Pipeline Schedule Variable') - end - end - end - # rubocop: enable CodeReuse/ActiveRecord - end - end -end diff --git a/lib/api/pipelines.rb b/lib/api/pipelines.rb deleted file mode 100644 index 1aac7b7deb4..00000000000 --- a/lib/api/pipelines.rb +++ /dev/null @@ -1,187 +0,0 @@ -# frozen_string_literal: true - -module API - class Pipelines < Grape::API::Instance - include PaginationParams - - before { authenticate_non_get! } - - params do - requires :id, type: String, desc: 'The project ID' - end - resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do - desc 'Get all Pipelines of the project' do - detail 'This feature was introduced in GitLab 8.11.' - success Entities::PipelineBasic - end - params do - use :pagination - optional :scope, type: String, values: %w[running pending finished branches tags], - desc: 'The scope of pipelines' - optional :status, type: String, values: ::Ci::HasStatus::AVAILABLE_STATUSES, - desc: 'The status of pipelines' - optional :ref, type: String, desc: 'The ref of pipelines' - optional :sha, type: String, desc: 'The sha of pipelines' - optional :yaml_errors, type: Boolean, desc: 'Returns pipelines with invalid configurations' - optional :name, type: String, desc: 'The name of the user who triggered pipelines' - optional :username, type: String, desc: 'The username of the user who triggered pipelines' - optional :updated_before, type: DateTime, desc: 'Return pipelines updated before the specified datetime. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ' - optional :updated_after, type: DateTime, desc: 'Return pipelines updated after the specified datetime. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ' - optional :order_by, type: String, values: ::Ci::PipelinesFinder::ALLOWED_INDEXED_COLUMNS, default: 'id', - desc: 'Order pipelines' - optional :sort, type: String, values: %w[asc desc], default: 'desc', - desc: 'Sort pipelines' - end - get ':id/pipelines' do - authorize! :read_pipeline, user_project - authorize! :read_build, user_project - - pipelines = ::Ci::PipelinesFinder.new(user_project, current_user, params).execute - present paginate(pipelines), with: Entities::PipelineBasic - end - - desc 'Create a new pipeline' do - detail 'This feature was introduced in GitLab 8.14' - success Entities::Pipeline - end - params do - requires :ref, type: String, desc: 'Reference' - optional :variables, Array, desc: 'Array of variables available in the pipeline' - end - post ':id/pipeline' do - Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-foss/issues/42124') - - authorize! :create_pipeline, user_project - - pipeline_params = declared_params(include_missing: false) - .merge(variables_attributes: params[:variables]) - .except(:variables) - - new_pipeline = ::Ci::CreatePipelineService.new(user_project, - current_user, - pipeline_params) - .execute(:api, ignore_skip_ci: true, save_on_errors: false) - - if new_pipeline.persisted? - present new_pipeline, with: Entities::Pipeline - else - render_validation_error!(new_pipeline) - end - end - - desc 'Gets a the latest pipeline for the project branch' do - detail 'This feature was introduced in GitLab 12.3' - success Entities::Pipeline - end - params do - optional :ref, type: String, desc: 'branch ref of pipeline' - end - get ':id/pipelines/latest' do - authorize! :read_pipeline, latest_pipeline - - present latest_pipeline, with: Entities::Pipeline - end - - desc 'Gets a specific pipeline for the project' do - detail 'This feature was introduced in GitLab 8.11' - success Entities::Pipeline - end - params do - requires :pipeline_id, type: Integer, desc: 'The pipeline ID' - end - get ':id/pipelines/:pipeline_id' do - authorize! :read_pipeline, pipeline - - present pipeline, with: Entities::Pipeline - end - - desc 'Gets the variables for a given pipeline' do - detail 'This feature was introduced in GitLab 11.11' - success Entities::Variable - end - params do - requires :pipeline_id, type: Integer, desc: 'The pipeline ID' - end - get ':id/pipelines/:pipeline_id/variables' do - authorize! :read_pipeline_variable, pipeline - - present pipeline.variables, with: Entities::Variable - end - - desc 'Gets the test report for a given pipeline' do - detail 'This feature was introduced in GitLab 13.0. Disabled by default behind feature flag `junit_pipeline_view`' - success TestReportEntity - end - params do - requires :pipeline_id, type: Integer, desc: 'The pipeline ID' - end - get ':id/pipelines/:pipeline_id/test_report' do - not_found! unless Feature.enabled?(:junit_pipeline_view, user_project) - - authorize! :read_build, pipeline - - present pipeline.test_reports, with: TestReportEntity, details: true - end - - desc 'Deletes a pipeline' do - detail 'This feature was introduced in GitLab 11.6' - http_codes [[204, 'Pipeline was deleted'], [403, 'Forbidden']] - end - params do - requires :pipeline_id, type: Integer, desc: 'The pipeline ID' - end - delete ':id/pipelines/:pipeline_id' do - authorize! :destroy_pipeline, pipeline - - destroy_conditionally!(pipeline) do - ::Ci::DestroyPipelineService.new(user_project, current_user).execute(pipeline) - end - end - - desc 'Retry builds in the pipeline' do - detail 'This feature was introduced in GitLab 8.11.' - success Entities::Pipeline - end - params do - requires :pipeline_id, type: Integer, desc: 'The pipeline ID' - end - post ':id/pipelines/:pipeline_id/retry' do - authorize! :update_pipeline, pipeline - - pipeline.retry_failed(current_user) - - present pipeline, with: Entities::Pipeline - end - - desc 'Cancel all builds in the pipeline' do - detail 'This feature was introduced in GitLab 8.11.' - success Entities::Pipeline - end - params do - requires :pipeline_id, type: Integer, desc: 'The pipeline ID' - end - post ':id/pipelines/:pipeline_id/cancel' do - authorize! :update_pipeline, pipeline - - pipeline.cancel_running - - status 200 - present pipeline.reset, with: Entities::Pipeline - end - end - - helpers do - def pipeline - strong_memoize(:pipeline) do - user_project.ci_pipelines.find(params[:pipeline_id]) - end - end - - def latest_pipeline - strong_memoize(:latest_pipeline) do - user_project.latest_pipeline_for_ref(params[:ref]) - end - end - end - end -end diff --git a/lib/gitlab/ci/pipeline/chain/validate/abilities.rb b/lib/gitlab/ci/pipeline/chain/validate/abilities.rb index a30b6c6ef0e..769d0dffd0b 100644 --- a/lib/gitlab/ci/pipeline/chain/validate/abilities.rb +++ b/lib/gitlab/ci/pipeline/chain/validate/abilities.rb @@ -19,7 +19,7 @@ module Gitlab end unless allowed_to_write_ref? - return error("Insufficient permissions for protected ref '#{command.ref}'") + error("Insufficient permissions for protected ref '#{command.ref}'") end end diff --git a/lib/gitlab/ci/pipeline/chain/validate/repository.rb b/lib/gitlab/ci/pipeline/chain/validate/repository.rb index 8f5445850d7..7977ce90443 100644 --- a/lib/gitlab/ci/pipeline/chain/validate/repository.rb +++ b/lib/gitlab/ci/pipeline/chain/validate/repository.rb @@ -18,7 +18,7 @@ module Gitlab end if @command.ambiguous_ref? - return error('Ref is ambiguous') + error('Ref is ambiguous') end end diff --git a/lib/gitlab/git_ref_validator.rb b/lib/gitlab/git_ref_validator.rb index dfff6823689..1330b06bf9c 100644 --- a/lib/gitlab/git_ref_validator.rb +++ b/lib/gitlab/git_ref_validator.rb @@ -19,7 +19,7 @@ module Gitlab begin Rugged::Reference.valid_name?("refs/heads/#{ref_name}") rescue ArgumentError - return false + false end end @@ -35,7 +35,7 @@ module Gitlab begin Rugged::Reference.valid_name?(expanded_name) rescue ArgumentError - return false + false end end end diff --git a/lib/gitlab/gitaly_client/repository_service.rb b/lib/gitlab/gitaly_client/repository_service.rb index 5b119fe616a..20ad6d0184b 100644 --- a/lib/gitlab/gitaly_client/repository_service.rb +++ b/lib/gitlab/gitaly_client/repository_service.rb @@ -201,9 +201,9 @@ module Gitlab response = GitalyClient.call(@storage, :repository_service, :fsck, request, timeout: GitalyClient.long_timeout) if response.error.empty? - return "", 0 + ["", 0] else - return response.error.b, 1 + [response.error.b, 1] end end diff --git a/lib/gitlab/middleware/go.rb b/lib/gitlab/middleware/go.rb index abdbccd3aa8..47d0b9ba8cb 100644 --- a/lib/gitlab/middleware/go.rb +++ b/lib/gitlab/middleware/go.rb @@ -101,7 +101,7 @@ module Gitlab if project # If a project is found and the user has access, we return the full project path - return project.full_path, project.default_branch + [project.full_path, project.default_branch] else # If not, we return the first two components as if it were a simple `namespace/project` path, # so that we don't reveal the existence of a nested project the user doesn't have access to. @@ -112,7 +112,7 @@ module Gitlab # `go get gitlab.com/group/subgroup/project/subpackage` will not work for private projects. # `go get gitlab.com/group/subgroup/project.git/subpackage` will work, since Go is smart enough # to figure that out. `import 'gitlab.com/...'` behaves the same as `go get`. - return simple_project_path, 'master' + [simple_project_path, 'master'] end end diff --git a/lib/gitlab/utils.rb b/lib/gitlab/utils.rb index e80cc51dc3b..5dfe8fc7ae3 100644 --- a/lib/gitlab/utils.rb +++ b/lib/gitlab/utils.rb @@ -56,7 +56,7 @@ module Gitlab # * Maximum length is 63 bytes # * First/Last Character is not a hyphen def slugify(str) - return str.downcase + str.downcase .gsub(/[^a-z0-9]/, '-')[0..62] .gsub(/(\A-+|-+\z)/, '') end diff --git a/lib/google_api/auth.rb b/lib/google_api/auth.rb index 319e5d2063c..7d9ff579c92 100644 --- a/lib/google_api/auth.rb +++ b/lib/google_api/auth.rb @@ -22,7 +22,7 @@ module GoogleApi def get_token(code) ret = client.auth_code.get_token(code, redirect_uri: redirect_uri) - return ret.token, ret.expires_at + [ret.token, ret.expires_at] end protected diff --git a/spec/requests/api/pipeline_schedules_spec.rb b/spec/requests/api/ci/pipeline_schedules_spec.rb similarity index 99% rename from spec/requests/api/pipeline_schedules_spec.rb rename to spec/requests/api/ci/pipeline_schedules_spec.rb index 86f3ff54b83..e0199b7b51c 100644 --- a/spec/requests/api/pipeline_schedules_spec.rb +++ b/spec/requests/api/ci/pipeline_schedules_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe API::PipelineSchedules do +RSpec.describe API::Ci::PipelineSchedules do let_it_be(:developer) { create(:user) } let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project, :repository, public_builds: false) } @@ -24,7 +24,7 @@ RSpec.describe API::PipelineSchedules do .each do |pipeline_schedule| create(:user).tap do |user| project.add_developer(user) - pipeline_schedule.update(owner: user) + pipeline_schedule.update!(owner: user) end pipeline_schedule.pipelines << build(:ci_pipeline, project: project) end diff --git a/spec/requests/api/pipelines_spec.rb b/spec/requests/api/ci/pipelines_spec.rb similarity index 99% rename from spec/requests/api/pipelines_spec.rb rename to spec/requests/api/ci/pipelines_spec.rb index b9bc8eabf2c..c9ca806e2c4 100644 --- a/spec/requests/api/pipelines_spec.rb +++ b/spec/requests/api/ci/pipelines_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe API::Pipelines do +RSpec.describe API::Ci::Pipelines do let_it_be(:user) { create(:user) } let_it_be(:non_member) { create(:user) }