diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-24 03:09:52 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-24 03:09:52 +0300 |
commit | 0abfd0b478192436e7328469320923a04885a3b7 (patch) | |
tree | 89d0c8221a93de4bddf86e83eae08b3c18bd6c1a | |
parent | 4e7abe540dbd1d170bfb2b3594e645cbfb48cac3 (diff) |
Add latest changes from gitlab-org/gitlab@master
29 files changed, 464 insertions, 145 deletions
diff --git a/.gitlab/ci/database.gitlab-ci.yml b/.gitlab/ci/database.gitlab-ci.yml index ace968ec249..6fd9ef62953 100644 --- a/.gitlab/ci/database.gitlab-ci.yml +++ b/.gitlab/ci/database.gitlab-ci.yml @@ -1,6 +1,36 @@ include: - local: .gitlab/ci/rails/shared.gitlab-ci.yml +db:rollback single-db-ci-connection: + extends: + - db:rollback + - .single-db-ci-connection + - .rails:rules:single-db-ci-connection + +db:migrate:reset single-db-ci-connection: + extends: + - db:migrate:reset + - .single-db-ci-connection + - .rails:rules:single-db-ci-connection + +db:check-schema-single-db-ci-connection: + extends: + - db:check-schema + - .single-db-ci-connection + - .rails:rules:single-db-ci-connection + +db:post_deployment_migrations_validator-single-db-ci-connection: + extends: + - db:post_deployment_migrations_validator + - .single-db-ci-connection + - .rails:rules:db:check-migrations-single-db-ci-connection + +db:backup_and_restore single-db-ci-connection: + extends: + - db:backup_and_restore + - .single-db-ci-connection + - .rails:rules:db-backup + db:rollback: extends: - .db-job-base @@ -97,7 +127,7 @@ db:backup_and_restore: GITLAB_ASSUME_YES: "1" script: - . scripts/prepare_build.sh - - bundle exec rake db:drop db:create db:structure:load db:seed_fu + - bundle exec rake db:drop db:create db:schema:load db:seed_fu - mkdir -p tmp/tests/public/uploads tmp/tests/{artifacts,pages,lfs-objects,terraform_state,registry,packages} - bundle exec rake gitlab:backup:create - date diff --git a/.gitlab/ci/rails.gitlab-ci.yml b/.gitlab/ci/rails.gitlab-ci.yml index 671325101e2..188e3519772 100644 --- a/.gitlab/ci/rails.gitlab-ci.yml +++ b/.gitlab/ci/rails.gitlab-ci.yml @@ -105,6 +105,18 @@ rspec background_migration pg12 single-db: - .single-db-rspec - .rails:rules:single-db +rspec migration pg12 single-db-ci-connection: + extends: + - rspec migration pg12 + - .single-db-rspec + - .rails:rules:single-db-ci-connection + +rspec background_migration pg12 single-db-ci-connection: + extends: + - rspec background_migration pg12 + - .single-db-rspec + - .rails:rules:single-db-ci-connection + rspec migration pg12 praefect: extends: - rspec migration pg12 @@ -428,6 +440,18 @@ rspec background_migration pg12-as-if-foss single-db: - .single-db-rspec - .rails:rules:single-db +rspec migration pg12-as-if-foss single-db-ci-connection: + extends: + - rspec migration pg12-as-if-foss + - .single-db-rspec + - .rails:rules:single-db-ci-connection + +rspec background_migration pg12-as-if-foss single-db-ci-connection: + extends: + - rspec background_migration pg12-as-if-foss + - .single-db-rspec + - .rails:rules:single-db-ci-connection + rspec unit pg12-as-if-foss: extends: - .rspec-base-pg12-as-if-foss @@ -520,6 +544,18 @@ rspec-ee background_migration pg12 single-db: - .single-db-rspec - .rails:rules:single-db +rspec-ee migration pg12 single-db-ci-connection: + extends: + - rspec-ee migration pg12 + - .single-db-rspec + - .rails:rules:single-db-ci-connection + +rspec-ee background_migration pg12 single-db-ci-connection: + extends: + - rspec-ee background_migration pg12 + - .single-db-rspec + - .rails:rules:single-db-ci-connection + rspec-ee migration pg12 praefect: extends: - rspec migration pg12 diff --git a/.gitlab/ci/rails/shared.gitlab-ci.yml b/.gitlab/ci/rails/shared.gitlab-ci.yml index ba0781a845f..0fa65b0be90 100644 --- a/.gitlab/ci/rails/shared.gitlab-ci.yml +++ b/.gitlab/ci/rails/shared.gitlab-ci.yml @@ -36,9 +36,17 @@ include: variables: DECOMPOSED_DB: "false" +.single-db-ci-connection: + extends: .single-db + variables: + CI_CONNECTION_DB: "true" + .single-db-rspec: extends: .single-db +.single-db-ci-connection-rspec: + extends: .single-db-ci-connection + .praefect-with-db: variables: GITALY_PRAEFECT_WITH_DB: '1' diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml index ee85ca82673..894dafca8c3 100644 --- a/.gitlab/ci/rules.gitlab-ci.yml +++ b/.gitlab/ci/rules.gitlab-ci.yml @@ -1238,6 +1238,19 @@ - <<: *if-merge-request changes: *db-patterns +.rails:rules:single-db-ci-connection: + rules: + - <<: *if-merge-request-labels-run-single-db + - <<: *if-merge-request + changes: *db-patterns + - <<: *if-default-branch-schedule-nightly + +.rails:rules:db:check-migrations-single-db-ci-connection: + rules: + - <<: *if-merge-request-labels-run-single-db + - <<: *if-merge-request + changes: *db-patterns + .rails:rules:db-backup: rules: - <<: *if-merge-request-labels-run-all-rspec diff --git a/.rubocop_todo/rake/require.yml b/.rubocop_todo/rake/require.yml index 9820ce7d03c..11c645d682a 100644 --- a/.rubocop_todo/rake/require.yml +++ b/.rubocop_todo/rake/require.yml @@ -2,7 +2,6 @@ Rake/Require: Details: grace period Exclude: - - 'lib/tasks/gitlab/assets.rake' - 'lib/tasks/gitlab/docs/redirect.rake' - 'lib/tasks/gitlab/graphql.rake' - 'lib/tasks/gitlab/lfs/migrate.rake' diff --git a/app/assets/javascripts/editor/constants.js b/app/assets/javascripts/editor/constants.js index d235319dfd7..64b6c809870 100644 --- a/app/assets/javascripts/editor/constants.js +++ b/app/assets/javascripts/editor/constants.js @@ -114,7 +114,7 @@ export const EXTENSION_MARKDOWN_BUTTONS = [ }, { id: 'link', - label: sprintf(s__('MarkdownEditor|Add a link (%{modifier_key}K)'), { + label: sprintf(s__('MarkdownEditor|Add a link (%{modifierKey}K)'), { modifierKey, }), data: { diff --git a/app/assets/javascripts/editor/extensions/source_editor_markdown_ext.js b/app/assets/javascripts/editor/extensions/source_editor_markdown_ext.js index 6105a577996..bef524761a0 100644 --- a/app/assets/javascripts/editor/extensions/source_editor_markdown_ext.js +++ b/app/assets/javascripts/editor/extensions/source_editor_markdown_ext.js @@ -1,5 +1,5 @@ import { insertMarkdownText } from '~/lib/utils/text_markdown'; -import { EDITOR_TOOLBAR_RIGHT_GROUP, EXTENSION_MARKDOWN_BUTTONS } from '../constants'; +import { EDITOR_TOOLBAR_LEFT_GROUP, EXTENSION_MARKDOWN_BUTTONS } from '../constants'; export class EditorMarkdownExtension { static get extensionName() { @@ -24,7 +24,7 @@ export class EditorMarkdownExtension { return { ...btn, icon: btn.id, - group: EDITOR_TOOLBAR_RIGHT_GROUP, + group: EDITOR_TOOLBAR_LEFT_GROUP, category: 'tertiary', onClick: (e) => instance.insertMarkdown(e), }; diff --git a/app/finders/milestones_finder.rb b/app/finders/milestones_finder.rb index 5fe55e88086..c266f589dda 100644 --- a/app/finders/milestones_finder.rb +++ b/app/finders/milestones_finder.rb @@ -30,9 +30,12 @@ class MilestonesFinder items = by_groups_and_projects(items) items = by_title(items) items = by_search_title(items) + items = by_search(items) items = by_state(items) items = by_timeframe(items) items = containing_date(items) + items = by_updated_at(items) + items = by_iids(items) order(items) end @@ -67,6 +70,12 @@ class MilestonesFinder end end + def by_search(items) + return items if params[:search].blank? + + items.search(params[:search]) + end + def by_state(items) Milestone.filter_by_state(items, params[:state]) end @@ -84,4 +93,16 @@ class MilestonesFinder def sort_by_expired_last?(sort_by) EXPIRED_LAST_SORTS.include?(sort_by) end + + def by_updated_at(items) + items = items.updated_before(params[:updated_before]) if params[:updated_before].present? + items = items.updated_after(params[:updated_after]) if params[:updated_after].present? + items + end + + def by_iids(items) + return items unless params[:iids].present? && !params[:include_parent_milestones] + + items.by_iid(params[:iids]) + end end diff --git a/app/models/badge.rb b/app/models/badge.rb index 0676de10d02..23e6f305c32 100644 --- a/app/models/badge.rb +++ b/app/models/badge.rb @@ -42,7 +42,7 @@ class Badge < ApplicationRecord private def build_rendered_url(url, project = nil) - return url unless valid? && project + return url unless project Gitlab::StringPlaceholderReplacer.replace_string_placeholders(url, PLACEHOLDERS_REGEX) do |arg| replace_placeholder_action(PLACEHOLDERS[arg], project) diff --git a/app/models/milestone.rb b/app/models/milestone.rb index b0676c25f8e..8ae1fab963f 100644 --- a/app/models/milestone.rb +++ b/app/models/milestone.rb @@ -8,6 +8,7 @@ class Milestone < ApplicationRecord include FromUnion include Importable include IidRoutes + include UpdatedAtFilterable prepend_mod_with('Milestone') # rubocop: disable Cop/InjectEnterpriseEditionModule @@ -26,6 +27,7 @@ class Milestone < ApplicationRecord has_many :events, as: :target, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent + scope :by_iid, ->(iid) { where(iid: iid) } scope :active, -> { with_state(:active) } scope :started, -> { active.where('milestones.start_date <= CURRENT_DATE') } scope :not_started, -> { active.where('milestones.start_date > CURRENT_DATE') } diff --git a/doc/api/group_milestones.md b/doc/api/group_milestones.md index fc95230cbba..52bce54119a 100644 --- a/doc/api/group_milestones.md +++ b/doc/api/group_milestones.md @@ -21,6 +21,8 @@ GET /groups/:id/milestones?state=active GET /groups/:id/milestones?state=closed GET /groups/:id/milestones?title=1.0 GET /groups/:id/milestones?search=version +GET /groups/:id/milestones?updated_before=2013-10-02T09%3A24%3A18Z +GET /groups/:id/milestones?updated_after=2013-10-02T09%3A24%3A18Z ``` Parameters: @@ -32,7 +34,9 @@ Parameters: | `state` | string | no | Return only `active` or `closed` milestones | | `title` | string | no | Return only the milestones having the given `title` | | `search` | string | no | Return only milestones with a title or description matching the provided string | -| `include_parent_milestones` | boolean | optional | Include milestones from parent group and its ancestors. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196066) in GitLab 13.4 | +| `include_parent_milestones` | boolean | no | Include milestones from parent group and its ancestors. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196066) in GitLab 13.4 | +| `updated_before` | datetime | no | Return only milestones updated before the given datetime. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). Introduced in GitLab 15.10 | +| `updated_after` | datetime | no | Return only milestones updated after the given datetime. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). Introduced in GitLab 15.10 | ```shell curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/5/milestones" diff --git a/doc/api/milestones.md b/doc/api/milestones.md index 998beeb9b3b..e1acf4c14bb 100644 --- a/doc/api/milestones.md +++ b/doc/api/milestones.md @@ -21,6 +21,8 @@ GET /projects/:id/milestones?state=active GET /projects/:id/milestones?state=closed GET /projects/:id/milestones?title=1.0 GET /projects/:id/milestones?search=version +GET /projects/:id/milestones?updated_before=2013-10-02T09%3A24%3A18Z +GET /projects/:id/milestones?updated_after=2013-10-02T09%3A24%3A18Z ``` Parameters: @@ -28,11 +30,13 @@ Parameters: | Attribute | Type | Required | Description | | ---------------------------- | ------ | -------- | ----------- | | `id` | integer or string | yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding) owned by the authenticated user | -| `iids[]` | integer array | optional | Return only the milestones having the given `iid` (Note: ignored if `include_parent_milestones` is set as `true`) | -| `state` | string | optional | Return only `active` or `closed` milestones | -| `title` | string | optional | Return only the milestones having the given `title` | -| `search` | string | optional | Return only milestones with a title or description matching the provided string | -| `include_parent_milestones` | boolean | optional | Include group milestones from parent group and its ancestors. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196066) in GitLab 13.4 | +| `iids[]` | integer array | no | Return only the milestones having the given `iid` (Note: ignored if `include_parent_milestones` is set as `true`) | +| `state` | string | no | Return only `active` or `closed` milestones | +| `title` | string | no | Return only the milestones having the given `title` | +| `search` | string | no | Return only milestones with a title or description matching the provided string | +| `include_parent_milestones` | boolean | no | Include group milestones from parent group and its ancestors. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/196066) in GitLab 13.4 | +| `updated_before` | datetime | no | Return only milestones updated before the given datetime. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). Introduced in GitLab 15.10 | +| `updated_after` | datetime | no | Return only milestones updated after the given datetime. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). Introduced in GitLab 15.10 | ```shell curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/milestones" diff --git a/doc/ci/yaml/includes.md b/doc/ci/yaml/includes.md index 79f0e870740..f93c09c0f20 100644 --- a/doc/ci/yaml/includes.md +++ b/doc/ci/yaml/includes.md @@ -20,13 +20,6 @@ To include a single configuration file, use either of these syntax options: include: '/templates/.after-script-template.yml' ``` -- `include` with a single file, and you specify the `include` type: - - ```yaml - include: - remote: 'https://gitlab.com/awesome-project/raw/main/.before-script-template.yml' - ``` - ## Include an array of configuration files You can include an array of configuration files: diff --git a/doc/user/group/manage.md b/doc/user/group/manage.md index 4679df1da8b..4a380fc51db 100644 --- a/doc/user/group/manage.md +++ b/doc/user/group/manage.md @@ -549,6 +549,77 @@ To enable group file templates: 1. Choose a project to act as the template repository. 1. Select **Save changes**. +## Group merge checks settings **(PREMIUM)** + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/372040) in GitLab 15.9 [with a flag](../../administration/feature_flags.md) name `support_group_level_merge_checks_setting`. Disabled by default. + +FLAG: +On self-managed GitLab, by default this feature is not available. To make it available, ask an administrator to +[enable the feature flag](../../administration/feature_flags.md) named `support_group_level_merge_checks_setting`. On GitLab.com, this feature is not +available. + +Group owners can set up merge request checks on a top-level group, which apply to all subgroups and projects. + +If the settings are inherited by a subgroup or project, they cannot be changed in the subgroup or project +that inherited them. + +### Require a successful pipeline for merge + +You can configure all child projects in your group to require a complete and successful pipeline before +merge. + +See also [the project-level setting](../project/merge_requests/merge_when_pipeline_succeeds.md#require-a-successful-pipeline-for-merge). + +Prerequisites: + +- You must be the owner of the group. + +To enable this setting: + +1. On the top bar, select **Main menu > Groups** and find your group. +1. On the left sidebar, select **Settings > General**. +1. Expand **Merge requests**. +1. Under **Merge checks**, select **Pipelines must succeed**. + This setting also prevents merge requests from being merged if there is no pipeline. +1. Select **Save changes**. + +#### Allow merge after skipped pipelines + +You can configure [skipped pipelines](../../ci/pipelines/index.md#skip-a-pipeline) from preventing merge requests from being merged. + +See also [the project-level setting](../project/merge_requests/merge_when_pipeline_succeeds.md#allow-merge-after-skipped-pipelines). + +Prerequisite: + +- You must be the owner of the group. + +To change this behavior: + +1. On the top bar, select **Main menu > Groups** and find your group. +1. On the left sidebar, select **Settings > General**. +1. Expand **Merge requests**. +1. Under **Merge checks**: + - Select **Pipelines must succeed**. + - Select **Skipped pipelines are considered successful**. +1. Select **Save changes**. + +### Prevent merge unless all threads are resolved + +You can prevent merge requests from being merged until all threads are resolved. When this setting is enabled, for all child projects in your group, the +**Unresolved threads** count in a merge request is shown in orange when at least one thread remains unresolved. + +Prerequisite: + +- You must be the owner of the group. + +To enable this setting: + +1. On the top bar, select **Main menu > Groups** and find your group. +1. On the left sidebar, select **Settings > General**. +1. Expand **Merge requests**. +1. Under **Merge checks**, select **All threads must be resolved**. +1. Select **Save changes**. + ## Group merge request approval settings **(PREMIUM)** > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/285458) in GitLab 13.9. [Deployed behind the `group_merge_request_approval_settings_feature_flag` flag](../../administration/feature_flags.md), disabled by default. diff --git a/doc/user/project/protected_branches.md b/doc/user/project/protected_branches.md index da53fe2f5e9..bbef12cd0e1 100644 --- a/doc/user/project/protected_branches.md +++ b/doc/user/project/protected_branches.md @@ -36,6 +36,40 @@ When a branch is protected, the default behavior enforces these restrictions on 1. No one can delete a protected branch using Git commands, however, users with at least Maintainer role can [delete a protected branch from the UI or API](#delete-a-protected-branch). +### When a branch matches multiple rules + +When a branch matches multiple rules, the **most permissive rule** determines the +level of protection for the branch. For example, consider these rules, which include +[wildcards](#configure-multiple-protected-branches-by-using-a-wildcard): + +| Branch name pattern | Allowed to merge | Allowed to push | +|---------------------|------------------------|-----------------| +| `v1.x` | Maintainer | Maintainer | +| `v1.*` | Maintainer + Developer | Maintainer | +| `v*` | No one | No one | + +A branch named `v1.x` matches all three branch name patterns: `v1.x`, `v1.*`, and `v*`. +As the most permissive option determines the behavior, the resulting permissions for branch `v1.x` are: + +- **Allowed to merge:** Of the three settings, `Maintainer + Developer` is most permissive, + and controls branch behavior as a result. Even though the branch also matched `v1.x` and `v*` + (which each have stricter permissions), users with the Developer role can merge into the branch. +- **Allowed to push:** Of the three settings, `Maintainer` is the most permissive, and controls + branch behavior as a result. Even though branches matching `v*` are set to `No one`, branches + that _also_ match `v1.x` or `v1.*` receive the more permissive `Maintainer` permission. + +To be certain that a rule controls the behavior of a branch, +_all_ other patterns that match must apply less or equally permissive rules. + +If you want to ensure that `No one` is allowed to push to branch `v1.x`, every pattern +that matches `v1.x` must set `Allowed to push` to `No one`, like this: + +| Branch name pattern | Allowed to merge | Allowed to push | +|---------------------|------------------------|-----------------| +| `v1.x` | Maintainer | No one | +| `v1.*` | Maintainer + Developer | No one | +| `v*` | No one | No one | + ### Set the default branch protection level Administrators can set a default branch protection level in the @@ -203,8 +237,7 @@ Members who can push to this branch can now also force push. ## Require Code Owner approval on a protected branch **(PREMIUM)** -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/13251) in GitLab 12.4. -> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35097) in GitLab 13.5, users and groups who can push to protected branches do not have to use a merge request to merge their feature branches. This means they can skip merge request approval rules. +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/35097) in GitLab 13.5, users and groups who can push to protected branches do not have to use a merge request to merge their feature branches. This means they can skip merge request approval rules. For a protected branch, you can require at least one approval by a [Code Owner](code_owners.md). diff --git a/lib/api/milestone_responses.rb b/lib/api/milestone_responses.rb index 2fd3239b44a..fb71cb0e791 100644 --- a/lib/api/milestone_responses.rb +++ b/lib/api/milestone_responses.rb @@ -20,6 +20,8 @@ module API optional :search, type: String, desc: 'The search criteria for the title or description of the milestone' optional :include_parent_milestones, type: Grape::API::Boolean, default: false, desc: 'Include group milestones from parent and its ancestors' + optional :updated_before, type: DateTime, desc: 'Return milestones updated before the specified datetime. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ' + optional :updated_after, type: DateTime, desc: 'Return milestones updated after the specified datetime. Format: ISO 8601 YYYY-MM-DDTHH:MM:SSZ' use :pagination end @@ -33,14 +35,9 @@ module API end def list_milestones_for(parent) - milestones = init_milestones_collection(parent) - milestones = Milestone.filter_by_state(milestones, params[:state]) - if params[:iids].present? && !params[:include_parent_milestones] - milestones = filter_by_iid(milestones, params[:iids]) - end - - milestones = filter_by_title(milestones, params[:title]) if params[:title] - milestones = filter_by_search(milestones, params[:search]) if params[:search] + milestones = MilestonesFinder.new( + params.merge(parent_finder_params(parent)) + ).execute present paginate(milestones), with: Entities::Milestone end @@ -84,6 +81,16 @@ module API present paginate(issuables), with: entity, current_user: current_user end + def parent_finder_params(parent) + include_parent = params[:include_parent_milestones].present? + + if parent.is_a?(Project) + { project_ids: parent.id, group_ids: (include_parent ? project_group_ids(parent) : nil) } + else + { group_ids: (include_parent ? group_and_ancestor_ids(parent) : parent.id) } + end + end + def build_finder_params(milestone, parent) finder_params = { milestone_title: milestone.title, sort: 'label_priority' } @@ -102,26 +109,6 @@ module API end end - def init_milestones_collection(parent) - milestones = if params[:include_parent_milestones].present? - parent_and_ancestors_milestones(parent) - else - parent.milestones - end - - milestones.order_id_desc - end - - def parent_and_ancestors_milestones(parent) - project_id, group_ids = if parent.is_a?(Project) - [parent.id, project_group_ids(parent)] - else - [nil, parent_group_ids(parent)] - end - - Milestone.for_projects_and_groups(project_id, group_ids) - end - def project_group_ids(parent) group = parent.group return unless group.present? @@ -129,7 +116,7 @@ module API group.self_and_ancestors.select(:id) end - def parent_group_ids(group) + def group_and_ancestor_ids(group) return unless group.present? group.self_and_ancestors diff --git a/lib/tasks/gitlab/assets.rake b/lib/tasks/gitlab/assets.rake index d8c0b1007e6..52a6ea6ae41 100644 --- a/lib/tasks/gitlab/assets.rake +++ b/lib/tasks/gitlab/assets.rake @@ -1,7 +1,5 @@ # frozen_string_literal: true -require 'fileutils' - module Tasks module Gitlab module Assets diff --git a/lib/tasks/gitlab/db.rake b/lib/tasks/gitlab/db.rake index 3ff512fd686..bd9f0252285 100644 --- a/lib/tasks/gitlab/db.rake +++ b/lib/tasks/gitlab/db.rake @@ -131,7 +131,7 @@ namespace :gitlab do end end - desc 'This adjusts and cleans db/structure.sql - it runs after db:structure:dump' + desc 'This adjusts and cleans db/structure.sql - it runs after db:schema:dump' task :clean_structure_sql do |task_name| ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config| structure_file = ActiveRecord::Tasks::DatabaseTasks.dump_filename(db_config.name) @@ -147,26 +147,13 @@ namespace :gitlab do Rake::Task[task_name].reenable end - # Inform Rake that custom tasks should be run every time rake db:structure:dump is run - # - # Rails 6.1 deprecates db:structure:dump in favor of db:schema:dump - Rake::Task['db:structure:dump'].enhance do - Rake::Task['gitlab:db:clean_structure_sql'].invoke - end - # Inform Rake that custom tasks should be run every time rake db:schema:dump is run Rake::Task['db:schema:dump'].enhance do Rake::Task['gitlab:db:clean_structure_sql'].invoke end ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name| - # Inform Rake that custom tasks should be run every time rake db:structure:dump is run - # - # Rails 6.1 deprecates db:structure:dump in favor of db:schema:dump - Rake::Task["db:structure:dump:#{name}"].enhance do - Rake::Task['gitlab:db:clean_structure_sql'].invoke - end - + # Inform Rake that custom tasks should be run every time rake db:schema:dump is run Rake::Task["db:schema:dump:#{name}"].enhance do Rake::Task['gitlab:db:clean_structure_sql'].invoke end diff --git a/qa/qa/resource/runner_base.rb b/qa/qa/resource/runner_base.rb index 399d1153dc2..9e38ba9ab64 100644 --- a/qa/qa/resource/runner_base.rb +++ b/qa/qa/resource/runner_base.rb @@ -35,7 +35,6 @@ module QA @config = nil @run_untagged = nil @name = "qa-runner-#{SecureRandom.hex(4)}" - @image = 'registry.gitlab.com/gitlab-org/gitlab-runner:alpine-v15.8.3' @executor = :shell @executor_image = 'registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-qa-alpine-ruby-2.7' end @@ -95,6 +94,8 @@ module QA def start_container_and_register @docker_container ||= Service::DockerRun::GitlabRunner.new(name).tap do |runner| + runner.image = image if image + Support::Retrier.retry_on_exception(sleep_interval: 5) do runner.pull end @@ -102,7 +103,6 @@ module QA runner.token = token runner.address = Runtime::Scenario.gitlab_address runner.tags = tags if tags - runner.image = image runner.config = config if config runner.executor = executor runner.executor_image = executor_image if executor == :docker diff --git a/qa/qa/service/docker_run/gitlab_runner.rb b/qa/qa/service/docker_run/gitlab_runner.rb index a8fcf8f9332..d40517ae535 100644 --- a/qa/qa/service/docker_run/gitlab_runner.rb +++ b/qa/qa/service/docker_run/gitlab_runner.rb @@ -16,7 +16,7 @@ module QA MSG def initialize(name) - @image = 'gitlab/gitlab-runner:alpine-v15.8.3' + @image = 'registry.gitlab.com/gitlab-org/gitlab-runner:alpine' @name = name || "qa-runner-#{SecureRandom.hex(4)}" @run_untagged = true @executor = :shell diff --git a/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb b/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb index 0f6bee951a7..51006dd1e38 100644 --- a/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb +++ b/qa/qa/specs/features/browser_ui/6_release/deploy_key/clone_using_deploy_key_spec.rb @@ -19,7 +19,6 @@ module QA resource.project = project resource.name = runner_name resource.tags = [runner_name] - resource.image = 'gitlab/gitlab-runner:alpine-v15.8.3' end end diff --git a/scripts/db_tasks b/scripts/db_tasks index 36040877abf..645e46e02d9 100755 --- a/scripts/db_tasks +++ b/scripts/db_tasks @@ -5,6 +5,7 @@ require 'yaml' rails_env = ENV.fetch('RAILS_ENV') database_config = YAML.load_file(File.join(File.expand_path('..', __dir__), 'config', 'database.yml'))[rails_env] +database_config.reject! { |_k, v| v["database_tasks"] == false } task = ARGV.shift raise ArgumentError, 'You need to pass a task name!' unless task @@ -14,4 +15,4 @@ cmd = ['bundle', 'exec', 'rake', task, *ARGV] puts "Running: `#{cmd.join(' ')}`" -system(*cmd) +exit 1 unless system(*cmd) diff --git a/scripts/prepare_build.sh b/scripts/prepare_build.sh index 500e61ab76a..ca3dd0eec57 100644 --- a/scripts/prepare_build.sh +++ b/scripts/prepare_build.sh @@ -14,7 +14,13 @@ if [ "$DECOMPOSED_DB" == "true" ]; then echo "Using decomposed database config (config/database.yml.decomposed-postgresql)" cp config/database.yml.decomposed-postgresql config/database.yml else + echo "Using decomposed database config (config/database.yml.postgresql)" cp config/database.yml.postgresql config/database.yml + + if [ "$CI_CONNECTION_DB" == "true" ]; then + echo "Enabling ci connection (database_tasks: false) in config/database.yml" + sed -i '/ci:/,/geo:/''s/^ # / /g' config/database.yml + fi fi # Set up Geo database if the job name matches `rspec-ee` or `geo`. diff --git a/spec/finders/milestones_finder_spec.rb b/spec/finders/milestones_finder_spec.rb index 8dd83df3a28..c4c62e21ad9 100644 --- a/spec/finders/milestones_finder_spec.rb +++ b/spec/finders/milestones_finder_spec.rb @@ -62,9 +62,31 @@ RSpec.describe MilestonesFinder do end context 'with filters' do - let_it_be(:milestone_1) { create(:milestone, group: group, state: 'closed', title: 'one test', start_date: now - 1.day, due_date: now) } - let_it_be(:milestone_3) { create(:milestone, project: project_1, state: 'closed', start_date: now + 2.days, due_date: now + 3.days) } + let_it_be(:milestone_1) do + create( + :milestone, + group: group, + state: 'closed', + title: 'one test', + start_date: now - 1.day, + due_date: now, + updated_at: now - 3.days + ) + end + + let_it_be(:milestone_3) do + create( + :milestone, + project: project_1, + state: 'closed', + description: 'three test', + start_date: now + 2.days, + due_date: now + 3.days, + updated_at: now - 5.days + ) + end + let(:result) { described_class.new(params).execute } let(:params) do { project_ids: [project_1.id, project_2.id], @@ -76,62 +98,96 @@ RSpec.describe MilestonesFinder do it 'filters by id' do params[:ids] = [milestone_1.id, milestone_2.id] - result = described_class.new(params).execute - expect(result).to contain_exactly(milestone_1, milestone_2) end it 'filters by active state' do params[:state] = 'active' - result = described_class.new(params).execute expect(result).to contain_exactly(milestone_2, milestone_4) end it 'filters by closed state' do params[:state] = 'closed' - result = described_class.new(params).execute expect(result).to contain_exactly(milestone_1, milestone_3) end it 'filters by title' do - result = described_class.new(params.merge(title: 'one test')).execute + params[:title] = 'one test' - expect(result.to_a).to contain_exactly(milestone_1) + expect(result).to contain_exactly(milestone_1) end it 'filters by search_title' do - result = described_class.new(params.merge(search_title: 'one t')).execute + params[:search_title] = 'test' + + expect(result).to contain_exactly(milestone_1) + end + + it 'filters by search (title, description)' do + params[:search] = 'test' - expect(result.to_a).to contain_exactly(milestone_1) + expect(result).to contain_exactly(milestone_1, milestone_3) end context 'by timeframe' do it 'returns milestones with start_date and due_date between timeframe' do params.merge!(start_date: now - 1.day, end_date: now + 3.days) - milestones = described_class.new(params).execute - - expect(milestones).to match_array([milestone_1, milestone_2, milestone_3]) + expect(result).to contain_exactly(milestone_1, milestone_2, milestone_3) end it 'returns milestones which starts before the timeframe' do milestone = create(:milestone, project: project_2, start_date: now - 5.days) params.merge!(start_date: now - 3.days, end_date: now - 2.days) - milestones = described_class.new(params).execute - - expect(milestones).to match_array([milestone]) + expect(result).to contain_exactly(milestone) end it 'returns milestones which ends after the timeframe' do milestone = create(:milestone, project: project_2, due_date: now + 6.days) params.merge!(start_date: now + 6.days, end_date: now + 7.days) - milestones = described_class.new(params).execute + expect(result).to contain_exactly(milestone) + end + end + + context 'by updated_at' do + it 'returns milestones updated before a given date' do + params[:updated_before] = 4.days.ago.iso8601 + + expect(result).to contain_exactly(milestone_3) + end + + it 'returns milestones updated after a given date' do + params[:updated_after] = 4.days.ago.iso8601 + + expect(result).to contain_exactly(milestone_1, milestone_2, milestone_4) + end + + it 'returns milestones updated between the given dates' do + params.merge!(updated_after: 6.days.ago.iso8601, updated_before: 4.days.ago.iso8601) + + expect(result).to contain_exactly(milestone_3) + end + end + + context 'by iids' do + before do + params[:iids] = 1 + end - expect(milestones).to match_array([milestone]) + it 'returns milestone for the given iids' do + expect(result).to contain_exactly(milestone_2, milestone_3, milestone_4) + end + + context 'when include_parent_milestones is true' do + it 'ignores the iid filter' do + params[:include_parent_milestones] = true + + expect(result).to contain_exactly(milestone_1, milestone_2, milestone_3, milestone_4) + end end end end diff --git a/spec/requests/api/group_milestones_spec.rb b/spec/requests/api/group_milestones_spec.rb index 91f64d02d43..2f05b0fcf21 100644 --- a/spec/requests/api/group_milestones_spec.rb +++ b/spec/requests/api/group_milestones_spec.rb @@ -4,35 +4,41 @@ require 'spec_helper' RSpec.describe API::GroupMilestones, feature_category: :team_planning do let_it_be(:user) { create(:user) } - let_it_be(:group) { create(:group, :private) } + let_it_be_with_refind(:group) { create(:group, :private) } let_it_be(:project) { create(:project, namespace: group) } let_it_be(:group_member) { create(:group_member, group: group, user: user) } - let_it_be(:closed_milestone) { create(:closed_milestone, group: group, title: 'version1', description: 'closed milestone') } - let_it_be(:milestone) { create(:milestone, group: group, title: 'version2', description: 'open milestone') } + let_it_be(:closed_milestone) do + create(:closed_milestone, group: group, title: 'version1', description: 'closed milestone') + end + + let_it_be_with_reload(:milestone) do + create(:milestone, group: group, title: 'version2', description: 'open milestone', updated_at: 4.days.ago) + end let(:route) { "/groups/#{group.id}/milestones" } + shared_examples 'listing all milestones' do + it 'returns correct list of milestones' do + get api(route, user), params: params + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response.size).to eq(milestones.size) + expect(json_response.map { |entry| entry["id"] }).to eq(milestones.map(&:id)) + end + end + it_behaves_like 'group and project milestones', "/groups/:id/milestones" describe 'GET /groups/:id/milestones' do - context 'when include_parent_milestones is true' do - let_it_be(:ancestor_group) { create(:group, :private) } - let_it_be(:ancestor_group_milestone) { create(:milestone, group: ancestor_group) } - let_it_be(:params) { { include_parent_milestones: true } } - - before_all do - group.update!(parent: ancestor_group) - end + let_it_be(:ancestor_group) { create(:group, :private) } + let_it_be(:ancestor_group_milestone) { create(:milestone, group: ancestor_group, updated_at: 2.days.ago) } - shared_examples 'listing all milestones' do - it 'returns correct list of milestones' do - get api(route, user), params: params + before_all do + group.update!(parent: ancestor_group) + end - expect(response).to have_gitlab_http_status(:ok) - expect(json_response.size).to eq(milestones.size) - expect(json_response.map { |entry| entry["id"] }).to eq(milestones.map(&:id)) - end - end + context 'when include_parent_milestones is true' do + let(:params) { { include_parent_milestones: true } } context 'when user has access to ancestor groups' do let(:milestones) { [ancestor_group_milestone, milestone, closed_milestone] } @@ -45,10 +51,26 @@ RSpec.describe API::GroupMilestones, feature_category: :team_planning do it_behaves_like 'listing all milestones' context 'when iids param is present' do - let_it_be(:params) { { include_parent_milestones: true, iids: [milestone.iid] } } + let(:params) { { include_parent_milestones: true, iids: [milestone.iid] } } it_behaves_like 'listing all milestones' end + + context 'when updated_before param is present' do + let(:params) { { updated_before: 1.day.ago.iso8601, include_parent_milestones: true } } + + it_behaves_like 'listing all milestones' do + let(:milestones) { [ancestor_group_milestone, milestone] } + end + end + + context 'when updated_after param is present' do + let(:params) { { updated_after: 1.day.ago.iso8601, include_parent_milestones: true } } + + it_behaves_like 'listing all milestones' do + let(:milestones) { [closed_milestone] } + end + end end context 'when user has no access to ancestor groups' do @@ -63,6 +85,22 @@ RSpec.describe API::GroupMilestones, feature_category: :team_planning do end end end + + context 'when updated_before param is present' do + let(:params) { { updated_before: 1.day.ago.iso8601 } } + + it_behaves_like 'listing all milestones' do + let(:milestones) { [milestone] } + end + end + + context 'when updated_after param is present' do + let(:params) { { updated_after: 1.day.ago.iso8601 } } + + it_behaves_like 'listing all milestones' do + let(:milestones) { [closed_milestone] } + end + end end describe 'GET /groups/:id/milestones/:milestone_id/issues' do diff --git a/spec/requests/api/project_milestones_spec.rb b/spec/requests/api/project_milestones_spec.rb index 9d722e4a445..978ac28ef73 100644 --- a/spec/requests/api/project_milestones_spec.rb +++ b/spec/requests/api/project_milestones_spec.rb @@ -6,8 +6,12 @@ RSpec.describe API::ProjectMilestones, feature_category: :team_planning do let_it_be(:user) { create(:user) } let_it_be_with_reload(:project) { create(:project, namespace: user.namespace) } let_it_be(:closed_milestone) { create(:closed_milestone, project: project, title: 'version1', description: 'closed milestone') } - let_it_be(:milestone) { create(:milestone, project: project, title: 'version2', description: 'open milestone') } let_it_be(:route) { "/projects/#{project.id}/milestones" } + let_it_be(:milestone) do + create(:milestone, project: project, title: 'version2', description: 'open milestone', updated_at: 5.days.ago) + end + + let(:params) { {} } before_all do project.add_reporter(user) @@ -15,38 +19,43 @@ RSpec.describe API::ProjectMilestones, feature_category: :team_planning do it_behaves_like 'group and project milestones', "/projects/:id/milestones" + shared_examples 'listing all milestones' do + it 'returns correct list of milestones' do + get api(route, user), params: params + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response.size).to eq(milestones.size) + expect(json_response.map { |entry| entry["id"] }).to match_array(milestones.map(&:id)) + end + end + describe 'GET /projects/:id/milestones' do - context 'when include_parent_milestones is true' do - let_it_be(:ancestor_group) { create(:group, :private) } - let_it_be(:group) { create(:group, :private, parent: ancestor_group) } - let_it_be(:ancestor_group_milestone) { create(:milestone, group: ancestor_group) } - let_it_be(:group_milestone) { create(:milestone, group: group) } + let_it_be(:ancestor_group) { create(:group, :private) } + let_it_be(:group) { create(:group, :private, parent: ancestor_group) } + let_it_be(:ancestor_group_milestone) { create(:milestone, group: ancestor_group, updated_at: 1.day.ago) } + let_it_be(:group_milestone) { create(:milestone, group: group, updated_at: 3.days.ago) } - let(:params) { { include_parent_milestones: true } } + context 'when project parent is a namespace' do + let(:milestones) { [milestone, closed_milestone] } - shared_examples 'listing all milestones' do - it 'returns correct list of milestones' do - get api(route, user), params: params + it_behaves_like 'listing all milestones' - expect(response).to have_gitlab_http_status(:ok) - expect(json_response.size).to eq(milestones.size) - expect(json_response.map { |entry| entry["id"] }).to eq(milestones.map(&:id)) - end + context 'when include_parent_milestones is true' do + let(:params) { { include_parent_milestones: true } } + + it_behaves_like 'listing all milestones' end + end - context 'when project parent is a namespace' do - it_behaves_like 'listing all milestones' do - let(:milestones) { [milestone, closed_milestone] } - end + context 'when project parent is a group' do + before_all do + project.update!(namespace: group) end - context 'when project parent is a group' do + context 'when include_parent_milestones is true' do + let(:params) { { include_parent_milestones: true } } let(:milestones) { [group_milestone, ancestor_group_milestone, milestone, closed_milestone] } - before_all do - project.update!(namespace: group) - end - it_behaves_like 'listing all milestones' context 'when iids param is present' do @@ -64,6 +73,38 @@ RSpec.describe API::ProjectMilestones, feature_category: :team_planning do expect(response).to have_gitlab_http_status(:not_found) end end + + context 'when updated_before param is present' do + let(:params) { { updated_before: 12.hours.ago.iso8601, include_parent_milestones: true } } + + it_behaves_like 'listing all milestones' do + let(:milestones) { [group_milestone, ancestor_group_milestone, milestone] } + end + end + + context 'when updated_after param is present' do + let(:params) { { updated_after: 2.days.ago.iso8601, include_parent_milestones: true } } + + it_behaves_like 'listing all milestones' do + let(:milestones) { [ancestor_group_milestone, closed_milestone] } + end + end + end + + context 'when updated_before param is present' do + let(:params) { { updated_before: 12.hours.ago.iso8601 } } + + it_behaves_like 'listing all milestones' do + let(:milestones) { [milestone] } + end + end + + context 'when updated_after param is present' do + let(:params) { { updated_after: 2.days.ago.iso8601 } } + + it_behaves_like 'listing all milestones' do + let(:milestones) { [closed_milestone] } + end end end end diff --git a/spec/tasks/gitlab/db_rake_spec.rb b/spec/tasks/gitlab/db_rake_spec.rb index a9977e07feb..e506144ea3e 100644 --- a/spec/tasks/gitlab/db_rake_spec.rb +++ b/spec/tasks/gitlab/db_rake_spec.rb @@ -16,7 +16,7 @@ RSpec.describe 'gitlab:db namespace rake task', :silence_stdout, feature_categor before do # Stub out db tasks allow(Rake::Task['db:migrate']).to receive(:invoke).and_return(true) - allow(Rake::Task['db:structure:load']).to receive(:invoke).and_return(true) + allow(Rake::Task['db:schema:load']).to receive(:invoke).and_return(true) allow(Rake::Task['db:seed_fu']).to receive(:invoke).and_return(true) end @@ -1049,14 +1049,6 @@ RSpec.describe 'gitlab:db namespace rake task', :silence_stdout, feature_categor skip_unless_ci_uses_database_tasks end - describe 'db:structure:dump against a single database' do - it 'invokes gitlab:db:clean_structure_sql' do - expect(Rake::Task['gitlab:db:clean_structure_sql']).to receive(:invoke).twice.and_return(true) - - expect { run_rake_task('db:structure:dump:main') }.not_to raise_error - end - end - describe 'db:schema:dump against a single database' do it 'invokes gitlab:db:clean_structure_sql' do expect(Rake::Task['gitlab:db:clean_structure_sql']).to receive(:invoke).once.and_return(true) diff --git a/workhorse/go.mod b/workhorse/go.mod index 5fc0d1c1679..1dc549fa0d4 100644 --- a/workhorse/go.mod +++ b/workhorse/go.mod @@ -7,7 +7,7 @@ require ( github.com/BurntSushi/toml v1.2.1 github.com/FZambia/sentinel v1.1.1 github.com/alecthomas/chroma/v2 v2.5.0 - github.com/aws/aws-sdk-go v1.44.202 + github.com/aws/aws-sdk-go v1.44.203 github.com/disintegration/imaging v1.6.2 github.com/getsentry/raven-go v0.2.0 github.com/golang-jwt/jwt/v4 v4.5.0 diff --git a/workhorse/go.sum b/workhorse/go.sum index cb20a361be5..1c0f897d636 100644 --- a/workhorse/go.sum +++ b/workhorse/go.sum @@ -544,8 +544,8 @@ github.com/aws/aws-sdk-go v1.43.11/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4 github.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.128/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.151/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= -github.com/aws/aws-sdk-go v1.44.202 h1:nk/DtYoAS7zX4SbfiQEJO+C0GBN8ZxXrkD+BozwLvZk= -github.com/aws/aws-sdk-go v1.44.202/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.44.203 h1:pcsP805b9acL3wUqa4JR2vg1k2wnItkDYNvfmcy6F+U= +github.com/aws/aws-sdk-go v1.44.203/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aws/aws-sdk-go-v2 v1.17.1 h1:02c72fDJr87N8RAC2s3Qu0YuvMRZKNZJ9F+lAehCazk= github.com/aws/aws-sdk-go-v2 v1.17.1/go.mod h1:JLnGeGONAyi2lWXI1p0PCIOIy333JMVK1U7Hf0aRFLw= |