Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
c742109766
commit
798e0b5920
2
Gemfile
2
Gemfile
|
@ -129,7 +129,7 @@ gem 'apollo_upload_server', '~> 2.1.0'
|
||||||
gem 'graphql-docs', '~> 2.1.0', group: [:development, :test]
|
gem 'graphql-docs', '~> 2.1.0', group: [:development, :test]
|
||||||
gem 'graphlient', '~> 0.5.0' # Used by BulkImport feature (group::import)
|
gem 'graphlient', '~> 0.5.0' # Used by BulkImport feature (group::import)
|
||||||
|
|
||||||
gem 'hashie'
|
gem 'hashie', '~> 5.0.0'
|
||||||
# Disable strong_params so that Mash does not respond to :permitted?
|
# Disable strong_params so that Mash does not respond to :permitted?
|
||||||
gem 'hashie-forbidden_attributes'
|
gem 'hashie-forbidden_attributes'
|
||||||
|
|
||||||
|
|
|
@ -259,7 +259,7 @@
|
||||||
{"name":"hana","version":"1.3.7","platform":"ruby","checksum":"5425db42d651fea08859811c29d20446f16af196308162894db208cac5ce9b0d"},
|
{"name":"hana","version":"1.3.7","platform":"ruby","checksum":"5425db42d651fea08859811c29d20446f16af196308162894db208cac5ce9b0d"},
|
||||||
{"name":"hangouts-chat","version":"0.0.5","platform":"ruby","checksum":"bdbeb6c6e4abc98f395cb273f53b39911b3aa9e248fbbf063242b021ced8b6b6"},
|
{"name":"hangouts-chat","version":"0.0.5","platform":"ruby","checksum":"bdbeb6c6e4abc98f395cb273f53b39911b3aa9e248fbbf063242b021ced8b6b6"},
|
||||||
{"name":"hashdiff","version":"1.0.1","platform":"ruby","checksum":"2cd4d04f5080314ecc8403c4e2e00dbaa282dff395e2d031bc16c8d501bdd6db"},
|
{"name":"hashdiff","version":"1.0.1","platform":"ruby","checksum":"2cd4d04f5080314ecc8403c4e2e00dbaa282dff395e2d031bc16c8d501bdd6db"},
|
||||||
{"name":"hashie","version":"4.1.0","platform":"ruby","checksum":"7890dcb9ec18a4b66acec797018c73824b89cef5eb8cda36e8e8501845e87a09"},
|
{"name":"hashie","version":"5.0.0","platform":"ruby","checksum":"9d6c4e51f2a36d4616cbc8a322d619a162d8f42815a792596039fc95595603da"},
|
||||||
{"name":"hashie-forbidden_attributes","version":"0.1.1","platform":"ruby","checksum":"3a6ed37f3a314e4fb1dd1e2df6eb7721bcadd023a30bc0b951b2b5285a790fb2"},
|
{"name":"hashie-forbidden_attributes","version":"0.1.1","platform":"ruby","checksum":"3a6ed37f3a314e4fb1dd1e2df6eb7721bcadd023a30bc0b951b2b5285a790fb2"},
|
||||||
{"name":"health_check","version":"3.1.0","platform":"ruby","checksum":"10146508237dc54ed7e24c292d8ba7fb8f9590cf26c66e325b947438c4103b57"},
|
{"name":"health_check","version":"3.1.0","platform":"ruby","checksum":"10146508237dc54ed7e24c292d8ba7fb8f9590cf26c66e325b947438c4103b57"},
|
||||||
{"name":"heapy","version":"0.2.0","platform":"ruby","checksum":"74141e845d61ffc7c1e8bf8b127c8cf94544ec7a1181aec613288682543585ea"},
|
{"name":"heapy","version":"0.2.0","platform":"ruby","checksum":"74141e845d61ffc7c1e8bf8b127c8cf94544ec7a1181aec613288682543585ea"},
|
||||||
|
|
|
@ -709,7 +709,7 @@ GEM
|
||||||
hana (1.3.7)
|
hana (1.3.7)
|
||||||
hangouts-chat (0.0.5)
|
hangouts-chat (0.0.5)
|
||||||
hashdiff (1.0.1)
|
hashdiff (1.0.1)
|
||||||
hashie (4.1.0)
|
hashie (5.0.0)
|
||||||
hashie-forbidden_attributes (0.1.1)
|
hashie-forbidden_attributes (0.1.1)
|
||||||
hashie (>= 3.0)
|
hashie (>= 3.0)
|
||||||
health_check (3.1.0)
|
health_check (3.1.0)
|
||||||
|
@ -1661,7 +1661,7 @@ DEPENDENCIES
|
||||||
haml_lint (~> 0.40.0)
|
haml_lint (~> 0.40.0)
|
||||||
hamlit (~> 2.15.0)
|
hamlit (~> 2.15.0)
|
||||||
hangouts-chat (~> 0.0.5)
|
hangouts-chat (~> 0.0.5)
|
||||||
hashie
|
hashie (~> 5.0.0)
|
||||||
hashie-forbidden_attributes
|
hashie-forbidden_attributes
|
||||||
health_check (~> 3.0)
|
health_check (~> 3.0)
|
||||||
html-pipeline (~> 2.13.2)
|
html-pipeline (~> 2.13.2)
|
||||||
|
|
|
@ -109,10 +109,11 @@ export default {
|
||||||
writePackageRegistryHelp: s__(
|
writePackageRegistryHelp: s__(
|
||||||
'DeployTokens|Allows read and write access to the package registry.',
|
'DeployTokens|Allows read and write access to the package registry.',
|
||||||
),
|
),
|
||||||
|
createTokenFailedAlert: s__('DeployTokens|Failed to create a new deployment token'),
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
formattedExpiryDate() {
|
formattedExpiryDate() {
|
||||||
return formatDate(this.expiresAt, 'yyyy-mm-dd');
|
return this.expiresAt ? formatDate(this.expiresAt, 'yyyy-mm-dd') : '';
|
||||||
},
|
},
|
||||||
newTokenCreatedMessage() {
|
newTokenCreatedMessage() {
|
||||||
return this.tokenType === 'group'
|
return this.tokenType === 'group'
|
||||||
|
@ -129,6 +130,9 @@ export default {
|
||||||
name: this.name,
|
name: this.name,
|
||||||
read_repository: this.readRepository,
|
read_repository: this.readRepository,
|
||||||
read_registry: this.readRegistry,
|
read_registry: this.readRegistry,
|
||||||
|
write_registry: this.writeRegistry,
|
||||||
|
read_package_registry: this.readPackageRegistry,
|
||||||
|
write_package_registry: this.writePackageRegistry,
|
||||||
username: this.username,
|
username: this.username,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -142,7 +146,8 @@ export default {
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
createAlert({
|
createAlert({
|
||||||
message: error.response.data.message,
|
message:
|
||||||
|
error?.response?.data?.message || this.$options.translations.createTokenFailedAlert,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { GlLink, GlTooltipDirective } from '@gitlab/ui';
|
import { GlLink, GlTooltipDirective, GlTruncate } from '@gitlab/ui';
|
||||||
import { __ } from '~/locale';
|
import { __ } from '~/locale';
|
||||||
import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate/tooltip_on_truncate.vue';
|
|
||||||
import timeagoMixin from '~/vue_shared/mixins/timeago';
|
import timeagoMixin from '~/vue_shared/mixins/timeago';
|
||||||
import {
|
import {
|
||||||
MANUAL_DEPLOY,
|
MANUAL_DEPLOY,
|
||||||
|
@ -18,7 +17,7 @@ export default {
|
||||||
components: {
|
components: {
|
||||||
GlLink,
|
GlLink,
|
||||||
MemoryUsage: () => import('./memory_usage.vue'),
|
MemoryUsage: () => import('./memory_usage.vue'),
|
||||||
TooltipOnTruncate,
|
GlTruncate,
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
GlTooltip: GlTooltipDirective,
|
GlTooltip: GlTooltipDirective,
|
||||||
|
@ -74,16 +73,19 @@ export default {
|
||||||
<div class="js-deployment-info deployment-info">
|
<div class="js-deployment-info deployment-info">
|
||||||
<template v-if="hasDeploymentMeta">
|
<template v-if="hasDeploymentMeta">
|
||||||
<span>{{ deployedText }}</span>
|
<span>{{ deployedText }}</span>
|
||||||
<tooltip-on-truncate :title="deployment.name" truncate-target="child" class="label-truncate">
|
<gl-link
|
||||||
<gl-link
|
:href="deployment.url"
|
||||||
:href="deployment.url"
|
target="_blank"
|
||||||
target="_blank"
|
rel="noopener noreferrer nofollow"
|
||||||
rel="noopener noreferrer nofollow"
|
class="js-deploy-meta gl-font-sm gl-pb-1"
|
||||||
class="js-deploy-meta gl-font-sm gl-pb-1"
|
>
|
||||||
>
|
<gl-truncate
|
||||||
{{ deployment.name }}
|
class="js-deploy-env-name"
|
||||||
</gl-link>
|
:text="deployment.name"
|
||||||
</tooltip-on-truncate>
|
position="middle"
|
||||||
|
with-tooltip
|
||||||
|
/>
|
||||||
|
</gl-link>
|
||||||
</template>
|
</template>
|
||||||
<span
|
<span
|
||||||
v-if="hasDeploymentTime"
|
v-if="hasDeploymentTime"
|
||||||
|
|
|
@ -72,7 +72,7 @@ export default {
|
||||||
:display="appButtonText"
|
:display="appButtonText"
|
||||||
:link="deploymentExternalUrl"
|
:link="deploymentExternalUrl"
|
||||||
size="small"
|
size="small"
|
||||||
css-class="deploy-link js-deploy-url inline gl-ml-3"
|
css-class="deploy-link js-deploy-url inline"
|
||||||
/>
|
/>
|
||||||
<modal-copy-button
|
<modal-copy-button
|
||||||
v-else
|
v-else
|
||||||
|
@ -116,7 +116,7 @@ export default {
|
||||||
:display="appButtonText"
|
:display="appButtonText"
|
||||||
:link="deploymentExternalUrl"
|
:link="deploymentExternalUrl"
|
||||||
size="small"
|
size="small"
|
||||||
css-class="deploy-link js-deploy-url inline gl-ml-3"
|
css-class="deploy-link js-deploy-url inline"
|
||||||
/>
|
/>
|
||||||
<modal-copy-button
|
<modal-copy-button
|
||||||
v-else
|
v-else
|
||||||
|
|
|
@ -391,6 +391,10 @@ $tabs-holder-z-index: 250;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
min-width: 100px;
|
min-width: 100px;
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: max-content minmax(0, max-content) max-content;
|
||||||
|
grid-gap: $gl-spacing-scale-2;
|
||||||
|
|
||||||
@include media-breakpoint-up(xs) {
|
@include media-breakpoint-up(xs) {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
@ -404,6 +408,7 @@ $tabs-holder-z-index: 250;
|
||||||
|
|
||||||
.deploy-heading,
|
.deploy-heading,
|
||||||
.merge-train-position-indicator {
|
.merge-train-position-indicator {
|
||||||
|
padding: $gl-padding-8;
|
||||||
@include media-breakpoint-up(md) {
|
@include media-breakpoint-up(md) {
|
||||||
padding: $gl-padding-8 $gl-padding;
|
padding: $gl-padding-8 $gl-padding;
|
||||||
}
|
}
|
||||||
|
@ -637,7 +642,6 @@ $tabs-holder-z-index: 250;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
.deploy-link,
|
|
||||||
.label-branch {
|
.label-branch {
|
||||||
&.label-truncate {
|
&.label-truncate {
|
||||||
// NOTE: This selector targets its children because some of the HTML comes from
|
// NOTE: This selector targets its children because some of the HTML comes from
|
||||||
|
|
|
@ -6,7 +6,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
||||||
|
|
||||||
# Troubleshooting topic type
|
# Troubleshooting topic type
|
||||||
|
|
||||||
Troubleshooting topics should be the last topics on a page.
|
Troubleshooting topics should be the final topics on a page.
|
||||||
|
|
||||||
If a page has more than five troubleshooting topics, put the content on a separate page that has troubleshooting information exclusively. Name the page `Troubleshooting <feature>`
|
If a page has more than five troubleshooting topics, put the content on a separate page that has troubleshooting information exclusively. Name the page `Troubleshooting <feature>`
|
||||||
and in the left nav, use the word `Troubleshooting` only.
|
and in the left nav, use the word `Troubleshooting` only.
|
||||||
|
@ -54,3 +54,13 @@ For the heading of a **Troubleshooting reference** topic:
|
||||||
- Use fewer than 70 characters.
|
- Use fewer than 70 characters.
|
||||||
|
|
||||||
If you do not put the full error in the title, include it in the body text.
|
If you do not put the full error in the title, include it in the body text.
|
||||||
|
|
||||||
|
## Rails console write functions
|
||||||
|
|
||||||
|
If the troubleshooting suggestion includes a function that changes data on the GitLab instance,
|
||||||
|
add the following warning:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
WARNING:
|
||||||
|
Commands that change data can cause damage if not run correctly or under the right conditions. Always run commands in a test environment first and have a backup instance ready to restore.
|
||||||
|
```
|
||||||
|
|
|
@ -32,7 +32,7 @@ For error tracking to work, you need two pieces:
|
||||||
|
|
||||||
### Deploying Sentry
|
### Deploying Sentry
|
||||||
|
|
||||||
You can sign up to the cloud hosted [Sentry](https://sentry.io), deploy your own [on-premise instance](https://github.com/getsentry/onpremise/), or use GitLab to [install Sentry to a Kubernetes cluster](../user/infrastructure/clusters/manage/management_project_applications/sentry.md).
|
You can sign up to the cloud hosted [Sentry](https://sentry.io) or deploy your own [on-premise instance](https://github.com/getsentry/onpremise/).
|
||||||
|
|
||||||
### Enabling Sentry
|
### Enabling Sentry
|
||||||
|
|
||||||
|
@ -156,11 +156,11 @@ You can find the feature configuration at **Settings > Monitor > Error Tracking*
|
||||||
|
|
||||||
1. Select **GitLab** as the error tracking backend for your project:
|
1. Select **GitLab** as the error tracking backend for your project:
|
||||||
|
|
||||||
![Error Tracking Settings](img/error_tracking_setting_v14_3.png)
|
![Error Tracking Settings](img/error_tracking_setting_v14_3.png)
|
||||||
|
|
||||||
1. Select **Save changes**. After page reload you should see a text field with the DSN string. Copy it.
|
1. Select **Save changes**. After page reload you should see a text field with the DSN string. Copy it.
|
||||||
|
|
||||||
![Error Tracking Settings DSN](img/error_tracking_setting_dsn_v14_4.png)
|
![Error Tracking Settings DSN](img/error_tracking_setting_dsn_v14_4.png)
|
||||||
|
|
||||||
1. Take the DSN from the previous step and configure your Sentry SDK with it. Errors are now
|
1. Take the DSN from the previous step and configure your Sentry SDK with it. Errors are now
|
||||||
reported to the GitLab collector and are visible in the [GitLab UI](#error-tracking-list).
|
reported to the GitLab collector and are visible in the [GitLab UI](#error-tracking-list).
|
||||||
|
|
|
@ -103,7 +103,6 @@ The [built-in supported applications](https://gitlab.com/gitlab-org/project-temp
|
||||||
- [GitLab Runner](../infrastructure/clusters/manage/management_project_applications/runner.md)
|
- [GitLab Runner](../infrastructure/clusters/manage/management_project_applications/runner.md)
|
||||||
- [Ingress](../infrastructure/clusters/manage/management_project_applications/ingress.md)
|
- [Ingress](../infrastructure/clusters/manage/management_project_applications/ingress.md)
|
||||||
- [Prometheus](../infrastructure/clusters/manage/management_project_applications/prometheus.md)
|
- [Prometheus](../infrastructure/clusters/manage/management_project_applications/prometheus.md)
|
||||||
- [Sentry](../infrastructure/clusters/manage/management_project_applications/sentry.md)
|
|
||||||
- [Vault](../infrastructure/clusters/manage/management_project_applications/vault.md)
|
- [Vault](../infrastructure/clusters/manage/management_project_applications/vault.md)
|
||||||
|
|
||||||
Each application has an `applications/{app}/values.yaml` file.
|
Each application has an `applications/{app}/values.yaml` file.
|
||||||
|
|
|
@ -13309,6 +13309,9 @@ msgstr ""
|
||||||
msgid "DeployTokens|Expires"
|
msgid "DeployTokens|Expires"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "DeployTokens|Failed to create a new deployment token"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
|
msgid "DeployTokens|Group deploy tokens allow access to the packages, repositories, and registry images within the group."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ module QA
|
||||||
RSpec.describe 'Plan' do
|
RSpec.describe 'Plan' do
|
||||||
include Support::API
|
include Support::API
|
||||||
|
|
||||||
describe 'Issue' do
|
describe 'Issue', product_group: :project_management do
|
||||||
let(:issue) do
|
let(:issue) do
|
||||||
Resource::Issue.fabricate_via_api!
|
Resource::Issue.fabricate_via_api!
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module QA
|
module QA
|
||||||
RSpec.describe 'Plan', :orchestrated, :smtp, :reliable do
|
RSpec.describe 'Plan', :orchestrated, :smtp, :reliable, product_group: :project_management do
|
||||||
describe 'Email Notification' do
|
describe 'Email Notification' do
|
||||||
include Support::API
|
include Support::API
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module QA
|
module QA
|
||||||
RSpec.describe 'Plan', :reliable do
|
RSpec.describe 'Plan', :reliable, product_group: :project_management do
|
||||||
let!(:user) do
|
let!(:user) do
|
||||||
Resource::User.fabricate_via_api! do |user|
|
Resource::User.fabricate_via_api! do |user|
|
||||||
user.name = "QA User <img src=x onerror=alert(2)<img src=x onerror=alert(1)>"
|
user.name = "QA User <img src=x onerror=alert(2)<img src=x onerror=alert(1)>"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module QA
|
module QA
|
||||||
RSpec.describe 'Plan', :reliable do
|
RSpec.describe 'Plan', :reliable, product_group: :project_management do
|
||||||
describe 'collapse comments in issue discussions' do
|
describe 'collapse comments in issue discussions' do
|
||||||
let(:my_first_reply) { 'My first reply' }
|
let(:my_first_reply) { 'My first reply' }
|
||||||
let(:one_reply) { '1 reply' }
|
let(:one_reply) { '1 reply' }
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module QA
|
module QA
|
||||||
RSpec.describe 'Plan', :reliable do
|
RSpec.describe 'Plan', :reliable, product_group: :project_management do
|
||||||
describe 'Issue comments' do
|
describe 'Issue comments' do
|
||||||
before do
|
before do
|
||||||
Flow::Login.sign_in
|
Flow::Login.sign_in
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module QA
|
module QA
|
||||||
RSpec.describe 'Plan', :smoke do
|
RSpec.describe 'Plan', :smoke, product_group: :project_management do
|
||||||
describe 'Issue creation' do
|
describe 'Issue creation' do
|
||||||
let(:project) { Resource::Project.fabricate_via_api! }
|
let(:project) { Resource::Project.fabricate_via_api! }
|
||||||
let(:closed_issue) { Resource::Issue.fabricate_via_api! { |issue| issue.project = project } }
|
let(:closed_issue) { Resource::Issue.fabricate_via_api! { |issue| issue.project = project } }
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module QA
|
module QA
|
||||||
RSpec.describe 'Plan', :reliable do
|
RSpec.describe 'Plan', :reliable, product_group: :project_management do
|
||||||
describe 'Custom issue templates' do
|
describe 'Custom issue templates' do
|
||||||
let(:template_name) { 'custom_issue_template' }
|
let(:template_name) { 'custom_issue_template' }
|
||||||
let(:template_content) { 'This is a custom issue template test' }
|
let(:template_content) { 'This is a custom issue template test' }
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module QA
|
module QA
|
||||||
RSpec.describe 'Plan', :reliable do
|
RSpec.describe 'Plan', :reliable, product_group: :project_management do
|
||||||
describe 'Issues list' do
|
describe 'Issues list' do
|
||||||
let(:project) do
|
let(:project) do
|
||||||
Resource::Project.fabricate_via_api! do |project|
|
Resource::Project.fabricate_via_api! do |project|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module QA
|
module QA
|
||||||
RSpec.describe 'Plan', :reliable do
|
RSpec.describe 'Plan', :reliable, product_group: :project_management do
|
||||||
describe 'filter issue comments activities' do
|
describe 'filter issue comments activities' do
|
||||||
before do
|
before do
|
||||||
Flow::Login.sign_in
|
Flow::Login.sign_in
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module QA
|
module QA
|
||||||
RSpec.describe 'Plan', :reliable do
|
RSpec.describe 'Plan', :reliable, product_group: :project_management do
|
||||||
describe 'issue suggestions' do
|
describe 'issue suggestions' do
|
||||||
let(:issue_title) { 'Issue Lists are awesome' }
|
let(:issue_title) { 'Issue Lists are awesome' }
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module QA
|
module QA
|
||||||
RSpec.describe 'Plan', :smoke do
|
RSpec.describe 'Plan', :smoke, product_group: :project_management do
|
||||||
describe 'mention' do
|
describe 'mention' do
|
||||||
let(:user) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) }
|
let(:user) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) }
|
||||||
let(:project) do
|
let(:project) do
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module QA
|
module QA
|
||||||
RSpec.describe 'Plan' do
|
RSpec.describe 'Plan', product_group: :project_management do
|
||||||
describe 'Assignees' do
|
describe 'Assignees' do
|
||||||
let(:user1) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) }
|
let(:user1) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) }
|
||||||
let(:user2) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_2, Runtime::Env.gitlab_qa_password_2) }
|
let(:user2) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_2, Runtime::Env.gitlab_qa_password_2) }
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module QA
|
module QA
|
||||||
RSpec.describe 'Plan', :reliable do
|
RSpec.describe 'Plan', :reliable, product_group: :project_management do
|
||||||
describe 'Issue board focus mode' do
|
describe 'Issue board focus mode' do
|
||||||
let(:project) do
|
let(:project) do
|
||||||
QA::Resource::Project.fabricate_via_api! do |project|
|
QA::Resource::Project.fabricate_via_api! do |project|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module QA
|
module QA
|
||||||
RSpec.describe 'Plan', :reliable do
|
RSpec.describe 'Plan', :reliable, product_group: :project_management do
|
||||||
describe 'Milestones' do
|
describe 'Milestones' do
|
||||||
include Support::Dates
|
include Support::Dates
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module QA
|
module QA
|
||||||
RSpec.describe 'Plan', :reliable do
|
RSpec.describe 'Plan', :reliable, product_group: :project_management do
|
||||||
describe 'Group milestone' do
|
describe 'Group milestone' do
|
||||||
include Support::Dates
|
include Support::Dates
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module QA
|
module QA
|
||||||
RSpec.describe 'Plan', :reliable do
|
RSpec.describe 'Plan', :reliable, product_group: :project_management do
|
||||||
describe 'Project milestone' do
|
describe 'Project milestone' do
|
||||||
include Support::Dates
|
include Support::Dates
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module QA
|
module QA
|
||||||
RSpec.describe 'Plan', :reliable do
|
RSpec.describe 'Plan', :reliable, product_group: :project_management do
|
||||||
describe 'Related issues' do
|
describe 'Related issues' do
|
||||||
let(:project) do
|
let(:project) do
|
||||||
Resource::Project.fabricate_via_api! do |project|
|
Resource::Project.fabricate_via_api! do |project|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module QA
|
module QA
|
||||||
RSpec.describe 'Plan', :transient do
|
RSpec.describe 'Plan', :transient, product_group: :project_management do
|
||||||
describe 'Discussion comments transient bugs' do
|
describe 'Discussion comments transient bugs' do
|
||||||
let(:user1) do
|
let(:user1) do
|
||||||
Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
|
Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#!/bin/sh
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
#
|
#
|
||||||
# This script runs the LicenseFinder gem to verify that all licenses are
|
# This script runs the LicenseFinder gem to verify that all licenses are
|
||||||
# compliant. However, bundler v2.2+ and LicenseFinder do not play well
|
# compliant. However, bundler v2.2+ and LicenseFinder do not play well
|
||||||
|
|
|
@ -18,6 +18,11 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
|
||||||
let(:build) { create(:ci_build, :with_deployment, environment: environment.name, pipeline: pipeline) }
|
let(:build) { create(:ci_build, :with_deployment, environment: environment.name, pipeline: pipeline) }
|
||||||
let!(:deployment) { build.deployment }
|
let!(:deployment) { build.deployment }
|
||||||
|
|
||||||
|
def assert_env_widget(text, env_name)
|
||||||
|
expect(find('.js-deploy-env-name')[:title]).to have_text(env_name)
|
||||||
|
expect(page).to have_content(text)
|
||||||
|
end
|
||||||
|
|
||||||
before do
|
before do
|
||||||
merge_request.update!(merge_commit_sha: sha)
|
merge_request.update!(merge_commit_sha: sha)
|
||||||
project.add_member(user, role)
|
project.add_member(user, role)
|
||||||
|
@ -33,7 +38,7 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
|
||||||
visit project_merge_request_path(project, merge_request)
|
visit project_merge_request_path(project, merge_request)
|
||||||
wait_for_requests
|
wait_for_requests
|
||||||
|
|
||||||
expect(page).to have_content("Deployed to #{environment.name}")
|
assert_env_widget("Deployed to", environment.name)
|
||||||
expect(find('.js-deploy-time')['title']).to eq(deployment.created_at.to_time.in_time_zone.to_s(:medium))
|
expect(find('.js-deploy-time')['title']).to eq(deployment.created_at.to_time.in_time_zone.to_s(:medium))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -47,8 +52,8 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
|
||||||
wait_for_requests
|
wait_for_requests
|
||||||
|
|
||||||
expect(page).to have_selector('.js-deployment-info', count: 1)
|
expect(page).to have_selector('.js-deployment-info', count: 1)
|
||||||
expect(page).to have_content("#{environment.name}")
|
expect(find('.js-deploy-env-name')[:title]).to have_text(environment.name)
|
||||||
expect(page).not_to have_content("#{environment2.name}")
|
expect(find('.js-deploy-env-name')[:title]).not_to have_text(environment2.name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -62,7 +67,7 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
|
||||||
visit project_merge_request_path(project, merge_request)
|
visit project_merge_request_path(project, merge_request)
|
||||||
wait_for_requests
|
wait_for_requests
|
||||||
|
|
||||||
expect(page).to have_content("Failed to deploy to #{environment.name}")
|
assert_env_widget("Failed to deploy to", environment.name)
|
||||||
expect(page).not_to have_css('.js-deploy-time')
|
expect(page).not_to have_css('.js-deploy-time')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -76,7 +81,7 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
|
||||||
visit project_merge_request_path(project, merge_request)
|
visit project_merge_request_path(project, merge_request)
|
||||||
wait_for_requests
|
wait_for_requests
|
||||||
|
|
||||||
expect(page).to have_content("Deploying to #{environment.name}")
|
assert_env_widget("Deploying to", environment.name)
|
||||||
expect(page).not_to have_css('.js-deploy-time')
|
expect(page).not_to have_css('.js-deploy-time')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -89,7 +94,7 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
|
||||||
visit project_merge_request_path(project, merge_request)
|
visit project_merge_request_path(project, merge_request)
|
||||||
wait_for_requests
|
wait_for_requests
|
||||||
|
|
||||||
expect(page).to have_content("Will deploy to #{environment.name}")
|
assert_env_widget("Will deploy to", environment.name)
|
||||||
expect(page).not_to have_css('.js-deploy-time')
|
expect(page).not_to have_css('.js-deploy-time')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -103,7 +108,7 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do
|
||||||
visit project_merge_request_path(project, merge_request)
|
visit project_merge_request_path(project, merge_request)
|
||||||
wait_for_requests
|
wait_for_requests
|
||||||
|
|
||||||
expect(page).to have_content("Canceled deployment to #{environment.name}")
|
assert_env_widget("Canceled deployment to", environment.name)
|
||||||
expect(page).not_to have_css('.js-deploy-time')
|
expect(page).not_to have_css('.js-deploy-time')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -64,7 +64,8 @@ RSpec.describe 'Merge request > User sees merge widget', :js do
|
||||||
wait_for_requests
|
wait_for_requests
|
||||||
|
|
||||||
page.within('.js-pre-deployment') do
|
page.within('.js-pre-deployment') do
|
||||||
expect(page).to have_content("Deployed to #{environment.name}")
|
expect(find('.js-deploy-env-name')[:title]).to have_text(environment.name)
|
||||||
|
expect(page).to have_content("Deployed to")
|
||||||
expect(find('.js-deploy-url')[:href]).to include(environment.formatted_external_url)
|
expect(find('.js-deploy-url')[:href]).to include(environment.formatted_external_url)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -59,6 +59,19 @@ describe('New Deploy Token', () => {
|
||||||
expect(checkbox.text()).toBe('read_registry');
|
expect(checkbox.text()).toBe('read_registry');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function submitTokenThenCheck() {
|
||||||
|
wrapper.findAllComponents(GlButton).at(0).vm.$emit('click');
|
||||||
|
|
||||||
|
return waitForPromises()
|
||||||
|
.then(() => nextTick())
|
||||||
|
.then(() => {
|
||||||
|
const [tokenUsername, tokenValue] = wrapper.findAllComponents(GlFormInputGroup).wrappers;
|
||||||
|
|
||||||
|
expect(tokenUsername.props('value')).toBe('test token username');
|
||||||
|
expect(tokenValue.props('value')).toBe('test token');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
it('should make a request to create a token on submit', () => {
|
it('should make a request to create a token on submit', () => {
|
||||||
const mockAxios = new MockAdapter(axios);
|
const mockAxios = new MockAdapter(axios);
|
||||||
|
|
||||||
|
@ -72,9 +85,18 @@ describe('New Deploy Token', () => {
|
||||||
const datepicker = wrapper.findAllComponents(GlDatepicker).at(0);
|
const datepicker = wrapper.findAllComponents(GlDatepicker).at(0);
|
||||||
datepicker.vm.$emit('input', date);
|
datepicker.vm.$emit('input', date);
|
||||||
|
|
||||||
const [readRepo, readRegistry] = wrapper.findAllComponents(GlFormCheckbox).wrappers;
|
const [
|
||||||
|
readRepo,
|
||||||
|
readRegistry,
|
||||||
|
writeRegistry,
|
||||||
|
readPackageRegistry,
|
||||||
|
writePackageRegistry,
|
||||||
|
] = wrapper.findAllComponents(GlFormCheckbox).wrappers;
|
||||||
readRepo.vm.$emit('input', true);
|
readRepo.vm.$emit('input', true);
|
||||||
readRegistry.vm.$emit('input', true);
|
readRegistry.vm.$emit('input', true);
|
||||||
|
writeRegistry.vm.$emit('input', true);
|
||||||
|
readPackageRegistry.vm.$emit('input', true);
|
||||||
|
writePackageRegistry.vm.$emit('input', true);
|
||||||
|
|
||||||
mockAxios
|
mockAxios
|
||||||
.onPost(createNewTokenPath, {
|
.onPost(createNewTokenPath, {
|
||||||
|
@ -84,20 +106,47 @@ describe('New Deploy Token', () => {
|
||||||
username: 'test username',
|
username: 'test username',
|
||||||
read_repository: true,
|
read_repository: true,
|
||||||
read_registry: true,
|
read_registry: true,
|
||||||
|
write_registry: true,
|
||||||
|
read_package_registry: true,
|
||||||
|
write_package_registry: true,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.replyOnce(200, { username: 'test token username', token: 'test token' });
|
.replyOnce(200, { username: 'test token username', token: 'test token' });
|
||||||
|
|
||||||
wrapper.findAllComponents(GlButton).at(0).vm.$emit('click');
|
return submitTokenThenCheck();
|
||||||
|
});
|
||||||
|
|
||||||
return waitForPromises()
|
it('should request a token without an expiration date', () => {
|
||||||
.then(() => nextTick())
|
const mockAxios = new MockAdapter(axios);
|
||||||
.then(() => {
|
|
||||||
const [tokenUsername, tokenValue] = wrapper.findAllComponents(GlFormInputGroup).wrappers;
|
|
||||||
|
|
||||||
expect(tokenUsername.props('value')).toBe('test token username');
|
const formInputs = wrapper.findAllComponents(GlFormInput);
|
||||||
expect(tokenValue.props('value')).toBe('test token');
|
const name = formInputs.at(0);
|
||||||
});
|
const username = formInputs.at(2);
|
||||||
|
name.vm.$emit('input', 'test never expire name');
|
||||||
|
username.vm.$emit('input', 'test never expire username');
|
||||||
|
|
||||||
|
const [, , , readPackageRegistry, writePackageRegistry] = wrapper.findAllComponents(
|
||||||
|
GlFormCheckbox,
|
||||||
|
).wrappers;
|
||||||
|
readPackageRegistry.vm.$emit('input', true);
|
||||||
|
writePackageRegistry.vm.$emit('input', true);
|
||||||
|
|
||||||
|
mockAxios
|
||||||
|
.onPost(createNewTokenPath, {
|
||||||
|
deploy_token: {
|
||||||
|
name: 'test never expire name',
|
||||||
|
expires_at: null,
|
||||||
|
username: 'test never expire username',
|
||||||
|
read_repository: false,
|
||||||
|
read_registry: false,
|
||||||
|
write_registry: false,
|
||||||
|
read_package_registry: true,
|
||||||
|
write_package_registry: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.replyOnce(200, { username: 'test token username', token: 'test token' });
|
||||||
|
|
||||||
|
return submitTokenThenCheck();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
import { mount } from '@vue/test-utils';
|
||||||
|
import { GlTruncate, GlLink } from '@gitlab/ui';
|
||||||
|
import DeploymentInfo from '~/vue_merge_request_widget/components/deployment/deployment_info.vue';
|
||||||
|
import { deploymentMockData } from './deployment_mock_data';
|
||||||
|
|
||||||
|
// This component is well covered in ./deployment_spec.js
|
||||||
|
// more component-specific tests are added below
|
||||||
|
describe('Deployment Info component', () => {
|
||||||
|
let wrapper;
|
||||||
|
|
||||||
|
const defaultDeploymentInfoOptions = {
|
||||||
|
computedDeploymentStatus: 'computed deployment status',
|
||||||
|
deployment: deploymentMockData,
|
||||||
|
showMetrics: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const factory = (options = {}) => {
|
||||||
|
const componentProps = { ...defaultDeploymentInfoOptions, ...options };
|
||||||
|
const componentOptions = { propsData: componentProps };
|
||||||
|
wrapper = mount(DeploymentInfo, componentOptions);
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
factory();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render gl-truncate for environment name', () => {
|
||||||
|
const envNameComponent = wrapper.findComponent(GlTruncate);
|
||||||
|
expect(envNameComponent.exists()).toBe(true, 'We should use gl-truncate for environment name');
|
||||||
|
expect(envNameComponent.props()).toEqual({
|
||||||
|
text: deploymentMockData.name,
|
||||||
|
withTooltip: true,
|
||||||
|
position: 'middle',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a link with a correct href to deployed environment', () => {
|
||||||
|
const envLink = wrapper.findComponent(GlLink);
|
||||||
|
expect(envLink.exists()).toBe(true, 'We should have gl-link pointing to deployed environment');
|
||||||
|
expect(envLink.attributes().href).toBe(deploymentMockData.url);
|
||||||
|
});
|
||||||
|
});
|
|
@ -125,6 +125,63 @@ RSpec.shared_context 'ProjectPolicyTable context' do
|
||||||
:private | :disabled | :anonymous | nil | 0
|
:private | :disabled | :anonymous | nil | 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# This table is based on permission_table_for_guest_feature_access,
|
||||||
|
# but takes into account note confidentiality. It is required on the context
|
||||||
|
# to have one regular note and one confidential note.
|
||||||
|
#
|
||||||
|
# project_level, :feature_access_level, :membership, :admin_mode, :expected_count
|
||||||
|
def permission_table_for_notes_feature_access
|
||||||
|
:public | :enabled | :admin | true | 2
|
||||||
|
:public | :enabled | :admin | false | 1
|
||||||
|
:public | :enabled | :reporter | nil | 2
|
||||||
|
:public | :enabled | :guest | nil | 1
|
||||||
|
:public | :enabled | :non_member | nil | 1
|
||||||
|
:public | :enabled | :anonymous | nil | 1
|
||||||
|
|
||||||
|
:public | :private | :admin | true | 2
|
||||||
|
:public | :private | :admin | false | 0
|
||||||
|
:public | :private | :reporter | nil | 2
|
||||||
|
:public | :private | :guest | nil | 1
|
||||||
|
:public | :private | :non_member | nil | 0
|
||||||
|
:public | :private | :anonymous | nil | 0
|
||||||
|
|
||||||
|
:public | :disabled | :reporter | nil | 0
|
||||||
|
:public | :disabled | :guest | nil | 0
|
||||||
|
:public | :disabled | :non_member | nil | 0
|
||||||
|
:public | :disabled | :anonymous | nil | 0
|
||||||
|
|
||||||
|
:internal | :enabled | :admin | true | 2
|
||||||
|
:internal | :enabled | :admin | false | 1
|
||||||
|
:internal | :enabled | :reporter | nil | 2
|
||||||
|
:internal | :enabled | :guest | nil | 1
|
||||||
|
:internal | :enabled | :non_member | nil | 1
|
||||||
|
:internal | :enabled | :anonymous | nil | 0
|
||||||
|
|
||||||
|
:internal | :private | :admin | true | 2
|
||||||
|
:internal | :private | :admin | false | 0
|
||||||
|
:internal | :private | :reporter | nil | 2
|
||||||
|
:internal | :private | :guest | nil | 1
|
||||||
|
:internal | :private | :non_member | nil | 0
|
||||||
|
:internal | :private | :anonymous | nil | 0
|
||||||
|
|
||||||
|
:internal | :disabled | :reporter | nil | 0
|
||||||
|
:internal | :disabled | :guest | nil | 0
|
||||||
|
:internal | :disabled | :non_member | nil | 0
|
||||||
|
:internal | :disabled | :anonymous | nil | 0
|
||||||
|
|
||||||
|
:private | :private | :admin | true | 2
|
||||||
|
:private | :private | :admin | false | 0
|
||||||
|
:private | :private | :reporter | nil | 2
|
||||||
|
:private | :private | :guest | nil | 1
|
||||||
|
:private | :private | :non_member | nil | 0
|
||||||
|
:private | :private | :anonymous | nil | 0
|
||||||
|
|
||||||
|
:private | :disabled | :reporter | nil | 0
|
||||||
|
:private | :disabled | :guest | nil | 0
|
||||||
|
:private | :disabled | :non_member | nil | 0
|
||||||
|
:private | :disabled | :anonymous | nil | 0
|
||||||
|
end
|
||||||
|
|
||||||
# This table is based on permission_table_for_guest_feature_access,
|
# This table is based on permission_table_for_guest_feature_access,
|
||||||
# but with a slight twist.
|
# but with a slight twist.
|
||||||
# Some features can be hidden away to GUEST, when project is private.
|
# Some features can be hidden away to GUEST, when project is private.
|
||||||
|
|
Loading…
Reference in New Issue