diff --git a/app/assets/javascripts/diffs/components/diff_stats.vue b/app/assets/javascripts/diffs/components/diff_stats.vue
index 0234fc4f40e1eb91c7f5703fcbc429bb68499aed..8bfc97b2da54c5733dc54dae8e6f8bfe441a754c 100644
--- a/app/assets/javascripts/diffs/components/diff_stats.vue
+++ b/app/assets/javascripts/diffs/components/diff_stats.vue
@@ -14,18 +14,21 @@ export default {
type: Number,
required: true,
},
- diffFilesLength: {
- type: Number,
+ diffFilesCountText: {
+ type: String,
required: false,
default: null,
},
},
computed: {
+ diffFilesLength() {
+ return parseInt(this.diffFilesCountText, 10);
+ },
filesText() {
return n__('file', 'files', this.diffFilesLength);
},
isCompareVersionsHeader() {
- return Boolean(this.diffFilesLength);
+ return Boolean(this.diffFilesCountText);
},
hasDiffFiles() {
return isNumber(this.diffFilesLength) && this.diffFilesLength >= 0;
@@ -44,7 +47,7 @@ export default {
>
- {{ diffFilesLength }} {{ filesText }}
+ {{ diffFilesCountText }} {{ filesText }}
diff --git a/changelogs/unreleased/33849-match-number-of-files-in-tab-counter-and-diff-stats.yml b/changelogs/unreleased/33849-match-number-of-files-in-tab-counter-and-diff-stats.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f5a97911f10876cd85f5e735751d5c2eed60c0bb
--- /dev/null
+++ b/changelogs/unreleased/33849-match-number-of-files-in-tab-counter-and-diff-stats.yml
@@ -0,0 +1,5 @@
+---
+title: Display files in tab counter same as diff stats
+merge_request: 37390
+author:
+type: fixed
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index b7432c4cbe6889a05f066f41eb92c89eacc89cb7..16228b78b34bc50578f657f9dffe49e67f80b527 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -589,6 +589,9 @@ Gitlab.ee do
Settings.cron_jobs['vulnerability_statistics_schedule_worker'] ||= Settingslogic.new({})
Settings.cron_jobs['vulnerability_statistics_schedule_worker']['cron'] ||= '15 1 * * *'
Settings.cron_jobs['vulnerability_statistics_schedule_worker']['job_class'] = 'Vulnerabilities::Statistics::ScheduleWorker'
+ Settings.cron_jobs['vulnerability_historical_statistics_deletion_worker'] ||= Settingslogic.new({})
+ Settings.cron_jobs['vulnerability_historical_statistics_deletion_worker']['cron'] ||= '15 3 * * *'
+ Settings.cron_jobs['vulnerability_historical_statistics_deletion_worker']['job_class'] = 'Vulnerabilities::HistoricalStatistics::DeletionWorker'
end
#
diff --git a/db/migrate/20200724100123_add_index_on_vulnerability_historical_statistics_date.rb b/db/migrate/20200724100123_add_index_on_vulnerability_historical_statistics_date.rb
new file mode 100644
index 0000000000000000000000000000000000000000..696f98b40f60948aa6bd45cd627655e820e56caa
--- /dev/null
+++ b/db/migrate/20200724100123_add_index_on_vulnerability_historical_statistics_date.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class AddIndexOnVulnerabilityHistoricalStatisticsDate < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_index :vulnerability_historical_statistics, [:date, :id]
+ end
+
+ def down
+ remove_concurrent_index :vulnerability_historical_statistics, [:date, :id]
+ end
+end
diff --git a/db/schema_migrations/20200724100123 b/db/schema_migrations/20200724100123
new file mode 100644
index 0000000000000000000000000000000000000000..8d3fbecedb679891e5dc678fc52dca5096e7d06f
--- /dev/null
+++ b/db/schema_migrations/20200724100123
@@ -0,0 +1 @@
+f55dccae8909110396882bd2c28be993eb32f33e880ed4a520d14071f70c9019
\ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 67ccb09421cd130ec21873afba70cdc80c8bb528..2258962328697ae77196a57bc479486b9e72519b 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -20802,6 +20802,8 @@ CREATE INDEX index_vulnerability_feedback_on_merge_request_id ON public.vulnerab
CREATE INDEX index_vulnerability_feedback_on_pipeline_id ON public.vulnerability_feedback USING btree (pipeline_id);
+CREATE INDEX index_vulnerability_historical_statistics_on_date_and_id ON public.vulnerability_historical_statistics USING btree (date, id);
+
CREATE UNIQUE INDEX index_vulnerability_identifiers_on_project_id_and_fingerprint ON public.vulnerability_identifiers USING btree (project_id, fingerprint);
CREATE INDEX index_vulnerability_issue_links_on_issue_id ON public.vulnerability_issue_links USING btree (issue_id);
diff --git a/doc/administration/troubleshooting/debug.md b/doc/administration/troubleshooting/debug.md
index f24ef3e84c56a432387fd6afd27c81c0461806a9..5daf34c101134d7d864919cdab37beb57930a541 100644
--- a/doc/administration/troubleshooting/debug.md
+++ b/doc/administration/troubleshooting/debug.md
@@ -7,6 +7,10 @@ in production.
Troubleshooting and debugging your GitLab instance often requires a
[Rails console](https://guides.rubyonrails.org/command_line.html#rails-console).
+See also:
+
+- [GitLab Rails Console Cheat Sheet](gitlab_rails_cheat_sheet.md).
+- [Navigating GitLab via Rails console](navigating_gitlab_via_rails_console.md).
**For Omnibus installations**
diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md
index dfe6131bdfd0335d782c191ac6e6aac8c2abf431..6bf4544bf70a135c6d6bf90a424af4346d2524fc 100644
--- a/doc/ci/yaml/README.md
+++ b/doc/ci/yaml/README.md
@@ -3695,7 +3695,7 @@ Once an uninterruptible job is running, the pipeline will never be canceled, reg
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15536) in GitLab 12.7.
-Sometimes running multiples jobs or pipelines at the same time in an environment
+Sometimes running multiple jobs or pipelines at the same time in an environment
can lead to errors during the deployment.
To avoid these errors, the `resource_group` attribute can be used to ensure that
diff --git a/doc/development/pipelines.md b/doc/development/pipelines.md
index d3623529cd4c828a04b611e3f30250aa786c541b..d1e7eb9d01fe3815bf304f9d8ad1d8283b816a2a 100644
--- a/doc/development/pipelines.md
+++ b/doc/development/pipelines.md
@@ -13,10 +13,38 @@ as much as possible.
## Overview
-### Pipeline types
+Pipelines for the GitLab project are created using the [`workflow:rules` keyword](../ci/yaml/README.md#workflowrules)
+feature of the GitLab CI/CD.
-Since we use the [`rules:`](../ci/yaml/README.md#rules) and [`needs:`](../ci/yaml/README.md#needs) keywords extensively,
-we have four main pipeline types which are described below. Note that an MR that includes multiple types of changes would
+Pipelines are always created for the following scenarios:
+
+- `master` branch, including on schedules, pushes, merges, and so on.
+- Merge requests.
+- Tags.
+- Stable, `auto-deploy`, and security branches.
+
+Pipeline creation is also affected by the following CI variables:
+
+- If `$FORCE_GITLAB_CI` is set, pipelines are created.
+- If `$GITLAB_INTERNAL` is not set, pipelines are not created.
+
+No pipeline is created in any other cases (for example, when pushing a branch with no
+MR for it).
+
+The source of truth for these workflow rules is defined in .
+
+### Pipelines for Merge Requests
+
+In general, pipelines for an MR fall into one or more of the following types,
+depending on the changes made in the MR:
+
+- [Docs-only MR pipeline](#docs-only-mr-pipeline): This is typically created for an MR that only changes documentation.
+- [Code-only MR pipeline](#code-only-mr-pipeline): This is typically created for an MR that only changes code, either backend or frontend.
+- [Frontend-only MR pipeline](#frontend-only-mr-pipeline): This is typically created for an MR that only changes frontend code.
+- [QA-only MR pipeline](#qa-only-mr-pipeline): This is typically created for an MR that only changes end to end tests related code.
+
+We use the [`rules:`](../ci/yaml/README.md#rules) and [`needs:`](../ci/yaml/README.md#needs) keywords extensively
+to determine the jobs that need to be run in a pipeline. Note that an MR that includes multiple types of changes would
have a pipelines that include jobs from multiple types (e.g. a combination of docs-only and code-only pipelines).
#### Docs-only MR pipeline
@@ -345,22 +373,6 @@ graph RL;
end
```
-### `workflow:rules`
-
-We're using the [`workflow:rules` keyword](../ci/yaml/README.md#workflowrules) to
-define default rules to determine whether or not a pipeline is created.
-
-These rules are defined in
-and are as follows:
-
-1. If `$FORCE_GITLAB_CI` is set, create a pipeline.
-1. For merge requests, create a pipeline.
-1. For `master` branch, create a pipeline (this includes on schedules, pushes, merges, etc.).
-1. For tags, create a pipeline.
-1. If `$GITLAB_INTERNAL` isn't set, don't create a pipeline.
-1. For stable, auto-deploy, and security branches, create a pipeline.
-1. For any other cases (e.g. when pushing a branch with no MR for it), no pipeline is created.
-
### PostgreSQL versions testing
#### Current versions testing
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 797f995e29d82d63a55101618d34f2dda43182c4..ab5b01e0dd0c0a1bb20474bf021559fe2f9c5076 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -15615,12 +15615,30 @@ msgstr ""
msgid "Network"
msgstr ""
+msgid "Network Policy|New rule"
+msgstr ""
+
+msgid "NetworkPolicies|.yaml mode"
+msgstr ""
+
+msgid "NetworkPolicies|Actions"
+msgstr ""
+
msgid "NetworkPolicies|Choose whether to enforce this policy."
msgstr ""
+msgid "NetworkPolicies|Create policy"
+msgstr ""
+
msgid "NetworkPolicies|Define this policy's location, conditions and actions."
msgstr ""
+msgid "NetworkPolicies|Description"
+msgstr ""
+
+msgid "NetworkPolicies|Editor mode"
+msgstr ""
+
msgid "NetworkPolicies|Enforcement status"
msgstr ""
@@ -15642,6 +15660,9 @@ msgstr ""
msgid "NetworkPolicies|Name"
msgstr ""
+msgid "NetworkPolicies|Network Policy"
+msgstr ""
+
msgid "NetworkPolicies|New policy"
msgstr ""
@@ -15663,6 +15684,21 @@ msgstr ""
msgid "NetworkPolicies|Policy editor"
msgstr ""
+msgid "NetworkPolicies|Policy preview"
+msgstr ""
+
+msgid "NetworkPolicies|Policy status"
+msgstr ""
+
+msgid "NetworkPolicies|Policy type"
+msgstr ""
+
+msgid "NetworkPolicies|Rule mode"
+msgstr ""
+
+msgid "NetworkPolicies|Rules"
+msgstr ""
+
msgid "NetworkPolicies|Something went wrong, failed to update policy"
msgstr ""
@@ -15672,6 +15708,9 @@ msgstr ""
msgid "NetworkPolicies|Status"
msgstr ""
+msgid "NetworkPolicies|YAML editor"
+msgstr ""
+
msgid "Never"
msgstr ""
diff --git a/spec/features/issues/update_issues_spec.rb b/spec/features/issues/update_issues_spec.rb
index dfe3a1bf1b39a2e2404118556b08b24c9ef957ae..eb78e4e24562a29ff912b355781b7c2721bc448b 100644
--- a/spec/features/issues/update_issues_spec.rb
+++ b/spec/features/issues/update_issues_spec.rb
@@ -8,7 +8,6 @@ RSpec.describe 'Multiple issue updating from issues#index', :js do
let!(:user) { create(:user)}
before do
- stub_feature_flags(vue_issuables_list: false)
project.add_maintainer(user)
sign_in(user)
end
@@ -52,7 +51,7 @@ RSpec.describe 'Multiple issue updating from issues#index', :js do
click_update_issues_button
page.within('.issue .controls') do
- expect(find('.author-link')["title"]).to have_content(user.name)
+ expect(find('.author-link')['href']).to have_content(user.website_url)
end
end
@@ -83,13 +82,15 @@ RSpec.describe 'Multiple issue updating from issues#index', :js do
find('.dropdown-menu-milestone a', text: milestone.title).click
click_update_issues_button
- expect(find('.issue')).to have_content milestone.title
+ expect(page.find('.issue')).to have_content milestone.title
end
it 'sets to no milestone' do
create_with_milestone
visit project_issues_path(project)
+ wait_for_requests
+
expect(first('.issue')).to have_content milestone.title
click_button 'Edit issues'
diff --git a/spec/frontend/diffs/components/compare_versions_spec.js b/spec/frontend/diffs/components/compare_versions_spec.js
index 7f69a6344c1aaba2db7c6c06e48c2f4667096386..7fdbc791589a8900aec61e7c61a0ff108d52de23 100644
--- a/spec/frontend/diffs/components/compare_versions_spec.js
+++ b/spec/frontend/diffs/components/compare_versions_spec.js
@@ -30,7 +30,7 @@ describe('CompareVersions', () => {
store,
propsData: {
mergeRequestDiffs: diffsMockData,
- diffFilesLength: 0,
+ diffFilesCountText: null,
...props,
},
});
diff --git a/spec/frontend/diffs/components/diff_stats_spec.js b/spec/frontend/diffs/components/diff_stats_spec.js
index 2bf1dd2f961efdff1d8ba4ad17cc4e7bc999304a..7a083fb6bde15d7b35e59cfce706ca6f7f9c21b3 100644
--- a/spec/frontend/diffs/components/diff_stats_spec.js
+++ b/spec/frontend/diffs/components/diff_stats_spec.js
@@ -4,7 +4,8 @@ import Icon from '~/vue_shared/components/icon.vue';
const TEST_ADDED_LINES = 100;
const TEST_REMOVED_LINES = 200;
-const DIFF_FILES_LENGTH = 300;
+const DIFF_FILES_COUNT = '300';
+const DIFF_FILES_COUNT_TRUNCATED = '300+';
describe('diff_stats', () => {
let wrapper;
@@ -22,45 +23,76 @@ describe('diff_stats', () => {
describe('diff stats group', () => {
const findDiffStatsGroup = () => wrapper.findAll('.diff-stats-group');
- it('is not rendered if diffFileLengths is empty', () => {
+ it('is not rendered if diffFilesCountText is empty', () => {
createComponent();
expect(findDiffStatsGroup().length).toBe(2);
});
- it('is not rendered if diffFileLengths is not a number', () => {
+ it('is not rendered if diffFilesCountText is not a number', () => {
createComponent({
- diffFilesLength: Number.NaN,
+ diffFilesCountText: null,
});
expect(findDiffStatsGroup().length).toBe(2);
});
});
- describe('amount displayed', () => {
- beforeEach(() => {
- createComponent({
- diffFilesLength: DIFF_FILES_LENGTH,
- });
+ describe('line changes', () => {
+ const findFileLine = name => wrapper.find(name);
+
+ it('shows the amount of lines added', () => {
+ expect(findFileLine('.js-file-addition-line').text()).toBe(TEST_ADDED_LINES.toString());
});
- const findFileLine = name => wrapper.find(name);
+ it('shows the amount of lines removed', () => {
+ expect(findFileLine('.js-file-deletion-line').text()).toBe(TEST_REMOVED_LINES.toString());
+ });
+ });
+
+ describe('files changes', () => {
const findIcon = name =>
wrapper
.findAll(Icon)
.filter(c => c.attributes('name') === name)
.at(0).element.parentNode;
- it('shows the amount of lines added', () => {
- expect(findFileLine('.js-file-addition-line').text()).toBe(TEST_ADDED_LINES.toString());
+ it('shows amount of file changed with plural "files" when 0 files has changed', () => {
+ const oneFileChanged = '0';
+
+ createComponent({
+ diffFilesCountText: oneFileChanged,
+ });
+
+ expect(findIcon('doc-code').textContent.trim()).toBe(`${oneFileChanged} files`);
});
- it('shows the amount of lines removed', () => {
- expect(findFileLine('.js-file-deletion-line').text()).toBe(TEST_REMOVED_LINES.toString());
+ it('shows amount of file changed with singular "file" when 1 file is changed', () => {
+ const oneFileChanged = '1';
+
+ createComponent({
+ diffFilesCountText: oneFileChanged,
+ });
+
+ expect(findIcon('doc-code').textContent.trim()).toBe(`${oneFileChanged} file`);
});
- it('shows the amount of files changed', () => {
- expect(findIcon('doc-code').textContent).toContain(DIFF_FILES_LENGTH);
+ it('shows amount of files change with plural "files" when multiple files are changed', () => {
+ createComponent({
+ diffFilesCountText: DIFF_FILES_COUNT,
+ });
+
+ expect(findIcon('doc-code').textContent.trim()).toContain(`${DIFF_FILES_COUNT} files`);
+ });
+
+ it('shows amount of files change with plural "files" when files changed is truncated', () => {
+ createComponent({
+ diffFilesCountText: DIFF_FILES_COUNT_TRUNCATED,
+ });
+
+ expect(findIcon('doc-code').textContent.trim()).toContain(
+ `${DIFF_FILES_COUNT_TRUNCATED} files`,
+ );
});
});
});