diff options
19 files changed, 163 insertions, 123 deletions
diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml index 496831acb65..185bbb36e60 100644 --- a/.rubocop_manual_todo.yml +++ b/.rubocop_manual_todo.yml @@ -412,8 +412,6 @@ Rails/TimeZone: # WIP: https://gitlab.com/gitlab-org/gitlab/-/issues/325836 RSpec/EmptyLineAfterFinalLetItBe: Exclude: - - ee/spec/controllers/admin/geo/projects_controller_spec.rb - - ee/spec/controllers/admin/projects_controller_spec.rb - ee/spec/controllers/groups/analytics/cycle_analytics/stages_controller_spec.rb - ee/spec/controllers/groups/analytics/cycle_analytics/summary_controller_spec.rb - ee/spec/controllers/groups/analytics/cycle_analytics/value_streams_controller_spec.rb diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index 51fc9206ad1..59eda4e677d 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -bf27075ea5ea1b26eef72fb931b21a00950cb7ec +f5c607b1ea9a59c35ae47b6b03bdf98ea183a379 diff --git a/app/assets/javascripts/projects/pipelines/charts/components/app.vue b/app/assets/javascripts/projects/pipelines/charts/components/app.vue index 8a4e6c4e51c..8d005373508 100644 --- a/app/assets/javascripts/projects/pipelines/charts/components/app.vue +++ b/app/assets/javascripts/projects/pipelines/charts/components/app.vue @@ -14,11 +14,7 @@ export default { import('ee_component/projects/pipelines/charts/components/lead_time_charts.vue'), }, inject: { - shouldRenderDeploymentFrequencyCharts: { - type: Boolean, - default: false, - }, - shouldRenderLeadTimeCharts: { + shouldRenderDoraCharts: { type: Boolean, default: false, }, @@ -32,12 +28,8 @@ export default { charts() { const chartsToShow = ['pipelines']; - if (this.shouldRenderDeploymentFrequencyCharts) { - chartsToShow.push('deployments'); - } - - if (this.shouldRenderLeadTimeCharts) { - chartsToShow.push('lead-time'); + if (this.shouldRenderDoraCharts) { + chartsToShow.push('deployments', 'lead-time'); } return chartsToShow; @@ -69,12 +61,14 @@ export default { <gl-tab :title="__('Pipelines')"> <pipeline-charts /> </gl-tab> - <gl-tab v-if="shouldRenderDeploymentFrequencyCharts" :title="__('Deployments')"> - <deployment-frequency-charts /> - </gl-tab> - <gl-tab v-if="shouldRenderLeadTimeCharts" :title="__('Lead Time')"> - <lead-time-charts /> - </gl-tab> + <template v-if="shouldRenderDoraCharts"> + <gl-tab :title="__('Deployments')"> + <deployment-frequency-charts /> + </gl-tab> + <gl-tab :title="__('Lead Time')"> + <lead-time-charts /> + </gl-tab> + </template> </gl-tabs> <pipeline-charts v-else /> </div> diff --git a/app/assets/javascripts/projects/pipelines/charts/index.js b/app/assets/javascripts/projects/pipelines/charts/index.js index 05866fb2fc9..5f5ee44c204 100644 --- a/app/assets/javascripts/projects/pipelines/charts/index.js +++ b/app/assets/javascripts/projects/pipelines/charts/index.js @@ -13,10 +13,7 @@ const apolloProvider = new VueApollo({ const mountPipelineChartsApp = (el) => { const { projectPath } = el.dataset; - const shouldRenderDeploymentFrequencyCharts = parseBoolean( - el.dataset.shouldRenderDeploymentFrequencyCharts, - ); - const shouldRenderLeadTimeCharts = parseBoolean(el.dataset.shouldRenderLeadTimeCharts); + const shouldRenderDoraCharts = parseBoolean(el.dataset.shouldRenderDoraCharts); return new Vue({ el, @@ -27,8 +24,7 @@ const mountPipelineChartsApp = (el) => { apolloProvider, provide: { projectPath, - shouldRenderDeploymentFrequencyCharts, - shouldRenderLeadTimeCharts, + shouldRenderDoraCharts, }, render: (createElement) => createElement(ProjectPipelinesCharts, {}), }); diff --git a/app/graphql/resolvers/concerns/board_issue_filterable.rb b/app/graphql/resolvers/concerns/board_issue_filterable.rb index 1943f9eb070..3484a1cc4ba 100644 --- a/app/graphql/resolvers/concerns/board_issue_filterable.rb +++ b/app/graphql/resolvers/concerns/board_issue_filterable.rb @@ -7,10 +7,10 @@ module BoardIssueFilterable def issue_filters(args) filters = args.to_h + set_filter_values(filters) if filters[:not] - filters[:not] = filters[:not].to_h set_filter_values(filters[:not]) end diff --git a/app/graphql/types/boards/board_issue_input_type.rb b/app/graphql/types/boards/board_issue_input_type.rb index 04f9341c44e..8c0e37e5cb7 100644 --- a/app/graphql/types/boards/board_issue_input_type.rb +++ b/app/graphql/types/boards/board_issue_input_type.rb @@ -2,14 +2,12 @@ module Types module Boards - class NegatedBoardIssueInputType < BoardIssueInputBaseType - end - class BoardIssueInputType < BoardIssueInputBaseType graphql_name 'BoardIssueInput' argument :not, NegatedBoardIssueInputType, required: false, + prepare: ->(negated_args, ctx) { negated_args.to_h }, description: <<~MD List of negated arguments. Warning: this argument is experimental and a subject to change in future. diff --git a/app/graphql/types/boards/negated_board_issue_input_type.rb b/app/graphql/types/boards/negated_board_issue_input_type.rb new file mode 100644 index 00000000000..a0fab2ae969 --- /dev/null +++ b/app/graphql/types/boards/negated_board_issue_input_type.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module Types + module Boards + class NegatedBoardIssueInputType < BoardIssueInputBaseType + end + end +end + +Types::Boards::NegatedBoardIssueInputType.prepend_if_ee('::EE::Types::Boards::NegatedBoardIssueInputType') diff --git a/app/helpers/graph_helper.rb b/app/helpers/graph_helper.rb index d2820325f23..bcbc67957eb 100644 --- a/app/helpers/graph_helper.rb +++ b/app/helpers/graph_helper.rb @@ -23,11 +23,7 @@ module GraphHelper ratio.to_i end - def should_render_deployment_frequency_charts - false - end - - def should_render_lead_time_charts + def should_render_dora_charts false end end diff --git a/app/views/projects/pipelines/charts.html.haml b/app/views/projects/pipelines/charts.html.haml index 76186ed5979..992407adf71 100644 --- a/app/views/projects/pipelines/charts.html.haml +++ b/app/views/projects/pipelines/charts.html.haml @@ -1,5 +1,4 @@ - page_title _('CI/CD Analytics') #js-project-pipelines-charts-app{ data: { project_path: @project.full_path, - should_render_deployment_frequency_charts: should_render_deployment_frequency_charts.to_s, - should_render_lead_time_charts: should_render_lead_time_charts.to_s } } + should_render_dora_charts: should_render_dora_charts.to_s } } diff --git a/changelogs/unreleased/issue-276385-remove-temporary_index_vulnerabilities_on_id.yml b/changelogs/unreleased/issue-276385-remove-temporary_index_vulnerabilities_on_id.yml new file mode 100644 index 00000000000..8053f2a3f25 --- /dev/null +++ b/changelogs/unreleased/issue-276385-remove-temporary_index_vulnerabilities_on_id.yml @@ -0,0 +1,5 @@ +--- +title: Remove temporary index from vulnerabilities table +merge_request: 57656 +author: Huzaifa Iftikhar @huzaifaiftikhar +type: removed diff --git a/db/post_migrate/20210328214434_remove_temporary_index_from_vulnerabilities_table.rb b/db/post_migrate/20210328214434_remove_temporary_index_from_vulnerabilities_table.rb new file mode 100644 index 00000000000..f3da1cc69c4 --- /dev/null +++ b/db/post_migrate/20210328214434_remove_temporary_index_from_vulnerabilities_table.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +class RemoveTemporaryIndexFromVulnerabilitiesTable < ActiveRecord::Migration[6.0] + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + INDEX_NAME = 'temporary_index_vulnerabilities_on_id' + + disable_ddl_transaction! + + def up + remove_concurrent_index_by_name :vulnerabilities, INDEX_NAME + end + + def down + add_concurrent_index :vulnerabilities, :id, where: "state = 2 AND (dismissed_at IS NULL OR dismissed_by_id IS NULL)", name: INDEX_NAME + end +end diff --git a/db/schema_migrations/20210328214434 b/db/schema_migrations/20210328214434 new file mode 100644 index 00000000000..a1d74aaa772 --- /dev/null +++ b/db/schema_migrations/20210328214434 @@ -0,0 +1 @@ +134fba876b69fd48697975066a734becf337f53baddd986a5c708ea6dd7cbd75
\ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 00c5881e672..f6b52332062 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -24367,8 +24367,6 @@ CREATE UNIQUE INDEX snippet_user_mentions_on_snippet_id_index ON snippet_user_me CREATE UNIQUE INDEX taggings_idx ON taggings USING btree (tag_id, taggable_id, taggable_type, context, tagger_id, tagger_type); -CREATE INDEX temporary_index_vulnerabilities_on_id ON vulnerabilities USING btree (id) WHERE ((state = 2) AND ((dismissed_at IS NULL) OR (dismissed_by_id IS NULL))); - CREATE UNIQUE INDEX term_agreements_unique_index ON term_agreements USING btree (user_id, term_id); CREATE INDEX tmp_idx_deduplicate_vulnerability_occurrences ON vulnerability_occurrences USING btree (project_id, report_type, location_fingerprint, primary_identifier_id, id); diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 11b58426569..bffedb97d6d 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -8287,6 +8287,14 @@ Values for sorting projects. | `SIMILARITY` | Most similar to the search query. | | `STORAGE` | Sort by storage size. | +### `NegatedIterationWildcardId` + +Negated Iteration ID wildcard values. + +| Value | Description | +| ----- | ----------- | +| `CURRENT` | Current iteration. | + ### `OncallRotationUnitEnum` Rotation length unit of an on-call rotation. diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index 61774d83a9a..ef201887ef1 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -1474,7 +1474,9 @@ job: Paths are relative to the project directory (`$CI_PROJECT_DIR`) and can't directly link outside it. -You can use glob patterns to match multiple files in any directory in the repository: +You can use [glob](https://en.wikipedia.org/wiki/Glob_(programming)) +patterns to match multiple files in any directory +in the repository: ```yaml job: @@ -1911,7 +1913,8 @@ WARNING: If you use `only:changes` with [only allow merge requests to be merged if the pipeline succeeds](../../user/project/merge_requests/merge_when_pipeline_succeeds.md#only-allow-merge-requests-to-be-merged-if-the-pipeline-succeeds), you should [also use `only:merge_requests`](#use-onlychanges-with-pipelines-for-merge-requests). Otherwise it may not work as expected. -You can also use glob patterns to match multiple files in either the root directory +You can also use [glob](https://en.wikipedia.org/wiki/Glob_(programming)) +patterns to match multiple files in either the root directory of the repository, or in _any_ directory in the repository. However, they must be wrapped in double quotes or GitLab can't parse them: @@ -3285,7 +3288,7 @@ archive. Similar to [`artifacts:paths`](#artifactspaths), `exclude` paths are relative to the project directory. You can use Wildcards that use [glob](https://en.wikipedia.org/wiki/Glob_(programming)) or -[`filepath.Match`](https://golang.org/pkg/path/filepath/#Match) patterns. +[`doublestar.PathMatch`](https://pkg.go.dev/github.com/bmatcuk/doublestar@v1.2.2?tab=doc#PathMatch) patterns. For example, to store all files in `binaries/`, but not `*.o` files located in subdirectories of `binaries/`: diff --git a/spec/frontend/projects/pipelines/charts/components/app_spec.js b/spec/frontend/projects/pipelines/charts/components/app_spec.js index ab1ce260c07..0cf05d4ac37 100644 --- a/spec/frontend/projects/pipelines/charts/components/app_spec.js +++ b/spec/frontend/projects/pipelines/charts/components/app_spec.js @@ -22,8 +22,7 @@ describe('ProjectsPipelinesChartsApp', () => { {}, { provide: { - shouldRenderDeploymentFrequencyCharts: true, - shouldRenderLeadTimeCharts: true, + shouldRenderDoraCharts: true, }, stubs: { DeploymentFrequencyCharts: DeploymentFrequencyChartsStub, @@ -41,39 +40,35 @@ describe('ProjectsPipelinesChartsApp', () => { const findGlTabs = () => wrapper.find(GlTabs); const findAllGlTabs = () => wrapper.findAll(GlTab); + const findGlTabAtIndex = (index) => findAllGlTabs().at(index); const findLeadTimeCharts = () => wrapper.find(LeadTimeChartsStub); const findDeploymentFrequencyCharts = () => wrapper.find(DeploymentFrequencyChartsStub); const findPipelineCharts = () => wrapper.find(PipelineCharts); - const expectCorrectTabs = ({ pipelines, leadTime, deploymentFreqency }) => { - it('renders the expected tabs', () => { - expect(findGlTabs().exists()).toBe(true); - - const allTabTitles = findAllGlTabs().wrappers.map((w) => w.attributes('title')); + describe('when all charts are available', () => { + beforeEach(() => { + createComponent(); + }); - if (pipelines) { - expect(allTabTitles).toContain('Pipelines'); - expect(findPipelineCharts().exists()).toBe(true); - } + it('renders tabs', () => { + expect(findGlTabs().exists()).toBe(true); - if (deploymentFreqency) { - expect(allTabTitles).toContain('Deployments'); - expect(findDeploymentFrequencyCharts().exists()).toBe(true); - } + expect(findGlTabAtIndex(0).attributes('title')).toBe('Pipelines'); + expect(findGlTabAtIndex(1).attributes('title')).toBe('Deployments'); + expect(findGlTabAtIndex(2).attributes('title')).toBe('Lead Time'); + }); - if (leadTime) { - expect(allTabTitles).toContain('Lead Time'); - expect(findLeadTimeCharts().exists()).toBe(true); - } + it('renders the pipeline charts', () => { + expect(findPipelineCharts().exists()).toBe(true); }); - }; - describe('when all charts are available', () => { - beforeEach(() => { - createComponent(); + it('renders the deployment frequency charts', () => { + expect(findDeploymentFrequencyCharts().exists()).toBe(true); }); - expectCorrectTabs({ pipelines: true, deploymentFreqency: true, leadTime: true }); + it('renders the lead time charts', () => { + expect(findLeadTimeCharts().exists()).toBe(true); + }); it('sets the tab and url when a tab is clicked', async () => { let chartsPath; @@ -131,7 +126,7 @@ describe('ProjectsPipelinesChartsApp', () => { expect(name).toBe('chart'); return chart ? [chart] : []; }); - createComponent({ provide: { shouldRenderDeploymentFrequencyCharts: true } }); + createComponent(); expect(findGlTabs().attributes('value')).toBe(tab); }); @@ -151,7 +146,7 @@ describe('ProjectsPipelinesChartsApp', () => { return []; }); - createComponent({ provide: { shouldRenderDeploymentFrequencyCharts: true } }); + createComponent(); expect(findGlTabs().attributes('value')).toBe('0'); @@ -168,30 +163,9 @@ describe('ProjectsPipelinesChartsApp', () => { }); }); - describe('when shouldRenderDeploymentFrequencyCharts is false', () => { - beforeEach(() => { - createComponent({ provide: { shouldRenderDeploymentFrequencyCharts: false } }); - }); - - expectCorrectTabs({ pipelines: true, deploymentFreqency: false, leadTime: true }); - }); - - describe('when shouldRenderLeadTimeCharts is false', () => { - beforeEach(() => { - createComponent({ provide: { shouldRenderLeadTimeCharts: false } }); - }); - - expectCorrectTabs({ pipelines: true, deploymentFreqency: true, leadTime: false }); - }); - - describe('when shouldRenderDeploymentFrequencyCharts and shouldRenderLeadTimeCharts are false', () => { + describe('when the dora charts are not available', () => { beforeEach(() => { - createComponent({ - provide: { - shouldRenderDeploymentFrequencyCharts: false, - shouldRenderLeadTimeCharts: false, - }, - }); + createComponent({ provide: { shouldRenderDoraCharts: false } }); }); it('does not render tabs', () => { diff --git a/spec/helpers/graph_helper_spec.rb b/spec/helpers/graph_helper_spec.rb index 5b5ad59ed0d..0930417accb 100644 --- a/spec/helpers/graph_helper_spec.rb +++ b/spec/helpers/graph_helper_spec.rb @@ -16,7 +16,7 @@ RSpec.describe GraphHelper do end end - describe '#should_render_deployment_frequency_charts' do + describe '#should_render_dora_charts' do let(:project) { create(:project, :private) } before do @@ -24,19 +24,7 @@ RSpec.describe GraphHelper do end it 'always returns false' do - expect(should_render_deployment_frequency_charts).to be(false) - end - end - - describe '#should_render_lead_time_charts' do - let(:project) { create(:project, :private) } - - before do - self.instance_variable_set(:@project, project) - end - - it 'always returns false' do - expect(should_render_lead_time_charts).to be(false) + expect(should_render_dora_charts).to be(false) end end end diff --git a/spec/lib/api/helpers_spec.rb b/spec/lib/api/helpers_spec.rb index 92326cd34d9..15b22fcf25e 100644 --- a/spec/lib/api/helpers_spec.rb +++ b/spec/lib/api/helpers_spec.rb @@ -47,6 +47,58 @@ RSpec.describe API::Helpers do end end + describe '#find_project!' do + let_it_be(:project) { create(:project, :public) } + let_it_be(:user) { create(:user) } + + shared_examples 'private project without access' do + before do + project.update_column(:visibility_level, Gitlab::VisibilityLevel.level_value('private')) + allow(subject).to receive(:authenticate_non_public?).and_return(false) + end + + it 'returns not found' do + expect(subject).to receive(:not_found!) + + subject.find_project!(project.id) + end + end + + context 'when user is authenticated' do + before do + subject.instance_variable_set(:@current_user, user) + subject.instance_variable_set(:@initial_current_user, user) + end + + context 'public project' do + it 'returns requested project' do + expect(subject.find_project!(project.id)).to eq(project) + end + end + + context 'private project' do + it_behaves_like 'private project without access' + end + end + + context 'when user is not authenticated' do + before do + subject.instance_variable_set(:@current_user, nil) + subject.instance_variable_set(:@initial_current_user, nil) + end + + context 'public project' do + it 'returns requested project' do + expect(subject.find_project!(project.id)).to eq(project) + end + end + + context 'private project' do + it_behaves_like 'private project without access' + end + end + end + describe '#find_namespace' do let(:namespace) { create(:namespace) } diff --git a/spec/requests/api/npm_project_packages_spec.rb b/spec/requests/api/npm_project_packages_spec.rb index e64b5ddc374..10271719a15 100644 --- a/spec/requests/api/npm_project_packages_spec.rb +++ b/spec/requests/api/npm_project_packages_spec.rb @@ -41,6 +41,15 @@ RSpec.describe API::NpmProjectPackages do project.add_developer(user) end + shared_examples 'successfully downloads the file' do + it 'returns the file' do + subject + + expect(response).to have_gitlab_http_status(:ok) + expect(response.media_type).to eq('application/octet-stream') + end + end + shared_examples 'a package file that requires auth' do it 'denies download with no token' do subject @@ -51,35 +60,28 @@ RSpec.describe API::NpmProjectPackages do context 'with access token' do let(:headers) { build_token_auth_header(token.token) } - it 'returns the file' do - subject - - expect(response).to have_gitlab_http_status(:ok) - expect(response.media_type).to eq('application/octet-stream') - end + it_behaves_like 'successfully downloads the file' end context 'with job token' do let(:headers) { build_token_auth_header(job.token) } - it 'returns the file' do - subject - - expect(response).to have_gitlab_http_status(:ok) - expect(response.media_type).to eq('application/octet-stream') - end + it_behaves_like 'successfully downloads the file' end end context 'a public project' do - it 'returns the file with no token needed' do - subject + it_behaves_like 'successfully downloads the file' + it_behaves_like 'a package tracking event', 'API::NpmPackages', 'pull_package' - expect(response).to have_gitlab_http_status(:ok) - expect(response.media_type).to eq('application/octet-stream') - end + context 'with a job token for a different user' do + let_it_be(:other_user) { create(:user) } + let_it_be_with_reload(:other_job) { create(:ci_build, :running, user: other_user) } - it_behaves_like 'a package tracking event', 'API::NpmPackages', 'pull_package' + let(:headers) { build_token_auth_header(other_job.token) } + + it_behaves_like 'successfully downloads the file' + end end context 'private project' do |