From 4ddf802cd229959db42f054e039efc329f083d8d Mon Sep 17 00:00:00 2001 From: Lee Tickett <lee@tickett.net> Date: Mon, 4 Jul 2022 14:19:55 +0000 Subject: [PATCH] Add due_date and improve CSV issue import docs Changelog: added --- .../issuable/import_csv/base_service.rb | 3 +- app/services/issues/build_service.rb | 15 ++++---- doc/user/project/issues/csv_import.md | 35 ++++++++++++++----- spec/fixtures/csv_complex.csv | 6 ++++ .../issues/import_csv_service_spec.rb | 24 +++++++++++++ ...able_import_csv_service_shared_examples.rb | 4 +++ 6 files changed, 70 insertions(+), 17 deletions(-) create mode 100644 spec/fixtures/csv_complex.csv diff --git a/app/services/issuable/import_csv/base_service.rb b/app/services/issuable/import_csv/base_service.rb index 4a2078a4e603..9b41c88159fb 100644 --- a/app/services/issuable/import_csv/base_service.rb +++ b/app/services/issuable/import_csv/base_service.rb @@ -23,7 +23,8 @@ def process_csv with_csv_lines.each do |row, line_no| issuable_attributes = { title: row[:title], - description: row[:description] + description: row[:description], + due_date: row[:due_date] } if create_issuable(issuable_attributes).persisted? diff --git a/app/services/issues/build_service.rb b/app/services/issues/build_service.rb index 1ebf9bb6ba24..75bd2b88e86e 100644 --- a/app/services/issues/build_service.rb +++ b/app/services/issues/build_service.rb @@ -81,8 +81,9 @@ def model_klass ::Issue end - def allowed_issue_params - allowed_params = [ + def public_params + # Additional params may be assigned later (in a CreateService for example) + public_issue_params = [ :title, :description, :confidential @@ -90,17 +91,17 @@ def allowed_issue_params params[:work_item_type] = WorkItems::Type.find_by(id: params[:work_item_type_id]) if params[:work_item_type_id].present? # rubocop: disable CodeReuse/ActiveRecord - allowed_params << :milestone_id if can?(current_user, :admin_issue, project) - allowed_params << :issue_type if create_issue_type_allowed?(project, params[:issue_type]) - allowed_params << :work_item_type if create_issue_type_allowed?(project, params[:work_item_type]&.base_type) + public_issue_params << :milestone_id if can?(current_user, :admin_issue, project) + public_issue_params << :issue_type if create_issue_type_allowed?(project, params[:issue_type]) + public_issue_params << :work_item_type if create_issue_type_allowed?(project, params[:work_item_type]&.base_type) - params.slice(*allowed_params) + params.slice(*public_issue_params) end def build_issue_params { author: current_user } .merge(issue_params_with_info_from_discussions) - .merge(allowed_issue_params) + .merge(public_params) .with_indifferent_access end diff --git a/doc/user/project/issues/csv_import.md b/doc/user/project/issues/csv_import.md index 2fe3d78194cc..1ae57c9a883a 100644 --- a/doc/user/project/issues/csv_import.md +++ b/doc/user/project/issues/csv_import.md @@ -6,9 +6,20 @@ info: To determine the technical writer assigned to the Stage/Group associated w # Importing issues from CSV **(FREE)** -Issues can be imported to a project by uploading a CSV file with the columns -`title` and `description`. Other columns are **not** imported. If you want to -retain columns such as labels and milestones, consider the [Move Issue feature](managing_issues.md#move-an-issue). +You can import issues to a project by uploading a CSV file with the following columns: + +| Name | Required? | Description | +|:--------------|:-----------------------|:-------------------------------------------------| +| `title` | **{check-circle}** Yes | Issue title. | +| `description` | **{check-circle}** Yes | Issue description. | +| `due_date` | **{dotted-circle}** No | Issue due date in `YYYY-MM-DD` format. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91317) in GitLab 15.2. | + +Data in other columns is not imported. + +You can use the `description` field to embed [quick actions](../quick_actions.md) to add other data to the issue. +For example, labels, assignees, and milestones. + +Alternatively, you can [move an issue](managing_issues.md#move-an-issue). Moving issues preserves more data. The user uploading the CSV file is set as the author of the imported issues. @@ -44,16 +55,22 @@ To import issues, GitLab requires CSV files have a specific format: | double-quote character | The double-quote (`"`) character is used to quote fields, enabling the use of the column separator in a field (see the third line in the sample CSV data below). To insert a double-quote (`"`) in a quoted field use two double-quote characters in succession (`""`). | | data rows | After the header row, following rows must use the same column order. The issue title is required, but the description is optional. | -If you have special characters in a field, (such as `\n` or `,`), surround the -characters with double quotes (`"`). +If you have special characters (for example, `,` or `\n`) or multiple lines in a field (for example, +when using [quick actions](../quick_actions.md)), surround the characters with double quotes (`"`). + +When using [quick actions](../quick_actions.md), each action must be on a separate line. Sample CSV data: ```plaintext -title,description -My Issue Title,My Issue Description -Another Title,"A description, with a comma" -"One More Title","One More Description" +title,description,due date +My Issue Title,My Issue Description,2022-06-28 +Another Title,"A description, with a comma", +"One More Title","One More Description", +An Issue with Quick Actions,"Hey can we change the frontend? + +/assign @sjones +/label ~frontend ~documentation", ``` ### File size diff --git a/spec/fixtures/csv_complex.csv b/spec/fixtures/csv_complex.csv new file mode 100644 index 000000000000..60d8aa5d6f75 --- /dev/null +++ b/spec/fixtures/csv_complex.csv @@ -0,0 +1,6 @@ +title,description,due date +Issue in ä¸æ–‡,Test description, +"Hello","World", +"Title with quote""","Description +/assign @csv_assignee +/estimate 1h",2022-06-28 diff --git a/spec/services/issues/import_csv_service_spec.rb b/spec/services/issues/import_csv_service_spec.rb index fa40b75190f9..9ad1d7dba9f9 100644 --- a/spec/services/issues/import_csv_service_spec.rb +++ b/spec/services/issues/import_csv_service_spec.rb @@ -5,6 +5,7 @@ RSpec.describe Issues::ImportCsvService do let(:project) { create(:project) } let(:user) { create(:user) } + let(:assignee) { create(:user, username: 'csv_assignee') } let(:service) do uploader = FileUploader.new(project) uploader.store!(file) @@ -16,4 +17,27 @@ let(:issuables) { project.issues } let(:email_method) { :import_issues_csv_email } end + + describe '#execute' do + let(:file) { fixture_file_upload('spec/fixtures/csv_complex.csv') } + + subject { service.execute } + + it 'sets all issueable attributes and executes quick actions' do + project.add_developer(user) + project.add_developer(assignee) + + expect { subject }.to change { issuables.count }.by 3 + + expect(issuables.reload).to include( + have_attributes( + title: 'Title with quote"', + description: 'Description', + time_estimate: 3600, + assignees: include(assignee), + due_date: Date.new(2022, 6, 28) + ) + ) + end + end end diff --git a/spec/support/services/issuable_import_csv_service_shared_examples.rb b/spec/support/services/issuable_import_csv_service_shared_examples.rb index 071181989697..0dea6cfb7291 100644 --- a/spec/support/services/issuable_import_csv_service_shared_examples.rb +++ b/spec/support/services/issuable_import_csv_service_shared_examples.rb @@ -37,6 +37,10 @@ end describe '#execute' do + before do + project.add_developer(user) + end + context 'invalid file extension' do let(:file) { fixture_file_upload('spec/fixtures/banana_sample.gif') } -- GitLab