Commit eb49c6f8 authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent a084b04ecb85
......@@ -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), '');
}
/**
......
......@@ -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">
......
......@@ -53,6 +53,6 @@ def group_link_params
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
......@@ -496,7 +496,7 @@ def visibility_level_allowed_by_sub_groups
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
......
......@@ -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
......
---
title: Allow to share groups with other groups
merge_request: 23185
author:
type: changed
---
title: Support dashes in LDAP group CN for sync on users first log in
merge_request: 20402
author:
type: fixed
---
title: Fix issue CSV export failing for some projects
merge_request: 23223
author:
type: fixed
......@@ -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
......
......@@ -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,
......
---
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).
......@@ -68,7 +68,7 @@ def recursive_cte
.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)
......
......@@ -10227,6 +10227,9 @@ msgstr ""
msgid "Invalid server response"
msgstr ""
msgid "Invalid start or end time format"
msgstr ""
msgid "Invalid two-factor code."
msgstr ""
......
......@@ -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: {
......
......@@ -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() {
......
......@@ -26,7 +26,6 @@ describe('collapsible registry container', () => {
...config,
store,
localVue,
attachToDocument: true,
});
beforeEach(() => {
......
......@@ -6,7 +6,6 @@ describe('Registry Project Empty state', () => {
beforeEach(() => {
wrapper = mount(projectEmptyState, {
attachToDocument: true,
propsData: {
noContainersImage: 'imageUrl',
helpPagePath: 'help',
......
......@@ -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({
......
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