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