summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/boards/components/board_list.vue2
-rw-r--r--app/assets/javascripts/error_tracking/components/error_details.vue6
-rw-r--r--app/controllers/groups/group_links_controller.rb2
-rw-r--r--app/models/group.rb2
-rw-r--r--app/views/groups/group_members/index.html.haml4
-rw-r--r--changelogs/unreleased/22986-share_group_with_group_ff_default_on.yml5
-rw-r--r--changelogs/unreleased/36753-dashes-not-supported-in-cn-for-ldap-group-sync-on-first-login.yml5
-rw-r--r--changelogs/unreleased/sh-fix-issue-197300.yml5
-rw-r--r--doc/administration/index.md1
-rw-r--r--doc/ci/environments.md5
-rw-r--r--doc/ci/environments/img/incremental_rollouts_play_v12_7.pngbin0 -> 94182 bytes
-rw-r--r--doc/ci/environments/img/timed_rollout_v12_7.pngbin0 -> 73699 bytes
-rw-r--r--doc/ci/environments/incremental_rollouts.md113
-rw-r--r--lib/gitlab/project_authorizations.rb2
-rw-r--r--locale/gitlab.pot3
-rw-r--r--spec/frontend/error_tracking/components/error_details_spec.js2
-rw-r--r--spec/frontend/registry/list/components/app_spec.js2
-rw-r--r--spec/frontend/registry/list/components/collapsible_container_spec.js1
-rw-r--r--spec/frontend/registry/list/components/project_empty_state_spec.js1
-rw-r--r--spec/frontend/registry/list/components/table_registry_spec.js6
20 files changed, 153 insertions, 14 deletions
diff --git a/app/assets/javascripts/boards/components/board_list.vue b/app/assets/javascripts/boards/components/board_list.vue
index 1e54d4d6b7d..ee889e0f7e0 100644
--- a/app/assets/javascripts/boards/components/board_list.vue
+++ b/app/assets/javascripts/boards/components/board_list.vue
@@ -256,7 +256,7 @@ export default {
let toList;
if (to) {
const containerEl = to.closest('.js-board-list');
- toList = boardsStore.findList('id', Number(containerEl.dataset.board));
+ toList = boardsStore.findList('id', Number(containerEl.dataset.board), '');
}
/**
diff --git a/app/assets/javascripts/error_tracking/components/error_details.vue b/app/assets/javascripts/error_tracking/components/error_details.vue
index 51a1ae50467..65cd2f044ae 100644
--- a/app/assets/javascripts/error_tracking/components/error_details.vue
+++ b/app/assets/javascripts/error_tracking/components/error_details.vue
@@ -251,8 +251,8 @@ export default {
<li>
<strong class="bold">{{ __('Sentry event') }}:</strong>
<gl-link
- class="d-inline-flex align-items-center"
v-track-event="trackClickErrorLinkToSentryOptions(GQLerror.externalUrl)"
+ class="d-inline-flex align-items-center"
:href="GQLerror.externalUrl"
target="_blank"
>
@@ -264,7 +264,9 @@ export default {
<strong class="bold">{{ __('First seen') }}:</strong>
{{ formatDate(GQLerror.firstSeen) }}
<gl-link :href="firstReleaseLink" target="_blank">
- <span>{{ __('Release') }}: {{ GQLerror.firstReleaseShortVersion.substr(0, 10) }}</span>
+ <span>
+ {{ __('Release') }}: {{ GQLerror.firstReleaseShortVersion.substr(0, 10) }}
+ </span>
</gl-link>
</li>
<li v-if="GQLerror.lastReleaseShortVersion">
diff --git a/app/controllers/groups/group_links_controller.rb b/app/controllers/groups/group_links_controller.rb
index 6796a862c00..d3360acd245 100644
--- a/app/controllers/groups/group_links_controller.rb
+++ b/app/controllers/groups/group_links_controller.rb
@@ -53,6 +53,6 @@ class Groups::GroupLinksController < Groups::ApplicationController
end
def check_feature_flag!
- render_404 unless Feature.enabled?(:share_group_with_group)
+ render_404 unless Feature.enabled?(:share_group_with_group, default_enabled: true)
end
end
diff --git a/app/models/group.rb b/app/models/group.rb
index 186253619fe..51b4fe4c1ce 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -496,7 +496,7 @@ class Group < Namespace
end
def max_member_access_for_user_from_shared_groups(user)
- return unless Feature.enabled?(:share_group_with_group)
+ return unless Feature.enabled?(:share_group_with_group, default_enabled: true)
group_group_link_table = GroupGroupLink.arel_table
group_member_table = GroupMember.arel_table
diff --git a/app/views/groups/group_members/index.html.haml b/app/views/groups/group_members/index.html.haml
index 6eb8a8947cc..048edb80d99 100644
--- a/app/views/groups/group_members/index.html.haml
+++ b/app/views/groups/group_members/index.html.haml
@@ -9,7 +9,7 @@
= _("Group members")
%hr
- if can_manage_members
- - if Feature.enabled?(:share_group_with_group)
+ - if Feature.enabled?(:share_group_with_group, default_enabled: true)
%ul.nav-links.nav.nav-tabs.gitlab-tabs{ role: 'tablist' }
%li.nav-tab{ role: 'presentation' }
%a.nav-link.active{ href: '#invite-member-pane', id: 'invite-member-tab', data: { toggle: 'tab' }, role: 'tab' }= _("Invite member")
@@ -18,7 +18,7 @@
.tab-content.gitlab-tab-content
.tab-pane.active{ id: 'invite-member-pane', role: 'tabpanel' }
= render_invite_member_for_group(@group, @group_member.access_level)
- - if Feature.enabled?(:share_group_with_group)
+ - if Feature.enabled?(:share_group_with_group, default_enabled: true)
.tab-pane{ id: 'invite-group-pane', role: 'tabpanel' }
= render 'shared/members/invite_group', submit_url: group_group_links_path(@group), access_levels: GroupMember.access_level_roles, default_access_level: @group_member.access_level, group_link_field: 'shared_with_group_id', group_access_field: 'shared_group_access'
- else
diff --git a/changelogs/unreleased/22986-share_group_with_group_ff_default_on.yml b/changelogs/unreleased/22986-share_group_with_group_ff_default_on.yml
new file mode 100644
index 00000000000..f271c9c89ac
--- /dev/null
+++ b/changelogs/unreleased/22986-share_group_with_group_ff_default_on.yml
@@ -0,0 +1,5 @@
+---
+title: Allow to share groups with other groups
+merge_request: 23185
+author:
+type: changed
diff --git a/changelogs/unreleased/36753-dashes-not-supported-in-cn-for-ldap-group-sync-on-first-login.yml b/changelogs/unreleased/36753-dashes-not-supported-in-cn-for-ldap-group-sync-on-first-login.yml
new file mode 100644
index 00000000000..93f3cce4376
--- /dev/null
+++ b/changelogs/unreleased/36753-dashes-not-supported-in-cn-for-ldap-group-sync-on-first-login.yml
@@ -0,0 +1,5 @@
+---
+title: Support dashes in LDAP group CN for sync on users first log in
+merge_request: 20402
+author:
+type: fixed
diff --git a/changelogs/unreleased/sh-fix-issue-197300.yml b/changelogs/unreleased/sh-fix-issue-197300.yml
new file mode 100644
index 00000000000..b54fcd24cc9
--- /dev/null
+++ b/changelogs/unreleased/sh-fix-issue-197300.yml
@@ -0,0 +1,5 @@
+---
+title: Fix issue CSV export failing for some projects
+merge_request: 23223
+author:
+type: fixed
diff --git a/doc/administration/index.md b/doc/administration/index.md
index 4cafb4eb87c..8172acd09b4 100644
--- a/doc/administration/index.md
+++ b/doc/administration/index.md
@@ -200,6 +200,7 @@ Learn how to install, configure, update, and maintain your GitLab instance.
- [Log system](logs.md): Where to look for logs.
- [Sidekiq Troubleshooting](troubleshooting/sidekiq.md): Debug when Sidekiq appears hung and is not processing jobs.
- [Troubleshooting Elasticsearch](troubleshooting/elasticsearch.md)
+- [GitLab application limits](instance_limits.md)
### Support Team Docs
diff --git a/doc/ci/environments.md b/doc/ci/environments.md
index 245a4d20e2d..55e93e19f66 100644
--- a/doc/ci/environments.md
+++ b/doc/ci/environments.md
@@ -232,6 +232,11 @@ declaring their names dynamically in `.gitlab-ci.yml`.
Dynamic environments are a fundamental part of [Review apps](review_apps/index.md).
+### Configuring incremental rollouts
+
+Learn how to release production changes to only a portion of your Kubernetes pods with
+[incremental rollouts](environments/incremental_rollouts.md).
+
#### Allowed variables
The `name` and `url` parameters for dynamic environments can use most available CI/CD variables,
diff --git a/doc/ci/environments/img/incremental_rollouts_play_v12_7.png b/doc/ci/environments/img/incremental_rollouts_play_v12_7.png
new file mode 100644
index 00000000000..314c4a07af0
--- /dev/null
+++ b/doc/ci/environments/img/incremental_rollouts_play_v12_7.png
Binary files differ
diff --git a/doc/ci/environments/img/timed_rollout_v12_7.png b/doc/ci/environments/img/timed_rollout_v12_7.png
new file mode 100644
index 00000000000..6b83bfc574e
--- /dev/null
+++ b/doc/ci/environments/img/timed_rollout_v12_7.png
Binary files differ
diff --git a/doc/ci/environments/incremental_rollouts.md b/doc/ci/environments/incremental_rollouts.md
new file mode 100644
index 00000000000..0fa0af6a9fb
--- /dev/null
+++ b/doc/ci/environments/incremental_rollouts.md
@@ -0,0 +1,113 @@
+---
+type: concepts, howto
+---
+
+# Incremental Rollouts with GitLab CI/CD
+
+When rolling out changes to your application, it is possible to release production changes
+to only a portion of your Kubernetes pods as a risk mitigation strategy. By releasing
+production changes gradually, error rates or performance degradation can be monitored, and
+if there are no problems, all pods can be updated.
+
+GitLab supports both manually triggered and timed rollouts to a Kubernetes production system
+using Incremental Rollouts. When using Manual Rollouts, the release of each tranche
+of pods is manually triggered, while in Timed Rollouts, the release is performed in
+tranches after a default pause of 5 minutes.
+Timed rollouts can also be manually triggered before the pause period has expired.
+
+Manual and Timed rollouts are included automatically in projects controlled by
+[AutoDevOps](../../topics/autodevops/index.md), but they are also configurable through
+GitLab CI/CD in the `.gitlab-ci.yml` configuration file.
+
+Manually triggered rollouts can be implemented with your [Continuously Delivery](../introduction/index.md#continuous-delivery)
+methodology, while timed rollouts do not require intervention and can be part of your
+[Continuously Deployment](../introduction/index.md#continuous-deployment) strategy.
+You can also combine both of them in a way that the app is deployed automatically
+unless you eventually intervene manually if necessary.
+
+We created sample applications to demonstrate the three options, which you can
+use as examples to build your own:
+
+- [Manual incremental rollouts](https://gitlab.com/gl-release/incremental-rollout-example/blob/master/.gitlab-ci.yml)
+- [Timed incremental rollouts](https://gitlab.com/gl-release/timed-rollout-example/blob/master/.gitlab-ci.yml)
+- [Both manual and timed rollouts](https://gitlab.com/gl-release/incremental-timed-rollout-example/blob/master/.gitlab-ci.yml)
+
+## Manual Rollouts
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/5415) in GitLab 10.8.
+
+It is possible to configure GitLab to do incremental rollouts manually through `.gitlab-ci.yml`. Manual configuration
+allows more control over the this feature. The steps in an incremental rollout depend on the
+number of pods that are defined for the deployment, which are configured when the Kubernetes
+cluster is created.
+
+For example, if your application has 10 pods and a 10% rollout job is run, the new instance of the
+application will be deployed to a single pod while the remaining 9 will present the previous instance.
+
+First we [define the template as manual](https://gitlab.com/gl-release/incremental-rollout-example/blob/master/.gitlab-ci.yml#L100-103):
+
+```yml
+.manual_rollout_template: &manual_rollout_template
+ <<: *rollout_template
+ stage: production
+ when: manual
+```
+
+Then we [define the rollout amount for each step](https://gitlab.com/gl-release/incremental-rollout-example/blob/master/.gitlab-ci.yml#L152-155):
+
+```yml
+rollout 10%:
+ <<: *manual_rollout_template
+ variables:
+ ROLLOUT_PERCENTAGE: 10
+```
+
+When the jobs are built, a **play** button will appear next to the job's name. Click the **play** button
+to release each stage of pods. You can also rollback by running a lower percentage job. Once 100%
+is reached, you cannot roll back using this method. It is still possible to roll back by redeploying
+the old version using the **Rollback** button on the environment page.
+
+![Play button](img/incremental_rollouts_play_v12_7.png)
+
+A [deployable application](https://gitlab.com/gl-release/incremental-rollout-example) is
+available, demonstrating manually triggered incremental rollouts.
+
+## Timed Rollouts
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/7545) in GitLab 11.4.
+
+Timed rollouts behave in the same way as manual rollouts, except that each job is defined with a delay
+in minutes before it will deploy. Clicking on the job will reveal the countdown.
+
+![Timed rollout](img/timed_rollout_v12_7.png)
+
+It is possible to combine this functionality with manual incremental rollouts so that the job will
+countdown and then deploy.
+
+First we [define the template as timed](https://gitlab.com/gl-release/timed-rollout-example/blob/master/.gitlab-ci.yml#L86-89):
+
+```yml
+.timed_rollout_template: &timed_rollout_template
+ <<: *rollout_template
+ when: delayed
+ start_in: 1 minutes
+```
+
+We can define the delay period using the `start_in` key:
+
+```yml
+start_in: 1 minutes
+```
+
+Then we [define the rollout amount for each step](https://gitlab.com/gl-release/timed-rollout-example/blob/master/.gitlab-ci.yml#L97-101):
+
+```yml
+timed rollout 30%:
+ <<: *timed_rollout_template
+ stage: timed rollout 30%
+ variables:
+ ROLLOUT_PERCENTAGE: 30
+```
+
+A [deployable application](https://gitlab.com/gl-release/timed-rollout-example) is
+available, [demonstrating configuration of timed rollouts](https://gitlab.com/gl-release/timed-rollout-example/blob/master/.gitlab-ci.yml#L86-95).
diff --git a/lib/gitlab/project_authorizations.rb b/lib/gitlab/project_authorizations.rb
index 4e5e2d4a6a9..e2271b1492c 100644
--- a/lib/gitlab/project_authorizations.rb
+++ b/lib/gitlab/project_authorizations.rb
@@ -68,7 +68,7 @@ module Gitlab
.select([namespaces[:id], members[:access_level]])
.except(:order)
- if Feature.enabled?(:share_group_with_group)
+ if Feature.enabled?(:share_group_with_group, default_enabled: true)
# Namespaces shared with any of the group
cte << Group.select([namespaces[:id], 'group_group_links.group_access AS access_level'])
.joins(join_group_group_links)
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 5f1f9c0d49f..06b9faec354 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -10227,6 +10227,9 @@ msgstr ""
msgid "Invalid server response"
msgstr ""
+msgid "Invalid start or end time format"
+msgstr ""
+
msgid "Invalid two-factor code."
msgstr ""
diff --git a/spec/frontend/error_tracking/components/error_details_spec.js b/spec/frontend/error_tracking/components/error_details_spec.js
index e19cb1fd3c1..378ef50f706 100644
--- a/spec/frontend/error_tracking/components/error_details_spec.js
+++ b/spec/frontend/error_tracking/components/error_details_spec.js
@@ -266,7 +266,7 @@ describe('ErrorDetails', () => {
});
});
- it('should display a link', () => {
+ it('should not display a link', () => {
mocks.$apollo.queries.GQLerror.loading = false;
wrapper.setData({
GQLerror: {
diff --git a/spec/frontend/registry/list/components/app_spec.js b/spec/frontend/registry/list/components/app_spec.js
index 7797f41a4b5..c2c220b2cd2 100644
--- a/spec/frontend/registry/list/components/app_spec.js
+++ b/spec/frontend/registry/list/components/app_spec.js
@@ -35,7 +35,6 @@ describe('Registry List', () => {
beforeEach(() => {
wrapper = mount(registry, {
- attachToDocument: true,
propsData,
computed: {
repos() {
@@ -61,7 +60,6 @@ describe('Registry List', () => {
describe('without data', () => {
beforeEach(() => {
wrapper = mount(registry, {
- attachToDocument: true,
propsData,
computed: {
repos() {
diff --git a/spec/frontend/registry/list/components/collapsible_container_spec.js b/spec/frontend/registry/list/components/collapsible_container_spec.js
index dda35b55af8..f969f0ba9ba 100644
--- a/spec/frontend/registry/list/components/collapsible_container_spec.js
+++ b/spec/frontend/registry/list/components/collapsible_container_spec.js
@@ -26,7 +26,6 @@ describe('collapsible registry container', () => {
...config,
store,
localVue,
- attachToDocument: true,
});
beforeEach(() => {
diff --git a/spec/frontend/registry/list/components/project_empty_state_spec.js b/spec/frontend/registry/list/components/project_empty_state_spec.js
index 0194abe6642..d29b9e47233 100644
--- a/spec/frontend/registry/list/components/project_empty_state_spec.js
+++ b/spec/frontend/registry/list/components/project_empty_state_spec.js
@@ -6,7 +6,6 @@ describe('Registry Project Empty state', () => {
beforeEach(() => {
wrapper = mount(projectEmptyState, {
- attachToDocument: true,
propsData: {
noContainersImage: 'imageUrl',
helpPagePath: 'help',
diff --git a/spec/frontend/registry/list/components/table_registry_spec.js b/spec/frontend/registry/list/components/table_registry_spec.js
index 935f93db883..b13797929dd 100644
--- a/spec/frontend/registry/list/components/table_registry_spec.js
+++ b/spec/frontend/registry/list/components/table_registry_spec.js
@@ -28,7 +28,11 @@ describe('table registry', () => {
const bulkDeletePath = 'path';
const mountWithStore = config =>
- mount(tableRegistry, { ...config, store, localVue, attachToDocument: true });
+ mount(tableRegistry, {
+ ...config,
+ store,
+ localVue,
+ });
beforeEach(() => {
store = new Vuex.Store({