Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-11-10 18:09:07 +00:00
parent ff06f859cd
commit 206b03aeae
152 changed files with 992 additions and 245 deletions

View File

@ -1 +1 @@
c6ba78e87bed03254417fe4cd52d377d88ac0b60
0926b9f8ff2215874eef0e22f750a74da5fe4321

View File

@ -372,7 +372,7 @@ group :development, :test do
gem 'gitlab-styles', '~> 5.0.0', require: false
gem 'scss_lint', '~> 0.56.0', require: false
gem 'scss_lint', '~> 0.59.0', require: false
gem 'haml_lint', '~> 0.36.0', require: false
gem 'bundler-audit', '~> 0.6.1', require: false

View File

@ -1081,9 +1081,8 @@ GEM
sawyer (0.8.2)
addressable (>= 2.3.5)
faraday (> 0.8, < 2.0)
scss_lint (0.56.0)
rake (>= 0.9, < 13)
sass (~> 3.5.3)
scss_lint (0.59.0)
sass (~> 3.5, >= 3.5.5)
securecompare (1.0.0)
seed-fu (2.3.7)
activerecord (>= 3.1)
@ -1484,7 +1483,7 @@ DEPENDENCIES
rugged (~> 0.28)
sanitize (~> 5.2.1)
sassc-rails (~> 2.1.0)
scss_lint (~> 0.56.0)
scss_lint (~> 0.59.0)
seed-fu (~> 2.3.7)
selenium-webdriver (~> 3.142)
sentry-raven (~> 3.0)

View File

