Commit 0b9e04bb authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents 07a680b2 d9823db2
......@@ -33,15 +33,17 @@ class BulkCreateIntegrationService
klass.insert_all(items_to_insert, returning: [:id])
end
# rubocop: disable CodeReuse/ActiveRecord
def run_callbacks(batch)
if integration.external_issue_tracker?
batch.update_all(has_external_issue_tracker: true)
Project.where(id: batch.select(:id)).update_all(has_external_issue_tracker: true)
end
if integration.external_wiki?
batch.update_all(has_external_wiki: true)
Project.where(id: batch.select(:id)).update_all(has_external_wiki: true)
end
end
# rubocop: enable CodeReuse/ActiveRecord
def service_hash
if integration.template?
......
- add_to_breadcrumbs _("Groups"), admin_groups_path
- breadcrumb_title @group.name
- page_title @group.name, _("Groups")
- current_user_is_group_owner = @group && @group.has_owner?(current_user)
.js-remove-member-modal
%h3.page-title
......@@ -116,7 +117,7 @@
= select_tag :access_level, options_for_select(@group.access_level_roles), class: "project-access-select select2"
%hr
= button_tag _('Add users to group'), class: "gl-button btn btn-success"
= render 'shared/members/requests', membership_source: @group, requesters: @requesters, force_mobile_view: true
= render 'shared/members/requests', membership_source: @group, group: @group, requesters: @requesters, force_mobile_view: true
.card
.card-header
......@@ -127,6 +128,11 @@
= sprite_icon('pencil-square', css_class: 'gl-icon')
= _('Manage access')
%ul.content-list.group-users-list.content-list.members-list
= render partial: 'shared/members/member', collection: @members, as: :member, locals: { show_controls: false }
= render partial: 'shared/members/member',
collection: @members, as: :member,
locals: { membership_source: @group,
group: @group,
show_controls: false,
current_user_is_group_owner: current_user_is_group_owner }
.card-footer
= paginate @members, param_name: 'members_page', theme: 'gitlab'
......@@ -2,6 +2,7 @@
- breadcrumb_title @project.full_name
- page_title @project.full_name, _("Projects")
- @content_class = "admin-projects"
- current_user_is_group_owner = @group && @group.has_owner?(current_user)
.js-remove-member-modal
%h3.page-title
......@@ -183,11 +184,16 @@
= sprite_icon('pencil-square', css_class: 'gl-icon')
= _('Manage access')
%ul.content-list.members-list
= render partial: 'shared/members/member', collection: @group_members, as: :member, locals: { show_controls: false }
= render partial: 'shared/members/member',
collection: @group_members, as: :member,
locals: { membership_source: @project,
group: @group,
show_controls: false,
current_user_is_group_owner: current_user_is_group_owner }
.card-footer
= paginate @group_members, param_name: 'group_members_page', theme: 'gitlab'
= render 'shared/members/requests', membership_source: @project, requesters: @requesters, force_mobile_view: true
= render 'shared/members/requests', membership_source: @project, group: @group, requesters: @requesters, force_mobile_view: true
.card
.card-header
......@@ -199,6 +205,11 @@
= sprite_icon('pencil-square', css_class: 'gl-icon')
= _('Manage access')
%ul.content-list.project_members.members-list
= render partial: 'shared/members/member', collection: @project_members, as: :member, locals: { show_controls: false }
= render partial: 'shared/members/member',
collection: @project_members, as: :member,
locals: { membership_source: @project,
group: @group,
show_controls: false,
current_user_is_group_owner: current_user_is_group_owner }
.card-footer
= paginate @project_members, param_name: 'project_members_page', theme: 'gitlab'
......@@ -4,6 +4,7 @@
- show_access_requests = can_manage_members && @requesters.exists?
- invited_active = params[:search_invited].present? || params[:invited_members_page].present?
- vue_members_list_enabled = Feature.enabled?(:vue_group_members_list, @group)
- current_user_is_group_owner = @group && @group.has_owner?(current_user)
- form_item_label_css_class = 'label-bold gl-mr-2 gl-mb-0 gl-py-2 align-self-md-center'
......@@ -71,7 +72,11 @@
.js-group-members-list{ data: group_members_list_data_attributes(@group, @members) }
- else
%ul.content-list.members-list{ data: { qa_selector: 'members_list' } }
= render partial: 'shared/members/member', collection: @members, as: :member
= render partial: 'shared/members/member',
collection: @members, as: :member,
locals: { membership_source: @group,
group: @group,
current_user_is_group_owner: current_user_is_group_owner }
= paginate @members, theme: 'gitlab', params: { invited_members_page: nil, search_invited: nil }
- if @group.shared_with_group_links.any?
#tab-groups.tab-pane
......@@ -97,7 +102,11 @@
.js-group-invited-members-list{ data: group_members_list_data_attributes(@group, @invited_members) }
- else
%ul.content-list.members-list
= render partial: 'shared/members/member', collection: @invited_members, as: :member
= render partial: 'shared/members/member',
collection: @invited_members, as: :member,
locals: { membership_source: @group,
group: @group,
current_user_is_group_owner: current_user_is_group_owner }
= paginate @invited_members, param_name: 'invited_members_page', theme: 'gitlab', params: { page: nil }
- if show_access_requests
#tab-access-requests.tab-pane
......@@ -109,4 +118,8 @@
.js-group-access-requests-list{ data: group_members_list_data_attributes(@group, @requesters) }
- else
%ul.content-list.members-list
= render partial: 'shared/members/member', collection: @requesters, as: :member
= render partial: 'shared/members/member',
collection: @requesters, as: :member,
locals: { membership_source: @group,
group: @group,
current_user_is_group_owner: current_user_is_group_owner }
- project = local_assigns.fetch(:project)
- members = local_assigns.fetch(:members)
- group = local_assigns.fetch(:group)
- current_user_is_group_owner = group && group.has_owner?(current_user)
.card
.card-header.flex-project-members-panel
......@@ -15,4 +17,8 @@
= label_tag :sort_by, _('Sort by'), class: 'col-form-label label-bold px-2'
= render 'shared/members/sort_dropdown'
%ul.content-list.members-list{ data: { qa_selector: 'members_list' } }
= render partial: 'shared/members/member', collection: members, as: :member
= render partial: 'shared/members/member',
collection: members, as: :member,
locals: { membership_source: project,
group: group,
current_user_is_group_owner: current_user_is_group_owner }
- page_title _("Members")
- can_admin_project_members = can?(current_user, :admin_project_member, @project)
- group = @project.group
.js-remove-member-modal
.row.gl-mt-3
......@@ -32,12 +33,12 @@
- elsif @project.allowed_to_share_with_group?
.invite-group= render 'shared/members/invite_group', access_levels: ProjectGroupLink.access_options, default_access_level: ProjectGroupLink.default_access, submit_url: project_group_links_path(@project), group_link_field: 'link_group_id', group_access_field: 'link_group_access'
= render 'shared/members/requests', membership_source: @project, requesters: @requesters
= render 'shared/members/requests', membership_source: @project, group: group, requesters: @requesters
.clearfix
%h5.member.existing-title
= _("Existing members and groups")
- if @group_links.any?
= render 'projects/project_members/groups', group_links: @group_links
= render 'projects/project_members/team', project: @project, members: @project_members
= render 'projects/project_members/team', project: @project, group: group, members: @project_members
= paginate @project_members, theme: "gitlab"
......@@ -6,7 +6,7 @@
- if issuable_mr > 0
%li.issuable-mr.gl-display-none.gl-display-sm-block.has-tooltip{ title: _('Related merge requests') }
= image_tag('icon-merge-request-unmerged.svg', class: 'icon-merge-request-unmerged')
= sprite_icon('merge-request', css_class: "gl-vertical-align-middle")
= issuable_mr
- if upvotes > 0
......
......@@ -2,6 +2,9 @@
- show_controls = local_assigns.fetch(:show_controls, true)
- force_mobile_view = local_assigns.fetch(:force_mobile_view, false)
- member = local_assigns.fetch(:member)
- current_user_is_group_owner = local_assigns.fetch(:current_user_is_group_owner, false)
- membership_source = local_assigns.fetch(:membership_source)
- group = local_assigns.fetch(:group)
- user = local_assigns.fetch(:user, member.user)
- source = member.source
- override = member.try(:override)
......@@ -25,13 +28,13 @@
= render 'shared/members/its_you_badge', user: user, current_user: current_user
= render_if_exists 'shared/members/ee/license_badge', user: user, group: @group
= render_if_exists 'shared/members/ee/license_badge', user: user, group: group, current_user_is_group_owner: current_user_is_group_owner
= render 'shared/members/blocked_badge', user: user
= render 'shared/members/two_factor_auth_badge', user: user
- if source.instance_of?(Group) && source != @group
- if source.instance_of?(Group) && source != membership_source
·
= link_to source.full_name, source, class: "gl-display-inline-block inline-link"
......@@ -57,10 +60,9 @@
= link_to member.created_by.name, user_path(member.created_by)
= time_ago_with_tooltip(member.created_at)
- if show_roles
- current_resource = @project || @group
.controls.member-controls.align-items-center
= render_if_exists 'shared/members/ee/ldap_tag', can_override: member.can_override?
- if show_controls && member.source == current_resource
- if show_controls && member.source == membership_source
- if member.can_resend_invite?
= link_to sprite_icon('paper-airplane'), polymorphic_path([:resend_invite, member]),
......@@ -88,7 +90,7 @@
class: ("is-active" if member.access_level == role_id),
data: { id: role_id, el_id: dom_id(member), qa_selector: "#{role.downcase}_access_level_link" }
= render_if_exists 'shared/members/ee/revert_ldap_group_sync_option',
group: @group,
group: group,
member: member,
can_override: member.can_override?
.clearable-input.member-form-control{ class: [("d-sm-inline-block" unless force_mobile_view)] }
......@@ -125,8 +127,8 @@
= _("Delete")
- unless force_mobile_view
= sprite_icon('remove', css_class: 'd-none d-sm-block gl-icon')
= render_if_exists 'shared/members/ee/override_member_buttons', group: @group, member: member, user: user, action: :edit, can_override: member.can_override?
= render_if_exists 'shared/members/ee/override_member_buttons', group: group, member: member, user: user, action: :edit, can_override: member.can_override?
- else
%span.member-access-text.user-access-role= member.human_access
= render_if_exists 'shared/members/ee/override_member_buttons', group: @group, member: member, user: user, action: :confirm, can_override: member.can_override?
= render_if_exists 'shared/members/ee/override_member_buttons', group: group, member: member, user: user, action: :confirm, can_override: member.can_override?
- membership_source = local_assigns.fetch(:membership_source)
- requesters = local_assigns.fetch(:requesters)
- force_mobile_view = local_assigns.fetch(:force_mobile_view, false)
- group = local_assigns.fetch(:group)
- current_user_is_group_owner = group && group.has_owner?(current_user)
- return if requesters.empty?
......@@ -10,4 +12,9 @@
%strong= membership_source.name
%span.badge.badge-pill= requesters.size
%ul.content-list.members-list
= render partial: 'shared/members/member', collection: requesters, as: :member, locals: { force_mobile_view: force_mobile_view }
= render partial: 'shared/members/member',
collection: requesters, as: :member,
locals: { membership_source: membership_source,
group: group,
force_mobile_view: force_mobile_view,
current_user_is_group_owner: current_user_is_group_owner }
---
title: Updated list view MR icon
merge_request: 46059
author:
type: fixed
......@@ -45,6 +45,61 @@ To protect an environment:
The protected environment will now appear in the list of protected environments.
### Use the API to protect an environment
Alternatively, you can use the API to protect an environment:
1. Use a project with a CI that creates an environment. For example:
```yaml
stages:
- test
- deploy
test:
stage: test
script:
- 'echo "Testing Application: ${CI_PROJECT_NAME}"'
production:
stage: deploy
when: manual
script:
- 'echo "Deploying to ${CI_ENVIRONMENT_NAME}"'
environment:
name: ${CI_JOB_NAME}
```
1. Use the UI to [create a new group](../../user/group/index.md#create-a-new-group).
For example, this group is called `protected-access-group` and has the group ID `9899826`. Note
that the rest of the examples in these steps use this group.
![Group Access](img/protected_access_group_v13_6.png)
1. Use the API to add a user to the group as a reporter:
```shell
$ curl --request POST --header "PRIVATE-TOKEN: xxxxxxxxxxxx" --data "user_id=3222377&access_level=20" "https://gitlab.com/api/v4/groups/9899826/members"
{"id":3222377,"name":"Sean Carroll","username":"sfcarroll","state":"active","avatar_url":"https://assets.gitlab-static.net/uploads/-/system/user/avatar/3222377/avatar.png","web_url":"https://gitlab.com/sfcarroll","access_level":20,"created_at":"2020-10-26T17:37:50.309Z","expires_at":null}
```
1. Use the API to add the group to the project as a reporter:
```shell
$ curl --request POST --header "PRIVATE-TOKEN: xxxxxxxxxxxx" --request POST "https://gitlab.com/api/v4/projects/22034114/share?group_id=9899826&group_access=20"
{"id":1233335,"project_id":22034114,"group_id":9899826,"group_access":20,"expires_at":null}
```
1. Use the API to add the group with protected environment access:
```shell
curl --header 'Content-Type: application/json' --request POST --data '{"name": "production", "deploy_access_levels": [{"group_id": 9899826}]}' --header "PRIVATE-TOKEN: xxxxxxxxxxx" "https://gitlab.com/api/v4/projects/22034114/protected_environments"
```
The group now has access and can be seen in the UI.
## Environment access by group membership
A user may be granted access to protected environments as part of
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Adding a new Service Component to GitLab
The GitLab product is made up of several service components that run as independent system processes in communication with each other. These services can be run on the same instance, or spread across different instances. A list of the existing components can be found in the [GitLab architecture overview](architecture.md).
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# API style guide
This style guide recommends best practices for API development.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Application limits development
This document provides a development guide for contributors to add application
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Application secrets
This page is a development guide for application secrets.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Approval Rules **(STARTER)**
This document explains the backend design and flow of all related functionality
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# GitLab architecture overview
## Software delivery
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Generating chaos in a test GitLab instance
As [Werner Vogels](https://twitter.com/Werner), the CTO at Amazon Web Services, famously put it, **Everything fails, all the time**.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Code comments
Whenever you add comment to the code that is expected to be addressed at any time
......
---
stage: Create
group: Source Code
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Code Intelligence
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/1576) in GitLab 13.1.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Creating enums
When creating a new enum, it should use the database type `SMALLINT`.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Danger bot
The GitLab CI/CD pipeline includes a `danger-review` job that uses [Danger](https://github.com/danger/danger)
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Setting Multiple Values
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/32921) in GitLab 13.5.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Delete existing migrations
When removing existing migrations from the GitLab project, you have to take into account
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Deprecation guidelines
This page includes information about how and when to remove or make breaking
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
description: "Learn how GitLab docs' global navigation works and how to add new items."
---
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# GitLab Docs monthly release process
When a new GitLab version is released on the 22nd, we need to create the respective
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Guidelines for implementing Enterprise Edition features
- **Write the code and the tests.**: As with any code, EE features should have
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Dealing with email in development
## Ensuring compatibility with mailer Sidekiq jobs
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Experiment Guide
Experiments can be conducted by any GitLab team, most often the teams from the [Growth Sub-department](https://about.gitlab.com/handbook/engineering/development/growth/). Experiments are not tied to releases because they will primarily target GitLab.com.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Accessibility & Readability
## Resources
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Architecture
When you are developing a new feature that requires architectural design, or if
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Axios
We use [Axios](https://github.com/axios/axios) to communicate with the server in Vue applications and most new code.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Frontend dependencies
## Package manager
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Design Patterns
## Singletons
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Frontend Development Process
You can find more about the organization of the frontend team in the [handbook](https://about.gitlab.com/handbook/engineering/frontend/).
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# DropLab
A generic dropdown for all of your custom dropdown needs.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Ajax
`Ajax` is a droplab plugin that allows for retrieving and rendering list data from a server.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Filter
`Filter` is a plugin that allows for filtering data that has been added
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# InputSetter
`InputSetter` is a plugin that allows for updating DOM out of the scope of droplab when a list item is clicked.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Emojis
GitLab supports native Unicode emojis and falls back to image-based emojis selectively
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Frontend FAQ
## Rules of Frontend FAQ
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Icons and SVG Illustrations
We manage our own icon and illustration library in the [`gitlab-svgs`](https://gitlab.com/gitlab-org/gitlab-svgs)
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Frontend Development Guidelines
This document describes various guidelines to ensure consistency and quality
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Implementing keyboard shortcuts
We use [Mousetrap](https://craig.is/killing/mice) to implement keyboard
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Performance
## Best Practices
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Principles
These principles will ensure that your frontend contribution starts off in the right direction.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Security
## Resources
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# HTML style guide
## Buttons
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# GitLab development style guides
See below for the relevant style guides, guidelines, linting, and other information for developing GitLab.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
disqus_identifier: 'https://docs.gitlab.com/ee/development/fe_guide/style_guide_js.html'
---
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
disqus_identifier: 'https://docs.gitlab.com/ee/development/fe_guide/style_guide_scss.html'
---
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Vue.js style guide
## Linting
......@@ -400,6 +406,199 @@ Useful links:
$('span').tooltip('_fixTitle');
```
## Vue testing
Over time, a number of programming patterns and style preferences have emerged in our efforts to effectively test Vue components.
The following guide describes some of these. **These are not strict guidelines**, but rather a collection of suggestions and
good practices that aim to provide insight into how we write Vue tests at GitLab.
### Mounting a component
Typically, when testing a Vue component, the component should be "re-mounted" in every test block.
To achieve this:
1. Create a mutable `wrapper` variable inside the top-level `describe` block.
1. Mount the component using [`mount`](https://vue-test-utils.vuejs.org/api/#mount)/[`shallowMount`](https://vue-test-utils.vuejs.org/api/#shallowMount).
1. Reassign the resulting [`Wrapper`](https://vue-test-utils.vuejs.org/api/wrapper/#wrapper) instance to our `wrapper` variable.
Creating a global, mutable wrapper provides a number of advantages, including the ability to:
- Define common functions for finding components/DOM elements:
```javascript
import MyComponent from '~/path/to/my_component.vue';
describe('MyComponent', () => {
let wrapper;
// this can now be reused across tests
const findMyComponent = wrapper.find(MyComponent);
// ...
})
```
- Use a `beforeEach` block to mount the component (see [the `createComponent` factory](#the-createcomponent-factory) for more information).
- Use an `afterEach` block to destroy the component, for example, `wrapper.destroy()`.
#### The `createComponent` factory
To avoid duplicating our mounting logic, it's useful to define a `createComponent` factory function
that we can reuse in each test block. This is a closure which should reassign our `wrapper` variable
to the result of [`mount`](https://vue-test-utils.vuejs.org/api/#mount) and [`shallowMount`](https://vue-test-utils.vuejs.org/api/#shallowMount):
```javascript
import MyComponent from '~/path/to/my_component.vue';
import { shallowMount } from '@vue/test-utils';
describe('MyComponent', () => {
// Initiate the "global" wrapper variable. This will be used throughout our test:
let wrapper;
// Define our `createComponent` factory:
function createComponent() {
// Mount component and reassign `wrapper`:
wrapper = shallowMount(MyComponent);
}
it('mounts', () => {
createComponent();
expect(wrapper.exists()).toBe(true);
});
it('`isLoading` prop defaults to `false`', () => {
createComponent();
expect(wrapper.props('isLoading')).toBe(false);
});
})
```
Similarly, we could further de-duplicate our test by calling `createComponent` in a `beforeEach` block:
```javascript
import MyComponent from '~/path/to/my_component.vue';
import { shallowMount } from '@vue/test-utils';
describe('MyComponent', () => {
// Initiate the "global" wrapper variable. This will be used throughout our test
let wrapper;
// define our `createComponent` factory
function createComponent() {
// mount component and reassign `wrapper`
wrapper = shallowMount(MyComponent);
}
beforeEach(() => {
createComponent();
});
it('mounts', () => {
expect(wrapper.exists()).toBe(true);
});
it('`isLoading` prop defaults to `false`', () => {
expect(wrapper.props('isLoading')).toBe(false);
});
})
```
#### `createComponent` best practices
1. Consider using a single (or a limited number of) object arguments over many arguments.
Defining single parameters for common data like `props` is okay,
but keep in mind our [JavaScript style guide](javascript.md#limit-number-of-parameters) and stay within the parameter number limit:
```javascript
// bad
function createComponent(data, props, methods, isLoading, mountFn) { }
// good
function createComponent({ data, props, methods, stubs, isLoading } = {}) { }
// good
function createComponent(props = {}, { data, methods, stubs, isLoading } = {}) { }
```
1. If you require both `mount` _and_ `shallowMount` within the same set of tests, it
can be useful define a `mountFn` parameter for the `createComponent` factory that accepts
the mounting function (`mount` or `shallowMount`) to be used to mount the component:
```javascript
import { shallowMount } from '@vue/test-utils';
function createComponent({ mountFn = shallowMount } = {}) { }
```
### Setting component state
1. Avoid using [`setProps`](https://vue-test-utils.vuejs.org/api/wrapper/#setprops) to set
component state wherever possible. Instead, set the component's
[`propsData`](https://vue-test-utils.vuejs.org/api/options.html#propsdata) when mounting the component:
```javascript
// bad
wrapper = shallowMount(MyComponent);
wrapper.setProps({
myProp: 'my cool prop'
});
// good
wrapper = shallowMount({ propsData: { myProp: 'my cool prop' } });
```
The exception here is when you wish to test component reactivity in some way.
For example, you may want to test the output of a component when after a particular watcher has executed.
Using `setProps` to test such behavior is okay.
### Accessing component state
1. When accessing props or attributes, prefer the `wrapper.props('myProp')` syntax over `wrapper.props().myProp`:
```javascript
// good
expect(wrapper.props().myProp).toBe(true);
expect(wrapper.attributes().myAttr).toBe(true);
// better
expect(wrapper.props('myProp').toBe(true);
expect(wrapper.attributes('myAttr')).toBe(true);
```
1. When asserting multiple props, check the deep equality of the `props()` object with [`toEqual`](https://jestjs.io/docs/en/expect#toequalvalue):
```javascript
// good
expect(wrapper.props('propA')).toBe('valueA');
expect(wrapper.props('propB')).toBe('valueB');
expect(wrapper.props('propC')).toBe('valueC');
// better
expect(wrapper.props()).toEqual({
propA: 'valueA',
propB: 'valueB',
propC: 'valueC',
});
```
1. If you are only interested in some of the props, you can use [`toMatchObject`](https://jestjs.io/docs/en/expect#tomatchobjectobject).
Prefer `toMatchObject` over [`expect.objectContaining`](https://jestjs.io/docs/en/expect#expectobjectcontainingobject):
```javascript
// good
expect(wrapper.props()).toEqual(expect.objectContaining({
propA: 'valueA',
propB: 'valueB',
}));
// better
expect(wrapper.props()).toMatchObject({
propA: 'valueA',
propB: 'valueB',
});
```
## The JavaScript/Vue Accord
The goal of this accord is to make sure we are all on the same page.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Vue
To get started with Vue, read through [their documentation](https://vuejs.org/v2/guide/).
......@@ -182,10 +188,13 @@ Check this [page](vuex.md) for more details.
## Style guide
Please refer to the Vue section of our [style guide](style/vue.md)
for best practices while writing your Vue components and templates.
for best practices while writing and testing your Vue components and templates.
## Testing Vue Components
Please refer to the [Vue testing style guide](style/vue.md#vue-testing)
for guidelines and best practices for testing your Vue components.
Each Vue component has a unique output. This output is always present in the render function.
Although we can test each method of a Vue component individually, our goal must be to test the output
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Migration to Vue 3
In order to prepare for the eventual migration to Vue 3.x, we should be wary about adding the following features to the codebase:
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Vuex
When there's a clear benefit to separating state management from components (e.g. due to state complexity) we recommend using [Vuex](https://vuex.vuejs.org) over any other Flux pattern. Otherwise, feel free to manage state within the components.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Features inside the `.gitlab/` directory
We have implemented standard features that depend on configuration files in the `.gitlab/` directory. You can find `.gitlab/` in various GitLab repositories.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# File Storage in GitLab
We use the [CarrierWave](https://github.com/carrierwaveuploader/carrierwave) gem to handle file upload, store and retrieval.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Foreign Keys & Associations
When adding an association to a model you must also add a foreign key. For
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# `Gemfile` guidelines
When adding a new entry to `Gemfile` or upgrading an existing dependency pay
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Dependency Management in Go
Go takes an unusual approach to dependency management, in that it is
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Gotchas
The purpose of this guide is to document potential "gotchas" that contributors
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# GraphQL development guidelines
This guide contains all the information to successfully contribute to GitLab's
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# GraphQL pagination
## Types of pagination
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Hash Indexes
PostgreSQL supports hash indexes besides the regular B-tree
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Internationalization for GitLab
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/10669) in GitLab 9.2.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Translate GitLab to your language
The text in GitLab's user interface is in American English by default.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Merging translations from CrowdIn
CrowdIn automatically syncs the `gitlab.pot` file with the CrowdIn service, presenting
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Proofread Translations
Most translations are contributed, reviewed, and accepted by the community. We
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Translating GitLab
For managing the translation process we use [CrowdIn](https://crowdin.com).
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Import/Export development documentation
Troubleshooting and general development guidelines and tips for the [Import/Export feature](../user/project/settings/import_export.md).
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Test Import Project
For testing, we can import our own [GitLab CE](https://gitlab.com/gitlab-org/gitlab-foss/) project (named `gitlabhq` in this case) under a group named `qa-perf-testing`. Project tarballs that can be used for testing can be found over on the [performance-data](https://gitlab.com/gitlab-org/quality/performance-data) project. A different project could be used if required.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
description: "Sometimes it is necessary to store large amounts of records at once, which can be inefficient
when iterating collections and performing individual `save`s. With the arrival of `insert_all`
in Rails 6, which operates at the row level (that is, using `Hash`es), GitLab has added a set
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Setting up a development environment
The following are required to install and test the app:
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Developing against interacting components or features
It's not uncommon that a single code change can reflect and interact with multiple parts of GitLab
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Iterating Tables In Batches
Rails provides a method called `in_batches` that can be used to iterate over
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Licensed feature availability **(STARTER)**
As of GitLab 9.4, we've been supporting a simplified version of licensed
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# GitLab Licensing and Compatibility
[GitLab Community Edition](https://gitlab.com/gitlab-org/gitlab-foss/) (CE) is licensed [under the terms of the MIT License](https://gitlab.com/gitlab-org/gitlab-foss/blob/master/LICENSE). [GitLab Enterprise Edition](https://gitlab.com/gitlab-org/gitlab/) (EE) is licensed under "[The GitLab Enterprise Edition (EE) license](https://gitlab.com/gitlab-org/gitlab/blob/master/LICENSE)" wherein there are more restrictions.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Mass inserting Rails models
Setting the environment variable [`MASS_INSERT=1`](rake_tasks.md#environment-variables)
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Merge Request Performance Guidelines
Each new introduced merge request **should be performant by default**.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Migration Style Guide
When writing migrations for GitLab, you have to take into account that
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Modules with instance variables could be considered harmful
## Background
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Database case study: Namespaces storage statistics
## Introduction
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Dependencies
## Adding Dependencies
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Accessibility
Using semantic HTML plays a key role when it comes to accessibility.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Components
## Graphs
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Development
## [Components](components.md)
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Performance
## Monitoring
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Frontend Development Guidelines
This guide contains all the information to successfully contribute to GitLab's frontend.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Dirty Submit
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/21115) in GitLab 11.3.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Modules
- [DirtySubmit](dirty_submit.md)
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Merge request widget extensions
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/44616) in GitLab 13.6.
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Tips
## Clearing production compiled assets
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Newlines style guide
This style guide recommends best practices for newlines in Ruby code.
......
---
stage: Enablement
group: Distribution
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# What you should know about Omnibus packages
Most users install GitLab using our Omnibus packages. As a developer it can be
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Ordering Table Columns in PostgreSQL
For GitLab we require that columns of new tables are ordered to use the
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Performance Guidelines
This document describes various guidelines to follow to ensure good and
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# GitLab permissions guide
There are multiple types of permissions across GitLab, and when implementing
......
---
stage: none
group: unassigned
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# `DeclarativePolicy` framework
The DeclarativePolicy framework is designed to assist in performance of policy checks, and to enable ease of extension for EE. The DSL code in `app/policies` is what `Ability.allowed?` uses to check whether a particular action is allowed on a subject.
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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