diff --git a/app/assets/javascripts/diffs/components/app.vue b/app/assets/javascripts/diffs/components/app.vue index 9bca555bf1d0891402c644c92e544c9fdd96f35e..fa379169c8717543671e93b59e93f4bb7b127f5f 100644 --- a/app/assets/javascripts/diffs/components/app.vue +++ b/app/assets/javascripts/diffs/components/app.vue @@ -405,7 +405,7 @@ export default {
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`, + ); }); }); });