summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/stylesheets/pages/convdev_index.scss36
-rw-r--r--app/assets/stylesheets/pages/profile.scss4
-rw-r--r--app/views/clusters/clusters/gcp/_gcp_not_configured.html.haml2
-rw-r--r--app/views/instance_statistics/conversational_development_index/_callout.html.haml2
-rw-r--r--app/views/instance_statistics/conversational_development_index/_card.html.haml6
-rw-r--r--app/views/instance_statistics/conversational_development_index/_disabled.html.haml2
-rw-r--r--app/views/instance_statistics/conversational_development_index/_no_data.html.haml2
-rw-r--r--app/views/instance_statistics/conversational_development_index/index.html.haml16
-rw-r--r--changelogs/unreleased/20978-add-allow-failure-in-pipeline-event.yaml6
-rw-r--r--changelogs/unreleased/23746-error-500-when-trying-to-destroy-oauth-application-entry-in-admin-a.yml5
-rw-r--r--db/migrate/20191107064946_update_oauth_open_id_requests_foreign_keys.rb29
-rw-r--r--db/migrate/20191120200015_add_index_to_grafana_integrations.rb15
-rw-r--r--db/schema.rb3
-rw-r--r--doc/development/documentation/workflow.md119
-rw-r--r--doc/development/testing_guide/end_to_end/quick_start_guide.md2
-rw-r--r--doc/user/project/integrations/webhooks.md5
-rw-r--r--lib/gitlab/data_builder/pipeline.rb1
-rw-r--r--lib/gitlab/grafana_embed_usage_data.rb16
-rw-r--r--lib/gitlab/usage_data.rb1
-rw-r--r--locale/gitlab.pot2
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb (renamed from qa/qa/specs/features/browser_ui/1_manage/mail/trigger_mail_notification_spec.rb)6
-rw-r--r--spec/factories/oauth_openid_requests.rb8
-rw-r--r--spec/lib/gitlab/data_builder/pipeline_spec.rb1
-rw-r--r--spec/lib/gitlab/grafana_embed_usage_data_spec.rb70
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb4
-rw-r--r--spec/models/oauth_access_grant_spec.rb17
26 files changed, 309 insertions, 71 deletions
diff --git a/app/assets/stylesheets/pages/convdev_index.scss b/app/assets/stylesheets/pages/convdev_index.scss
index 52fcdf4a405..6b6dce43dba 100644
--- a/app/assets/stylesheets/pages/convdev_index.scss
+++ b/app/assets/stylesheets/pages/convdev_index.scss
@@ -1,24 +1,24 @@
$space-between-cards: 8px;
-.convdev-empty svg {
+.devops-empty svg {
margin: 64px auto 32px;
max-width: 420px;
}
-.convdev-header {
+.devops-header {
margin-top: $gl-padding;
margin-bottom: $gl-padding;
padding: 0 4px;
display: flex;
align-items: center;
- .convdev-header-title {
+ .devops-header-title {
font-size: 48px;
line-height: 1;
margin: 0;
}
- .convdev-header-subtitle {
+ .devops-header-subtitle {
font-size: 22px;
line-height: 1;
color: $gl-text-color-secondary;
@@ -36,13 +36,13 @@ $space-between-cards: 8px;
}
}
-.convdev-cards {
+.devops-cards {
display: flex;
justify-content: center;
flex-wrap: wrap;
}
-.convdev-card-wrapper {
+.devops-card-wrapper {
display: flex;
flex-direction: column;
align-items: stretch;
@@ -70,7 +70,7 @@ $space-between-cards: 8px;
}
}
-.convdev-card {
+.devops-card {
border: solid 1px $border-color;
border-radius: 3px;
border-top-width: 3px;
@@ -79,7 +79,7 @@ $space-between-cards: 8px;
flex-grow: 1;
}
-.convdev-card-low {
+.devops-card-low {
border-top-color: $red-400;
.board-card-score-big {
@@ -87,7 +87,7 @@ $space-between-cards: 8px;
}
}
-.convdev-card-average {
+.devops-card-average {
border-top-color: $orange-400;
.board-card-score-big {
@@ -95,7 +95,7 @@ $space-between-cards: 8px;
}
}
-.convdev-card-high {
+.devops-card-high {
border-top-color: $green-400;
.board-card-score-big {
@@ -103,7 +103,7 @@ $space-between-cards: 8px;
}
}
-.convdev-card-title {
+.devops-card-title {
margin: $gl-padding auto auto;
max-width: 100px;
@@ -170,7 +170,7 @@ $space-between-cards: 8px;
}
}
-.convdev-steps {
+.devops-steps {
margin-top: $gl-padding;
height: 1px;
min-width: 100%;
@@ -179,7 +179,7 @@ $space-between-cards: 8px;
background: $border-color;
}
-.convdev-step {
+.devops-step {
$step-positions: 5% 10% 30% 42% 48% 55% 60% 70% 75% 90%;
@each $pos in $step-positions {
$i: index($step-positions, $pos);
@@ -212,7 +212,7 @@ $space-between-cards: 8px;
height: auto;
width: auto;
- .convdev-step-title {
+ .devops-step-title {
max-height: 2em;
opacity: 1;
transition: opacity 0.2s;
@@ -233,7 +233,7 @@ $space-between-cards: 8px;
}
}
-.convdev-step-title {
+.devops-step-title {
max-height: 0;
opacity: 0;
text-transform: uppercase;
@@ -242,14 +242,14 @@ $space-between-cards: 8px;
font-size: 12px;
}
-.convdev-high-score {
+.devops-high-score {
color: $green-400;
}
-.convdev-average-score {
+.devops-average-score {
color: $orange-400;
}
-.convdev-low-score {
+.devops-low-score {
color: $red-400;
}
diff --git a/app/assets/stylesheets/pages/profile.scss b/app/assets/stylesheets/pages/profile.scss
index 87cef43b923..66773e8efca 100644
--- a/app/assets/stylesheets/pages/profile.scss
+++ b/app/assets/stylesheets/pages/profile.scss
@@ -349,7 +349,7 @@ table.u2f-registrations {
vertical-align: top;
}
- &.convdev {
+ &.devops {
margin: 0 0 0 30px;
svg {
@@ -382,7 +382,7 @@ table.u2f-registrations {
height: 75px;
}
- &.convdev {
+ &.devops {
margin: $gl-padding auto 0;
svg {
diff --git a/app/views/clusters/clusters/gcp/_gcp_not_configured.html.haml b/app/views/clusters/clusters/gcp/_gcp_not_configured.html.haml
index b57e45e9812..f1f26a0aab8 100644
--- a/app/views/clusters/clusters/gcp/_gcp_not_configured.html.haml
+++ b/app/views/clusters/clusters/gcp/_gcp_not_configured.html.haml
@@ -1,3 +1,3 @@
- documentation_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path("integration/google") }
- link_end = '<a/>'.html_safe
-= s_('Google authentication is not %{link_start}property configured%{link_end}. Ask your GitLab administrator if you want to use this service.').html_safe % { link_start: documentation_link_start, link_end: link_end }
+= s_('Google authentication is not %{link_start}properly configured%{link_end}. Ask your GitLab administrator if you want to use this service.').html_safe % { link_start: documentation_link_start, link_end: link_end }
diff --git a/app/views/instance_statistics/conversational_development_index/_callout.html.haml b/app/views/instance_statistics/conversational_development_index/_callout.html.haml
index a4256e23979..15e31fa3d9c 100644
--- a/app/views/instance_statistics/conversational_development_index/_callout.html.haml
+++ b/app/views/instance_statistics/conversational_development_index/_callout.html.haml
@@ -9,5 +9,5 @@
= _('Introducing Your Conversational Development Index')
%p
= _('Your Conversational Development Index gives an overview of how you are using GitLab from a feature perspective. View how you compare with other organizations, discover features you are not using, and learn best practices through blog posts and white papers.')
- .svg-container.convdev
+ .svg-container.devops
= custom_icon('convdev_overview')
diff --git a/app/views/instance_statistics/conversational_development_index/_card.html.haml b/app/views/instance_statistics/conversational_development_index/_card.html.haml
index 76af55dcf7a..c63bd96a175 100644
--- a/app/views/instance_statistics/conversational_development_index/_card.html.haml
+++ b/app/views/instance_statistics/conversational_development_index/_card.html.haml
@@ -1,6 +1,6 @@
-.convdev-card-wrapper
- .convdev-card{ class: "convdev-card-#{score_level(card.percentage_score)}" }
- .convdev-card-title
+.devops-card-wrapper
+ .devops-card{ class: "devops-card-#{score_level(card.percentage_score)}" }
+ .devops-card-title
%h3
= card.title
.light-text
diff --git a/app/views/instance_statistics/conversational_development_index/_disabled.html.haml b/app/views/instance_statistics/conversational_development_index/_disabled.html.haml
index b854e15d36f..ddcbdf6dd27 100644
--- a/app/views/instance_statistics/conversational_development_index/_disabled.html.haml
+++ b/app/views/instance_statistics/conversational_development_index/_disabled.html.haml
@@ -1,4 +1,4 @@
-.container.convdev-empty
+.container.devops-empty
.col-sm-12.justify-content-center.text-center
= custom_icon('convdev_no_index')
%h4= _('Usage ping is not enabled')
diff --git a/app/views/instance_statistics/conversational_development_index/_no_data.html.haml b/app/views/instance_statistics/conversational_development_index/_no_data.html.haml
index 4e8f34cd574..2031bced4fc 100644
--- a/app/views/instance_statistics/conversational_development_index/_no_data.html.haml
+++ b/app/views/instance_statistics/conversational_development_index/_no_data.html.haml
@@ -1,4 +1,4 @@
-.container.convdev-empty
+.container.devops-empty
.col-sm-12.justify-content-center.text-center
= custom_icon('convdev_no_data')
%h4= _('Data is still calculating...')
diff --git a/app/views/instance_statistics/conversational_development_index/index.html.haml b/app/views/instance_statistics/conversational_development_index/index.html.haml
index 49c8fdc9630..f9a40152380 100644
--- a/app/views/instance_statistics/conversational_development_index/index.html.haml
+++ b/app/views/instance_statistics/conversational_development_index/index.html.haml
@@ -11,23 +11,23 @@
- elsif @metric.blank?
= render 'no_data'
- else
- .convdev
- .convdev-header
- %h2.convdev-header-title{ class: "convdev-#{score_level(@metric.average_percentage_score)}-score" }
+ .devops
+ .devops-header
+ %h2.devops-header-title{ class: "devops-#{score_level(@metric.average_percentage_score)}-score" }
= number_to_percentage(@metric.average_percentage_score, precision: 1)
- .convdev-header-subtitle
+ .devops-header-subtitle
= _('index')
%br
= _('score')
= link_to icon('question-circle', 'aria-hidden' => 'true'), help_page_path('user/instance_statistics/convdev')
- .convdev-cards.board-card-container
+ .devops-cards.board-card-container
- @metric.cards.each do |card|
= render 'card', card: card
- .convdev-steps.d-none.d-lg-block.d-xl-block
+ .devops-steps.d-none.d-lg-block.d-xl-block
- @metric.idea_to_production_steps.each_with_index do |step, index|
- .convdev-step{ class: "convdev-#{score_level(step.percentage_score)}-score" }
+ .devops-step{ class: "devops-#{score_level(step.percentage_score)}-score" }
= custom_icon("i2p_step_#{index + 1}")
- %h4.convdev-step-title
+ %h4.devops-step-title
= step.title
diff --git a/changelogs/unreleased/20978-add-allow-failure-in-pipeline-event.yaml b/changelogs/unreleased/20978-add-allow-failure-in-pipeline-event.yaml
new file mode 100644
index 00000000000..2a7e731e0be
--- /dev/null
+++ b/changelogs/unreleased/20978-add-allow-failure-in-pipeline-event.yaml
@@ -0,0 +1,6 @@
+---
+title: |
+ Add allow failure in pipeline webhook event
+merge_request: 20978
+author: Gaetan Semet
+type: added
diff --git a/changelogs/unreleased/23746-error-500-when-trying-to-destroy-oauth-application-entry-in-admin-a.yml b/changelogs/unreleased/23746-error-500-when-trying-to-destroy-oauth-application-entry-in-admin-a.yml
new file mode 100644
index 00000000000..c69f1748242
--- /dev/null
+++ b/changelogs/unreleased/23746-error-500-when-trying-to-destroy-oauth-application-entry-in-admin-a.yml
@@ -0,0 +1,5 @@
+---
+title: Use cascading deletes for deleting oauth_openid_requests upon deleting an oauth_access_grant
+merge_request: 19617
+author:
+type: fixed
diff --git a/db/migrate/20191107064946_update_oauth_open_id_requests_foreign_keys.rb b/db/migrate/20191107064946_update_oauth_open_id_requests_foreign_keys.rb
new file mode 100644
index 00000000000..439610758a6
--- /dev/null
+++ b/db/migrate/20191107064946_update_oauth_open_id_requests_foreign_keys.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+class UpdateOauthOpenIdRequestsForeignKeys < ActiveRecord::Migration[5.2]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_foreign_key(:oauth_openid_requests, :oauth_access_grants, column: :access_grant_id, on_delete: :cascade, name: new_foreign_key_name)
+ remove_foreign_key_if_exists(:oauth_openid_requests, name: existing_foreign_key_name)
+ end
+
+ def down
+ add_concurrent_foreign_key(:oauth_openid_requests, :oauth_access_grants, column: :access_grant_id, on_delete: false, name: existing_foreign_key_name)
+ remove_foreign_key_if_exists(:oauth_openid_requests, name: new_foreign_key_name)
+ end
+
+ private
+
+ def new_foreign_key_name
+ concurrent_foreign_key_name(:oauth_openid_requests, :access_grant_id)
+ end
+
+ def existing_foreign_key_name
+ 'fk_oauth_openid_requests_oauth_access_grants_access_grant_id'
+ end
+end
diff --git a/db/migrate/20191120200015_add_index_to_grafana_integrations.rb b/db/migrate/20191120200015_add_index_to_grafana_integrations.rb
new file mode 100644
index 00000000000..87292c86e97
--- /dev/null
+++ b/db/migrate/20191120200015_add_index_to_grafana_integrations.rb
@@ -0,0 +1,15 @@
+class AddIndexToGrafanaIntegrations < ActiveRecord::Migration[5.2]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :grafana_integrations, :enabled, where: 'enabled IS TRUE'
+ end
+
+ def down
+ remove_concurrent_index :grafana_integrations, :enabled
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 2715c5717f7..253d82e790b 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -1888,6 +1888,7 @@ ActiveRecord::Schema.define(version: 2019_11_25_140458) do
t.string "encrypted_token_iv", limit: 255, null: false
t.string "grafana_url", limit: 1024, null: false
t.boolean "enabled", default: false, null: false
+ t.index ["enabled"], name: "index_grafana_integrations_on_enabled", where: "(enabled IS TRUE)"
t.index ["project_id"], name: "index_grafana_integrations_on_project_id"
end
@@ -4535,7 +4536,7 @@ ActiveRecord::Schema.define(version: 2019_11_25_140458) do
add_foreign_key "notes", "projects", name: "fk_99e097b079", on_delete: :cascade
add_foreign_key "notes", "reviews", name: "fk_2e82291620", on_delete: :nullify
add_foreign_key "notification_settings", "users", name: "fk_0c95e91db7", on_delete: :cascade
- add_foreign_key "oauth_openid_requests", "oauth_access_grants", column: "access_grant_id", name: "fk_oauth_openid_requests_oauth_access_grants_access_grant_id"
+ add_foreign_key "oauth_openid_requests", "oauth_access_grants", column: "access_grant_id", name: "fk_77114b3b09", on_delete: :cascade
add_foreign_key "operations_feature_flag_scopes", "operations_feature_flags", column: "feature_flag_id", on_delete: :cascade
add_foreign_key "operations_feature_flags", "projects", on_delete: :cascade
add_foreign_key "operations_feature_flags_clients", "projects", on_delete: :cascade
diff --git a/doc/development/documentation/workflow.md b/doc/development/documentation/workflow.md
index c373b976453..e48c940dc21 100644
--- a/doc/development/documentation/workflow.md
+++ b/doc/development/documentation/workflow.md
@@ -15,12 +15,31 @@ documentation is associated with:
Documentation is not usually required when a "backstage feature" is added or changed, and does not
directly affect the way that any user or administrator interacts with GitLab.
+## Documentation labels
+
+Regardless of the type of issue or merge request, certain labels are required when documentation
+is added or updated. The following are added by the issue or merge request author:
+
+- An appropriate [type label](../contributing/issue_workflow.md#type-labels). For example,
+ `~backstage`.
+- The [stage label](../contributing/issue_workflow.md#stage-labels) and
+ [group label](../contributing/issue_workflow.md#group-labels). For example, `~devops::create` and
+ `~group::source code`.
+- The `~documentation` [specialization label](../contributing/issue_workflow.md#specialization-labels).
+
+The following are also added by members of the Technical Writing team:
+
+- A documentation [scoped label](../../user/project/labels.md#scoped-labels-premium) with the
+ `docs::` prefix. For example, `~docs::improvement`.
+- The `~Technical Writing` [team label](../contributing/issue_workflow.md#team-labels).
+
## For a product change
This documentation is required for any new or changed feature and is:
-- Created or updated as part of feature development, typically via the same merge request as the
- feature code.
+- Created or updated as part of feature development, almost always in the same merge request as the
+ feature code. Including documentation in the same merge request as the code eliminates the
+ possibility that code and documentation get out of sync.
- Required with the delivery of a feature for a specific milestone as part of GitLab's
[definition of done](../contributing/merge_request_workflow.md#definition-of-done).
- Often linked from the release post.
@@ -100,28 +119,10 @@ Prior to merging, documentation changes committed by the developer must be revie
- The code reviewer for the merge request. This is known as a technical review.
- Optionally, others involved in the work, such as other developers or the Product Manager.
-- Optionally, the Technical Writer for the DevOps stage group.
+- The Technical Writer for the DevOps stage group, except in exceptional circumstances where a
+ [post-merge review](#post-merge-reviews) can be requested.
- A maintainer of the project.
-If not assigned to a Technical Writer for review prior to merging, a review must be scheduled
-immediately after merge by the developer or maintainer. For this,
-create an issue using the [Doc Review description template](https://gitlab.com/gitlab-org/gitlab/issues/new?issuable_template=Doc%20Review)
-and link to it from the merged merge request that introduced the documentation change.
-
-To decide whether to request a Technical Writer review before or after merge, consider:
-
-- The amount of time left before the milestone release. If there is less than three days
- remaining, seek a post-merge review and ping the writer via Slack to ensure the review is
- completed in time.
-- The size of the change and your degree of confidence in having early users (for example,
- GitLab.com users) of features use your documentation as written.
-- That pre-merge Technical Writer reviews should be most common when the code is complete well in
- advance of a milestone release and for larger documentation changes.
-- You can request a post-merge Technical Writer review if it's important to get the code part of
- a merge request merged as soon as possible.
-- The Technical Writer can also help decide that documentation can be merged without Technical
- writer review, with the review to occur soon after merge.
-
#### Product Managers
Product Managers are responsible for the [documentation requirements](#documentation-requirements)
@@ -149,10 +150,12 @@ will do the following:
Technical Writers are responsible for:
+- Participating in issues discussions and reviewing MRs for the upcoming milestone.
- Reviewing documentation requirements in issues when called upon.
- Answering questions, and helping and providing advice throughout the authoring and editing
process.
-- Reviewing all new and updated documentation content, whether before merge or after it is merged.
+- Reviewing all significant new and updated documentation content, whether before merge or after it
+ is merged.
- Assisting the developer and Product Manager with feature documentation delivery.
##### Planning
@@ -228,7 +231,7 @@ have this section by default.
Anyone can add these details, but the Product Manager who assigns the issue to a specific release
milestone will ensure these details are present and finalized by the time of that milestone's kickoff.
-Developers, Technical Writers, and others may help further refine this plan at any time.
+Developers, Technical Writers, and others may help further refine this plan at any time on request.
The following details should be included:
@@ -283,13 +286,23 @@ To update GitLab documentation:
TIP: **Tip:**
Work in a fork if you do not have developer access to the GitLab project.
-Ping the Technical Writer for the relevant [DevOps stage group](https://about.gitlab.com/handbook/product/technical-writing/index.html#assignments)
-in your issue or merge request, or within `#docs` if you are a member of GitLab's Slack workspace, if you:
+Request help from the Technical Writing team if you:
- Need help to choose the correct place for documentation.
- Want to discuss a documentation idea or outline.
- Want to request any other help.
+To request help:
+
+1. Locate the the Technical Writer for the relevant
+ [DevOps stage group](https://about.gitlab.com/handbook/product/technical-writing/index.html#assignments).
+1. Either:
+ - If urgent help is required, directly assign the Technical Writer in the issue or
+ [in the merge request](../../user/project/merge_requests/creating_merge_requests.md#multiple-assignees-starter).
+ - If non-urgent help is required, ping the Technical Writer in the issue or merge request.
+
+If you are a member of GitLab's Slack workspace, you can request help in `#docs`.
+
### Reviewing and merging
Anyone with Maintainer access to the relevant GitLab project can merge documentation changes.
@@ -307,11 +320,10 @@ The process involves the following:
or other appropriate colleague to confirm accuracy, clarity, and completeness. This can be skipped
for minor fixes without substantive content changes.
- Technical Writer (Optional). If not completed for a merge request prior to merging, must be scheduled
- post-merge. To request a:
+ post-merge. Schedule post-merge reviews only if an urgent merge is required. To request a:
- Pre-merge review, assign the Technical Writer listed for the applicable
[DevOps stage group](https://about.gitlab.com/handbook/product/technical-writing/index.html#assignments).
- - Post-merge review, [create an issue for one](https://gitlab.com/gitlab-org/gitlab/issues/new?issuable_template=Doc%20Review)
- and link it from the MR that makes the documentation change.
+ - Post-merge review, see [Post-merge reviews](#post-merge-reviews).
- Maintainer. For merge requests, Maintainers:
- Can always request any of the above reviews.
- Review before or after a Technical Writer review.
@@ -319,7 +331,7 @@ The process involves the following:
- Ensure the appropriate labels are applied, including any required to pick a merge request into
a release.
- Ensure that, if there has not been a Technical Writer review completed or scheduled, they
- [create the required issue](https://gitlab.com/gitlab-org/gitlab/issues/new?issuable_template=Doc%20Review), assign to the technical writer of the given stage group,
+ [create the required issue](https://gitlab.com/gitlab-org/gitlab/issues/new?issuable_template=Doc%20Review), assign to the Technical Writer of the given stage group,
and link it from the merge request.
The process is reflected in the **Documentation**
@@ -330,3 +342,50 @@ The process is reflected in the **Documentation**
If you have ideas for further documentation resources please
[create an issue](https://gitlab.com/gitlab-org/gitlab/issues/new?issuable_template=Documentation)
using the Documentation template.
+
+## Post-merge reviews
+
+If not assigned to a Technical Writer for review prior to merging, a review must be scheduled
+immediately after merge by the developer or maintainer. For this,
+create an issue using the [Doc Review description template](https://gitlab.com/gitlab-org/gitlab/issues/new?issuable_template=Doc%20Review)
+and link to it from the merged merge request that introduced the documentation change.
+
+Circumstances where a regular pre-merge Technical Writer review might be skipped include:
+
+- There is a short amount of time left before the milestone release. If there are less than three days
+ remaining, seek a post-merge review and ping the writer via Slack to ensure the review is
+ completed as soon as possible.
+- The size of the change is small and you have a high degree of confidence
+ that early users of the feature (for example, GitLab.com users) can easily
+ use the documentation as written.
+
+Remember:
+
+- At GitLab, we treat documentation like code. As with code, documentation must be reviewed to
+ ensure quality.
+- Documentation forms part of the GitLab [definition of done](../contributing/merge_request_workflow.md#definition-of-done).
+- That pre-merge Technical Writer reviews should be most common when the code is complete well in
+ advance of a milestone release and for larger documentation changes.
+- You can request a post-merge Technical Writer review of documentation if it's important to get the
+ code with which it ships merged as soon as possible. In this case, the author of the original MR
+ will address the feedback provided by the Technical Writer in a follow-up MR.
+- The Technical Writer can also help decide that documentation can be merged without Technical
+ writer review, with the review to occur soon after merge.
+
+### Before merging
+
+Ensure the following if skipping an initial Technical Writer review:
+
+- That [product badges](styleguide.md#product-badges) are applied.
+- That the GitLab [version](styleguide.md#text-for-documentation-requiring-version-text) that
+ introduced the feature has been included.
+- That changes to headings don't affect in-app hyperlinks.
+- Specific [user permissions](../../user/permissions.md) are documented.
+- That new documents are linked from higher-level indexes, for discoverability.
+- Style guide is followed:
+ - For [directories and files](styleguide.md#working-with-directories-and-files).
+ - For [images](styleguide.md#images).
+
+NOTE: **Note:**
+Merge requests that change the location of documentation must always be reviewed by a Technical
+Writer prior to merging.
diff --git a/doc/development/testing_guide/end_to_end/quick_start_guide.md b/doc/development/testing_guide/end_to_end/quick_start_guide.md
index 16a45bc5ef0..fb820ac22a2 100644
--- a/doc/development/testing_guide/end_to_end/quick_start_guide.md
+++ b/doc/development/testing_guide/end_to_end/quick_start_guide.md
@@ -591,7 +591,7 @@ filter_output = search_field_tag search_id, nil, class: "dropdown-input-field",
> `data-qa-*` data attributes and CSS classes starting with `qa-` are used solely for the purpose of QA and testing.
> By defining these, we add **testability** to the application.
>
-> When defining a data attribute like: `qa_selector: 'labels_block'`, it should match the element definition: `element :labels_block`. We use a [sanity test](https://gitlab.com/gitlab-org/gitlab-foss/tree/master/qa/qa/page#how-did-we-solve-fragile-tests-problem) to check that defined elements have their respective selectors in the specified views.
+> When defining a data attribute like: `qa_selector: 'labels_block'`, it should match the element definition: `element :labels_block`. We use a [sanity test](https://gitlab.com/gitlab-org/gitlab-foss/tree/master/doc/development/testing_guide/end_to_end/page_objects.md#how-did-we-solve-fragile-tests-problem) to check that defined elements have their respective selectors in the specified views.
#### Updates in the `QA::Page::Base` class
diff --git a/doc/user/project/integrations/webhooks.md b/doc/user/project/integrations/webhooks.md
index d0f538a4b52..f027fb69157 100644
--- a/doc/user/project/integrations/webhooks.md
+++ b/doc/user/project/integrations/webhooks.md
@@ -1076,6 +1076,7 @@ X-Gitlab-Event: Pipeline Hook
"finished_at": null,
"when": "manual",
"manual": true,
+ "allow_failure": false,
"user":{
"name": "Administrator",
"username": "root",
@@ -1097,6 +1098,7 @@ X-Gitlab-Event: Pipeline Hook
"finished_at": null,
"when": "on_success",
"manual": false,
+ "allow_failure": false,
"user":{
"name": "Administrator",
"username": "root",
@@ -1123,6 +1125,7 @@ X-Gitlab-Event: Pipeline Hook
"finished_at": "2016-08-12 15:26:29 UTC",
"when": "on_success",
"manual": false,
+ "allow_failure": false,
"user":{
"name": "Administrator",
"username": "root",
@@ -1149,6 +1152,7 @@ X-Gitlab-Event: Pipeline Hook
"finished_at": "2016-08-12 15:25:26 UTC",
"when": "on_success",
"manual": false,
+ "allow_failure": false,
"user":{
"name": "Administrator",
"username": "root",
@@ -1175,6 +1179,7 @@ X-Gitlab-Event: Pipeline Hook
"finished_at": null,
"when": "on_success",
"manual": false,
+ "allow_failure": false,
"user":{
"name": "Administrator",
"username": "root",
diff --git a/lib/gitlab/data_builder/pipeline.rb b/lib/gitlab/data_builder/pipeline.rb
index da3d6c47431..8e699de8164 100644
--- a/lib/gitlab/data_builder/pipeline.rb
+++ b/lib/gitlab/data_builder/pipeline.rb
@@ -61,6 +61,7 @@ module Gitlab
finished_at: build.finished_at,
when: build.when,
manual: build.action?,
+ allow_failure: build.allow_failure,
user: build.user.try(:hook_attrs),
runner: build.runner && runner_hook_attrs(build.runner),
artifacts_file: {
diff --git a/lib/gitlab/grafana_embed_usage_data.rb b/lib/gitlab/grafana_embed_usage_data.rb
new file mode 100644
index 00000000000..78a87623e1f
--- /dev/null
+++ b/lib/gitlab/grafana_embed_usage_data.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Gitlab
+ class GrafanaEmbedUsageData
+ class << self
+ def issue_count
+ # rubocop:disable CodeReuse/ActiveRecord
+ Issue.joins('JOIN grafana_integrations USING (project_id)')
+ .where("issues.description LIKE '%' || grafana_integrations.grafana_url || '%'")
+ .where(grafana_integrations: { enabled: true })
+ .count
+ # rubocop:enable CodeReuse/ActiveRecord
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb
index b6effac25c6..a0ff34c76e2 100644
--- a/lib/gitlab/usage_data.rb
+++ b/lib/gitlab/usage_data.rb
@@ -84,6 +84,7 @@ module Gitlab
issues: count(Issue),
issues_with_associated_zoom_link: count(ZoomMeeting.added_to_issue),
issues_using_zoom_quick_actions: count(ZoomMeeting.select(:issue_id).distinct),
+ issues_with_embedded_grafana_charts_approx: ::Gitlab::GrafanaEmbedUsageData.issue_count,
keys: count(Key),
label_lists: count(List.label),
lfs_objects: count(LfsObject),
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 68d3e795434..108097542c2 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -8581,7 +8581,7 @@ msgstr ""
msgid "Google Takeout"
msgstr ""
-msgid "Google authentication is not %{link_start}property configured%{link_end}. Ask your GitLab administrator if you want to use this service."
+msgid "Google authentication is not %{link_start}properly configured%{link_end}. Ask your GitLab administrator if you want to use this service."
msgstr ""
msgid "Got it"
diff --git a/qa/qa/specs/features/browser_ui/1_manage/mail/trigger_mail_notification_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb
index d3bb269bcb3..57063e91532 100644
--- a/qa/qa/specs/features/browser_ui/1_manage/mail/trigger_mail_notification_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/email/trigger_email_notification_spec.rb
@@ -1,8 +1,8 @@
# frozen_string_literal: true
module QA
- context 'Manage', :orchestrated, :smtp do
- describe 'mail notification' do
+ context 'Plan', :orchestrated, :smtp do
+ describe 'Email Notification' do
let(:user) do
Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
end
@@ -17,7 +17,7 @@ module QA
Flow::Login.sign_in
end
- it 'user receives email for project invitation' do
+ it 'is received by a user for project invitation' do
Flow::Project.add_member(project: project, username: user.username)
expect(page).to have_content(/@#{user.username}(\n| )?Given access/)
diff --git a/spec/factories/oauth_openid_requests.rb b/spec/factories/oauth_openid_requests.rb
new file mode 100644
index 00000000000..82d89b5c8ca
--- /dev/null
+++ b/spec/factories/oauth_openid_requests.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :oauth_openid_request, class: 'Doorkeeper::OpenidConnect::Request' do
+ access_grant factory: :oauth_access_grant
+ sequence(:nonce) { |n| n.to_s }
+ end
+end
diff --git a/spec/lib/gitlab/data_builder/pipeline_spec.rb b/spec/lib/gitlab/data_builder/pipeline_spec.rb
index 931477d19c2..635bf56b72e 100644
--- a/spec/lib/gitlab/data_builder/pipeline_spec.rb
+++ b/spec/lib/gitlab/data_builder/pipeline_spec.rb
@@ -34,6 +34,7 @@ describe Gitlab::DataBuilder::Pipeline do
expect(build_data).to be_a(Hash)
expect(build_data[:id]).to eq(build.id)
expect(build_data[:status]).to eq(build.status)
+ expect(build_data[:allow_failure]).to eq(build.allow_failure)
expect(project_data).to eq(project.hook_attrs(backward: false))
expect(data[:merge_request]).to be_nil
end
diff --git a/spec/lib/gitlab/grafana_embed_usage_data_spec.rb b/spec/lib/gitlab/grafana_embed_usage_data_spec.rb
new file mode 100644
index 00000000000..162db46719b
--- /dev/null
+++ b/spec/lib/gitlab/grafana_embed_usage_data_spec.rb
@@ -0,0 +1,70 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::GrafanaEmbedUsageData do
+ describe '#issue_count' do
+ subject { described_class.issue_count }
+
+ let(:project) { create(:project) }
+ let(:description_with_embed) { "Some comment\n\nhttps://grafana.example.com/d/xvAk4q0Wk/go-processes?orgId=1&from=1573238522762&to=1573240322762&var-job=prometheus&var-interval=10m&panelId=1&fullscreen" }
+ let(:description_with_unintegrated_embed) { "Some comment\n\nhttps://grafana.exp.com/d/xvAk4q0Wk/go-processes?orgId=1&from=1573238522762&to=1573240322762&var-job=prometheus&var-interval=10m&panelId=1&fullscreen" }
+ let(:description_with_non_grafana_inline_metric) { "Some comment\n\n#{Gitlab::Routing.url_helpers.metrics_namespace_project_environment_url(*['foo', 'bar', 12])}" }
+
+ shared_examples "zero count" do
+ it "does not count the issue" do
+ expect(subject).to eq(0)
+ end
+ end
+
+ context 'with project grafana integration enabled' do
+ before do
+ create(:grafana_integration, project: project, enabled: true)
+ end
+
+ context 'with valid and invalid embeds' do
+ before do
+ # Valid
+ create(:issue, project: project, description: description_with_embed)
+ create(:issue, project: project, description: description_with_embed)
+ # In-Valid
+ create(:issue, project: project, description: description_with_unintegrated_embed)
+ create(:issue, project: project, description: description_with_non_grafana_inline_metric)
+ create(:issue, project: project, description: nil)
+ create(:issue, project: project, description: '')
+ create(:issue, project: project)
+ end
+
+ it 'counts only the issues with embeds' do
+ expect(subject).to eq(2)
+ end
+ end
+ end
+
+ context 'with project grafana integration disabled' do
+ before do
+ create(:grafana_integration, project: project, enabled: false)
+ end
+
+ context 'with one issue having a grafana link in the description and one without' do
+ before do
+ create(:issue, project: project, description: description_with_embed)
+ create(:issue, project: project)
+ end
+
+ it_behaves_like('zero count')
+ end
+ end
+
+ context 'with an un-integrated project' do
+ context 'with one issue having a grafana link in the description and one without' do
+ before do
+ create(:issue, project: project, description: description_with_embed)
+ create(:issue, project: project)
+ end
+
+ it_behaves_like('zero count')
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index 484684eeb65..713ddca6c2b 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -53,6 +53,8 @@ describe Gitlab::UsageData do
create(:grafana_integration, project: projects[1], enabled: true)
create(:grafana_integration, project: projects[2], enabled: false)
+ allow(Gitlab::GrafanaEmbedUsageData).to receive(:issue_count).and_return(2)
+
ProjectFeature.first.update_attribute('repository_access_level', 0)
end
@@ -152,6 +154,7 @@ describe Gitlab::UsageData do
issues
issues_with_associated_zoom_link
issues_using_zoom_quick_actions
+ issues_with_embedded_grafana_charts_approx
keys
label_lists
labels
@@ -211,6 +214,7 @@ describe Gitlab::UsageData do
expect(count_data[:projects_with_error_tracking_enabled]).to eq(1)
expect(count_data[:issues_with_associated_zoom_link]).to eq(2)
expect(count_data[:issues_using_zoom_quick_actions]).to eq(3)
+ expect(count_data[:issues_with_embedded_grafana_charts_approx]).to eq(2)
expect(count_data[:clusters_enabled]).to eq(4)
expect(count_data[:project_clusters_enabled]).to eq(3)
diff --git a/spec/models/oauth_access_grant_spec.rb b/spec/models/oauth_access_grant_spec.rb
new file mode 100644
index 00000000000..955dae906f3
--- /dev/null
+++ b/spec/models/oauth_access_grant_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe OauthAccessGrant do
+ let(:user) { create(:user) }
+ let(:application) { create(:oauth_application, owner: user) }
+
+ describe '#delete' do
+ it 'cascades to oauth_openid_requests' do
+ access_grant = create(:oauth_access_grant, application: application)
+ create(:oauth_openid_request, access_grant: access_grant)
+
+ expect { access_grant.delete }.to change(Doorkeeper::OpenidConnect::Request, :count).by(-1)
+ end
+ end
+end