diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue index 1dcbd77a92d..63c492c8bcd 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue +++ b/app/assets/javascripts/pipelines/components/pipelines_list/pipeline_url.vue @@ -2,6 +2,7 @@ import { GlIcon, GlLink, GlTooltipDirective } from '@gitlab/ui'; import { __ } from '~/locale'; import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue'; +import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue'; import { ICONS } from '../../constants'; import PipelineLabels from './pipeline_labels.vue'; @@ -11,6 +12,7 @@ export default { GlLink, PipelineLabels, TooltipOnTruncate, + UserAvatarLink, }, directives: { GlTooltip: GlTooltipDirective, @@ -169,6 +171,15 @@ export default { {{ commitShortSha }} + diff --git a/app/graphql/resolvers/groups_resolver.rb b/app/graphql/resolvers/groups_resolver.rb index abd3bf9e6e0..6cfdba240f0 100644 --- a/app/graphql/resolvers/groups_resolver.rb +++ b/app/graphql/resolvers/groups_resolver.rb @@ -30,7 +30,7 @@ module Resolvers GroupsFinder .new(context[:current_user], args.merge(parent: parent)) .execute - .reorder('name ASC') + .reorder(name: :asc) end # rubocop: enable CodeReuse/ActiveRecord end diff --git a/app/models/project.rb b/app/models/project.rb index 91189afb72d..7796bdf67e2 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -383,7 +383,7 @@ class Project < ApplicationRecord has_many :source_pipelines, class_name: 'Ci::Sources::Pipeline', foreign_key: :project_id has_many :import_failures, inverse_of: :project - has_many :jira_imports, -> { order 'jira_imports.created_at' }, class_name: 'JiraImportState', inverse_of: :project + has_many :jira_imports, -> { order(JiraImportState.arel_table[:created_at].asc) }, class_name: 'JiraImportState', inverse_of: :project has_many :daily_build_group_report_results, class_name: 'Ci::DailyBuildGroupReportResult' has_many :ci_feature_usages, class_name: 'Projects::CiFeatureUsage' diff --git a/app/models/work_items/type.rb b/app/models/work_items/type.rb index 080513b28e9..e2d38dc9903 100644 --- a/app/models/work_items/type.rb +++ b/app/models/work_items/type.rb @@ -37,7 +37,7 @@ module WorkItems validates :icon_name, length: { maximum: 255 } scope :default, -> { where(namespace: nil) } - scope :order_by_name_asc, -> { order('LOWER(name)') } + scope :order_by_name_asc, -> { order(arel_table[:name].lower.asc) } scope :by_type, ->(base_type) { where(base_type: base_type) } def self.default_by_type(type) diff --git a/db/post_migrate/20220322094410_remove_wiki_notes.rb b/db/post_migrate/20220322094410_remove_wiki_notes.rb new file mode 100644 index 00000000000..c3705e1e20f --- /dev/null +++ b/db/post_migrate/20220322094410_remove_wiki_notes.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +class RemoveWikiNotes < Gitlab::Database::Migration[1.0] + disable_ddl_transaction! + + class Note < ApplicationRecord + self.table_name = 'notes' + self.inheritance_column = :_type_disabled + end + + def up + return unless Gitlab.dev_or_test_env? || Gitlab.staging? || Gitlab.com? + + Note.where(noteable_type: 'Wiki', id: [97, 98, 110, 242, 272]).delete_all + end + + def down + # NO-OP + end +end diff --git a/db/schema_migrations/20220322094410 b/db/schema_migrations/20220322094410 new file mode 100644 index 00000000000..1ad1682e22c --- /dev/null +++ b/db/schema_migrations/20220322094410 @@ -0,0 +1 @@ +09722b398f82651c433f6b05962827351e6e7c0841f2a6414feb206bb831e523 \ No newline at end of file diff --git a/doc/api/users.md b/doc/api/users.md index 7c7931df43a..448edcdf9c8 100644 --- a/doc/api/users.md +++ b/doc/api/users.md @@ -1850,7 +1850,7 @@ POST /users/:user_id/personal_access_tokens | `user_id` | integer | yes | The ID of the user | | `name` | string | yes | The name of the personal access token | | `expires_at` | date | no | The expiration date of the personal access token in ISO format (`YYYY-MM-DD`) | -| `scopes` | array | yes | The array of scopes of the personal access token (`api`, `read_user`, `read_api`, `read_repository`, `write_repository`) | +| `scopes` | array | yes | The array of scopes of the personal access token. See [personal access token scopes](../user/profile/personal_access_tokens.md#personal-access-token-scopes) for possible values. | ```shell curl --request POST --header "PRIVATE-TOKEN: " --data "name=mytoken" --data "expires_at=2017-04-04" \ diff --git a/doc/development/internal_api/index.md b/doc/development/internal_api/index.md index ef58d6c2c44..cdbc674e0a5 100644 --- a/doc/development/internal_api/index.md +++ b/doc/development/internal_api/index.md @@ -621,7 +621,7 @@ Example response: "name":"premium", "trial":false, "auto_renew":null, - "upgradable":false + "upgradable":false, }, "usage": { "seats_in_subscription":10, @@ -672,7 +672,7 @@ Example response: "name":"premium", "trial":false, "auto_renew":null, - "upgradable":false + "upgradable":false, }, "usage": { "seats_in_subscription":80, @@ -711,7 +711,8 @@ Example response: "name":"premium", "trial":false, "auto_renew":null, - "upgradable":false + "upgradable":false, + "exclude_guests":false, }, "usage": { "seats_in_subscription":80, diff --git a/doc/user/profile/personal_access_tokens.md b/doc/user/profile/personal_access_tokens.md index 1fbbe438370..4c132094d24 100644 --- a/doc/user/profile/personal_access_tokens.md +++ b/doc/user/profile/personal_access_tokens.md @@ -98,8 +98,8 @@ A personal access token can perform actions based on the assigned scopes. | `read_api` | Read-only for the complete API, including all groups and projects, the Container Registry, and the Package Registry. ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28944) in GitLab 12.10.) | | `read_repository` | Read-only (pull) for the repository through `git clone`. | | `write_repository` | Read-write (pull, push) for the repository through `git clone`. | -| `read_registry` | Read-only (pull) for [Container Registry](../packages/container_registry/index.md) images if a project is private and authorization is required. | -| `write_registry` | Read-write (push) for [Container Registry](../packages/container_registry/index.md) images if a project is private and authorization is required. ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28958) in GitLab 12.10.) | +| `read_registry` | Read-only (pull) for [Container Registry](../packages/container_registry/index.md) images if a project is private and authorization is required. Available only when the Container Registry is enabled. | +| `write_registry` | Read-write (push) for [Container Registry](../packages/container_registry/index.md) images if a project is private and authorization is required. Available only when the Container Registry is enabled. ([Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28958) in GitLab 12.10.) | | `sudo` | API actions as any user in the system (if the authenticated user is an administrator). | ## When personal access tokens expire diff --git a/qa/qa/service/praefect_manager.rb b/qa/qa/service/praefect_manager.rb index c364b00629c..1215268919c 100644 --- a/qa/qa/service/praefect_manager.rb +++ b/qa/qa/service/praefect_manager.rb @@ -530,9 +530,17 @@ module QA storage_repositories[2..-3] end + def modify_repo_access_time(node, repo_path, update_time) + repo = "/var/opt/gitlab/git-data/repositories/#{repo_path}" + shell(%{ + docker exec --user git #{node} bash -c 'find #{repo} -exec touch -d "#{update_time}" {} \\;' + }) + end + def add_repo_to_disk(node, repo_path) cmd = "GIT_DIR=. git init --initial-branch=main /var/opt/gitlab/git-data/repositories/#{repo_path}" shell "docker exec --user git #{node} bash -c '#{cmd}'" + modify_repo_access_time(node, repo_path, "24 hours ago") end def remove_repo_from_disk(repo_path) diff --git a/spec/frontend/pipelines/pipeline_url_spec.js b/spec/frontend/pipelines/pipeline_url_spec.js index 2a0aeed917c..c6104a13216 100644 --- a/spec/frontend/pipelines/pipeline_url_spec.js +++ b/spec/frontend/pipelines/pipeline_url_spec.js @@ -1,5 +1,6 @@ import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import PipelineUrlComponent from '~/pipelines/components/pipelines_list/pipeline_url.vue'; +import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue'; import { mockPipeline, mockPipelineBranch, mockPipelineTag } from './mock_data'; const projectPath = 'test/test'; @@ -57,6 +58,30 @@ describe('Pipeline Url Component', () => { expect(findCommitShortSha().exists()).toBe(true); }); + describe('commit user avatar', () => { + it('renders when commit author exists', () => { + const pipelineBranch = mockPipelineBranch(); + const { avatar_url, name, path } = pipelineBranch.pipeline.commit.author; + createComponent(pipelineBranch); + + const component = wrapper.findComponent(UserAvatarLink); + expect(component.exists()).toBe(true); + expect(component.props()).toMatchObject({ + imgSize: 16, + imgSrc: avatar_url, + imgAlt: name, + linkHref: path, + tooltipText: name, + }); + }); + + it('does not render when commit author does not exist', () => { + createComponent(); + + expect(wrapper.findComponent(UserAvatarLink).exists()).toBe(false); + }); + }); + it('should render commit icon tooltip', () => { createComponent({}, true); diff --git a/spec/migrations/remove_wiki_notes_spec.rb b/spec/migrations/remove_wiki_notes_spec.rb new file mode 100644 index 00000000000..2ffebdee106 --- /dev/null +++ b/spec/migrations/remove_wiki_notes_spec.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_migration! + +RSpec.describe RemoveWikiNotes, :migration do + let(:notes) { table(:notes) } + + it 'removes all wiki notes' do + notes.create!(id: 97, note: 'Wiki note', noteable_type: 'Wiki') + notes.create!(id: 98, note: 'Commit note', noteable_type: 'Commit') + notes.create!(id: 110, note: 'Issue note', noteable_type: 'Issue') + notes.create!(id: 242, note: 'MergeRequest note', noteable_type: 'MergeRequest') + + expect(notes.where(noteable_type: 'Wiki').size).to eq(1) + + expect { migrate! }.to change { notes.count }.by(-1) + + expect(notes.where(noteable_type: 'Wiki').size).to eq(0) + end + + context 'when not staging nor com' do + it 'does not remove notes' do + allow(::Gitlab).to receive(:com?).and_return(false) + allow(::Gitlab).to receive(:dev_or_test_env?).and_return(false) + allow(::Gitlab).to receive(:staging?).and_return(false) + + notes.create!(id: 97, note: 'Wiki note', noteable_type: 'Wiki') + + expect { migrate! }.not_to change { notes.count } + end + end +end