Add latest changes from gitlab-org/gitlab@master
|
@ -106,6 +106,7 @@ linters:
|
|||
- Cop/LineBreakAfterGuardClauses
|
||||
- Cop/LineBreakAroundConditionalBlock
|
||||
- Cop/ProjectPathHelper
|
||||
- Gitlab/FeatureAvailableUsage
|
||||
- GitlabSecurity/PublicSend
|
||||
- Layout/EmptyLineAfterGuardClause
|
||||
- Layout/LeadingCommentSpace
|
||||
|
|
|
@ -3580,3 +3580,239 @@ Gitlab/DelegatePredicateMethods:
|
|||
- 'ee/app/models/ee/namespace.rb'
|
||||
- 'ee/app/models/license.rb'
|
||||
- 'lib/gitlab/ci/trace/stream.rb'
|
||||
|
||||
# Offense count: 298
|
||||
Gitlab/FeatureAvailableUsage:
|
||||
Exclude:
|
||||
- 'app/controllers/projects/application_controller.rb'
|
||||
- 'app/graphql/types/project_type.rb'
|
||||
- 'app/helpers/events_helper.rb'
|
||||
- 'app/helpers/labels_helper.rb'
|
||||
- 'app/policies/project_policy.rb'
|
||||
- 'app/views/groups/issues.html.haml'
|
||||
- 'app/views/groups/merge_requests.html.haml'
|
||||
- 'app/views/shared/boards/_switcher.html.haml'
|
||||
- 'ee/app/controllers/concerns/description_diff_actions.rb'
|
||||
- 'ee/app/controllers/concerns/ee/boards_actions.rb'
|
||||
- 'ee/app/controllers/concerns/security_dashboards_permissions.rb'
|
||||
- 'ee/app/controllers/ee/boards/lists_controller.rb'
|
||||
- 'ee/app/controllers/ee/groups/application_controller.rb'
|
||||
- 'ee/app/controllers/ee/groups/group_members_controller.rb'
|
||||
- 'ee/app/controllers/ee/projects/autocomplete_sources_controller.rb'
|
||||
- 'ee/app/controllers/ee/projects/issues_controller.rb'
|
||||
- 'ee/app/controllers/ee/projects/security/configuration_controller.rb'
|
||||
- 'ee/app/controllers/ee/projects/settings/ci_cd_controller.rb'
|
||||
- 'ee/app/controllers/ee/projects/settings/operations_controller.rb'
|
||||
- 'ee/app/controllers/ee/projects/settings/repository_controller.rb'
|
||||
- 'ee/app/controllers/groups/analytics/application_controller.rb'
|
||||
- 'ee/app/controllers/groups/audit_events_controller.rb'
|
||||
- 'ee/app/controllers/groups/bulk_update_controller.rb'
|
||||
- 'ee/app/controllers/groups/contribution_analytics_controller.rb'
|
||||
- 'ee/app/controllers/groups/epics_controller.rb'
|
||||
- 'ee/app/controllers/groups/hooks_controller.rb'
|
||||
- 'ee/app/controllers/groups/issues_analytics_controller.rb'
|
||||
- 'ee/app/controllers/groups/iterations_controller.rb'
|
||||
- 'ee/app/controllers/projects/analytics/issues_analytics_controller.rb'
|
||||
- 'ee/app/controllers/projects/audit_events_controller.rb'
|
||||
- 'ee/app/controllers/projects/cluster_agents_controller.rb'
|
||||
- 'ee/app/controllers/projects/iterations/inherited_controller.rb'
|
||||
- 'ee/app/controllers/projects/iterations_controller.rb'
|
||||
- 'ee/app/controllers/projects/path_locks_controller.rb'
|
||||
- 'ee/app/controllers/projects/subscriptions_controller.rb'
|
||||
- 'ee/app/finders/autocomplete/vulnerabilities_autocomplete_finder.rb'
|
||||
- 'ee/app/finders/clusters/agents_finder.rb'
|
||||
- 'ee/app/finders/ee/alert_management/alerts_finder.rb'
|
||||
- 'ee/app/finders/ee/alert_management/http_integrations_finder.rb'
|
||||
- 'ee/app/finders/ee/group_projects_finder.rb'
|
||||
- 'ee/app/graphql/ee/types/group_type.rb'
|
||||
- 'ee/app/graphql/mutations/dast/profiles/create.rb'
|
||||
- 'ee/app/graphql/mutations/dast/profiles/run.rb'
|
||||
- 'ee/app/graphql/mutations/dast/profiles/update.rb'
|
||||
- 'ee/app/graphql/mutations/instance_security_dashboard/remove_project.rb'
|
||||
- 'ee/app/graphql/resolvers/boards/epic_boards_resolver.rb'
|
||||
- 'ee/app/graphql/resolvers/clusters/agent_tokens_resolver.rb'
|
||||
- 'ee/app/graphql/resolvers/epics_resolver.rb'
|
||||
- 'ee/app/helpers/ee/analytics/navbar_helper.rb'
|
||||
- 'ee/app/helpers/ee/application_helper.rb'
|
||||
- 'ee/app/helpers/ee/boards_helper.rb'
|
||||
- 'ee/app/helpers/ee/clusters_helper.rb'
|
||||
- 'ee/app/helpers/ee/dashboard_helper.rb'
|
||||
- 'ee/app/helpers/ee/form_helper.rb'
|
||||
- 'ee/app/helpers/ee/graph_helper.rb'
|
||||
- 'ee/app/helpers/ee/groups_helper.rb'
|
||||
- 'ee/app/helpers/ee/issues_helper.rb'
|
||||
- 'ee/app/helpers/ee/lock_helper.rb'
|
||||
- 'ee/app/helpers/ee/operations_helper.rb'
|
||||
- 'ee/app/helpers/ee/projects/incidents_helper.rb'
|
||||
- 'ee/app/helpers/ee/projects_helper.rb'
|
||||
- 'ee/app/helpers/ee/releases_helper.rb'
|
||||
- 'ee/app/helpers/ee/search_helper.rb'
|
||||
- 'ee/app/helpers/ee/tree_helper.rb'
|
||||
- 'ee/app/helpers/groups/security_features_helper.rb'
|
||||
- 'ee/app/models/approval_state.rb'
|
||||
- 'ee/app/models/concerns/approvable.rb'
|
||||
- 'ee/app/models/concerns/ee/project_security_scanners_information.rb'
|
||||
- 'ee/app/models/concerns/ee/protected_ref_access.rb'
|
||||
- 'ee/app/models/concerns/has_timelogs_report.rb'
|
||||
- 'ee/app/models/concerns/insights_feature.rb'
|
||||
- 'ee/app/models/ee/board.rb'
|
||||
- 'ee/app/models/ee/ci/build.rb'
|
||||
- 'ee/app/models/ee/ci/build_dependencies.rb'
|
||||
- 'ee/app/models/ee/ci/pipeline.rb'
|
||||
- 'ee/app/models/ee/group.rb'
|
||||
- 'ee/app/models/ee/group_member.rb'
|
||||
- 'ee/app/models/ee/issue.rb'
|
||||
- 'ee/app/models/ee/list.rb'
|
||||
- 'ee/app/models/ee/merge_request.rb'
|
||||
- 'ee/app/models/ee/milestone_release.rb'
|
||||
- 'ee/app/models/ee/namespace.rb'
|
||||
- 'ee/app/models/ee/namespace_setting.rb'
|
||||
- 'ee/app/models/ee/project.rb'
|
||||
- 'ee/app/models/ee/project_ci_cd_setting.rb'
|
||||
- 'ee/app/models/namespace_statistics.rb'
|
||||
- 'ee/app/models/project_security_setting.rb'
|
||||
- 'ee/app/models/saml_provider.rb'
|
||||
- 'ee/app/policies/compliance_management/framework_policy.rb'
|
||||
- 'ee/app/policies/compliance_management/framework_policy.rb'
|
||||
- 'ee/app/policies/ee/group_policy.rb'
|
||||
- 'ee/app/policies/ee/namespace_policy.rb'
|
||||
- 'ee/app/policies/ee/project_policy.rb'
|
||||
- 'ee/app/policies/ee/protected_branch_policy.rb'
|
||||
- 'ee/app/presenters/ee/label_presenter.rb'
|
||||
- 'ee/app/presenters/epic_presenter.rb'
|
||||
- 'ee/app/presenters/merge_request_approver_presenter.rb'
|
||||
- 'ee/app/serializers/dashboard_operations_project_entity.rb'
|
||||
- 'ee/app/serializers/ee/environment_entity.rb'
|
||||
- 'ee/app/serializers/ee/evidences/release_entity.rb'
|
||||
- 'ee/app/serializers/ee/note_entity.rb'
|
||||
- 'ee/app/services/boards/epic_boards/update_service.rb'
|
||||
- 'ee/app/services/ci/audit_variable_change_service.rb'
|
||||
- 'ee/app/services/clusters/agent_tokens/create_service.rb'
|
||||
- 'ee/app/services/clusters/agents/create_service.rb'
|
||||
- 'ee/app/services/dashboard/projects/create_service.rb'
|
||||
- 'ee/app/services/dashboard/projects/list_service.rb'
|
||||
- 'ee/app/services/dast/profiles/create_service.rb'
|
||||
- 'ee/app/services/dast/profiles/update_service.rb'
|
||||
- 'ee/app/services/dast_on_demand_scans/create_service.rb'
|
||||
- 'ee/app/services/dast_site_tokens/create_service.rb'
|
||||
- 'ee/app/services/dast_site_validations/create_service.rb'
|
||||
- 'ee/app/services/dast_site_validations/revoke_service.rb'
|
||||
- 'ee/app/services/dast_site_validations/validate_service.rb'
|
||||
- 'ee/app/services/ee/alert_management/http_integrations/create_service.rb'
|
||||
- 'ee/app/services/ee/audit_event_service.rb'
|
||||
- 'ee/app/services/ee/boards/issues/list_service.rb'
|
||||
- 'ee/app/services/ee/boards/lists/create_service.rb'
|
||||
- 'ee/app/services/ee/boards/update_service.rb'
|
||||
- 'ee/app/services/ee/groups/create_service.rb'
|
||||
- 'ee/app/services/ee/ide/schemas_config_service.rb'
|
||||
- 'ee/app/services/ee/issuable_base_service.rb'
|
||||
- 'ee/app/services/ee/issue_links/create_service.rb'
|
||||
- 'ee/app/services/ee/issues/build_service.rb'
|
||||
- 'ee/app/services/ee/lfs/lock_file_service.rb'
|
||||
- 'ee/app/services/ee/lfs/unlock_file_service.rb'
|
||||
- 'ee/app/services/ee/merge_requests/approval_service.rb'
|
||||
- 'ee/app/services/ee/merge_requests/build_service.rb'
|
||||
- 'ee/app/services/ee/merge_requests/merge_base_service.rb'
|
||||
- 'ee/app/services/ee/merge_requests/refresh_service.rb'
|
||||
- 'ee/app/services/ee/merge_requests/update_service.rb'
|
||||
- 'ee/app/services/ee/projects/create_service.rb'
|
||||
- 'ee/app/services/ee/protected_branches/create_service.rb'
|
||||
- 'ee/app/services/ee/releases/create_evidence_service.rb'
|
||||
- 'ee/app/services/ee/search/group_service.rb'
|
||||
- 'ee/app/services/iterations/cadences/create_service.rb'
|
||||
- 'ee/app/services/iterations/cadences/update_service.rb'
|
||||
- 'ee/app/services/iterations/create_service.rb'
|
||||
- 'ee/app/services/iterations/update_service.rb'
|
||||
- 'ee/app/services/merge_requests/sync_report_approver_approval_rules.rb'
|
||||
- 'ee/app/services/merge_requests/update_blocks_service.rb'
|
||||
- 'ee/app/services/projects/mark_for_deletion_service.rb'
|
||||
- 'ee/app/services/quality_management/test_cases/create_service.rb'
|
||||
- 'ee/app/services/requirements_management/process_test_reports_service.rb'
|
||||
- 'ee/app/services/security/store_scans_service.rb'
|
||||
- 'ee/app/views/groups/_templates_setting.html.haml'
|
||||
- 'ee/app/views/groups/contribution_analytics/show.html.haml'
|
||||
- 'ee/app/views/groups/ee/_settings_nav.html.haml'
|
||||
- 'ee/app/views/groups/epics/index.html.haml'
|
||||
- 'ee/app/views/groups/epics/show.html.haml'
|
||||
- 'ee/app/views/groups/epics/show.html.haml'
|
||||
- 'ee/app/views/groups/hooks/index.html.haml'
|
||||
- 'ee/app/views/groups/roadmap/show.html.haml'
|
||||
- 'ee/app/views/groups/settings/_allowed_email_domain.html.haml'
|
||||
- 'ee/app/views/groups/settings/_ip_restriction.html.haml'
|
||||
- 'ee/app/views/layouts/nav/_test_cases_link.html.haml'
|
||||
- 'ee/app/views/layouts/nav/sidebar/_project_iterations_link.html.haml'
|
||||
- 'ee/app/views/projects/_merge_request_approvals_settings.html.haml'
|
||||
- 'ee/app/views/projects/_merge_request_settings.html.haml'
|
||||
- 'ee/app/views/projects/_merge_request_settings_description_text.html.haml'
|
||||
- 'ee/app/views/projects/audit_events/index.html.haml'
|
||||
- 'ee/app/views/projects/blob/_header_file_locks.html.haml'
|
||||
- 'ee/app/views/projects/issues/_related_issues.html.haml'
|
||||
- 'ee/app/views/projects/merge_requests/show.html.haml'
|
||||
- 'ee/app/views/projects/merge_requests/show.html.haml'
|
||||
- 'ee/app/views/projects/merge_requests/show.html.haml'
|
||||
- 'ee/app/views/projects/merge_requests/show.html.haml'
|
||||
- 'ee/app/views/projects/merge_requests/show.html.haml'
|
||||
- 'ee/app/views/projects/merge_requests/show.html.haml'
|
||||
- 'ee/app/views/projects/merge_requests/show.html.haml'
|
||||
- 'ee/app/views/projects/merge_requests/show.html.haml'
|
||||
- 'ee/app/views/projects/merge_requests/show.html.haml'
|
||||
- 'ee/app/views/projects/pipelines/_tabs_content.html.haml'
|
||||
- 'ee/app/views/projects/protected_branches/ee/_code_owner_approval_form.html.haml'
|
||||
- 'ee/app/views/projects/protected_branches/ee/_code_owner_approval_table.html.haml'
|
||||
- 'ee/app/views/projects/protected_branches/ee/_code_owner_approval_table_head.html.haml'
|
||||
- 'ee/app/views/projects/push_rules/_index.html.haml'
|
||||
- 'ee/app/views/projects/settings/_default_issue_template.html.haml'
|
||||
- 'ee/app/views/projects/settings/_marked_for_removal.html.haml'
|
||||
- 'ee/app/views/projects/settings/_restore.html.haml'
|
||||
- 'ee/app/views/projects/settings/ci_cd/_auto_rollback.html.haml'
|
||||
- 'ee/app/views/projects/settings/ci_cd/_pipeline_subscriptions.html.haml'
|
||||
- 'ee/app/views/projects/settings/operations/_status_page.html.haml'
|
||||
- 'ee/app/views/projects/settings/repository/_protected_branches.html.haml'
|
||||
- 'ee/app/views/projects/sidebar/_repository_locked_files.html.haml'
|
||||
- 'ee/app/views/shared/issuable/_board_create_list_dropdown.html.haml'
|
||||
- 'ee/app/views/shared/issuable/_board_create_list_dropdown.html.haml'
|
||||
- 'ee/app/views/shared/issuable/_group_bulk_update_sidebar.html.haml'
|
||||
- 'ee/app/views/shared/issuable/_iteration_select.html.haml'
|
||||
- 'ee/app/views/shared/issuable/form/_default_templates.html.haml'
|
||||
- 'ee/app/views/shared/labels/_create_label_help_text.html.haml'
|
||||
- 'ee/app/views/shared/promotions/_promote_mr_features.html.haml'
|
||||
- 'ee/app/views/shared/promotions/_promote_mr_features.html.haml'
|
||||
- 'ee/app/views/shared/promotions/_promote_repository_features.html.haml'
|
||||
- 'ee/app/views/shared/promotions/_promote_repository_features.html.haml'
|
||||
- 'ee/app/views/shared/promotions/_promote_repository_features.html.haml'
|
||||
- 'ee/app/views/shared/promotions/_promote_repository_features.html.haml'
|
||||
- 'ee/app/views/shared/promotions/_promote_repository_features.html.haml'
|
||||
- 'ee/app/views/shared/promotions/_promote_repository_features.html.haml'
|
||||
- 'ee/app/workers/analytics/code_review_metrics_worker.rb'
|
||||
- 'ee/app/workers/group_saml_group_sync_worker.rb'
|
||||
- 'ee/lib/api/external_approval_rules.rb'
|
||||
- 'ee/lib/api/helpers/epics_helpers.rb'
|
||||
- 'ee/lib/api/ldap_group_links.rb'
|
||||
- 'ee/lib/ee/api/entities/approval_state.rb'
|
||||
- 'ee/lib/ee/api/entities/board.rb'
|
||||
- 'ee/lib/ee/api/entities/group.rb'
|
||||
- 'ee/lib/ee/api/entities/issue.rb'
|
||||
- 'ee/lib/ee/api/entities/project.rb'
|
||||
- 'ee/lib/ee/api/groups.rb'
|
||||
- 'ee/lib/ee/api/helpers.rb'
|
||||
- 'ee/lib/ee/api/internal/kubernetes.rb'
|
||||
- 'ee/lib/ee/api/job_artifacts.rb'
|
||||
- 'ee/lib/ee/api/projects.rb'
|
||||
- 'ee/lib/ee/gitlab/alert_management/payload/generic.rb'
|
||||
- 'ee/lib/ee/gitlab/checks/diff_check.rb'
|
||||
- 'ee/lib/ee/gitlab/gon_helper.rb'
|
||||
- 'ee/lib/ee/gitlab/tree_summary.rb'
|
||||
- 'ee/lib/gitlab/alert_management.rb'
|
||||
- 'ee/lib/gitlab/auth/group_saml/group_lookup.rb'
|
||||
- 'ee/lib/gitlab/ci/pipeline/chain/config/content/compliance.rb'
|
||||
- 'ee/lib/gitlab/code_owners.rb'
|
||||
- 'ee/lib/gitlab/import_export/group/group_and_descendants_repo_restorer.rb'
|
||||
- 'ee/lib/gitlab/incident_management.rb'
|
||||
- 'ee/lib/gitlab/path_locks_finder.rb'
|
||||
- 'ee/lib/incident_management/incident_sla.rb'
|
||||
- 'ee/spec/models/ee/namespace_spec.rb'
|
||||
- 'ee/spec/models/instance_security_dashboard_spec.rb'
|
||||
- 'ee/spec/models/license_spec.rb'
|
||||
- 'ee/spec/models/project_spec.rb'
|
||||
- 'lib/api/helpers/related_resources_helpers.rb'
|
||||
- 'spec/models/concerns/featurable_spec.rb'
|
||||
|
|
|
@ -51,10 +51,6 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
...mapActions(['toggleBoardItem', 'setAssignees']),
|
||||
updateAssignees(data) {
|
||||
const assignees = data.issueSetAssignees?.issue?.assignees?.nodes || [];
|
||||
this.setAssignees(assignees);
|
||||
},
|
||||
handleClose() {
|
||||
this.toggleBoardItem({ boardItem: this.activeIssue, sidebarType: this.sidebarType });
|
||||
},
|
||||
|
@ -78,7 +74,7 @@ export default {
|
|||
:full-path="fullPath"
|
||||
:initial-assignees="activeIssue.assignees"
|
||||
class="assignee"
|
||||
@assignees-updated="updateAssignees"
|
||||
@assignees-updated="setAssignees"
|
||||
/>
|
||||
<board-sidebar-epic-select class="epic" />
|
||||
<div>
|
||||
|
|
|
@ -69,6 +69,7 @@ export default {
|
|||
'milestoneTitle',
|
||||
'releaseTag',
|
||||
'search',
|
||||
'myReactionEmoji',
|
||||
]);
|
||||
filterParams.not = transformNotFilters(filters);
|
||||
commit(types.SET_FILTERS, filterParams);
|
||||
|
|
|
@ -66,8 +66,8 @@ export default {
|
|||
},
|
||||
listClasses() {
|
||||
return {
|
||||
'gl-pl-7': this.nestedLevel === 1,
|
||||
'gl-pl-9': this.nestedLevel === 2,
|
||||
'gl-pl-9': this.nestedLevel === 1,
|
||||
'gl-pl-11-5': this.nestedLevel === 2,
|
||||
};
|
||||
},
|
||||
},
|
||||
|
|
|
@ -88,8 +88,8 @@ export default {
|
|||
},
|
||||
listClasses() {
|
||||
return {
|
||||
'gl-pl-7': this.nestedLevel === 1,
|
||||
'gl-pl-8': this.nestedLevel === 2,
|
||||
'gl-pl-9': this.nestedLevel === 1,
|
||||
'gl-pl-11-5': this.nestedLevel === 2,
|
||||
};
|
||||
},
|
||||
},
|
||||
|
|
|
@ -51,7 +51,7 @@ export default {
|
|||
if (!this.nestedSummary) {
|
||||
return ['gl-px-5'];
|
||||
}
|
||||
return ['gl-pl-7', 'gl-pr-5', { 'gl-bg-gray-10': this.statusIcon === ICON_WARNING }];
|
||||
return ['gl-pl-9', 'gl-pr-5', { 'gl-bg-gray-10': this.statusIcon === ICON_WARNING }];
|
||||
},
|
||||
statusIconSize() {
|
||||
if (!this.nestedSummary) {
|
||||
|
|
|
@ -24,7 +24,7 @@ export default {
|
|||
n__(
|
||||
'Reports|Failed %{count} time in %{base_branch} in the last 14 days',
|
||||
'Reports|Failed %{count} times in %{base_branch} in the last 14 days',
|
||||
this.issue.recent_failures.count,
|
||||
this.issue.recent_failures?.count,
|
||||
),
|
||||
this.issue.recent_failures,
|
||||
);
|
||||
|
@ -44,20 +44,20 @@ export default {
|
|||
<template>
|
||||
<div class="gl-display-flex gl-mt-2 gl-mb-2">
|
||||
<issue-status-icon :status="status" :status-icon-size="24" class="gl-mr-3" />
|
||||
<gl-badge
|
||||
v-if="showRecentFailures"
|
||||
variant="warning"
|
||||
class="gl-mr-2"
|
||||
data-testid="test-issue-body-recent-failures"
|
||||
>
|
||||
{{ recentFailureMessage }}
|
||||
</gl-badge>
|
||||
<gl-button
|
||||
button-text-classes="gl-white-space-normal! gl-word-break-all gl-text-left"
|
||||
variant="link"
|
||||
data-testid="test-issue-body-description"
|
||||
@click="openModal({ issue })"
|
||||
>
|
||||
<gl-badge
|
||||
v-if="showRecentFailures"
|
||||
variant="warning"
|
||||
class="gl-mr-2"
|
||||
data-testid="test-issue-body-recent-failures"
|
||||
>
|
||||
{{ recentFailureMessage }}
|
||||
</gl-badge>
|
||||
{{ issue.name }}
|
||||
</gl-button>
|
||||
</div>
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
GlDropdownItem,
|
||||
GlIcon,
|
||||
} from '@gitlab/ui';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { __, s__ } from '~/locale';
|
||||
import ModalCopyButton from '~/vue_shared/components/modal_copy_button.vue';
|
||||
import {
|
||||
|
@ -79,7 +80,7 @@ export default {
|
|||
return Object.keys(this.selectedPlatform).length > 0;
|
||||
},
|
||||
instructionsEmpty() {
|
||||
return Object.keys(this.instructions).length === 0;
|
||||
return isEmpty(this.instructions);
|
||||
},
|
||||
groupId() {
|
||||
return this.group?.id ?? '';
|
||||
|
@ -212,10 +213,7 @@ export default {
|
|||
<pre
|
||||
class="gl-bg-gray gl-flex-fill-1 gl-white-space-pre-line"
|
||||
data-testid="binary-instructions"
|
||||
>
|
||||
|
||||
{{ instructions.installInstructions }}
|
||||
</pre
|
||||
>{{ instructions.installInstructions }}</pre
|
||||
>
|
||||
<modal-copy-button
|
||||
:title="$options.i18n.copyInstructions"
|
||||
|
|
|
@ -30,9 +30,11 @@ class Admin::GroupsController < Admin::ApplicationController
|
|||
|
||||
def new
|
||||
@group = Group.new
|
||||
@group.build_admin_note
|
||||
end
|
||||
|
||||
def edit
|
||||
@group.build_admin_note unless @group.admin_note
|
||||
end
|
||||
|
||||
def create
|
||||
|
@ -49,6 +51,8 @@ class Admin::GroupsController < Admin::ApplicationController
|
|||
end
|
||||
|
||||
def update
|
||||
@group.build_admin_note unless @group.admin_note
|
||||
|
||||
if @group.update(group_params)
|
||||
redirect_to [:admin, @group], notice: _('Group was successfully updated.')
|
||||
else
|
||||
|
@ -105,7 +109,10 @@ class Admin::GroupsController < Admin::ApplicationController
|
|||
:require_two_factor_authentication,
|
||||
:two_factor_grace_period,
|
||||
:project_creation_level,
|
||||
:subgroup_creation_level
|
||||
:subgroup_creation_level,
|
||||
admin_note_attributes: [
|
||||
:note
|
||||
]
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -46,6 +46,9 @@ class Namespace < ApplicationRecord
|
|||
has_one :aggregation_schedule, class_name: 'Namespace::AggregationSchedule'
|
||||
has_one :package_setting_relation, inverse_of: :namespace, class_name: 'PackageSetting'
|
||||
|
||||
has_one :admin_note, inverse_of: :namespace
|
||||
accepts_nested_attributes_for :admin_note, update_only: true
|
||||
|
||||
validates :owner, presence: true, unless: ->(n) { n.type == "Group" }
|
||||
validates :name,
|
||||
presence: true,
|
||||
|
@ -284,8 +287,13 @@ class Namespace < ApplicationRecord
|
|||
false
|
||||
end
|
||||
|
||||
# Deprecated, use #licensed_feature_available? instead. Remove once Namespace#feature_available? isn't used anymore.
|
||||
def feature_available?(feature)
|
||||
licensed_feature_available?(feature)
|
||||
end
|
||||
|
||||
# Overridden in EE::Namespace
|
||||
def feature_available?(_feature)
|
||||
def licensed_feature_available?(_feature)
|
||||
false
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Namespace::AdminNote < ApplicationRecord
|
||||
belongs_to :namespace, inverse_of: :admin_note
|
||||
validates :namespace, presence: true
|
||||
validates :note, length: { maximum: 1000 }
|
||||
end
|
|
@ -2324,6 +2324,11 @@ class Project < ApplicationRecord
|
|||
.external_authorization_service_default_label
|
||||
end
|
||||
|
||||
# Overridden in EE::Project
|
||||
def licensed_feature_available?(_feature)
|
||||
false
|
||||
end
|
||||
|
||||
def licensed_features
|
||||
[]
|
||||
end
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
class ProjectFeature < ApplicationRecord
|
||||
include Featurable
|
||||
|
||||
# When updating this array, make sure to update rubocop/cop/gitlab/feature_available_usage.rb as well.
|
||||
FEATURES = %i[
|
||||
issues
|
||||
forking
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
= render 'shared/group_form', f: f
|
||||
= render 'shared/group_form_description', f: f
|
||||
|
||||
= render 'shared/admin/admin_note_form', f: f
|
||||
|
||||
= render_if_exists 'shared/old_repository_size_limit_setting', form: f, type: :group
|
||||
= render_if_exists 'admin/namespace_plan', f: f
|
||||
|
||||
|
|
|
@ -103,6 +103,8 @@
|
|||
%span.monospace= project.full_path + '.git'
|
||||
|
||||
.col-md-6
|
||||
= render 'shared/admin/admin_note'
|
||||
|
||||
- if can?(current_user, :admin_group_member, @group)
|
||||
.card
|
||||
.card-header
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
%legend= _('Admin notes')
|
||||
.form-group.row
|
||||
.col-sm-2.col-form-label
|
||||
= f.label :note, s_('AdminNote|Note')
|
||||
= f.label :note, s_('Admin|Note')
|
||||
.col-sm-10
|
||||
= f.text_area :note, class: 'form-control gl-form-input gl-form-textarea'
|
||||
|
|
|
@ -19,5 +19,5 @@
|
|||
type: 'group',
|
||||
reset_token_url: reset_registration_token_group_settings_ci_cd_path,
|
||||
project_path: '',
|
||||
group_path: @group.path }
|
||||
group_path: @group.full_path }
|
||||
%br
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
- if @group.admin_note.present?
|
||||
- text = @group.admin_note.note
|
||||
.card.border-info
|
||||
.card-header.bg-info.gl-text-white
|
||||
= s_('Admin|Admin notes')
|
||||
.card-body
|
||||
%p= text
|
|
@ -0,0 +1,6 @@
|
|||
.form-group.row
|
||||
= f.fields_for :admin_note do |an|
|
||||
.col-sm-2.col-form-label.gl-text-right
|
||||
= an.label :note, s_('Admin|Admin notes')
|
||||
.col-sm-10
|
||||
= an.text_area :note, class: 'form-control'
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Validate NOT NULL constraint on gitlab_subscriptions namespace_id
|
||||
merge_request: 57113
|
||||
author:
|
||||
type: other
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix updating GraphQL boards cards on assignees update
|
||||
merge_request: 57687
|
||||
author:
|
||||
type: fixed
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: Display error message when runner installation instructions modal cannot be
|
||||
loaded correctly
|
||||
merge_request: 57588
|
||||
author:
|
||||
type: fixed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Allow admin users to define admin notes on groups.
|
||||
merge_request: 47825
|
||||
author:
|
||||
type: added
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix test report merge request widget summary and issues alignment
|
||||
merge_request: 56768
|
||||
author:
|
||||
type: fixed
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CreateAdminNotes < ActiveRecord::Migration[6.0]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
DOWNTIME = false
|
||||
|
||||
def up
|
||||
create_table_with_constraints :namespace_admin_notes do |t|
|
||||
t.timestamps_with_timezone
|
||||
t.references :namespace, null: false, foreign_key: { on_delete: :cascade }
|
||||
t.text :note
|
||||
|
||||
t.text_limit :note, 1000
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
drop_table :namespace_admin_notes
|
||||
end
|
||||
end
|
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ValidateNotNullConstraintOnGitlabSubscriptionsNamespaceId < ActiveRecord::Migration[6.0]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
DOWNTIME = false
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
validate_not_null_constraint :gitlab_subscriptions, :namespace_id
|
||||
end
|
||||
|
||||
def down
|
||||
# no-op
|
||||
end
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
7c33bd30af66ebb9a837c72e2ced107f015d4a22c7b6393554a9299bf3907cc0
|
|
@ -0,0 +1 @@
|
|||
e177c2cc0b59eea54de10417445b391cea7dd308547077aea34054fac22b9e40
|
|
@ -13147,7 +13147,8 @@ CREATE TABLE gitlab_subscriptions (
|
|||
auto_renew boolean,
|
||||
seats_in_use integer DEFAULT 0 NOT NULL,
|
||||
seats_owed integer DEFAULT 0 NOT NULL,
|
||||
trial_extension_type smallint
|
||||
trial_extension_type smallint,
|
||||
CONSTRAINT check_77fea3f0e7 CHECK ((namespace_id IS NOT NULL))
|
||||
);
|
||||
|
||||
CREATE SEQUENCE gitlab_subscriptions_id_seq
|
||||
|
@ -14640,6 +14641,24 @@ CREATE SEQUENCE milestones_id_seq
|
|||
|
||||
ALTER SEQUENCE milestones_id_seq OWNED BY milestones.id;
|
||||
|
||||
CREATE TABLE namespace_admin_notes (
|
||||
id bigint NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
namespace_id bigint NOT NULL,
|
||||
note text,
|
||||
CONSTRAINT check_e9d2e71b5d CHECK ((char_length(note) <= 1000))
|
||||
);
|
||||
|
||||
CREATE SEQUENCE namespace_admin_notes_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
ALTER SEQUENCE namespace_admin_notes_id_seq OWNED BY namespace_admin_notes.id;
|
||||
|
||||
CREATE TABLE namespace_aggregation_schedules (
|
||||
namespace_id integer NOT NULL
|
||||
);
|
||||
|
@ -19510,6 +19529,8 @@ ALTER TABLE ONLY metrics_users_starred_dashboards ALTER COLUMN id SET DEFAULT ne
|
|||
|
||||
ALTER TABLE ONLY milestones ALTER COLUMN id SET DEFAULT nextval('milestones_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY namespace_admin_notes ALTER COLUMN id SET DEFAULT nextval('namespace_admin_notes_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY namespace_statistics ALTER COLUMN id SET DEFAULT nextval('namespace_statistics_id_seq'::regclass);
|
||||
|
||||
ALTER TABLE ONLY namespaces ALTER COLUMN id SET DEFAULT nextval('namespaces_id_seq'::regclass);
|
||||
|
@ -20238,9 +20259,6 @@ ALTER TABLE ONLY chat_teams
|
|||
ALTER TABLE vulnerability_scanners
|
||||
ADD CONSTRAINT check_37608c9db5 CHECK ((char_length(vendor) <= 255)) NOT VALID;
|
||||
|
||||
ALTER TABLE gitlab_subscriptions
|
||||
ADD CONSTRAINT check_77fea3f0e7 CHECK ((namespace_id IS NOT NULL)) NOT VALID;
|
||||
|
||||
ALTER TABLE sprints
|
||||
ADD CONSTRAINT check_ccd8a1eae0 CHECK ((start_date IS NOT NULL)) NOT VALID;
|
||||
|
||||
|
@ -20895,6 +20913,9 @@ ALTER TABLE ONLY milestone_releases
|
|||
ALTER TABLE ONLY milestones
|
||||
ADD CONSTRAINT milestones_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY namespace_admin_notes
|
||||
ADD CONSTRAINT namespace_admin_notes_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY namespace_aggregation_schedules
|
||||
ADD CONSTRAINT namespace_aggregation_schedules_pkey PRIMARY KEY (namespace_id);
|
||||
|
||||
|
@ -23122,6 +23143,8 @@ CREATE INDEX index_mr_metrics_on_target_project_id_merged_at_nulls_last ON merge
|
|||
|
||||
CREATE INDEX index_mr_metrics_on_target_project_id_merged_at_time_to_merge ON merge_request_metrics USING btree (target_project_id, merged_at, created_at) WHERE (merged_at > created_at);
|
||||
|
||||
CREATE INDEX index_namespace_admin_notes_on_namespace_id ON namespace_admin_notes USING btree (namespace_id);
|
||||
|
||||
CREATE UNIQUE INDEX index_namespace_aggregation_schedules_on_namespace_id ON namespace_aggregation_schedules USING btree (namespace_id);
|
||||
|
||||
CREATE UNIQUE INDEX index_namespace_root_storage_statistics_on_namespace_id ON namespace_root_storage_statistics USING btree (namespace_id);
|
||||
|
@ -25964,6 +25987,9 @@ ALTER TABLE ONLY approval_merge_request_rules_approved_approvers
|
|||
ALTER TABLE ONLY operations_feature_flags_clients
|
||||
ADD CONSTRAINT fk_rails_6650ed902c FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY namespace_admin_notes
|
||||
ADD CONSTRAINT fk_rails_666166ea7b FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY web_hook_logs
|
||||
ADD CONSTRAINT fk_rails_666826e111 FOREIGN KEY (web_hook_id) REFERENCES web_hooks(id) ON DELETE CASCADE;
|
||||
|
||||
|
|
|
@ -8,10 +8,10 @@ type: reference, api
|
|||
# DORA4 Analytics Group API **(ULTIMATE SELF)**
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/291747) in GitLab 13.9.
|
||||
> - It's [deployed behind a feature flag](../user/feature_flags.md), disabled by default.
|
||||
> - It's disabled on GitLab.com.
|
||||
> - It's not recommended for production use.
|
||||
> - To use it in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-dora4-analytics-group-api). **(ULTIMATE SELF)**
|
||||
> - [Deployed behind a feature flag](../user/feature_flags.md), disabled by default.
|
||||
> - Disabled on GitLab.com.
|
||||
> - Not recommended for production use.
|
||||
> - To use in GitLab self-managed instances, ask a GitLab administrator to [enable it](#enable-or-disable-dora4-analytics-group-api).
|
||||
|
||||
WARNING:
|
||||
This feature might not be available to you. Check the **version history** note above for details.
|
||||
|
|
|
@ -6,9 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
# Feature Flags API **(FREE)**
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9566) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.5.
|
||||
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212318) to [GitLab Starter](https://about.gitlab.com/pricing/) in 13.4.
|
||||
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212318) to [GitLab Free](https://about.gitlab.com/pricing/) in 13.5.
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9566) in GitLab Premium 12.5.
|
||||
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212318) to GitLab Free in 13.5.
|
||||
|
||||
API for accessing resources of [GitLab Feature Flags](../operations/feature_flags.md).
|
||||
|
||||
|
|
|
@ -6,9 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
# Legacy Feature Flags API **(FREE)**
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9566) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.5.
|
||||
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212318) to [GitLab Starter](https://about.gitlab.com/pricing/) in 13.4.
|
||||
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212318) to [GitLab Free](https://about.gitlab.com/pricing/) in 13.5.
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9566) in GitLab Premium 12.5.
|
||||
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/212318) to GitLab Free in 13.5.
|
||||
|
||||
WARNING:
|
||||
This API is deprecated and [scheduled for removal in GitLab 14.0](https://gitlab.com/gitlab-org/gitlab/-/issues/213369). Use [this API](feature_flags.md) instead.
|
||||
|
|
|
@ -463,7 +463,8 @@ The following GitLab features are used among others:
|
|||
|
||||
## Testing
|
||||
|
||||
For more information on documentation testing, see [Documentation testing](testing.md)
|
||||
For more information about documentation testing, see the [Documentation testing](testing.md)
|
||||
guide.
|
||||
|
||||
## Danger Bot
|
||||
|
||||
|
|
|
@ -153,6 +153,14 @@ This issue occurs when...
|
|||
The workaround is...
|
||||
```
|
||||
|
||||
For the topic title:
|
||||
|
||||
- Consider including at least a partial error message in the title.
|
||||
- Use fewer than 70 characters.
|
||||
|
||||
Remember to include the complete error message in the topics content if it is
|
||||
not complete in the title.
|
||||
|
||||
## Other information on a topic
|
||||
|
||||
Topics include other information.
|
||||
|
|
|
@ -1038,7 +1038,7 @@ To identify a high-traffic table for GitLab.com the following measures are consi
|
|||
Note that the metrics linked here are GitLab-internal only:
|
||||
|
||||
- [Read operations](https://thanos.gitlab.net/graph?g0.range_input=2h&g0.max_source_resolution=0s&g0.expr=topk(500%2C%20sum%20by%20(relname)%20(rate(pg_stat_user_tables_seq_tup_read%7Benvironment%3D%22gprd%22%7D%5B12h%5D)%20%2B%20rate(pg_stat_user_tables_idx_scan%7Benvironment%3D%22gprd%22%7D%5B12h%5D)%20%2B%20rate(pg_stat_user_tables_idx_tup_fetch%7Benvironment%3D%22gprd%22%7D%5B12h%5D)))&g0.tab=1)
|
||||
- [Number of records](https://thanos.gitlab.net/graph?g0.range_input=2h&g0.max_source_resolution=0s&g0.expr=topk(500%2C%20sum%20by%20(relname)%20(rate(pg_stat_user_tables_n_live_tup%7Benvironment%3D%22gprd%22%7D%5B12h%5D)))&g0.tab=1)
|
||||
- [Size](https://thanos.gitlab.net/graph?g0.range_input=2h&g0.max_source_resolution=0s&g0.expr=topk(500%2C%20sum%20by%20(relname)%20(rate(pg_total_relation_size_bytes%7Benvironment%3D%22gprd%22%7D%5B12h%5D)))&g0.tab=1) is greater than 10 GB
|
||||
- [Number of records](https://thanos.gitlab.net/graph?g0.range_input=2h&g0.max_source_resolution=0s&g0.expr=topk(500%2C%20max%20by%20(relname)%20(pg_stat_user_tables_n_live_tup%7Benvironment%3D%22gprd%22%7D))&g0.tab=1)
|
||||
- [Size](https://thanos.gitlab.net/graph?g0.range_input=2h&g0.max_source_resolution=0s&g0.expr=topk(500%2C%20max%20by%20(relname)%20(pg_total_relation_size_bytes%7Benvironment%3D%22gprd%22%7D))&g0.tab=1) is greater than 10 GB
|
||||
|
||||
Any table which has some high read operation compared to current [high-traffic tables](https://gitlab.com/gitlab-org/gitlab/-/blob/master/rubocop/rubocop-migrations.yml#L4) might be a good candidate.
|
||||
|
|
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 32 KiB |
|
@ -8,443 +8,316 @@ type: howto
|
|||
|
||||
# Install GitLab on Microsoft Azure **(FREE SELF)**
|
||||
|
||||
WARNING:
|
||||
This guide is deprecated and pending an update. For the time being, use the GitLab
|
||||
[image in the Azure Marketplace](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/gitlabinc1586447921813.gitlabee?tab=Overview).
|
||||
For users of the Microsoft Azure business cloud, GitLab has a pre-configured offering in
|
||||
the [Azure Marketplace](https://azuremarketplace.microsoft.com/en-us/marketplace/).
|
||||
This tutorial describes installing GitLab
|
||||
Enterprise Edition in a single Virtual Machine (VM).
|
||||
|
||||
Azure is Microsoft's business cloud and GitLab is a pre-configured offering on
|
||||
the Azure Marketplace. Hopefully, you aren't surprised to hear that Microsoft
|
||||
and Azure have embraced open source software like Ubuntu, Red Hat Enterprise Linux,
|
||||
and of course - GitLab! This means that you can spin up a pre-configured
|
||||
GitLab VM and have your very own private GitLab up and running in around 30
|
||||
minutes. Let's get started.
|
||||
## Prerequisite
|
||||
|
||||
## Getting started
|
||||
You'll need an account on Azure. Use of the following methods to obtain an account:
|
||||
|
||||
First, you'll need an account on Azure. There are three ways to do this:
|
||||
|
||||
- If your company (or you) already has an account, then you are ready to go!
|
||||
- You can also open your own Azure account for free. _At time of writing_, you get $200
|
||||
of credit to spend on Azure services for 30 days. You can use this credit to try out paid Azure
|
||||
services, exploring Microsoft's cloud for free. Even after the first 30 days, you never have to pay
|
||||
anything unless you decide to transition to paid services with a Pay-As-You-Go Azure subscription.
|
||||
This is a great way to try out Azure and cloud computing, and you can
|
||||
[read more in their comprehensive FAQ](https://azure.microsoft.com/en-us/free/free-account-faq/).
|
||||
- If you or your company already have an account with a subscription, use that account.
|
||||
If not, you can [open your own Azure account for free](https://azure.microsoft.com/en-us/free/).
|
||||
Azure's free trial gives you $200 credit to explore Azure for 30 days.
|
||||
[Read more in Azure's comprehensive FAQ](https://azure.microsoft.com/en-us/free/free-account-faq/).
|
||||
- If you have an MSDN subscription, you can activate your Azure subscriber benefits. Your MSDN
|
||||
subscription gives you recurring Azure credits every month, so why not put those credits to use and
|
||||
try out GitLab right now?
|
||||
subscription gives you recurring Azure credits every month, so you can use
|
||||
those credits and try out GitLab.
|
||||
|
||||
## Working with Azure
|
||||
## Deploy and configure GitLab
|
||||
|
||||
Once you have an Azure account, you can get started. [Log in to Azure](https://portal.azure.com)
|
||||
and the first thing you will see is the Dashboard:
|
||||
Because GitLab is already installed in a pre-configured image, all you have to do is
|
||||
create a new VM:
|
||||
|
||||
![Azure Dashboard](img/azure-dashboard.png)
|
||||
1. [Visit the GitLab offering in the marketplace](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/gitlabinc1586447921813.gitlabee?tab=Overview)
|
||||
1. Select **Get it now** and you will be presented with the **Create this app in Azure** window.
|
||||
Select **Continue**.
|
||||
1. Select one of the following options from the Azure portal:
|
||||
- Select **Create** to create a VM from scratch.
|
||||
- Select **Start with a pre-set configuration** to get started with some
|
||||
pre-configured options. You can modify these configurations at any time.
|
||||
|
||||
The Dashboard gives you a quick overview of Azure resources, and from here you can build VMs,
|
||||
create SQL Databases, author websites, and perform lots of other cloud tasks.
|
||||
|
||||
## Create New VM
|
||||
|
||||
The [Azure Marketplace](https://azuremarketplace.microsoft.com/en-us/marketplace/) is an online store for pre-configured applications and
|
||||
services which have been optimized for the cloud by software vendors like GitLab,
|
||||
available on the Azure Marketplace as pre-configured solutions. In this tutorial
|
||||
we will install GitLab Community Edition.
|
||||
|
||||
To begin creating a new GitLab VM, click on the **+ New** icon, type "GitLab" into the search
|
||||
box, and then click the **"GitLab Community Edition"** search result:
|
||||
|
||||
![Azure - New - Search for 'GitLab'](img/azure-new-search-gitlab.png)
|
||||
|
||||
A new "blade" window will pop-out, where you can read more about the **"GitLab Community Edition"**
|
||||
offering which is freely available under the MIT Expat License:
|
||||
|
||||
![Azure - New - Select 'GitLab Community Edition'](img/azure-new-gitlab-ce.png)
|
||||
|
||||
Click **"Create"** and you will be presented with the "Create virtual machine" blade:
|
||||
|
||||
![Azure - Create Virtual Machine - Basics](img/azure-create-virtual-machine-basics.png)
|
||||
|
||||
## Basics
|
||||
|
||||
The first items we need to configure are the basic settings of the underlying virtual machine:
|
||||
|
||||
1. Enter a `Name` for the VM - e.g. **"GitLab-CE"**
|
||||
1. Select a `VM disk type` - either **HDD** _(slower, lower cost)_ or **SSD** _(faster, higher cost)_
|
||||
1. Enter a `User name` - e.g. `gitlab-admin`
|
||||
1. Select an `Authentication type`, either **SSH public key** or **Password**:
|
||||
|
||||
NOTE:
|
||||
If you're unsure which authentication type to use, select **Password**
|
||||
|
||||
1. If you chose **SSH public key** - enter your `SSH public key` into the field provided
|
||||
_(read the [SSH documentation](../../ssh/README.md) to learn more about how to set up SSH
|
||||
public keys)_
|
||||
1. If you chose **Password** - enter the password you wish to use _(this is the password that you
|
||||
will use later in this tutorial to [SSH](https://en.wikipedia.org/wiki/Secure_Shell) into the VM, so make sure it's a strong password/passphrase)_
|
||||
|
||||
1. Choose the appropriate `Subscription` tier for your Azure account
|
||||
1. Choose an existing `Resource Group` or create a new one - e.g. **"GitLab-CE-Azure"**
|
||||
|
||||
NOTE:
|
||||
A "Resource group" is a way to group related resources together for easier administration.
|
||||
We chose "GitLab-CE-Azure", but your resource group can have the same name as your VM.
|
||||
|
||||
1. Choose a `Location` - if you're unsure, select the default location
|
||||
|
||||
Here are the settings we've used:
|
||||
|
||||
![Azure - Create Virtual Machine - Basics Completed](img/azure-create-virtual-machine-basics-password.png)
|
||||
|
||||
Check the settings you have entered, and then click **"OK"** when you're ready to proceed.
|
||||
|
||||
## Size
|
||||
|
||||
Next, you need to choose the size of your VM - selecting features such as the number of CPU cores,
|
||||
the amount of RAM, the size of storage (and its speed), etc.
|
||||
For the sake of this guide, we'll create the VM from scratch, so
|
||||
select **Create**.
|
||||
|
||||
NOTE:
|
||||
In common with other cloud vendors, Azure operates a resource/usage pricing model, i.e.
|
||||
the more resources your VM consumes the more it will cost you to run, so make your selection
|
||||
carefully. You'll see that Azure provides an _estimated_ monthly cost beneath each VM Size to help
|
||||
guide your selection.
|
||||
|
||||
The default size - the lowest cost **"DS1_V2 Standard"** VM - meets the minimum system requirements
|
||||
to run a small GitLab environment for testing and evaluation purposes, and so we're going to go
|
||||
ahead and select this one, but please choose the size which best meets your own requirements:
|
||||
|
||||
![Azure - Create Virtual Machine - Size](img/azure-create-virtual-machine-size.png)
|
||||
|
||||
NOTE:
|
||||
Be aware that while your VM is active (known as "allocated"), it will incur
|
||||
"compute charges" which, ultimately, you will be billed for. So, even if you're using the
|
||||
free trial credits, you'll likely want to learn
|
||||
Be aware that while your VM is active (known as "allocated"), it incurs
|
||||
compute charges for which you'll be billed. Even if you're using the
|
||||
free trial credits, you'll want to know
|
||||
[how to properly shutdown an Azure VM to save money](https://build5nines.com/properly-shutdown-azure-vm-to-save-money/).
|
||||
See the [Azure pricing calculator](https://azure.microsoft.com/en-us/pricing/calculator/)
|
||||
to learn how much resources can cost.
|
||||
|
||||
Go ahead and click your chosen size, then click **"Select"** when you're ready to proceed to the
|
||||
next step.
|
||||
After you create the virtual machine, use the information in the following
|
||||
sections to configure it.
|
||||
|
||||
## Settings
|
||||
### Configure the Basics tab
|
||||
|
||||
On the next blade, you're asked to configure the Storage, Network and Extension settings.
|
||||
We've gone with the default settings as they're sufficient for test-driving GitLab, but please
|
||||
choose the settings which best meet your own requirements:
|
||||
The first items you need to configure are the basic settings of the underlying virtual machine:
|
||||
|
||||
![Azure - Create Virtual Machine - Settings](img/azure-create-virtual-machine-settings.png)
|
||||
1. Select the subscription model and a resource group (create a new one if it
|
||||
doesn't exist).
|
||||
1. Enter a name for the VM, for example `GitLab`.
|
||||
1. Select a region.
|
||||
1. In **Availability options**, select **Availability zone** and set it to `1`.
|
||||
Read more about the [availability zones](https://docs.microsoft.com/en-us/azure/virtual-machines/availability).
|
||||
1. Ensure the selected image is set to **GitLab - Gen1**.
|
||||
1. Select the VM size based on the [hardware requirements](../requirements.md#hardware-requirements).
|
||||
Because the minimum system requirements to run a GitLab environment for up to 500 users
|
||||
is covered by the `D4s_v3` size, select that option.
|
||||
1. Set the authentication type to **SSH public key**.
|
||||
1. Enter a user name or leave the one that is automatically created. This is
|
||||
the user you'll use to connect to the VM through SSH. By default, the user
|
||||
has root access.
|
||||
1. Determine if you want to provide your own SSH key or let Azure create one for you.
|
||||
Read the [SSH documentation](../../ssh/README.md) to learn more about how to set up SSH
|
||||
public keys.
|
||||
|
||||
Review the settings and then click **"OK"** when you're ready to proceed to the last step.
|
||||
Review your entered settings, and then proceed to the Disks tab.
|
||||
|
||||
## Purchase
|
||||
### Configure the Disks tab
|
||||
|
||||
The Purchase page is the last step and here you will be presented with the price per hour for your
|
||||
new VM. You'll be billed only for the VM itself (e.g. "Standard DS1 v2") because the
|
||||
**"GitLab Community Edition"** marketplace solution is free to use at 0 USD/hr:
|
||||
For the disks:
|
||||
|
||||
![Azure - Create Virtual Machine - Purchase](img/azure-create-virtual-machine-purchase.png)
|
||||
1. For the OS disk type, select **Premium SSD**.
|
||||
1. Select the default encryption.
|
||||
|
||||
NOTE:
|
||||
At this stage, you can review and modify the any of the settings you have made during all
|
||||
previous steps, just click on any of the four steps to re-open them.
|
||||
[Read more about the types of disks](https://docs.microsoft.com/en-us/azure/virtual-machines/managed-disks-overview) that Azure provides.
|
||||
|
||||
When you have read and agreed to the terms of use and are ready to proceed, click **"Purchase"**.
|
||||
Review your settings, and then proceed to the Networking tab.
|
||||
|
||||
## Deployment
|
||||
### Configure the Networking tab
|
||||
|
||||
At this point, Azure will begin deploying your new VM. The deployment process will take a few
|
||||
minutes to complete, with progress displayed on the **"Deployment"** blade:
|
||||
Use this tab to define the network connectivity for your
|
||||
virtual machine, by configuring network interface card (NIC) settings.
|
||||
You can leave them at their default settings.
|
||||
|
||||
![Azure - Create Virtual Machine - Deployment](img/azure-create-virtual-machine-deployment.png)
|
||||
Azure creates a security group by default and the VM is assigned to it.
|
||||
The GitLab image in the marketplace has the following ports open by default:
|
||||
|
||||
Once the deployment process is complete, the new VM and its associated resources will be displayed
|
||||
on the Azure Dashboard (you may need to refresh the page):
|
||||
| Port | Description |
|
||||
|------|-------------|
|
||||
| 80 | Enable the VM to respond to HTTP requests, allowing public access. |
|
||||
| 443 | Enable our VM to respond to HTTPS requests, allowing public access. |
|
||||
| 22 | Enable our VM to respond to SSH connection requests, allowing public access (with authentication) to remote terminal sessions. |
|
||||
|
||||
![Azure - Dashboard - All resources](img/azure-dashboard-running-resources.png)
|
||||
If you want to change the ports or add any rules, you can do it
|
||||
after the VM is created by going to the Networking settings in the left sidebar,
|
||||
while in the VM dashboard.
|
||||
|
||||
The new VM can also be accessed by clicking the `All resources` or `Virtual machines` icons in the
|
||||
Azure Portal sidebar navigation menu.
|
||||
### Configure the Management tab
|
||||
|
||||
## Set up a domain name
|
||||
Use this tab to configure monitoring and management options
|
||||
for your VM. You don't need to change the default settings.
|
||||
|
||||
The VM will have a public IP address (static by default), but Azure allows us to assign a friendly
|
||||
DNS name to the VM, so let's go ahead and do that.
|
||||
### Configure the Advanced tab
|
||||
|
||||
From the Dashboard, click on the **"GitLab-CE"** tile to open the management blade for the new VM.
|
||||
The public IP address that the VM uses is shown in the 'Essentials' section:
|
||||
Use this tab to add additional configuration, agents, scripts
|
||||
or applications through virtual machine extensions or `cloud-init`. You don't
|
||||
need to change the default settings.
|
||||
|
||||
![Azure - VM - Management - Public IP Address](img/azure-vm-management-public-ip.png)
|
||||
### Configure the Tags tab
|
||||
|
||||
Click on the public IP address - which should open the **"Public IP address - Configuration"** blade,
|
||||
then click on **"Configuration"** (under "Settings"). Now enter a friendly DNS name for your instance
|
||||
in the `DNS name label` field:
|
||||
Use this tab to add name/value pairs that enable you to categorize
|
||||
resources. You don't need to change the default settings.
|
||||
|
||||
![Azure - VM - Domain Name](img/azure-vm-domain-name.png)
|
||||
### Review and create the VM
|
||||
|
||||
In the screenshot above, you'll see that we've set the `DNS name label` to `gitlab-ce-test`.
|
||||
This will make our VM accessible at `gitlab-ce-test.centralus.cloudapp.azure.com`
|
||||
_(the full domain name of your own VM will be different, of course)_.
|
||||
The final tab presents you with all of your selected options,
|
||||
where you can review and modify your choices from the
|
||||
previous steps. Azure will run validation tests in the background,
|
||||
and if you provided all of the required settings, you can
|
||||
create the VM.
|
||||
|
||||
Click **"Save"** for the changes to take effect.
|
||||
After you select **Create**, if you had opted for Azure to create an SSH key pair
|
||||
for you, you'll be asked to download the private SSH key. Download the key, as you'll
|
||||
need it to SSH into the VM.
|
||||
|
||||
NOTE:
|
||||
If you want to use your own domain name, you will need to add a DNS `A` record at your
|
||||
domain registrar which points to the public IP address of your Azure VM. If you do this, you'll need
|
||||
to make sure your VM is configured to use a _static_ public IP address (i.e. not a _dynamic_ one)
|
||||
or you will have to reconfigure the DNS `A` record each time Azure reassigns your VM a new public IP
|
||||
address. Read [Public IP addresses](https://docs.microsoft.com/en-us/azure/virtual-network/public-ip-addresses) to learn more.
|
||||
After you download the key, the deployment begins.
|
||||
|
||||
## Let's open some ports
|
||||
### Finish deployment
|
||||
|
||||
At this stage you should have a running and fully operational VM. However, none of the services on
|
||||
your VM (e.g. GitLab) will be publicly accessible via the internet until you have opened up the
|
||||
necessary ports to enable access to those services.
|
||||
At this point, Azure begins to deploy your new VM. The deployment process
|
||||
takes a few minutes to complete. After it's complete, the new VM and its
|
||||
associated resources are displayed on the Azure Dashboard.
|
||||
Select **Go to resource** to visit the dashboard of the VM.
|
||||
|
||||
Ports are opened by adding _security rules_ to the **"Network security group"** (NSG) which our VM
|
||||
has been assigned to. If you followed the process above, then Azure will have automatically created
|
||||
an NSG named `GitLab-CE-nsg` and assigned the `GitLab-CE` VM to it.
|
||||
GitLab is now deployed and ready to be used. Before doing so, however,
|
||||
you need to set up the domain name and configure GitLab to use it.
|
||||
|
||||
NOTE:
|
||||
If you gave your VM a different name then the NSG automatically created by Azure will
|
||||
also have a different name - the name you have your VM, with `-nsg` appended to it.
|
||||
### Set up a domain name
|
||||
|
||||
You can navigate to the NSG settings via many different routes in the Azure Portal, but one of the
|
||||
simplest ways is to go to the Azure Dashboard, and then click on the Network Security Group listed
|
||||
in the **"All resources"** tile:
|
||||
The VM has a public IP address (static by default), but Azure allows you
|
||||
to assign a descriptive DNS name to the VM:
|
||||
|
||||
![Azure - Dashboard - All resources - Network security group](img/azure-dashboard-highlight-nsg.png)
|
||||
1. From the VM dashboard, select **Configure** under **DNS name**.
|
||||
1. Enter a descriptive DNS name for your instance in the **DNS name label** field,
|
||||
for example `gitlab-prod`. This will make the VM accessible at
|
||||
`gitlab-prod.eastus.cloudapp.azure.com`.
|
||||
1. Select **Save** for the changes to take effect.
|
||||
|
||||
With the **"Network security group"** blade open, click on **"Inbound security rules"** under
|
||||
**"Settings"**:
|
||||
Eventually, you'll want to use your own domain name. To do this, you need to add a DNS `A` record
|
||||
with your domain registrar that points to the public IP address of your Azure VM.
|
||||
You can use [Azure's DNS](https://docs.microsoft.com/en-us/azure/dns/dns-delegate-domain-azure-dns)
|
||||
or some [other registrar](https://docs.gitlab.com/omnibus/settings/dns.html).
|
||||
|
||||
![Azure - Network security group - Inbound security rules](img/azure-nsg-inbound-sec-rules-highlight.png)
|
||||
### Change the GitLab external URL
|
||||
|
||||
Next, click **"Add"**:
|
||||
GitLab uses `external_url` in its configuration file to set up the domain name.
|
||||
If you don't set this up, when you visit the Azure friendly name, you'll
|
||||
instead be redirected to the public IP.
|
||||
|
||||
![Azure - Network security group - Inbound security rules - Add](img/azure-nsg-inbound-sec-rules-add-highlight.png)
|
||||
To set up the GitLab external URL:
|
||||
|
||||
### Which ports to open?
|
||||
1. Connect to GitLab through SSH by going to **Settings > Connect** from the VM
|
||||
dashboard, and follow the instructions. Remember to sign in with the username
|
||||
and SSH key you specified when you [created the VM](#configure-the-basics-tab).
|
||||
The Azure VM domain name will be the one you
|
||||
[set up previously](#set-up-a-domain-name). If you didn't set up a domain name for
|
||||
your VM, you can use the IP address in its place.
|
||||
|
||||
Like all servers, our VM will be running many services. However, we want to open up the correct
|
||||
ports to enable public internet access to two services in particular:
|
||||
In the case of our example:
|
||||
|
||||
1. **HTTP** (port 80) - opening port 80 will enable our VM to respond to HTTP requests, allowing
|
||||
public access to the instance of GitLab running on our VM.
|
||||
1. **SSH** (port 22) - opening port 22 will enable our VM to respond to SSH connection requests,
|
||||
allowing public access (with authentication) to remote terminal sessions
|
||||
_(you'll see why we need [SSH](https://en.wikipedia.org/wiki/Secure_Shell) access to our VM [later on in this tutorial](#maintaining-your-gitlab-instance))_
|
||||
```shell
|
||||
ssh -i <private key path> gitlab-azure@gitlab-prod.eastus.cloudapp.azure.com
|
||||
```
|
||||
|
||||
### Open HTTP on Port 80
|
||||
NOTE:
|
||||
If you need to reset your credentials, read
|
||||
[how to reset SSH credentials for a user on an Azure VM](https://docs.microsoft.com/en-us/troubleshoot/azure/virtual-machines/troubleshoot-ssh-connection#reset-ssh-credentials-for-a-user).
|
||||
|
||||
In the **"Add inbound security rule"** blade, let's open port 80 so that our VM will accept HTTP
|
||||
connections:
|
||||
1. Open `/etc/gitlab/gitlab.rb` with your editor.
|
||||
1. Find `external_url` and replace it with your own domain name. For the sake
|
||||
of this example, we'll use the friendly domain name that Azure set up.
|
||||
If you use `https` in the URL, Let's Encrypt will be
|
||||
[automatically enabled](https://docs.gitlab.com/omnibus/settings/ssl.html#lets-encrypt-integration),
|
||||
and you'll have HTTPS by default:
|
||||
|
||||
![Azure - Add inbound security rules - HTTP](img/azure-add-inbound-sec-rule-http.png)
|
||||
```ruby
|
||||
external_url 'https://gitlab-prod.eastus.cloudapp.azure.com'
|
||||
```
|
||||
|
||||
1. Enter **"HTTP"** in the `Name` field
|
||||
1. Select **HTTP** from the options in the `Service` dropdown list
|
||||
1. Make sure the `Action` is set to **Allow**
|
||||
1. Click **"OK"**
|
||||
1. Find the following settings and comment them out, so that GitLab doesn't
|
||||
pick up the wrong certificates:
|
||||
|
||||
### Open SSH on Port 22
|
||||
```ruby
|
||||
# nginx['redirect_http_to_https'] = true
|
||||
# nginx['ssl_certificate'] = "/etc/gitlab/ssl/server.crt"
|
||||
# nginx['ssl_certificate_key'] = "/etc/gitlab/ssl/server.key"
|
||||
```
|
||||
|
||||
Repeat the above process, adding a second Inbound security rule to open port 22, enabling our VM to
|
||||
accept [SSH](https://en.wikipedia.org/wiki/Secure_Shell) connections:
|
||||
1. Reconfigure GitLab for the changes to take effect. Run the
|
||||
following command every time you make changes to `/etc/gitlab/gitlab.rb`:
|
||||
|
||||
![Azure - Add inbound security rules - SSH](img/azure-add-inbound-sec-rule-ssh.png)
|
||||
```shell
|
||||
sudo gitlab-ctl reconfigure
|
||||
```
|
||||
|
||||
1. Enter **"SSH"** in the `Name` field
|
||||
1. Select **SSH** from the options in the `Service` dropdown list
|
||||
1. Make sure the `Action` is set to **Allow**
|
||||
1. Click **"OK"**
|
||||
You can now visit GitLab with your browser at the new external URL.
|
||||
|
||||
It will take a moment for Azure to add each new Inbound Security Rule (and you may need to click on
|
||||
**"Inbound security rules"** to refresh the list), but once completed, you should see the two new
|
||||
rules in the list:
|
||||
### Visit GitLab for the first time
|
||||
|
||||
![Azure - Inbound security rules - List](img/azure-inbound-sec-rules-list.png)
|
||||
Use the domain name you set up earlier to visit your new GitLab instance
|
||||
in your browser. In this example, it's `https://gitlab-prod.eastus.cloudapp.azure.com`.
|
||||
|
||||
## Connecting to GitLab
|
||||
The first thing you'll see is the sign-in page. GitLab creates an admin user by default.
|
||||
The credentials are:
|
||||
|
||||
Use the domain name you set up earlier (or the public IP address) to visit your new GitLab instance
|
||||
in your browser. If everything has gone according to plan you should be presented with the
|
||||
following page, asking you to set a _new_ password for the administrator account automatically
|
||||
created by GitLab:
|
||||
- Username: `root`
|
||||
- Password: the password is automatically created, and there are [two ways to
|
||||
find it](https://docs.bitnami.com/azure/faq/get-started/find-credentials).
|
||||
|
||||
![GitLab - Change Password](img/gitlab-change-password.png)
|
||||
After signing in, be sure to immediately [change the password](../../user/profile/index.md#change-your-password).
|
||||
|
||||
Enter your _new_ password into both form fields, and then click **"Change your password"**.
|
||||
|
||||
Once you have changed the password you will be redirected to the GitLab login page. Use `root` as
|
||||
the username, enter the new password you set in the previous step, and then click **"Sign in"**:
|
||||
|
||||
![GitLab - Login](img/gitlab-login.png)
|
||||
|
||||
### Success?
|
||||
|
||||
After signing in successfully, you should see the GitLab Projects page displaying a
|
||||
**"Welcome to GitLab!"** message:
|
||||
|
||||
![GitLab - Projects Page](img/gitlab-home.png)
|
||||
|
||||
If so, you now have a working GitLab instance on your own private Azure VM. **Congratulations!**
|
||||
|
||||
## Creating your first GitLab project
|
||||
|
||||
You can skip this section if you are familiar with Git and GitLab. Otherwise, let's create our first
|
||||
project. From the Welcome page, click **"New Project"**.
|
||||
|
||||
Let's give our project a name and a description, and then accept the default values for everything
|
||||
else:
|
||||
|
||||
1. Enter **"demo"** into the `Project path` project name field
|
||||
1. Enter a `description`, e.g. **"My awesome demo project!"**
|
||||
1. Click **"Create project"**
|
||||
|
||||
![GitLab - New Project](img/gitlab-new-project.png)
|
||||
|
||||
Once the new project has been created (which should only take a moment), you'll be redirected to
|
||||
homepage for the project:
|
||||
|
||||
![GitLab - Empty Project](img/gitlab-project-home-empty.png)
|
||||
|
||||
If you scroll further down the project's home page, you'll see some basic instructions on how to
|
||||
set up a local clone of your new repository and push and pull from it:
|
||||
|
||||
![GitLab - Empty Project - Basic Instructions](img/gitlab-project-home-instructions.png)
|
||||
|
||||
**That's it! You now have your own private GitLab environment installed and running in the cloud!**
|
||||
|
||||
## Maintaining your GitLab instance
|
||||
## Maintain your GitLab instance
|
||||
|
||||
It's important to keep your GitLab environment up-to-date. The GitLab team is constantly making
|
||||
enhancements and occasionally you may need to update for security reasons. So let's review how to
|
||||
update GitLab.
|
||||
enhancements and occasionally you may need to update for security reasons. Use the information
|
||||
in this section whenever you need to update GitLab.
|
||||
|
||||
### Checking our current version
|
||||
### Check the current version
|
||||
|
||||
To check which version of GitLab we're currently running, click on the "Admin Area" link - it's the
|
||||
the wrench icon displayed in the top-right, next to the search box.
|
||||
To determine the version of GitLab you're currently running,
|
||||
go to the **{admin}** **Admin Area**, and you will find the version
|
||||
under the **Components** table.
|
||||
|
||||
In the following screenshot you can see an **"update asap"** notification message in the top-right.
|
||||
This particular message indicates that there is a newer version of GitLab available which contains
|
||||
one or more security fixes:
|
||||
If there's a newer available version of GitLab that contains one or more
|
||||
security fixes, GitLab displays an **Update asap** notification message that
|
||||
encourages you to [update](#update-gitlab).
|
||||
|
||||
![GitLab - update asap](img/gitlab-admin-area.png)
|
||||
### Update GitLab
|
||||
|
||||
Under the **"Components"** section, we can see that our VM is currently running version `8.6.5` of
|
||||
GitLab. This is the version of GitLab which was contained in the Azure Marketplace
|
||||
**"GitLab Community Edition"** offering we used to build the VM when we wrote this tutorial.
|
||||
To update GitLab to the latest version:
|
||||
|
||||
NOTE:
|
||||
The version of GitLab in your own VM instance may well be different, but the update
|
||||
process will still be the same.
|
||||
1. Connect to the VM through SSH.
|
||||
1. Update GitLab:
|
||||
|
||||
### Connect via SSH
|
||||
```shell
|
||||
sudo apt update
|
||||
sudo apt install gitlab-ee
|
||||
```
|
||||
|
||||
To perform an update, we need to connect directly to our Azure VM instance and run some commands
|
||||
from the terminal. Our Azure VM is actually a server running Linux (Ubuntu), so we'll need to
|
||||
connect to it using SSH ([Secure Shell](https://en.wikipedia.org/wiki/Secure_Shell)).
|
||||
This command updates GitLab and its associated components to the latest versions,
|
||||
and can take time to complete. You'll see various update tasks being
|
||||
completed in your terminal.
|
||||
|
||||
If you're running Windows, you'll need to connect using [PuTTY](https://www.putty.org) or an equivalent Windows SSH client.
|
||||
If you're running Linux or macOS, then you already have an SSH client installed.
|
||||
NOTE:
|
||||
If you get an error like
|
||||
`E: The repository 'https://packages.gitlab.com/gitlab/gitlab-ee/debian buster InRelease' is not signed.`,
|
||||
see the [troubleshooting section](#update-the-gpg-key-for-the-gitlab-repositories).
|
||||
|
||||
Remember to sign in with the username and password you specified when you
|
||||
[created your Azure VM](#basics).
|
||||
1. After the update process is complete, you'll see a message like the
|
||||
following:
|
||||
|
||||
If you need to reset your VM password, read
|
||||
[how to reset SSH credentials for a user on an Azure VM](https://docs.microsoft.com/en-us/troubleshoot/azure/virtual-machines/troubleshoot-ssh-connection).
|
||||
```plaintext
|
||||
Upgrade complete! If your GitLab server is misbehaving try running
|
||||
|
||||
#### SSH from the command-line
|
||||
sudo gitlab-ctl restart
|
||||
|
||||
If you're running [SSH](https://en.wikipedia.org/wiki/Secure_Shell) from the command-line (terminal), then type in the following command to
|
||||
connect to your VM, substituting `username` and `your-azure-domain-name.com` for the correct values.
|
||||
before anything else.
|
||||
```
|
||||
|
||||
Again, remember that your Azure VM domain name will be the one you
|
||||
[set up previously in the tutorial](#set-up-a-domain-name). If you didn't set up a domain name for
|
||||
your VM, you can use the IP address in its place in the following command:
|
||||
|
||||
```shell
|
||||
ssh username@your-azure-domain-name.com
|
||||
```
|
||||
|
||||
Provide your password at the prompt to authenticate.
|
||||
|
||||
#### SSH from Windows (PuTTY)
|
||||
|
||||
If you're using [PuTTY](https://www.putty.org) in Windows as your [SSH](https://en.wikipedia.org/wiki/Secure_Shell) client, then you might want to take a quick
|
||||
read on [using PuTTY in Windows](https://mediatemple.net/community/products/dv/204404604/using-ssh-in-putty-).
|
||||
|
||||
### Updating GitLab
|
||||
|
||||
After signing in by using SSH, enter the following command to update GitLab to
|
||||
the latest version:
|
||||
|
||||
```shell
|
||||
sudo apt-get update && sudo apt-get install gitlab-ce
|
||||
```
|
||||
|
||||
This command updates GitLab and its associated components to the latest versions,
|
||||
so it will take a little time to complete. You'll see various update tasks being
|
||||
completed in your SSH terminal window:
|
||||
|
||||
![GitLab updating](img/gitlab-ssh-update-in-progress.png)
|
||||
|
||||
After the update process is complete, you'll see a message like this:
|
||||
|
||||
```plaintext
|
||||
Upgrade complete! If your GitLab server is misbehaving try running
|
||||
|
||||
sudo gitlab-ctl restart
|
||||
|
||||
before anything else.
|
||||
```
|
||||
|
||||
#### Check out your updated GitLab
|
||||
|
||||
Refresh your GitLab instance in the browser and navigate to the Admin Area. You should now have an
|
||||
Refresh your GitLab instance in the browser and go to the Admin Area. You should now have an
|
||||
up-to-date GitLab instance.
|
||||
|
||||
When we wrote this tutorial our Azure VM GitLab instance was updated to the latest version at time
|
||||
of writing (`9.4.0`). You can see that the message which was previously displaying **"update asap"**
|
||||
is now showing **"up-to-date"**:
|
||||
## Next steps and further configuration
|
||||
|
||||
![GitLab up to date](img/gitlab-admin-area-9.4.0.png)
|
||||
Now that you have a functional GitLab instance, follow the
|
||||
[next steps](../index.md#next-steps) to learn what more you can do with your
|
||||
new installation.
|
||||
|
||||
## Conclusion
|
||||
## Troubleshooting
|
||||
|
||||
Naturally, we believe that GitLab is a great Git repository tool. However, GitLab is a whole lot
|
||||
more than that too. GitLab unifies issues, code review, CI and CD into a single UI, helping you to
|
||||
move faster from idea to production, and in this tutorial we showed you how quick and easy it is to
|
||||
set up and run your own instance of GitLab on Azure, Microsoft's cloud service.
|
||||
This section describes common errors you can encounter.
|
||||
|
||||
Azure is a great way to experiment with GitLab, and if you decide (as we hope) that GitLab is for
|
||||
you, you can continue to use Azure as your secure, scalable cloud provider or of course run GitLab
|
||||
on any cloud service you choose.
|
||||
### Update the GPG key for the GitLab repositories
|
||||
|
||||
## Where to next?
|
||||
NOTE:
|
||||
This is a temporary fix until the GitLab image is updated with the new
|
||||
GPG key.
|
||||
|
||||
Check out our other [Technical Articles](../../topics/index.md) or browse the [GitLab Documentation](../../README.md) to learn more about GitLab.
|
||||
The pre-configured GitLab image in Azure (provided by Bitnami) uses
|
||||
a GPG key [deprecated in April 2020](https://about.gitlab.com/blog/2020/03/30/gpg-key-for-gitlab-package-repositories-metadata-changing/).
|
||||
|
||||
### Useful links
|
||||
If you try to update the repositories, you'll get the following error:
|
||||
|
||||
- [GitLab Community Edition](https://about.gitlab.com/features/)
|
||||
- [GitLab Enterprise Edition](https://about.gitlab.com/features/#ee)
|
||||
- [Microsoft Azure](https://azure.microsoft.com/en-us/)
|
||||
- [Azure - Free Account FAQ](https://azure.microsoft.com/en-us/free/free-account-faq/)
|
||||
- [Azure - Marketplace](https://azuremarketplace.microsoft.com/en-us/marketplace/)
|
||||
- [Azure Portal](https://portal.azure.com)
|
||||
- [Azure - Pricing Calculator](https://azure.microsoft.com/en-us/pricing/calculator/)
|
||||
- [Azure - Troubleshoot SSH Connections to an Azure Linux VM](https://docs.microsoft.com/en-us/troubleshoot/azure/virtual-machines/troubleshoot-ssh-connection)
|
||||
- [Azure - Properly Shutdown an Azure VM](https://build5nines.com/properly-shutdown-azure-vm-to-save-money/)
|
||||
- [SSH](https://en.wikipedia.org/wiki/Secure_Shell), [PuTTY](https://www.putty.org) and [Using SSH in PuTTY](https://mediatemple.net/community/products/dv/204404604/using-ssh-in-putty-)
|
||||
<!-- vale gitlab.ReferenceLinks = NO -->
|
||||
|
||||
<!-- ## Troubleshooting
|
||||
```plaintext
|
||||
[ 21.023494] apt-setup[1198]: W: GPG error: https://packages.gitlab.com/gitlab/gitlab-ee/debian buster InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 3F01618A51312F3F
|
||||
[ 21.024033] apt-setup[1198]: E: The repository 'https://packages.gitlab.com/gitlab/gitlab-ee/debian buster InRelease' is not signed.
|
||||
```
|
||||
|
||||
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
|
||||
one might have when setting this up, or when something is changed, or on upgrading, it's
|
||||
important to describe those, too. Think of things that may go wrong and include them here.
|
||||
This is important to minimize requests for support and to avoid doc comments with
|
||||
questions that you know someone might ask.
|
||||
<!-- vale gitlab.ReferenceLinks = YES -->
|
||||
|
||||
Each scenario can be a third-level heading, e.g. `### Getting error message X`.
|
||||
If you have none to add when creating a doc, leave this section in place
|
||||
but commented out to help encourage others to add to it in the future. -->
|
||||
To fix this, fetch the new GPG key:
|
||||
|
||||
```shell
|
||||
sudo apt install gpg-agent
|
||||
curl "https://gitlab-org.gitlab.io/omnibus-gitlab/gitlab_new_gpg.key" --output /tmp/omnibus_gitlab_gpg.key
|
||||
sudo apt-key add /tmp/omnibus_gitlab_gpg.key
|
||||
```
|
||||
|
||||
You can now [update GitLab](#update-gitlab). For more information, read about the
|
||||
[packages signatures](https://docs.gitlab.com/omnibus/update/package_signatures.html).
|
||||
|
|
|
@ -200,7 +200,7 @@ An invoice is generated for the renewal and available for viewing or download on
|
|||
|
||||
### Seat Link
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/208832) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.9.
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/208832) in GitLab 12.9.
|
||||
|
||||
Seat Link allows GitLab Inc. to provide our GitLab self-managed customers with prorated charges for user growth throughout the year using a quarterly reconciliation process.
|
||||
|
||||
|
@ -269,7 +269,7 @@ You can view the exact JSON payload in the administration panel. To view the pay
|
|||
|
||||
#### Disable Seat Link
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/212375) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.10.
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/212375) in GitLab 12.10.
|
||||
|
||||
Seat Link is enabled by default.
|
||||
|
||||
|
|
|
@ -670,8 +670,8 @@ and stored by Docker, it is not possible for GitLab to parse this data and meet
|
|||
## Limitations
|
||||
|
||||
- Moving or renaming existing Container Registry repositories is not supported
|
||||
once you have pushed images, because the images are signed, and the
|
||||
signature includes the repository name. To move or rename a repository with a
|
||||
once you have pushed images, because the images are stored in a path that matches
|
||||
the repository path. To move or rename a repository with a
|
||||
Container Registry, you must delete all existing images.
|
||||
- Prior to GitLab 12.10, any tags that use the same image ID as the `latest` tag
|
||||
are not deleted by the cleanup policy.
|
||||
|
|
|
@ -93,7 +93,6 @@ The following table depicts the various user permission levels in a project.
|
|||
| View Code Review analytics **(STARTER)** | | ✓ | ✓ | ✓ | ✓ |
|
||||
| View Repository analytics | | ✓ | ✓ | ✓ | ✓ |
|
||||
| View Error Tracking list | | ✓ | ✓ | ✓ | ✓ |
|
||||
| Create new merge request | | ✓ | ✓ | ✓ | ✓ |
|
||||
| View metrics dashboard annotations | | ✓ | ✓ | ✓ | ✓ |
|
||||
| Archive/reopen requirements **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
|
||||
| Create/edit requirements **(ULTIMATE)** | | ✓ | ✓ | ✓ | ✓ |
|
||||
|
@ -108,6 +107,7 @@ The following table depicts the various user permission levels in a project.
|
|||
| Upload [Design Management](project/issues/design_management.md) files | | | ✓ | ✓ | ✓ |
|
||||
| Create/edit [releases](project/releases/index.md)| | | ✓ | ✓ | ✓ |
|
||||
| Delete [releases](project/releases/index.md)| | | | ✓ | ✓ |
|
||||
| Create new merge request | | | ✓ | ✓ | ✓ |
|
||||
| Create new branches | | | ✓ | ✓ | ✓ |
|
||||
| Push to non-protected branches | | | ✓ | ✓ | ✓ |
|
||||
| Force push to non-protected branches | | | ✓ | ✓ | ✓ |
|
||||
|
|
|
@ -23,8 +23,13 @@ module Gitlab
|
|||
parent_id.present? || parent.present?
|
||||
end
|
||||
|
||||
# Deprecated, use #licensed_feature_available? instead. Remove once Namespace#feature_available? isn't used anymore.
|
||||
def feature_available?(feature)
|
||||
licensed_feature_available?(feature)
|
||||
end
|
||||
|
||||
# Overridden in EE::Namespace
|
||||
def feature_available?(_feature)
|
||||
def licensed_feature_available?(_feature)
|
||||
false
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2238,9 +2238,6 @@ msgstr ""
|
|||
msgid "AdminDashboard|Error loading the statistics. Please try again"
|
||||
msgstr ""
|
||||
|
||||
msgid "AdminNote|Note"
|
||||
msgstr ""
|
||||
|
||||
msgid "AdminProjects| You’re about to permanently delete the project %{projectName}, its repository, and all related resources including issues, merge requests, etc.. Once you confirm and press %{strong_start}Delete project%{strong_end}, it cannot be undone or recovered."
|
||||
msgstr ""
|
||||
|
||||
|
@ -2676,6 +2673,12 @@ msgstr ""
|
|||
msgid "Admin|Additional users must be reviewed and approved by a system administrator. Learn more about %{help_link_start}usage caps%{help_link_end}."
|
||||
msgstr ""
|
||||
|
||||
msgid "Admin|Admin notes"
|
||||
msgstr ""
|
||||
|
||||
msgid "Admin|Note"
|
||||
msgstr ""
|
||||
|
||||
msgid "Admin|View pending user approvals"
|
||||
msgstr ""
|
||||
|
||||
|
@ -8642,6 +8645,12 @@ msgstr ""
|
|||
msgid "CorpusManagement|Fuzz testing corpus management"
|
||||
msgstr ""
|
||||
|
||||
msgid "CorpusManagement|New corpus"
|
||||
msgstr ""
|
||||
|
||||
msgid "CorpusManagement|Total Size: %{totalSize}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Could not add admins as members"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module RuboCop
|
||||
module Cop
|
||||
module Gitlab
|
||||
# Cop that checks for correct calling of #feature_available?
|
||||
class FeatureAvailableUsage < RuboCop::Cop::Cop
|
||||
OBSERVED_METHOD = :feature_available?
|
||||
LICENSED_FEATURE_LITERAL_ARG_MSG = '`feature_available?` should not be called for features that can be licensed (`%s` given), use `licensed_feature_available?(feature)` instead.'
|
||||
LICENSED_FEATURE_DYNAMIC_ARG_MSG = "`feature_available?` should not be called for features that can be licensed (`%s` isn't a literal so we cannot say if it's legit or not), using `licensed_feature_available?(feature)` may be more appropriate."
|
||||
NOT_ENOUGH_ARGS_MSG = '`feature_available?` should be called with two arguments: `feature` and `user`.'
|
||||
FEATURES = %i[
|
||||
issues
|
||||
forking
|
||||
merge_requests
|
||||
wiki
|
||||
snippets
|
||||
builds
|
||||
repository
|
||||
pages
|
||||
metrics_dashboard
|
||||
analytics
|
||||
operations
|
||||
security_and_compliance
|
||||
container_registry
|
||||
].freeze
|
||||
EE_FEATURES = %i[requirements].freeze
|
||||
ALL_FEATURES = (FEATURES + EE_FEATURES).freeze
|
||||
SPECIAL_CLASS = %w[License].freeze
|
||||
|
||||
def on_send(node)
|
||||
return unless method_name(node) == OBSERVED_METHOD
|
||||
return if caller_is_special_case?(node)
|
||||
return if feature_name(node).nil?
|
||||
return if ALL_FEATURES.include?(feature_name(node)) && args_count(node) == 2
|
||||
|
||||
if !ALL_FEATURES.include?(feature_name(node))
|
||||
add_offense(node, location: :expression, message: licensed_feature_message(node))
|
||||
elsif args_count(node) < 2
|
||||
add_offense(node, location: :expression, message: NOT_ENOUGH_ARGS_MSG)
|
||||
end
|
||||
end
|
||||
|
||||
def licensed_feature_message(node)
|
||||
message_template = dynamic_feature?(node) ? LICENSED_FEATURE_DYNAMIC_ARG_MSG : LICENSED_FEATURE_LITERAL_ARG_MSG
|
||||
|
||||
message_template % feature_arg_name(node)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def method_name(node)
|
||||
node.children[1]
|
||||
end
|
||||
|
||||
def class_caller(node)
|
||||
node.children[0]&.const_name.to_s
|
||||
end
|
||||
|
||||
def caller_is_special_case?(node)
|
||||
SPECIAL_CLASS.include?(class_caller(node))
|
||||
end
|
||||
|
||||
def feature_arg(node)
|
||||
node.children[2]
|
||||
end
|
||||
|
||||
def dynamic_feature?(node)
|
||||
feature = feature_arg(node)
|
||||
return false unless feature
|
||||
|
||||
!feature.literal?
|
||||
end
|
||||
|
||||
def feature_name(node)
|
||||
feature = feature_arg(node)
|
||||
return unless feature
|
||||
return feature.children.compact.join('.') if dynamic_feature?(node)
|
||||
return feature.value if feature.respond_to?(:value)
|
||||
|
||||
feature.type
|
||||
end
|
||||
|
||||
def feature_arg_name(node)
|
||||
feature = feature_arg(node)
|
||||
return unless feature
|
||||
return feature.children.compact.join('.') if dynamic_feature?(node)
|
||||
return feature.children[0].inspect if feature.literal?
|
||||
|
||||
feature.type
|
||||
end
|
||||
|
||||
def args_count(node)
|
||||
node.children[2..].size
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -37,6 +37,12 @@ RSpec.describe Admin::GroupsController do
|
|||
post :create, params: { group: { path: 'test', name: 'test' } }
|
||||
end.to change { NamespaceSetting.count }.by(1)
|
||||
end
|
||||
|
||||
it 'creates admin_note for group' do
|
||||
expect do
|
||||
post :create, params: { group: { path: 'test', name: 'test', admin_note_attributes: { note: 'test' } } }
|
||||
end.to change { Namespace::AdminNote.count }.by(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT #members_update' do
|
||||
|
|
|
@ -35,6 +35,7 @@ RSpec.describe 'Admin Groups' do
|
|||
expect(page).to have_field('group_path')
|
||||
expect(page).to have_field('group_visibility_level_0')
|
||||
expect(page).to have_field('description')
|
||||
expect(page).to have_field('group_admin_note_attributes_note')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -47,10 +48,12 @@ RSpec.describe 'Admin Groups' do
|
|||
path_component = 'gitlab'
|
||||
group_name = 'GitLab group name'
|
||||
group_description = 'Description of group for GitLab'
|
||||
group_admin_note = 'A note about this group by an admin'
|
||||
|
||||
fill_in 'group_path', with: path_component
|
||||
fill_in 'group_name', with: group_name
|
||||
fill_in 'group_description', with: group_description
|
||||
fill_in 'group_admin_note_attributes_note', with: group_admin_note
|
||||
click_button "Create group"
|
||||
|
||||
expect(current_path).to eq admin_group_path(Group.find_by(path: path_component))
|
||||
|
@ -61,6 +64,8 @@ RSpec.describe 'Admin Groups' do
|
|||
expect(li_texts).to match group_name
|
||||
expect(li_texts).to match path_component
|
||||
expect(li_texts).to match group_description
|
||||
p_texts = content.all('p').collect(&:text).join('/n')
|
||||
expect(p_texts).to match group_admin_note
|
||||
end
|
||||
|
||||
it 'shows the visibility level radio populated with the default value' do
|
||||
|
@ -116,6 +121,16 @@ RSpec.describe 'Admin Groups' do
|
|||
|
||||
expect(page).to have_link(group.name, href: group_path(group))
|
||||
end
|
||||
|
||||
it 'has a note if one is available' do
|
||||
group = create(:group, :private)
|
||||
note_text = 'A group administrator note'
|
||||
group.update!(admin_note_attributes: { note: note_text })
|
||||
|
||||
visit admin_group_path(group)
|
||||
|
||||
expect(page).to have_text(note_text)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'group edit' do
|
||||
|
@ -145,6 +160,36 @@ RSpec.describe 'Admin Groups' do
|
|||
|
||||
expect(name_field.value).to eq original_name
|
||||
end
|
||||
|
||||
it 'adding an admin note to group without one' do
|
||||
group = create(:group, :private)
|
||||
expect(group.admin_note).to be_nil
|
||||
|
||||
visit admin_group_edit_path(group)
|
||||
admin_note_text = 'A note by an administrator'
|
||||
|
||||
fill_in 'group_admin_note_attributes_note', with: admin_note_text
|
||||
click_button 'Save changes'
|
||||
|
||||
expect(page).to have_content(admin_note_text)
|
||||
end
|
||||
|
||||
it 'editing an existing group admin note' do
|
||||
admin_note_text = 'A note by an administrator'
|
||||
new_admin_note_text = 'A new note by an administrator'
|
||||
group = create(:group, :private)
|
||||
group.create_admin_note(note: admin_note_text)
|
||||
|
||||
visit admin_group_edit_path(group)
|
||||
|
||||
admin_note_field = find('#group_admin_note_attributes_note')
|
||||
expect(admin_note_field.value).to eq(admin_note_text)
|
||||
|
||||
fill_in 'group_admin_note_attributes_note', with: new_admin_note_text
|
||||
click_button 'Save changes'
|
||||
|
||||
expect(page).to have_content(new_admin_note_text)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'add user into a group', :js do
|
||||
|
|
|
@ -17,8 +17,6 @@ RSpec.describe 'Project issue boards sidebar assignee', :js do
|
|||
let(:card) { find('.board:nth-child(2)').first('.board-card') }
|
||||
|
||||
before do
|
||||
stub_feature_flags(graphql_board_lists: false)
|
||||
|
||||
project.add_maintainer(user)
|
||||
|
||||
sign_in(user)
|
||||
|
|
|
@ -52,7 +52,7 @@ describe('Test issue body', () => {
|
|||
});
|
||||
|
||||
it('renders issue name', () => {
|
||||
expect(findDescription().text()).toBe(failedIssue.name);
|
||||
expect(findDescription().text()).toContain(failedIssue.name);
|
||||
});
|
||||
|
||||
it('renders failed status icon', () => {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { GlAlert } from '@gitlab/ui';
|
||||
import { shallowMount, createLocalVue } from '@vue/test-utils';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import createMockApollo from 'helpers/mock_apollo_helper';
|
||||
|
@ -14,7 +15,10 @@ localVue.use(VueApollo);
|
|||
describe('RunnerInstructions component', () => {
|
||||
let wrapper;
|
||||
let fakeApollo;
|
||||
let runnerPlatformsHandler;
|
||||
let runnerSetupInstructionsHandler;
|
||||
|
||||
const findAlert = () => wrapper.findComponent(GlAlert);
|
||||
const findModalButton = () => wrapper.find('[data-testid="show-modal-button"]');
|
||||
const findPlatformButtons = () => wrapper.findAll('[data-testid="platform-button"]');
|
||||
const findArchitectureDropdownItems = () =>
|
||||
|
@ -22,10 +26,10 @@ describe('RunnerInstructions component', () => {
|
|||
const findBinaryInstructionsSection = () => wrapper.find('[data-testid="binary-instructions"]');
|
||||
const findRunnerInstructionsSection = () => wrapper.find('[data-testid="runner-instructions"]');
|
||||
|
||||
beforeEach(async () => {
|
||||
const createComponent = () => {
|
||||
const requestHandlers = [
|
||||
[getRunnerPlatforms, jest.fn().mockResolvedValue(mockGraphqlRunnerPlatforms)],
|
||||
[getRunnerSetupInstructions, jest.fn().mockResolvedValue(mockGraphqlInstructions)],
|
||||
[getRunnerPlatforms, runnerPlatformsHandler],
|
||||
[getRunnerSetupInstructions, runnerSetupInstructionsHandler],
|
||||
];
|
||||
|
||||
fakeApollo = createMockApollo(requestHandlers);
|
||||
|
@ -37,6 +41,13 @@ describe('RunnerInstructions component', () => {
|
|||
localVue,
|
||||
apolloProvider: fakeApollo,
|
||||
});
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
runnerPlatformsHandler = jest.fn().mockResolvedValue(mockGraphqlRunnerPlatforms);
|
||||
runnerSetupInstructionsHandler = jest.fn().mockResolvedValue(mockGraphqlInstructions);
|
||||
|
||||
createComponent();
|
||||
|
||||
await wrapper.vm.$nextTick();
|
||||
});
|
||||
|
@ -46,6 +57,10 @@ describe('RunnerInstructions component', () => {
|
|||
wrapper = null;
|
||||
});
|
||||
|
||||
it('should not show alert', () => {
|
||||
expect(findAlert().exists()).toBe(false);
|
||||
});
|
||||
|
||||
it('should show the "Show Runner installation instructions" button', () => {
|
||||
const button = findModalButton();
|
||||
|
||||
|
@ -110,4 +125,23 @@ describe('RunnerInstructions component', () => {
|
|||
|
||||
expect(runner.text()).toMatch(mockGraphqlInstructions.data.runnerSetup.registerInstructions);
|
||||
});
|
||||
|
||||
describe('when instructions cannot be loaded', () => {
|
||||
beforeEach(async () => {
|
||||
runnerSetupInstructionsHandler.mockRejectedValue();
|
||||
|
||||
createComponent();
|
||||
|
||||
await wrapper.vm.$nextTick();
|
||||
});
|
||||
|
||||
it('should show alert', () => {
|
||||
expect(findAlert().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('should not show instructions', () => {
|
||||
expect(findBinaryInstructionsSection().exists()).toBe(false);
|
||||
expect(findRunnerInstructionsSection().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Namespace::AdminNote, type: :model do
|
||||
let!(:namespace) { create(:namespace) }
|
||||
|
||||
describe 'associations' do
|
||||
it { is_expected.to belong_to :namespace }
|
||||
end
|
||||
|
||||
describe 'validations' do
|
||||
it { is_expected.to validate_presence_of(:namespace) }
|
||||
it { is_expected.to validate_length_of(:note).is_at_most(1000) }
|
||||
end
|
||||
end
|
|
@ -21,6 +21,7 @@ RSpec.describe Namespace do
|
|||
it { is_expected.to have_many :custom_emoji }
|
||||
it { is_expected.to have_one :package_setting_relation }
|
||||
it { is_expected.to have_one :onboarding_progress }
|
||||
it { is_expected.to have_one :admin_note }
|
||||
end
|
||||
|
||||
describe 'validations' do
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'fast_spec_helper'
|
||||
require 'rubocop'
|
||||
require 'rubocop/rspec/support'
|
||||
require_relative '../../../../rubocop/cop/gitlab/feature_available_usage'
|
||||
|
||||
RSpec.describe RuboCop::Cop::Gitlab::FeatureAvailableUsage do
|
||||
subject(:cop) { described_class.new }
|
||||
|
||||
context 'no arguments given' do
|
||||
it 'does not flag the use of Gitlab::Sourcegraph.feature_available? with no arguments' do
|
||||
expect_no_offenses('Gitlab::Sourcegraph.feature_available?')
|
||||
expect_no_offenses('subject { described_class.feature_available? }')
|
||||
end
|
||||
end
|
||||
|
||||
context 'one argument given' do
|
||||
it 'does not flag the use of License.feature_available?' do
|
||||
expect_no_offenses('License.feature_available?(:push_rules)')
|
||||
end
|
||||
|
||||
it 'flags the use with a dynamic feature as nil' do
|
||||
expect_offense(<<~SOURCE)
|
||||
feature_available?(nil)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^ `feature_available?` should not be called for features that can be licensed (`nil` given), use `licensed_feature_available?(feature)` instead.
|
||||
SOURCE
|
||||
expect_offense(<<~SOURCE)
|
||||
project.feature_available?(nil)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `feature_available?` should not be called for features that can be licensed (`nil` given), use `licensed_feature_available?(feature)` instead.
|
||||
SOURCE
|
||||
end
|
||||
|
||||
it 'flags the use with an OSS project feature' do
|
||||
expect_offense(<<~SOURCE)
|
||||
project.feature_available?(:issues)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `feature_available?` should be called with two arguments: `feature` and `user`.
|
||||
SOURCE
|
||||
expect_offense(<<~SOURCE)
|
||||
feature_available?(:issues)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^ `feature_available?` should be called with two arguments: `feature` and `user`.
|
||||
SOURCE
|
||||
end
|
||||
|
||||
it 'flags the use with a feature that is not a project feature' do
|
||||
expect_offense(<<~SOURCE)
|
||||
feature_available?(:foo)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^ `feature_available?` should not be called for features that can be licensed (`:foo` given), use `licensed_feature_available?(feature)` instead.
|
||||
SOURCE
|
||||
expect_offense(<<~SOURCE)
|
||||
project.feature_available?(:foo)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `feature_available?` should not be called for features that can be licensed (`:foo` given), use `licensed_feature_available?(feature)` instead.
|
||||
SOURCE
|
||||
expect_offense(<<~SOURCE)
|
||||
feature_available?(foo)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^ `feature_available?` should not be called for features that can be licensed (`foo` isn't a literal so we cannot say if it's legit or not), using `licensed_feature_available?(feature)` may be more appropriate.
|
||||
SOURCE
|
||||
expect_offense(<<~SOURCE)
|
||||
foo = :feature
|
||||
feature_available?(foo)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^ `feature_available?` should not be called for features that can be licensed (`foo` isn't a literal so we cannot say if it's legit or not), using `licensed_feature_available?(feature)` may be more appropriate.
|
||||
SOURCE
|
||||
end
|
||||
end
|
||||
|
||||
context 'two arguments given' do
|
||||
it 'does not flag the use with an OSS project feature' do
|
||||
expect_no_offenses('feature_available?(:issues, user)')
|
||||
expect_no_offenses('project.feature_available?(:issues, user)')
|
||||
end
|
||||
|
||||
it 'does not flag the use with an EE project feature' do
|
||||
expect_no_offenses('feature_available?(:requirements, user)')
|
||||
expect_no_offenses('project.feature_available?(:requirements, user)')
|
||||
end
|
||||
|
||||
it 'flags the use with a dynamic feature as a method call with two args' do
|
||||
expect_offense(<<~SOURCE)
|
||||
feature_available?(:foo, current_user)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `feature_available?` should not be called for features that can be licensed (`:foo` given), use `licensed_feature_available?(feature)` instead.
|
||||
SOURCE
|
||||
expect_offense(<<~SOURCE)
|
||||
project.feature_available?(:foo, current_user)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `feature_available?` should not be called for features that can be licensed (`:foo` given), use `licensed_feature_available?(feature)` instead.
|
||||
SOURCE
|
||||
expect_offense(<<~SOURCE)
|
||||
feature_available?(foo, current_user)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `feature_available?` should not be called for features that can be licensed (`foo` isn't a literal so we cannot say if it's legit or not), using `licensed_feature_available?(feature)` may be more appropriate.
|
||||
SOURCE
|
||||
expect_offense(<<~SOURCE)
|
||||
project.feature_available?(foo, current_user)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `feature_available?` should not be called for features that can be licensed (`foo` isn't a literal so we cannot say if it's legit or not), using `licensed_feature_available?(feature)` may be more appropriate.
|
||||
SOURCE
|
||||
end
|
||||
end
|
||||
end
|