Commit 8db35493 authored by Mathieu Parent's avatar Mathieu Parent

Allow to define a default CI configuration path for new projects

Fixes: #20598
parent 69ed0d41
......@@ -176,6 +176,7 @@ module ApplicationSettingsHelper
:container_registry_token_expire_delay,
:default_artifacts_expire_in,
:default_branch_protection,
:default_ci_config_path,
:default_group_visibility,
:default_project_creation,
:default_project_visibility,
......
......@@ -297,6 +297,12 @@ class ApplicationSetting < ApplicationRecord
pass: :external_auth_client_key_pass,
if: -> (setting) { setting.external_auth_client_cert.present? }
validates :default_ci_config_path,
format: { without: %r{(\.{2}|\A/)},
message: N_('cannot include leading slash or directory traversal.') },
length: { maximum: 255 },
allow_blank: true
attr_encrypted :asset_proxy_secret_key,
mode: :per_attribute_iv,
key: Settings.attr_encrypted_db_key_base_truncated,
......
......@@ -42,6 +42,7 @@ module ApplicationSettingImplementation
container_registry_token_expire_delay: 5,
default_artifacts_expire_in: '30 days',
default_branch_protection: Settings.gitlab['default_branch_protection'],
default_ci_config_path: nil,
default_group_visibility: Settings.gitlab.default_projects_features['visibility_level'],
default_project_creation: Settings.gitlab['default_project_creation'],
default_project_visibility: Settings.gitlab.default_projects_features['visibility_level'],
......
......@@ -92,6 +92,7 @@ class Project < ApplicationRecord
default_value_for :snippets_enabled, gitlab_config_features.snippets
default_value_for :only_allow_merge_if_all_discussions_are_resolved, false
default_value_for :remove_source_branch_after_merge, true
default_value_for(:ci_config_path) { Gitlab::CurrentSettings.default_ci_config_path }
add_authentication_token_field :runners_token, encrypted: -> { Feature.enabled?(:projects_tokens_optional_encryption, default_enabled: true) ? :optional : :required }
......
......@@ -53,5 +53,11 @@
= s_('AdminSettings|Environment variables are protected by default')
.form-text.text-muted
= s_('AdminSettings|When creating a new environment variable it will be protected by default.')
.form-group
= f.label :ci_config_path, _('Default CI configuration path'), class: 'label-bold'
= f.text_field :default_ci_config_path, class: 'form-control', placeholder: '.gitlab-ci.yml'
%p.form-text.text-muted
= _("The default CI configuration path for new projects.").html_safe
= link_to icon('question-circle'), help_page_path('user/project/pipelines/settings', anchor: 'custom-ci-config-path'), target: '_blank'
= f.submit _('Save changes'), class: "btn btn-success"
---
title: Allow to define a default CI configuration path for new projects
merge_request: 18073
author: Mathieu Parent
type: added
# frozen_string_literal: true
class DefaultCiConfigPath < ActiveRecord::Migration[5.2]
DOWNTIME = false
def up
add_column :application_settings, :default_ci_config_path, :string, limit: 255
end
def down
remove_column :application_settings, :default_ci_config_path
end
end
......@@ -351,6 +351,7 @@ ActiveRecord::Schema.define(version: 2019_11_12_115317) do
t.text "encrypted_eks_secret_access_key"
t.string "snowplow_app_id"
t.datetime_with_timezone "productivity_analytics_start_date"
t.string "default_ci_config_path", limit: 255
t.index ["custom_project_templates_group_id"], name: "index_application_settings_on_custom_project_templates_group_id"
t.index ["file_template_project_id"], name: "index_application_settings_on_file_template_project_id"
t.index ["instance_administration_project_id"], name: "index_applicationsettings_on_instance_administration_project_id"
......
......@@ -40,6 +40,7 @@ Example response:
"domain_blacklist_enabled" : false,
"domain_blacklist" : [],
"created_at" : "2016-01-04T15:44:55.176Z",
"default_ci_config_path" : null,
"default_project_visibility" : "private",
"default_group_visibility" : "private",
"gravatar_enabled" : true,
......@@ -113,6 +114,7 @@ Example response:
"restricted_visibility_levels": [],
"max_attachment_size": 10,
"session_expire_delay": 10080,
"default_ci_config_path" : null,
"default_project_visibility": "internal",
"default_snippet_visibility": "private",
"default_group_visibility": "private",
......@@ -198,6 +200,7 @@ are listed in the descriptions of the relevant settings.
| `container_registry_token_expire_delay` | integer | no | Container Registry token duration in minutes. |
| `default_artifacts_expire_in` | string | no | Set the default expiration time for each job's artifacts. |
| `default_branch_protection` | integer | no | Determine if developers can push to master. Can take: `0` _(not protected, both developers and maintainers can push new commits, force push, or delete the branch)_, `1` _(partially protected, developers and maintainers can push new commits, but cannot force push or delete the branch)_ or `2` _(fully protected, developers cannot push new commits, but maintainers can; no-one can force push or delete the branch)_ as a parameter. Default is `2`. |
| `default_ci_config_path` | string | no | Default CI configuration path for new projects (`.gitlab-ci.yml` if not set). |
| `default_group_visibility` | string | no | What visibility level new groups receive. Can take `private`, `internal` and `public` as a parameter. Default is `private`. |
| `default_project_creation` | integer | no | Default project creation protection. Can take: `0` _(No one)_, `1` _(Maintainers)_ or `2` _(Developers + Maintainers)_|
| `default_projects_limit` | integer | no | Project limit per user. Default is `100000`. |
......
......@@ -134,6 +134,19 @@ Once that time passes, the jobs will be archived and no longer able to be
retried. Make it empty to never expire jobs. It has to be no less than 1 day,
for example: <code>15 days</code>, <code>1 month</code>, <code>2 years</code>.
## Default CI configuration path
> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/18073) in GitLab 12.5.
The default CI configuration file path for new projects can be set in the Admin
area of your GitLab instance (`.gitlab-ci.yml` if not set):
1. Go to **Admin area > Settings > Continuous Integration and Deployment**.
1. Input the new path in the **Default CI configuration path** field.
1. Hit **Save changes** for the changes to take effect.
It is also possible to specify a [custom CI configuration path for a specific project](../../project/pipelines/settings.md#custom-ci-configuration-path).
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
......
......@@ -42,6 +42,7 @@ module API
optional :asset_proxy_whitelist, type: Array[String], coerce_with: Validations::Types::CommaSeparatedToArray.coerce, desc: 'Assets that match these domain(s) will NOT be proxied. Wildcards allowed. Your GitLab installation URL is automatically whitelisted.'
optional :container_registry_token_expire_delay, type: Integer, desc: 'Authorization token duration (minutes)'
optional :default_artifacts_expire_in, type: String, desc: "Set the default expiration time for each job's artifacts"
optional :default_ci_config_path, type: String, desc: 'The instance default CI configuration path for new projects'
optional :default_project_creation, type: Integer, values: ::Gitlab::Access.project_creation_values, desc: 'Determine if developers can create projects in the group'
optional :default_branch_protection, type: Integer, values: ::Gitlab::Access.protection_values, desc: 'Determine if developers can push to master'
optional :default_group_visibility, type: String, values: Gitlab::VisibilityLevel.string_values, desc: 'The default group visibility'
......
......@@ -5241,6 +5241,9 @@ msgstr ""
msgid "Default Branch"
msgstr ""
msgid "Default CI configuration path"
msgstr ""
msgid "Default artifacts expiration"
msgstr ""
......@@ -16840,6 +16843,9 @@ msgstr ""
msgid "The content of this page is not encoded in UTF-8. Edits can only be made via the Git repository."
msgstr ""
msgid "The default CI configuration path for new projects."
msgstr ""
msgid "The dependency list details information about the components used within your project."
msgstr ""
......
......@@ -2029,24 +2029,37 @@ describe Project do
end
describe '#ci_config_path=' do
let(:project) { create(:project) }
using RSpec::Parameterized::TableSyntax
it 'sets nil' do
project.update!(ci_config_path: nil)
let(:project) { create(:project) }
expect(project.ci_config_path).to be_nil
where(:default_ci_config_path, :project_ci_config_path, :expected_ci_config_path) do
nil | :notset | :default
nil | nil | :default
nil | '' | :default
nil | "cust\0om/\0/path" | 'custom//path'
'' | :notset | :default
'' | nil | :default
'' | '' | :default
'' | "cust\0om/\0/path" | 'custom//path'
'global/path' | :notset | 'global/path'
'global/path' | nil | :default
'global/path' | '' | :default
'global/path' | "cust\0om/\0/path" | 'custom//path'
end
it 'sets a string' do
project.update!(ci_config_path: 'foo/.gitlab_ci.yml')
expect(project.ci_config_path).to eq('foo/.gitlab_ci.yml')
end
with_them do
before do
stub_application_setting(default_ci_config_path: default_ci_config_path)
it 'sets a string but removes all null characters' do
project.update!(ci_config_path: "f\0oo/\0/.gitlab_ci.yml")
if project_ci_config_path != :notset
project.ci_config_path = project_ci_config_path
end
end
expect(project.ci_config_path).to eq('foo//.gitlab_ci.yml')
it 'returns the correct path' do
expect(project.ci_config_path.presence || :default).to eq(expected_ci_config_path)
end
end
end
......
......@@ -18,6 +18,7 @@ describe API::Settings, 'Settings' do
expect(json_response['password_authentication_enabled']).to be_truthy
expect(json_response['plantuml_enabled']).to be_falsey
expect(json_response['plantuml_url']).to be_nil
expect(json_response['default_ci_config_path']).to be_nil
expect(json_response['default_project_visibility']).to be_a String
expect(json_response['default_snippet_visibility']).to be_a String
expect(json_response['default_group_visibility']).to be_a String
......@@ -49,6 +50,7 @@ describe API::Settings, 'Settings' do
it "updates application settings" do
put api("/application/settings", admin),
params: {
default_ci_config_path: 'debian/salsa-ci.yml',
default_projects_limit: 3,
default_project_creation: 2,
password_authentication_enabled_for_web: false,
......@@ -80,6 +82,7 @@ describe API::Settings, 'Settings' do
}
expect(response).to have_gitlab_http_status(200)
expect(json_response['default_ci_config_path']).to eq('debian/salsa-ci.yml')
expect(json_response['default_projects_limit']).to eq(3)
expect(json_response['default_project_creation']).to eq(::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS)
expect(json_response['password_authentication_enabled_for_web']).to be_falsey
......
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