@ -58,7 +58,7 @@ export default {
</gl-link>
</div>
</div>
<div class="blob-viewer" data-qa-selector="blob_viewer_content">
<div class="blob-viewer" data-qa-selector="blob_viewer_content" itemprop="about">
<gl-loading-icon v-if="loading > 0" size="md" color="dark" class="my-4 mx-auto" />
<div v-else-if="readme" ref="readme" v-html="readme.html"></div>
</div>

View File

@ -1,6 +1,7 @@
<script>
import $ from 'jquery';
import { GlButton } from '@gitlab/ui';
import { produce } from 'immer';
import { __ } from '~/locale';
import { deprecatedCreateFlash as createFlash } from '~/flash';
import MergeRequest from '~/merge_request';
@ -80,12 +81,18 @@ export default {
return;
}
const data = store.readQuery({
const sourceData = store.readQuery({
query: getStateQuery,
variables: mergeRequestQueryVariables,
});
data.project.mergeRequest.workInProgress = workInProgress;
data.project.mergeRequest.title = title;
const data = produce(sourceData, draftState => {
// eslint-disable-next-line no-param-reassign
draftState.project.mergeRequest.workInProgress = workInProgress;
// eslint-disable-next-line no-param-reassign
draftState.project.mergeRequest.title = title;
});
store.writeQuery({
query: getStateQuery,
data,

View File

@ -10,7 +10,12 @@ Vue.use(Translate);
Vue.use(VueApollo);
const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(),
defaultClient: createDefaultClient(
{},
{
assumeImmutableResults: true,
},
),
});
export default () => {

View File

@ -0,0 +1,24 @@
import * as types from './mutation_types';
import { fetchDiffData } from '../../utils';
export const setDiffEndpoint = ({ commit }, path) => commit(types.SET_DIFF_ENDPOINT, path);
export const requestDiff = ({ commit }) => commit(types.REQUEST_DIFF);
export const receiveDiffSuccess = ({ commit }, response) =>
commit(types.RECEIVE_DIFF_SUCCESS, response);
export const receiveDiffError = ({ commit }, response) =>
commit(types.RECEIVE_DIFF_ERROR, response);
export const fetchDiff = ({ state, rootState, dispatch }) => {
dispatch('requestDiff');
return fetchDiffData(rootState, state.paths.diffEndpoint, 'sast')
.then(data => {
dispatch('receiveDiffSuccess', data);
})
.catch(() => {
dispatch('receiveDiffError');
});
};

View File

@ -0,0 +1,10 @@
import state from './state';
import mutations from './mutations';
import * as actions from './actions';
export default {
namespaced: true,
state,
mutations,
actions,
};

View File

@ -0,0 +1,4 @@
export const RECEIVE_DIFF_SUCCESS = 'RECEIVE_DIFF_SUCCESS';
export const RECEIVE_DIFF_ERROR = 'RECEIVE_DIFF_ERROR';
export const REQUEST_DIFF = 'REQUEST_DIFF';
export const SET_DIFF_ENDPOINT = 'SET_DIFF_ENDPOINT';

View File

@ -0,0 +1,31 @@
import Vue from 'vue';
import * as types from './mutation_types';
import { parseDiff } from '../../utils';
export default {
[types.SET_DIFF_ENDPOINT](state, path) {
Vue.set(state.paths, 'diffEndpoint', path);
},
[types.REQUEST_DIFF](state) {
state.isLoading = true;
},
[types.RECEIVE_DIFF_SUCCESS](state, { diff, enrichData }) {
const { added, fixed, existing } = parseDiff(diff, enrichData);
const baseReportOutofDate = diff.base_report_out_of_date || false;
const hasBaseReport = Boolean(diff.base_report_created_at);
state.isLoading = false;
state.newIssues = added;
state.resolvedIssues = fixed;
state.allIssues = existing;
state.baseReportOutofDate = baseReportOutofDate;
state.hasBaseReport = hasBaseReport;
},
[types.RECEIVE_DIFF_ERROR](state) {
state.isLoading = false;
state.hasError = true;
},
};

View File

@ -0,0 +1,16 @@
export default () => ({
paths: {
head: null,
base: null,
diffEndpoint: null,
},
isLoading: false,
hasError: false,
newIssues: [],
resolvedIssues: [],
allIssues: [],
baseReportOutofDate: false,
hasBaseReport: false,
});

View File

@ -0,0 +1,70 @@
import pollUntilComplete from '~/lib/utils/poll_until_complete';
import axios from '~/lib/utils/axios_utils';
export const fetchDiffData = (state, endpoint, category) => {
const requests = [pollUntilComplete(endpoint)];
if (state.canReadVulnerabilityFeedback) {
requests.push(axios.get(state.vulnerabilityFeedbackPath, { params: { category } }));
}
return Promise.all(requests).then(([diffResponse, enrichResponse]) => ({
diff: diffResponse.data,
enrichData: enrichResponse?.data ?? [],
}));
};
/**
* Returns given vulnerability enriched with the corresponding
* feedback (`dismissal` or `issue` type)
* @param {Object} vulnerability
* @param {Array} feedback
*/
export const enrichVulnerabilityWithFeedback = (vulnerability, feedback = []) =>
feedback
.filter(fb => fb.project_fingerprint === vulnerability.project_fingerprint)
.reduce((vuln, fb) => {
if (fb.feedback_type === 'dismissal') {
return {
...vuln,
isDismissed: true,
dismissalFeedback: fb,
};
}
if (fb.feedback_type === 'issue' && fb.issue_iid) {
return {
...vuln,
hasIssue: true,
issue_feedback: fb,
};
}
if (fb.feedback_type === 'merge_request' && fb.merge_request_iid) {
return {
...vuln,
hasMergeRequest: true,
merge_request_feedback: fb,
};
}
return vuln;
}, vulnerability);
/**
* Generates the added, fixed, and existing vulnerabilities from the API report.
*
* @param {Object} diff The original reports.
* @param {Object} enrichData Feedback data to add to the reports.
* @returns {Object}
*/
export const parseDiff = (diff, enrichData) => {
const enrichVulnerability = vulnerability => ({
...enrichVulnerabilityWithFeedback(vulnerability, enrichData),
category: vulnerability.report_type,
title: vulnerability.message || vulnerability.name,
});
return {
added: diff.added ? diff.added.map(enrichVulnerability) : [],
fixed: diff.fixed ? diff.fixed.map(enrichVulnerability) : [],
existing: diff.existing ? diff.existing.map(enrichVulnerability) : [],
};
};

View File

@ -0,0 +1,24 @@
# frozen_string_literal: true
module StatAnchorsHelper
def stat_anchor_attrs(anchor)
{}.tap do |attrs|
attrs[:class] = %w(nav-link gl-display-flex gl-align-items-center) << extra_classes(anchor)
attrs[:itemprop] = anchor.itemprop if anchor.itemprop
end
end
private
def button_attribute(anchor)
"btn-#{anchor.class_modifier || 'missing'}"
end
def extra_classes(anchor)
if anchor.is_link
'stat-link'
else
"btn #{button_attribute(anchor)}"
end
end
end

View File

@ -7,6 +7,7 @@ module Ci
include Importable
include AfterCommitQueue
include Ci::HasRef
extend ::Gitlab::Utils::Override
InvalidBridgeTypeError = Class.new(StandardError)
InvalidTransitionError = Class.new(StandardError)
@ -203,8 +204,11 @@ module Ci
end
end
override :dependency_variables
def dependency_variables
[]
return [] unless ::Feature.enabled?(:ci_bridge_dependency_variables, project)
super
end
def target_revision_ref

View File

@ -571,14 +571,6 @@ module Ci
end
end
def dependency_variables
return [] if all_dependencies.empty?
Gitlab::Ci::Variables::Collection.new.concat(
Ci::JobVariable.where(job: all_dependencies).dotenv_source
)
end
def features
{ trace_sections: true }
end
@ -828,10 +820,6 @@ module Ci
Gitlab::Ci::Build::Credentials::Factory.new(self).create!
end
def all_dependencies
dependencies.all
end
def has_valid_build_dependencies?
dependencies.valid?
end
@ -994,12 +982,6 @@ module Ci
end
end
def dependencies
strong_memoize(:dependencies) do
Ci::BuildDependencies.new(self)
end
end
def build_data
@build_data ||= Gitlab::DataBuilder::Build.build(self)
end

View File

@ -103,5 +103,25 @@ module Ci
pipeline.ensure_scheduling_type!
reset
end
def dependency_variables
return [] if all_dependencies.empty?
Gitlab::Ci::Variables::Collection.new.concat(
Ci::JobVariable.where(job: all_dependencies).dotenv_source
)
end
def all_dependencies
dependencies.all
end
private
def dependencies
strong_memoize(:dependencies) do
Ci::BuildDependencies.new(self)
end
end
end
end

View File

@ -13,7 +13,7 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
presents :project
AnchorData = Struct.new(:is_link, :label, :link, :class_modifier, :icon)
AnchorData = Struct.new(:is_link, :label, :link, :class_modifier, :icon, :itemprop)
MAX_TOPICS_TO_SHOW = 3
def statistic_icon(icon_name = 'plus-square-o')
@ -277,7 +277,9 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
AnchorData.new(false,
icon + content_tag(:span, license_short_name, class: 'project-stat-value'),
license_path,
'default')
'default',
nil,
'license')
else
if current_user && can_current_user_push_to_default_branch?
AnchorData.new(false,

View File

@ -2,6 +2,7 @@
- page_description @project.description_html unless page_description
- header_title project_title(@project) unless header_title
- nav "project"
- page_itemtype 'http://schema.org/SoftwareSourceCode'
- display_subscription_banner!
- display_namespace_storage_limit_alert!
- @left_sidebar = true

View File

@ -7,17 +7,17 @@
.row.gl-mb-3
.home-panel-title-row.col-md-12.col-lg-6.d-flex
.avatar-container.rect-avatar.s64.home-panel-avatar.gl-flex-shrink-0.gl-w-11.gl-h-11.gl-mr-3.float-none
= project_icon(@project, alt: @project.name, class: 'avatar avatar-tile s64', width: 64, height: 64)
= project_icon(@project, alt: @project.name, class: 'avatar avatar-tile s64', width: 64, height: 64, itemprop: 'image')
.d-flex.flex-column.flex-wrap.align-items-baseline
.d-inline-flex.align-items-baseline
%h1.home-panel-title.gl-mt-3.gl-mb-2.gl-font-size-h1.gl-line-height-24.gl-font-weight-bold{ data: { qa_selector: 'project_name_content' } }
%h1.home-panel-title.gl-mt-3.gl-mb-2.gl-font-size-h1.gl-line-height-24.gl-font-weight-bold{ data: { qa_selector: 'project_name_content' }, itemprop: 'name' }
= @project.name
%span.visibility-icon.text-secondary.gl-ml-2.has-tooltip{ data: { container: 'body' }, title: visibility_icon_description(@project) }
= visibility_level_icon(@project.visibility_level, options: { class: 'icon' })
= render_if_exists 'compliance_management/compliance_framework/compliance_framework_badge', project: @project
.home-panel-metadata.d-flex.flex-wrap.text-secondary.gl-font-base.gl-font-weight-normal.gl-line-height-normal
- if can?(current_user, :read_project, @project)
%span.text-secondary
%span.text-secondary{ itemprop: 'identifier' }
= s_('ProjectPage|Project ID: %{project_id}') % { project_id: @project.id }
- if current_user
%span.access-request-links.gl-ml-3
@ -30,10 +30,10 @@
- project_topics_classes = "badge badge-pill badge-secondary gl-mr-2"
- explore_project_topic_path = explore_projects_path(tag: topic)
- if topic.length > max_project_topic_length
%a{ class: "#{ project_topics_classes } str-truncated-30 has-tooltip", data: { container: "body" }, title: topic, href: explore_project_topic_path }
%a{ class: "#{ project_topics_classes } str-truncated-30 has-tooltip", data: { container: "body" }, title: topic, href: explore_project_topic_path, itemprop: 'keywords' }
= topic.titleize
- else
%a{ class: project_topics_classes, href: explore_project_topic_path }
%a{ class: project_topics_classes, href: explore_project_topic_path, itemprop: 'keywords' }
= topic.titleize
- if @project.has_extra_topics?
@ -61,7 +61,7 @@
.home-panel-home-desc.mt-1
- if @project.description.present?
.home-panel-description.text-break
.home-panel-description-markdown.read-more-container
.home-panel-description-markdown.read-more-container{ itemprop: 'abstract' }
= markdown_field(@project, :description)
%button.btn.btn-blank.btn-link.js-read-more-trigger.d-lg-none{ type: "button" }
= _("Read more")

View File

@ -5,5 +5,5 @@
%ul.nav
- anchors.each do |anchor|
%li.nav-item
= link_to_if anchor.link, anchor.label, anchor.link, class: anchor.is_link ? 'nav-link stat-link d-flex align-items-center' : "nav-link btn btn-#{anchor.class_modifier || 'missing'} d-flex align-items-center" do
= link_to_if(anchor.link, anchor.label, anchor.link, stat_anchor_attrs(anchor)) do
.stat-text.d-flex.align-items-center{ class: ('btn btn-default disabled' if project_buttons) }= anchor.label

View File

@ -0,0 +1,5 @@
---
title: Add structured data for projects
merge_request: 46858
author:
type: added

View File

@ -1,8 +1,8 @@
---
name: approval_suggestions
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38992
rollout_issue_url:
milestone:
milestone: '13.3'
type: development
group:
group: group::composition analysis
default_enabled: true

View File

@ -1,8 +1,8 @@
---
name: async_commit_diff_files
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38450
rollout_issue_url:
milestone:
milestone: '13.3'
type: development
group:
group: group::source code
default_enabled: false

View File

@ -1,8 +1,8 @@
---
name: auto_devops_banner_disabled
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/14218
rollout_issue_url:
milestone:
milestone: '10.0'
type: development
group:
default_enabled: false

View File

@ -1,8 +1,8 @@
---
name: branch_list_keyset_pagination
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35819
rollout_issue_url:
milestone:
milestone: '13.2'
type: development
group:
group: group::source code
default_enabled: false

View File

@ -1,8 +1,8 @@
---
name: bulk_update_health_status
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33065
rollout_issue_url:
milestone:
milestone: '13.2'
type: development
group: group::portfolio management
default_enabled: true

View File

@ -0,0 +1,7 @@
---
name: ci_bridge_dependency_variables
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46530
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/273734
type: development
group: group::pipeline authoring
default_enabled: false

View File

@ -1,6 +1,6 @@
---
name: ci_jwt_signing_key
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34249
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/258546
milestone: '13.6'
type: development

View File

@ -1,8 +1,8 @@
---
name: ci_store_pipeline_messages
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33762
rollout_issue_url:
milestone:
milestone: '13.2'
type: development
group: group::continuous integration
default_enabled: true

View File

@ -1,7 +1,7 @@
---
name: default_merge_ref_for_diffs
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34472
rollout_issue_url:
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/276917
milestone: '13.4'
type: development
group: group::source code

View File

@ -1,8 +1,8 @@
---
name: feature_flags_legacy_read_only
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38353
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/240985
milestone: '13.7'
milestone: '13.3'
type: development
group: group::progressive delivery
default_enabled: true

View File

@ -1,8 +1,8 @@
---
name: force_autodevops_on_by_default
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/21136
rollout_issue_url:
milestone:
milestone: '11.3'
type: development
group:
group: group::configure
default_enabled: false

View File

@ -1,8 +1,8 @@
---
name: grape_gitlab_json
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36472
rollout_issue_url:
milestone:
milestone: '13.2'
type: development
group:
group: group::source code
default_enabled: true

View File

@ -1,8 +1,8 @@
---
name: graphql_logging
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/27885
rollout_issue_url:
milestone:
milestone: '12.0'
type: development
group:
default_enabled: true

View File

@ -1,8 +1,8 @@
---
name: hide_jump_to_next_unresolved_in_threads
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37873
rollout_issue_url:
milestone:
milestone: '13.3'
type: development
group:
group: group::source code
default_enabled: true

View File

@ -1,8 +1,8 @@
---
name: lfs_check
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/27451
rollout_issue_url:
milestone:
milestone: '11.11'
type: development
group:
default_enabled: true

View File

@ -1,8 +1,8 @@
---
name: merge_red_head_comments_position_on_demand
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34148
rollout_issue_url:
milestone:
milestone: '13.1'
type: development
group:
group: group::source code
default_enabled: true

View File

@ -1,8 +1,8 @@
---
name: merge_ref_auto_sync
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/29569
rollout_issue_url:
milestone:
milestone: '12.1'
type: development
group:
group: group::source code
default_enabled: true

View File

@ -1,8 +1,8 @@
---
name: merge_ref_auto_sync_lock
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/31082
rollout_issue_url:
milestone:
milestone: '12.2'
type: development
group:
group: group::source code
default_enabled: true

View File

@ -1,8 +1,8 @@
---
name: remove_legacy_github_client
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37555
rollout_issue_url:
milestone:
milestone: '13.3'
type: development
group: group::import
default_enabled: false

View File

@ -1,8 +1,8 @@
---
name: remove_resolve_note
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/45549
rollout_issue_url:
milestone:
milestone: '13.6'
type: development
group: group::source code
default_enabled: true

View File

@ -1,8 +1,8 @@
---
name: rugged_commit_tree_entry
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/25896
rollout_issue_url:
milestone:
milestone: '11.9'
type: development
group:
group: group::gitaly
default_enabled: false

View File

@ -1,8 +1,8 @@
---
name: rugged_list_commits_by_oid
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/27441
rollout_issue_url:
milestone:
milestone: '11.10'
type: development
group:
group: group::gitaly
default_enabled: false

View File

@ -1,8 +1,8 @@
---
name: snippets_binary_blob
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/37419
rollout_issue_url:
milestone:
milestone: '13.3'
type: development
group: group::editor
default_enabled: false

View File

@ -1,8 +1,8 @@
---
name: squash_options
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/33930
rollout_issue_url:
milestone:
milestone: '13.2'
type: development
group:
group: group::source code
default_enabled: true

View File

@ -1,8 +1,8 @@
---
name: sse_image_uploads
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35126
rollout_issue_url:
milestone:
milestone: '13.2'
type: development
group:
group: group::static site editor
default_enabled: false

View File

@ -1,8 +1,8 @@
---
name: webauthn
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26692
rollout_issue_url:
milestone:
milestone: '13.4'
type: development
group:
group: group::access
default_enabled: false

View File

@ -1,8 +1,8 @@
---
name: gitlab_sidekiq_enable_semi_reliable_fetcher
introduced_by_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/23854
rollout_issue_url:
milestone:
milestone: '11.6'
type: ops
group:
group: group::geo
default_enabled: true

View File

@ -11,6 +11,8 @@ GitLab offers a way to view the changes made within the GitLab server for owners
GitLab system administrators can also take advantage of the logs located on the
file system. See [the logs system documentation](logs.md) for more details.
You can generate an [Audit report](audit_reports.md) of audit events.
## Overview
**Audit Events** is a tool for GitLab owners and administrators

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

View File

@ -4,17 +4,12 @@ group: Geo
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
---
# Geo self-service framework (alpha)
# Geo self-service framework
NOTE: **Note:**
This document might be subjected to change. It's a
proposal we're working on and once the implementation is complete this
documentation will be updated. Follow progress in the
[epic](https://gitlab.com/groups/gitlab-org/-/epics/2161).
NOTE: **Note:**
The Geo self-service framework is currently in
alpha. If you need to replicate a new data type, reach out to the Geo
This document is subject to change as we continue to implement and iterate on the framework.
Follow the progress in the [epic](https://gitlab.com/groups/gitlab-org/-/epics/2161).
If you need to replicate a new data type, reach out to the Geo
team to discuss the options. You can contact them in `#g_geo` on Slack
or mention `@geo-team` in the issue or merge request.
@ -26,38 +21,40 @@ minimal effort of the engineer who created a data type.
## Nomenclature
Before digging into the API, developers need to know some Geo-specific
naming conventions.
naming conventions:
Model
: A model is an Active Model, which is how it is known in the entire
- **Model**:
A model is an Active Model, which is how it is known in the entire
Rails codebase. It usually is tied to a database table. From Geo
perspective, a model can have one or more resources.
Resource
: A resource is a piece of data that belongs to a model and is
- **Resource**:
A resource is a piece of data that belongs to a model and is
produced by a GitLab feature. It is persisted using a storage
mechanism. By default, a resource is not a replicable.
mechanism. By default, a resource is not a Geo replicable.
Data type
: Data type is how a resource is stored. Each resource should
- **Data type**:
Data type is how a resource is stored. Each resource should
fit in one of the data types Geo supports:
:- Git repository
:- Blob
:- Database
: For more detail, see [Data types](../../administration/geo/replication/datatypes.md).
- Git repository
- Blob
- Database
Geo Replicable
: A Replicable is a resource Geo wants to sync across Geo nodes. There
For more detail, see [Data types](../../administration/geo/replication/datatypes.md).
- **Geo Replicable**:
A Replicable is a resource Geo wants to sync across Geo nodes. There
is a limited set of supported data types of replicables. The effort
required to implement replication of a resource that belongs to one
of the known data types is minimal.
Geo Replicator
: A Geo Replicator is the object that knows how to replicate a
- **Geo Replicator**:
A Geo Replicator is the object that knows how to replicate a
replicable. It's responsible for:
:- Firing events (producer)
:- Consuming events (consumer)
: It's tied to the Geo Replicable data type. All replicators have a
- Firing events (producer)
- Consuming events (consumer)
It's tied to the Geo Replicable data type. All replicators have a
common interface that can be used to process (that is, produce and
consume) events. It takes care of the communication between the
primary node (where events are produced) and the secondary node
@ -65,8 +62,8 @@ Geo Replicator
Geo in their feature will use the API of replicators to make this
happen.
Geo Domain-Specific Language
: The syntactic sugar that allows engineers to easily specify which
- **Geo Domain-Specific Language**:
The syntactic sugar that allows engineers to easily specify which
resources should be replicated and how.
## Geo Domain-Specific Language
@ -144,7 +141,7 @@ replicator.model_record
```
The replicator can be used to generate events, for example in
ActiveRecord hooks:
`ActiveRecord` hooks:
```ruby
after_create_commit -> { replicator.publish_created_event }
@ -207,14 +204,12 @@ For example, to add support for files referenced by a `Widget` model with a
end
```
NOTE: **Note:**
If there is a common constraint for records to be available for replication,
make sure to also overwrite the `available_replicables` scope.
1. Create `ee/app/replicators/geo/widget_replicator.rb`. Implement the
`#carrierwave_uploader` method which should return a `CarrierWave::Uploader`.
And implement the class method `.model` to return the `Widget` class.
`#carrierwave_uploader` method which should return a `CarrierWave::Uploader`,
and implement the class method `.model` to return the `Widget` class:
```ruby
# frozen_string_literal: true
@ -241,7 +236,7 @@ For example, to add support for files referenced by a `Widget` model with a
```
1. Add this replicator class to the method `replicator_classes` in
`ee/lib/gitlab/geo.rb`:
`ee/lib/gitlab/geo.rb`:
```ruby
REPLICATOR_CLASSES = [
@ -252,8 +247,8 @@ For example, to add support for files referenced by a `Widget` model with a
```
1. Create `ee/spec/replicators/geo/widget_replicator_spec.rb` and perform
the setup necessary to define the `model_record` variable for the shared
examples.
the necessary setup to define the `model_record` variable for the shared
examples:
```ruby
# frozen_string_literal: true
@ -324,9 +319,7 @@ For example, to add support for files referenced by a `Widget` model with a
```
1. Update `REGISTRY_CLASSES` in `ee/app/workers/geo/secondary/registry_consistency_worker.rb`.
1. Add `widget_registry` to `ActiveSupport::Inflector.inflections` in `config/initializers_before_autoloader/000_inflections.rb`.
1. Create `ee/spec/factories/geo/widget_registry.rb`:
```ruby
@ -380,17 +373,17 @@ For example, to add support for files referenced by a `Widget` model with a
end
```
Widgets should now be replicated by Geo!
Widgets should now be replicated by Geo.
#### Verification
There are two ways to add verification related fields so that the Geo primary
can track verification state:
can track verification state.
##### Option 1: Add verification state fields to the existing `widgets` table itself
1. Add a migration to add columns ordered according to [our guidelines](../ordering_table_columns.md)
for verification state to the widgets table:
for verification state to the widgets table:
```ruby
# frozen_string_literal: true
@ -467,7 +460,7 @@ for verification state to the widgets table:
1. Create a `widget_states` table and add a partial index on `verification_failure` and
`verification_checksum` to ensure re-verification can be performed efficiently. Order
the columns according to [our guidelines](../ordering_table_columns.md):
the columns according to [the guidelines](../ordering_table_columns.md):
```ruby
# frozen_string_literal: true
@ -525,12 +518,12 @@ for verification state to the widgets table:
To do: Add verification on secondaries. This should be done as part of
[Geo: Self Service Framework - First Implementation for Package File verification](https://gitlab.com/groups/gitlab-org/-/epics/1817)
Widgets should now be verified by Geo!
Widgets should now be verified by Geo.
#### Metrics
Metrics are gathered by `Geo::MetricsUpdateWorker`, persisted in
`GeoNodeStatus` for display in the UI, and sent to Prometheus.
`GeoNodeStatus` for display in the UI, and sent to Prometheus:
1. Add fields `widgets_count`, `widgets_checksummed_count`,
`widgets_checksum_failed_count`, `widgets_synced_count`,
@ -570,7 +563,7 @@ Metrics are gathered by `Geo::MetricsUpdateWorker`, persisted in
attribute. Check out `spec/factories/merge_request_diffs.rb` for an example.
Widget replication and verification metrics should now be available in the API,
the Admin Area UI, and Prometheus!
the Admin Area UI, and Prometheus.
#### GraphQL API
@ -587,7 +580,6 @@ the Admin Area UI, and Prometheus!
1. Add the new `widget_registries` field name to the `expected_fields` array in
`ee/spec/graphql/types/geo/geo_node_type_spec.rb`.
1. Create `ee/app/graphql/resolvers/geo/widget_registries_resolver.rb`:
```ruby
@ -696,14 +688,14 @@ the Admin Area UI, and Prometheus!
```
Individual widget synchronization and verification data should now be available
via the GraphQL API!
via the GraphQL API.
1. Take care of replicating "update" events. Geo Framework does not currently support
replicating "update" events because all entities added to the framework, by this time,
are immutable. If this is the case
for the entity you're going to add, please follow <https://gitlab.com/gitlab-org/gitlab/-/issues/118743>
and <https://gitlab.com/gitlab-org/gitlab/-/issues/118745> as examples to add the new event type.
Please also remove this notice when you've added it.
Make sure to replicate the "update" events. Geo Framework does not currently support
replicating "update" events because all entities added to the framework, by this time,
are immutable. If this is the case
for the entity you're going to add, follow <https://gitlab.com/gitlab-org/gitlab/-/issues/118743>
and <https://gitlab.com/gitlab-org/gitlab/-/issues/118745> as examples to add the new event type.
Also, remove this notice when you've added it.
#### Admin UI
@ -711,7 +703,7 @@ To do: This should be done as part of
[Geo: Implement frontend for Self-Service Framework replicables](https://gitlab.com/groups/gitlab-org/-/epics/2525)
Widget sync and verification data (aggregate and individual) should now be
available in the Admin UI!
available in the Admin UI.
#### Releasing the feature

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@ -119,7 +119,7 @@ repository, you can run `git remote -v`.
If there are [merge conflicts](#merge-conflicts), Git will prompt you to fix
them before continuing the rebase.
To learn more, check Git's documentation on [rebasing](ttps://git-scm.com/book/en/v2/Git-Branching-Rebasing)
To learn more, check Git's documentation on [rebasing](https://git-scm.com/book/en/v2/Git-Branching-Rebasing)
and [rebasing strategies](https://git-scm.com/book/en/v2/Git-Branching-Rebasing).
### Interactive rebase

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Some files were not shown because too many files have changed in this diff Show More