Commit bb4e5bea authored by James Fargher's avatar James Fargher

Merge branch '2557-select-default-template-from-gitlab-folder-take-2' into 'master'

Support default templates for issues/MRs via .gitlab/ folders

See merge request gitlab-org/gitlab!78302
parents 273981d9 baf82c90
......@@ -38,7 +38,13 @@ module IssuablesDescriptionTemplatesHelper
# Only local templates will be listed if licenses for inherited templates are not present
all_templates = all_templates.values.flatten.map { |tpl| tpl[:name] }.compact.uniq
all_templates.find { |tmpl_name| tmpl_name == params[:issuable_template] }
template = all_templates.find { |tmpl_name| tmpl_name == params[:issuable_template] }
unless issuable.description.present?
template ||= all_templates.find { |tmpl_name| tmpl_name.casecmp?('default') }
end
template
end
def available_service_desk_templates_for(project)
......
......@@ -114,7 +114,9 @@ To re-use templates [you've created](../project/description_templates.md#create-
You might also be interested in templates for various
[file types in groups](../group/index.md#group-file-templates).
### Set a default template for merge requests and issues **(PREMIUM)**
### Set a default template for merge requests and issues
> `Default.md` template [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78302) in GitLab 14.8.
In a project, you can choose a default description template for new issues and merge requests.
As a result, every time a new merge request or issue is created, it's pre-filled with the text you
......@@ -125,17 +127,29 @@ Prerequisites:
- On your project's left sidebar, select **Settings > General** and expand **Visibility, project features, permissions**.
Ensure issues or merge requests are set to either **Everyone with access** or **Only Project Members**.
To set a default description template for merge requests:
To set a default description template for merge requests, either:
1. Go to your project's **Settings**.
1. Select **Expand** under the **Merge requests** header.
1. Fill in the **Default description template for merge requests** text area.
1. Select **Save changes**.
- [Create a merge request template](#create-a-merge-request-template) named `Default.md` and save it in `.gitlab/merge_request_templates/`.
This will not overwrite the default template if one has been set in the project settings.
- Users on GitLab Premium and higher: set the default template in project settings:
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings**.
1. Expand **Merge requests**.
1. Fill in the **Default description template for merge requests** text area.
1. Select **Save changes**.
To set a default description template for issues, either:
To set a default description template for issues:
- [Create an issue template](#create-an-issue-template) named `Default.md` and save it in `.gitlab/issue_templates/`.
This will not overwrite the default template if one has been set in the project settings.
- Users on GitLab Premium and higher: set the default template in project settings:
1. Select **Expand** under **Default issue template**.
1. Fill in the **Default description template for issues** text area.
1. On the top bar, select **Menu > Projects** and find your project.
1. On the left sidebar, select **Settings**.
1. Expand **Default issue template**.
1. Fill in the **Default description template for issues** text area.
1. Select **Save changes**.
Because GitLab merge request and issues support [Markdown](../markdown.md), you can use it to format
headings, lists, and so on.
......@@ -143,6 +157,16 @@ headings, lists, and so on.
You can also provide `issues_template` and `merge_requests_template` attributes in the
[Projects REST API](../../api/projects.md) to keep your default issue and merge request templates up to date.
#### Priority of description templates
When you set [merge request and issue description templates](#set-a-default-template-for-merge-requests-and-issues)
in various places, they have the following priorities in a project.
The ones higher up override the ones below:
1. Template selected in project settings.
1. `Default.md` from the parent group.
1. `Default.md` from the project repository.
## Example description template
We use description templates for issues and merge requests in the
......
......@@ -26,7 +26,7 @@ RSpec.describe Projects::IssuesController do
context 'licensed' do
before do
stub_licensed_features(issue_weights: true, epics: true, security_dashboard: true)
stub_licensed_features(issue_weights: true, epics: true, security_dashboard: true, issuable_default_templates: true)
end
describe '#index' do
......@@ -82,6 +82,33 @@ RSpec.describe Projects::IssuesController do
expect(assigns(:issue).confidential).to eq(true)
end
end
context 'default templates' do
let(:selected_field) { 'data-selected="Default"' }
let(:files) { { '.gitlab/issue_templates/Default.md' => '' } }
subject { get :new, params: { namespace_id: project.namespace, project_id: project } }
context 'when a template has been set via project settings' do
let(:project) { create(:project, :custom_repo, namespace: namespace, issues_template: 'Content', files: files ) }
it 'does not select a default template' do
subject
expect(response.body).not_to include(selected_field)
end
end
context 'when a template has not been set via project settings' do
let(:project) { create(:project, :custom_repo, namespace: namespace, files: files ) }
it 'selects a default template' do
subject
expect(response.body).to include(selected_field)
end
end
end
end
describe '#create' do
......
......@@ -12,6 +12,53 @@ RSpec.describe Projects::MergeRequests::CreationsController do
sign_in(viewer)
end
describe 'GET #new' do
render_views
context 'default templates' do
let(:selected_field) { 'data-selected="Default"' }
let(:files) { { '.gitlab/merge_request_templates/Default.md' => '' } }
subject do
get :new,
params: {
namespace_id: project.namespace,
project_id: project,
merge_request: {
source_project_id: project.id,
source_branch: 'feature',
target_project_id: project.id,
target_branch: 'master'
}
}
end
before do
project.repository.create_branch('feature', 'master')
end
context 'when a template has been set via project settings' do
let(:project) { create(:project, :custom_repo, merge_requests_template: 'Content', files: files ) }
it 'does not select a default template' do
subject
expect(response.body).not_to include(selected_field)
end
end
context 'when a template has not been set via project settings' do
let(:project) { create(:project, :custom_repo, files: files ) }
it 'selects a default template' do
subject
expect(response.body).to include(selected_field)
end
end
end
end
describe 'POST #create' do
let(:created_merge_request) { assigns(:merge_request) }
......
......@@ -340,6 +340,58 @@ RSpec.describe Projects::MergeRequestsController do
end
end
describe 'GET #edit' do
render_views
let(:params) do
{
namespace_id: project.namespace.to_param,
project_id: project,
id: merge_request.iid
}
end
subject { get :edit, params: params }
context 'default templates' do
let(:selected_field) { 'data-selected="Default"' }
let(:files) { { '.gitlab/merge_request_templates/Default.md' => '' } }
let(:project) { create(:project, :custom_repo, files: files ) }
context 'when a merge request description has content' do
let(:merge_request) { create(:merge_request_with_diffs, source_project: project, author: author, description: 'An existing description') }
it 'does not select a default template' do
subject
expect(response.body).not_to include(selected_field)
end
end
context 'when a merge request description is blank' do
let(:merge_request) { create(:merge_request_with_diffs, source_project: project, author: author, description: '') }
context 'when a default template does not exist in the repository' do
let(:project) { create(:project ) }
it 'does not select a default template' do
subject
expect(response.body).not_to include(selected_field)
end
end
context 'when a default template exists in the repository' do
it 'selects a default template' do
subject
expect(response.body).to include(selected_field)
end
end
end
end
end
describe 'GET #dependency_scanning_reports' do
let_it_be_with_reload(:merge_request) { create(:ee_merge_request, :with_dependency_scanning_reports, source_project: project, author: author) }
......
......@@ -72,6 +72,37 @@ RSpec.describe IssuablesDescriptionTemplatesHelper, :clean_gitlab_redis_cache do
].to_json
expect(helper.available_service_desk_templates_for(@project)).to eq(value)
end
context 'when no issuable_template parameter or default template is present' do
it 'does not select a template' do
expect(helper.selected_template(project)).to be(nil)
end
end
context 'when an issuable_template parameter has been provided' do
before do
allow(helper).to receive(:params).and_return({ issuable_template: 'another_issue_template' })
end
it 'selects the issuable template' do
expect(helper.selected_template(project)).to eq('another_issue_template')
end
end
context 'when there is a default template' do
let(:templates) do
{
"" => [
{ name: "another_issue_template", id: "another_issue_template", project_id: project.id },
{ name: "default", id: "default", project_id: project.id }
]
}
end
it 'selects the default template' do
expect(helper.selected_template(project)).to eq('default')
end
end
end
context 'when there are not templates in the project' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment