diff options
22 files changed, 190 insertions, 81 deletions
diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml index a4a932c7dd0..a9fd63c75cb 100644 --- a/.gitlab/ci/rules.gitlab-ci.yml +++ b/.gitlab/ci/rules.gitlab-ci.yml @@ -374,7 +374,6 @@ - "jest.config.{base,integration,unit}.js" - "config/helpers/**/*.js" - "vendor/assets/javascripts/**/*" - - "{,ee/,jh/}app/assets/**/*.graphql" ################ # Shared rules # diff --git a/app/assets/javascripts/artifacts_settings/index.js b/app/assets/javascripts/artifacts_settings/index.js index 531b42bc185..5c9f1c3129c 100644 --- a/app/assets/javascripts/artifacts_settings/index.js +++ b/app/assets/javascripts/artifacts_settings/index.js @@ -6,7 +6,7 @@ import createDefaultClient from '~/lib/graphql'; Vue.use(VueApollo); const apolloProvider = new VueApollo({ - defaultClient: createDefaultClient(), + defaultClient: createDefaultClient({}, { assumeImmutableResults: true }), }); export default (containerId = 'js-artifacts-settings-app') => { diff --git a/app/services/ci/update_pending_build_service.rb b/app/services/ci/update_pending_build_service.rb index dcba06e60bf..d546dbcfe3d 100644 --- a/app/services/ci/update_pending_build_service.rb +++ b/app/services/ci/update_pending_build_service.rb @@ -2,7 +2,7 @@ module Ci class UpdatePendingBuildService - VALID_PARAMS = %i[instance_runners_enabled].freeze + VALID_PARAMS = %i[instance_runners_enabled namespace_id namespace_traversal_ids].freeze InvalidParamsError = Class.new(StandardError) InvalidModelError = Class.new(StandardError) diff --git a/app/services/groups/transfer_service.rb b/app/services/groups/transfer_service.rb index b7eae06b963..6c223cc11b8 100644 --- a/app/services/groups/transfer_service.rb +++ b/app/services/groups/transfer_service.rb @@ -29,6 +29,7 @@ module Groups update_group_attributes ensure_ownership update_integrations + update_pending_builds! end post_update_hooks(@updated_project_ids) @@ -217,6 +218,15 @@ module Groups PropagateIntegrationWorker.perform_async(integration.id) end end + + def update_pending_builds! + update_params = { + namespace_traversal_ids: group.traversal_ids, + namespace_id: group.id + } + + ::Ci::UpdatePendingBuildService.new(group, update_params).execute + end end end diff --git a/app/services/projects/transfer_service.rb b/app/services/projects/transfer_service.rb index 27376173f07..4764462e06f 100644 --- a/app/services/projects/transfer_service.rb +++ b/app/services/projects/transfer_service.rb @@ -104,6 +104,8 @@ module Projects update_repository_configuration(@new_path) execute_system_hooks + + update_pending_builds! end post_update_hooks(project) @@ -253,6 +255,15 @@ module Projects project.integrations.with_default_settings.delete_all Integration.create_from_active_default_integrations(project, :project_id) end + + def update_pending_builds! + update_params = { + namespace_id: new_namespace.id, + namespace_traversal_ids: new_namespace.traversal_ids + } + + ::Ci::UpdatePendingBuildService.new(project, update_params).execute + end end end diff --git a/data/deprecations/14-2-deprecation-task-runner.yml b/data/deprecations/14-2-deprecation-task-runner.yml new file mode 100644 index 00000000000..963d978a568 --- /dev/null +++ b/data/deprecations/14-2-deprecation-task-runner.yml @@ -0,0 +1,16 @@ +- name: "Rename Task Runner pod to Toolbox" # The name of the feature to be deprecated + announcement_milestone: "14.2" # The milestone when this feature was first announced as deprecated. + announcement_date: "2021-08-22" # The date of the milestone release when this feature was first announced as deprecated + removal_milestone: "14.4" # The milestone when this feature is planned to be removed + body: | # Do not modify this line, instead modify the lines below. + The Task Runner pod is used to execute periodic housekeeping tasks within the GitLab application and is often confused with the GitLab Runner. Thus, [Task Runner will be renamed to Toolbox](https://gitlab.com/groups/gitlab-org/charts/-/epics/25). + + This will result in the rename of the sub-chart: `gitlab/task-runner` to `gitlab/toolbox`. Resulting pods will be named along the lines of `{{ .Release.Name }}-toolbox`, which will often be `gitlab-toolbox`. They will be locatable with the label `app=toolbox`. + + stage: # (optional - may be required in the future) String value of the stage that the feature was created in. e.g., Growth + tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate] + issue_url: # (optional) This is a link to the deprecation issue in GitLab + documentation_url: # (optional) This is a link to the current documentation page + image_url: # (optional) This is a link to a thumbnail image depicting the feature + video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg + removal_date: "2021-10-22" # (optional - may be required in the future) YYYY-MM-DD format - the date of the milestone release when this feature is planned to be removed diff --git a/data/deprecations/distribution_deprecations_14-3.yml b/data/deprecations/distribution_deprecations_14-3.yml index 05263383151..fb691b5aa84 100644 --- a/data/deprecations/distribution_deprecations_14-3.yml +++ b/data/deprecations/distribution_deprecations_14-3.yml @@ -1,6 +1,6 @@ - name: "Rename Task Runner pod to Toolbox" # The name of the feature to be deprecated announcement_milestone: "14.2" # The milestone when this feature was first announced as deprecated. - announcement_date: "2021-09-22" + announcement_date: "2021-08-22" removal_milestone: "14.4" # the milestone when this feature is planned to be removed body: | # Do not modify this line, instead modify the lines below. The Task Runner pod is used to execute periodic housekeeping tasks within the GitLab application and is often confused with the GitLab Runner. Thus, [Task Runner will be renamed to Toolbox](https://gitlab.com/groups/gitlab-org/charts/-/epics/25). diff --git a/doc/push_rules/push_rules.md b/doc/push_rules/push_rules.md index 9a8c0d79395..5c656b2b5a7 100644 --- a/doc/push_rules/push_rules.md +++ b/doc/push_rules/push_rules.md @@ -49,7 +49,7 @@ branch name. Your developers may not remember that policy, so they might push to various branches, and CI pipelines might not work as expected. By restricting the branch names globally in Push Rules, such mistakes are prevented. -Any branch name that doesn't match your push rule is rejected. +All branch names that don't match your push rule are rejected. Note that the name of your default branch is always allowed, regardless of the branch naming regular expression (regex) specified. GitLab is configured this way @@ -109,7 +109,7 @@ The following options are available: | Prevent pushing secret files | GitLab rejects any files that are likely to contain secrets. See the [forbidden file names](#prevent-pushing-secrets-to-the-repository). | | Require expression in commit messages | Only commit messages that match this regular expression are allowed to be pushed. Leave empty to allow any commit message. Uses multiline mode, which can be disabled using `(?-m)`. | | Reject expression in commit messages | Only commit messages that do not match this regular expression are allowed to be pushed. Leave empty to allow any commit message. Uses multiline mode, which can be disabled using `(?-m)`. | -| Restrict by branch name | Only branch names that match this regular expression are allowed to be pushed. Leave empty to allow any branch name. | +| Restrict by branch name | Only branch names that match this regular expression are allowed to be pushed. Leave empty to allow all branch names. | | Restrict by commit author's email | Only commit author's email that match this regular expression are allowed to be pushed. Leave empty to allow any email. | | Prohibited file names | Any committed filenames that match this regular expression and do not already exist in the repository are not allowed to be pushed. Leave empty to allow any filenames. See [common examples](#prohibited-file-names). | | Maximum file size | Pushes that contain added or updated files that exceed this file size (in MB) are rejected. Set to 0 to allow files of any size. Files tracked by Git LFS are exempted. | diff --git a/doc/update/deprecations.md b/doc/update/deprecations.md index d453c5d8336..043a5865bd9 100644 --- a/doc/update/deprecations.md +++ b/doc/update/deprecations.md @@ -64,4 +64,4 @@ The Task Runner pod is used to execute periodic housekeeping tasks within the Gi This will result in the rename of the sub-chart: `gitlab/task-runner` to `gitlab/toolbox`. Resulting pods will be named along the lines of `{{ .Release.Name }}-toolbox`, which will often be `gitlab-toolbox`. They will be locatable with the label `app=toolbox`. -Announced: 2021-09-22 +Announced: 2021-08-22 diff --git a/doc/user/clusters/agent/index.md b/doc/user/clusters/agent/index.md index d2dc57c0849..b28b2393e07 100644 --- a/doc/user/clusters/agent/index.md +++ b/doc/user/clusters/agent/index.md @@ -444,6 +444,37 @@ the current project, and the configuration directory for each agent: Additional management interfaces are planned for the GitLab Kubernetes Agent. [Provide more feedback in the related epic](https://gitlab.com/groups/gitlab-org/-/epics/4739). +## Remove the GitLab Kubernetes Agent + +1. Remove an Agent record with GraphQL by deleting the `clusterAgent` and the `clusterAgentToken`. + + ```graphql + mutation deleteAgent { + clusterAgentDelete(input: { id: "<cluster-agent-id>" } ) { + errors + } + } + + mutation deleteToken { + clusterAgentTokenDelete(input: { id: "<cluster-agent-token-id>" }) { + errors + } + } + ``` + +1. Verify whether the removal occurred successfully. If the output in the Pod logs includes `unauthenticated`, it means that the agent was successfully removed: + + ```json + {"level":"warn","time":"2021-04-29T23:44:07.598Z","msg":"GetConfiguration.Recv failed","error":"rpc error: + code = Unauthenticated desc = unauthenticated"} + ``` + +1. Delete the GitLab Kubernetes Agent in your cluster: + + ```shell + kubectl delete -n gitlab-kubernetes-agent -f ./resources.yml + ``` + ## Troubleshooting If you face any issues while using GitLab Kubernetes Agent, you can read the @@ -455,7 +486,9 @@ kubectl logs -f -l=app=gitlab-kubernetes-agent -n gitlab-kubernetes-agent GitLab administrators can additionally view the [Kubernetes Agent Server logs](../../../administration/clusters/kas.md#troubleshooting). -### Agent logs - Transport: Error while dialing failed to WebSocket dial +### Agent logs + +#### Transport: Error while dialing failed to WebSocket dial ```json {"level":"warn","time":"2020-11-04T10:14:39.368Z","msg":"GetConfiguration failed","error":"rpc error: code = Unavailable desc = connection error: desc = \"transport: Error while dialing failed to WebSocket dial: failed to send handshake request: Get \\\"https://gitlab-kas:443/-/kubernetes-agent\\\": dial tcp: lookup gitlab-kas on 10.60.0.10:53: no such host\""} @@ -473,7 +506,7 @@ This error occurs if the `kas-address` doesn't include a trailing slash. To fix `wss` or `ws` URL ends with a training slash, such as `wss://GitLab.host.tld:443/-/kubernetes-agent/` or `ws://GitLab.host.tld:80/-/kubernetes-agent/`. -### Agent logs - ValidationError(Deployment.metadata) +#### ValidationError(Deployment.metadata) ```json {"level":"info","time":"2020-10-30T08:56:54.329Z","msg":"Synced","project_id":"root/kas-manifest001","resource_key":"apps/Deployment/kas-test001/nginx-deployment","sync_result":"error validating data: [ValidationError(Deployment.metadata): unknown field \"replicas\" in io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta, ValidationError(Deployment.metadata): unknown field \"selector\" in io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta, ValidationError(Deployment.metadata): unknown field \"template\" in io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta]"} @@ -483,7 +516,7 @@ This error is shown if a manifest file is malformed, and Kubernetes can't create specified objects. Make sure that your manifest files are valid. You may try using them to create objects in Kubernetes directly for more troubleshooting. -### Agent logs - Error while dialing failed to WebSocket dial: failed to send handshake request +#### Error while dialing failed to WebSocket dial: failed to send handshake request ```json {"level":"warn","time":"2020-10-30T09:50:51.173Z","msg":"GetConfiguration failed","error":"rpc error: code = Unavailable desc = connection error: desc = \"transport: Error while dialing failed to WebSocket dial: failed to send handshake request: Get \\\"https://GitLabhost.tld:443/-/kubernetes-agent\\\": net/http: HTTP/1.x transport connection broken: malformed HTTP response \\\"\\\\x00\\\\x00\\\\x06\\\\x04\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x00\\\\x05\\\\x00\\\\x00@\\\\x00\\\"\""} @@ -499,7 +532,7 @@ issue is in progress, directly edit the deployment with the `kubectl edit deployment gitlab-kas` command, and change `--listen-websocket=true` to `--listen-websocket=false`. After running that command, you should be able to use `grpc://gitlab-kas.<YOUR-NAMESPACE>:8150`. -### Agent logs - Decompressor is not installed for grpc-encoding +#### Decompressor is not installed for grpc-encoding ```json {"level":"warn","time":"2020-11-05T05:25:46.916Z","msg":"GetConfiguration.Recv failed","error":"rpc error: code = Unimplemented desc = grpc: Decompressor is not installed for grpc-encoding \"gzip\""} @@ -508,7 +541,7 @@ issue is in progress, directly edit the deployment with the This error is shown if the version of the agent is newer that the version of KAS. To fix it, make sure that both `agentk` and KAS use the same versions. -### Agent logs - Certificate signed by unknown authority +#### Certificate signed by unknown authority ```json {"level":"error","time":"2021-02-25T07:22:37.158Z","msg":"Reverse tunnel","mod_name":"reverse_tunnel","error":"Connect(): rpc error: code = Unavailable desc = connection error: desc = \"transport: Error while dialing failed to WebSocket dial: failed to send handshake request: Get \\\"https://GitLabhost.tld:443/-/kubernetes-agent/\\\": x509: certificate signed by unknown authority\""} @@ -580,34 +613,3 @@ Alternatively, you can mount the certificate file at a different location and in mountPath: /tmp/myCA.pem subPath: myCA.pem ``` - -## Remove the GitLab Kubernetes Agent - -1. Remove an Agent record with GraphQL by deleting the `clusterAgent` and the `clusterAgentToken`. - - ```graphql - mutation deleteAgent { - clusterAgentDelete(input: { id: "<cluster-agent-id>" } ) { - errors - } - } - - mutation deleteToken { - clusterAgentTokenDelete(input: { id: "<cluster-agent-token-id>" }) { - errors - } - } - ``` - -1. Verify whether the removal occurred successfully. If the output in the Pod logs includes `unauthenticated`, it means that the agent was successfully removed: - - ```json - {"level":"warn","time":"2021-04-29T23:44:07.598Z","msg":"GetConfiguration.Recv failed","error":"rpc error: - code = Unauthenticated desc = unauthenticated"} - ``` - -1. Delete the GitLab Kubernetes Agent in your cluster: - - ```shell - kubectl delete -n gitlab-kubernetes-agent -f ./resources.yml - ``` diff --git a/doc/user/group/contribution_analytics/index.md b/doc/user/group/contribution_analytics/index.md index a2d7f358cd9..b13dd3f63cb 100644 --- a/doc/user/group/contribution_analytics/index.md +++ b/doc/user/group/contribution_analytics/index.md @@ -11,15 +11,18 @@ info: To determine the technical writer assigned to the Stage/Group associated w With Contribution Analytics you can get an overview of the [contribution actions](../../../api/events.md#action-types) in your group. -To view the Contribution Analytics, go to your group and select **Analytics > Contribution**. - -## Use cases - - Analyze your team's contributions over a period of time, and offer a bonus for the top contributors. - Identify opportunities for improvement with group members who may benefit from additional support. +## View Contribution Analytics + +To view Contribution Analytics: + +1. On the top bar, select **Menu > Groups** and find your group. +1. On the left sidebar, select **Analytics > Contribution**. + ## Using Contribution Analytics There are three main bar graphs that illustrate the number of contributions per group diff --git a/doc/user/markdown.md b/doc/user/markdown.md index 4149307c45a..5eab5fcb513 100644 --- a/doc/user/markdown.md +++ b/doc/user/markdown.md @@ -955,6 +955,10 @@ Do not change to a reference style link. ![alt text](img/markdown_logo.png "Title Text") +In the rare case where you need to set a specific height or width for an image, +you can use the `img` HTML tag instead of Markdown and set its `height` and +`width` parameters. + #### Videos If this section isn't rendered correctly, [view it in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#videos). diff --git a/doc/user/project/merge_requests/approvals/rules.md b/doc/user/project/merge_requests/approvals/rules.md index 7e168fb239a..6dc06d22028 100644 --- a/doc/user/project/merge_requests/approvals/rules.md +++ b/doc/user/project/merge_requests/approvals/rules.md @@ -225,7 +225,7 @@ approval rule for certain branches: 1. Go to your project and select **Settings**. 1. Expand **Merge request (MR) approvals**. 1. Select a **Target branch**: - - To protect all branches, select **Any branch**. + - To protect all branches, select **All branches**. - To select a specific branch, select it from the list: ![Scoped to protected branch](img/scoped_to_protected_branch_v13_10.png) diff --git a/doc/user/project/merge_requests/status_checks.md b/doc/user/project/merge_requests/status_checks.md index 399d7958bbf..08b82462187 100644 --- a/doc/user/project/merge_requests/status_checks.md +++ b/doc/user/project/merge_requests/status_checks.md @@ -93,7 +93,7 @@ for doesn't appear immediately. The search box requires **three** alphanumeric characters to be entered for the search to begin. If you want the status check to be applied to **all** merge requests, -you can select the **Any branch** option. +you can select the **All branches** option. ## Delete a status check diff --git a/jest.config.base.js b/jest.config.base.js index 3ace87c49bc..978be4e2919 100644 --- a/jest.config.base.js +++ b/jest.config.base.js @@ -102,7 +102,7 @@ module.exports = (path, options = {}) => { return { clearMocks: true, testMatch, - moduleFileExtensions: ['js', 'json', 'vue'], + moduleFileExtensions: ['js', 'json', 'vue', 'gql', 'graphql'], moduleNameMapper, collectCoverageFrom, coverageDirectory: coverageDirectory(), diff --git a/locale/gitlab.pot b/locale/gitlab.pot index cfb5d02d4ab..029198a83e5 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -3934,9 +3934,6 @@ msgstr "" msgid "Any Milestone" msgstr "" -msgid "Any branch" -msgstr "" - msgid "Any eligible user" msgstr "" @@ -4121,7 +4118,7 @@ msgstr "" msgid "Apply template" msgstr "" -msgid "Apply this approval rule to any branch or a specific protected branch." +msgid "Apply this approval rule to all branches or a specific protected branch." msgstr "" msgid "Applying" @@ -32177,7 +32174,7 @@ msgstr "" msgid "StatusCheck|An error occurred fetching the status checks." msgstr "" -msgid "StatusCheck|Apply this status check to any branch or a specific protected branch." +msgid "StatusCheck|Apply this status check to all branches or a specific protected branch." msgstr "" msgid "StatusCheck|Check for a status response in Merge Requests. Failures do not block merges. %{link_start}Learn more%{link_end}." diff --git a/package.json b/package.json index 6f90551109a..fc1630acf09 100644 --- a/package.json +++ b/package.json @@ -123,7 +123,7 @@ "dateformat": "^4.5.1", "deckar01-task_list": "^2.3.1", "diff": "^3.4.0", - "dompurify": "^2.3.2", + "dompurify": "^2.3.3", "dropzone": "^4.2.0", "editorconfig": "^0.15.3", "emoji-regex": "^7.0.3", diff --git a/spec/factories/ci/pending_builds.rb b/spec/factories/ci/pending_builds.rb index 31e42e1bc9e..28258b0339f 100644 --- a/spec/factories/ci/pending_builds.rb +++ b/spec/factories/ci/pending_builds.rb @@ -9,5 +9,6 @@ FactoryBot.define do namespace { project.namespace } minutes_exceeded { false } tag_ids { build.tags_ids } + namespace_traversal_ids { project.namespace.traversal_ids } end end diff --git a/spec/services/ci/update_pending_build_service_spec.rb b/spec/services/ci/update_pending_build_service_spec.rb index d842042de40..d36564938c8 100644 --- a/spec/services/ci/update_pending_build_service_spec.rb +++ b/spec/services/ci/update_pending_build_service_spec.rb @@ -3,21 +3,23 @@ require 'spec_helper' RSpec.describe Ci::UpdatePendingBuildService do - describe '#execute' do - let_it_be(:group) { create(:group) } - let_it_be(:project) { create(:project, namespace: group) } - let_it_be(:pending_build_1) { create(:ci_pending_build, project: project, instance_runners_enabled: false) } - let_it_be(:pending_build_2) { create(:ci_pending_build, project: project, instance_runners_enabled: true) } - let_it_be(:update_params) { { instance_runners_enabled: true } } + let_it_be(:group) { create(:group) } + let_it_be(:project) { create(:project, namespace: group) } + let_it_be_with_reload(:pending_build_1) { create(:ci_pending_build, project: project, instance_runners_enabled: false) } + let_it_be_with_reload(:pending_build_2) { create(:ci_pending_build, project: project, instance_runners_enabled: true) } + let_it_be(:update_params) { { instance_runners_enabled: true } } + + let(:service) { described_class.new(model, update_params) } - subject(:service) { described_class.new(model, update_params).execute } + describe '#execute' do + subject(:update_pending_builds) { service.execute } context 'validations' do context 'when model is invalid' do let(:model) { pending_build_1 } it 'raises an error' do - expect { service }.to raise_error(described_class::InvalidModelError) + expect { update_pending_builds }.to raise_error(described_class::InvalidModelError) end end @@ -26,7 +28,7 @@ RSpec.describe Ci::UpdatePendingBuildService do let(:update_params) { { minutes_exceeded: true } } it 'raises an error' do - expect { service }.to raise_error(described_class::InvalidParamsError) + expect { update_pending_builds }.to raise_error(described_class::InvalidParamsError) end end end @@ -35,10 +37,10 @@ RSpec.describe Ci::UpdatePendingBuildService do let(:model) { group } it 'updates all pending builds', :aggregate_failures do - service + update_pending_builds - expect(pending_build_1.reload.instance_runners_enabled).to be_truthy - expect(pending_build_2.reload.instance_runners_enabled).to be_truthy + expect(pending_build_1.instance_runners_enabled).to be_truthy + expect(pending_build_2.instance_runners_enabled).to be_truthy end context 'when ci_pending_builds_maintain_shared_runners_data is disabled' do @@ -47,10 +49,10 @@ RSpec.describe Ci::UpdatePendingBuildService do end it 'does not update all pending builds', :aggregate_failures do - service + update_pending_builds - expect(pending_build_1.reload.instance_runners_enabled).to be_falsey - expect(pending_build_2.reload.instance_runners_enabled).to be_truthy + expect(pending_build_1.instance_runners_enabled).to be_falsey + expect(pending_build_2.instance_runners_enabled).to be_truthy end end end @@ -59,10 +61,10 @@ RSpec.describe Ci::UpdatePendingBuildService do let(:model) { project } it 'updates all pending builds', :aggregate_failures do - service + update_pending_builds - expect(pending_build_1.reload.instance_runners_enabled).to be_truthy - expect(pending_build_2.reload.instance_runners_enabled).to be_truthy + expect(pending_build_1.instance_runners_enabled).to be_truthy + expect(pending_build_2.instance_runners_enabled).to be_truthy end context 'when ci_pending_builds_maintain_shared_runners_data is disabled' do @@ -71,10 +73,10 @@ RSpec.describe Ci::UpdatePendingBuildService do end it 'does not update all pending builds', :aggregate_failures do - service + update_pending_builds - expect(pending_build_1.reload.instance_runners_enabled).to be_falsey - expect(pending_build_2.reload.instance_runners_enabled).to be_truthy + expect(pending_build_1.instance_runners_enabled).to be_falsey + expect(pending_build_2.instance_runners_enabled).to be_truthy end end end diff --git a/spec/services/groups/transfer_service_spec.rb b/spec/services/groups/transfer_service_spec.rb index 889b5551746..e7928c9c2d5 100644 --- a/spec/services/groups/transfer_service_spec.rb +++ b/spec/services/groups/transfer_service_spec.rb @@ -651,6 +651,30 @@ RSpec.describe Groups::TransferService do expect(project1.public?).to be_truthy end end + + context 'when group has pending builds' do + let_it_be(:project) { create(:project, :public, namespace: group.reload) } + let_it_be(:other_project) { create(:project) } + let_it_be(:pending_build) { create(:ci_pending_build, project: project) } + let_it_be(:unrelated_pending_build) { create(:ci_pending_build, project: other_project) } + + before do + group.add_owner(user) + new_parent_group.add_owner(user) + end + + it 'updates pending builds for the group', :aggregate_failures do + transfer_service.execute(new_parent_group) + + pending_build.reload + unrelated_pending_build.reload + + expect(pending_build.namespace_id).to eq(group.id) + expect(pending_build.namespace_traversal_ids).to eq(group.traversal_ids) + expect(unrelated_pending_build.namespace_id).to eq(other_project.namespace_id) + expect(unrelated_pending_build.namespace_traversal_ids).to eq(other_project.namespace.traversal_ids) + end + end end context 'when transferring a subgroup into root group' do diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb index d96573e26af..9c0f80e174a 100644 --- a/spec/services/projects/transfer_service_spec.rb +++ b/spec/services/projects/transfer_service_spec.rb @@ -143,6 +143,28 @@ RSpec.describe Projects::TransferService do end end end + + context 'when project has pending builds' do + let!(:other_project) { create(:project) } + let!(:pending_build) { create(:ci_pending_build, project: project.reload) } + let!(:unrelated_pending_build) { create(:ci_pending_build, project: other_project) } + + before do + group.reload + end + + it 'updates pending builds for the project', :aggregate_failures do + execute_transfer + + pending_build.reload + unrelated_pending_build.reload + + expect(pending_build.namespace_id).to eq(group.id) + expect(pending_build.namespace_traversal_ids).to eq(group.traversal_ids) + expect(unrelated_pending_build.namespace_id).to eq(other_project.namespace_id) + expect(unrelated_pending_build.namespace_traversal_ids).to eq(other_project.namespace.traversal_ids) + end + end end context 'when transfer fails' do @@ -203,6 +225,24 @@ RSpec.describe Projects::TransferService do shard_name: project.repository_storage ) end + + context 'when project has pending builds' do + let!(:other_project) { create(:project) } + let!(:pending_build) { create(:ci_pending_build, project: project.reload) } + let!(:unrelated_pending_build) { create(:ci_pending_build, project: other_project) } + + it 'does not update pending builds for the project', :aggregate_failures do + attempt_project_transfer + + pending_build.reload + unrelated_pending_build.reload + + expect(pending_build.namespace_id).to eq(project.namespace_id) + expect(pending_build.namespace_traversal_ids).to eq(project.namespace.traversal_ids) + expect(unrelated_pending_build.namespace_id).to eq(other_project.namespace_id) + expect(unrelated_pending_build.namespace_traversal_ids).to eq(other_project.namespace.traversal_ids) + end + end end context 'namespace -> no namespace' do diff --git a/yarn.lock b/yarn.lock index 40fbea6ec3e..f5af5247db4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4675,10 +4675,10 @@ dompurify@2.3.0: resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.0.tgz#07bb39515e491588e5756b1d3e8375b5964814e2" integrity sha512-VV5C6Kr53YVHGOBKO/F86OYX6/iLTw2yVSI721gKetxpHCK/V5TaLEf9ODjRgl1KLSWRMY6cUhAbv/c+IUnwQw== -dompurify@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.2.tgz#c773efa410abb5c087c7caf44934fefa448f6e60" - integrity sha512-jXJnvWloI+scD+N5uBikpUMsYXZb0LCAXxLFAOLS5duCzKfXLqBCpuINvFOiI4eJgTLggrngljT18HNoakHUsA== +dompurify@^2.3.2, dompurify@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.3.tgz#c1af3eb88be47324432964d8abc75cf4b98d634c" + integrity sha512-dqnqRkPMAjOZE0FogZ+ceJNM2dZ3V/yNOuFB7+39qpO93hHhfRpHw3heYQC7DPK9FqbQTfBKUJhiSfz4MvXYwg== domutils@^1.5.1: version "1.7.0" |