Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-11-03 15:11:31 +00:00
parent 720cf69815
commit e6fa9529b4
123 changed files with 1127 additions and 564 deletions

View File

@ -0,0 +1,63 @@
.shared-as-if-jh:
variables:
SANDBOX_PROJECT: "gitlab-org-sandbox/gitlab-jh-validation"
SANDBOX_REPOSITORY: "https://dummy:${AS_IF_JH_TOKEN}@gitlab.com/${SANDBOX_PROJECT}.git"
GITLAB_JH_MIRROR_PROJECT: "33019816"
AS_IF_JH_BRANCH: "as-if-jh/${CI_COMMIT_REF_NAME}"
JH_FILES_TO_COMMIT: "jh package.json yarn.lock"
add-jh-files:
extends:
- .shared-as-if-jh
- .as-if-jh:rules:prepare-as-if-jh
image: ${GITLAB_DEPENDENCY_PROXY}ruby:${RUBY_VERSION}
stage: prepare
before_script:
- source ./scripts/utils.sh
- source ./scripts/setup/as-if-jh.sh
- install_gitlab_gem
script:
- prepare_jh_branch
- download_jh_path ${JH_FILES_TO_COMMIT}
- echoinfo "Changes after downloading JiHu files:"
- git diff
- git status
artifacts:
expire_in: 2d
paths:
# This should match JH_FILES_TO_COMMIT
- jh/
- package.json
- yarn.lock
prepare-as-if-jh-branch:
extends:
- .shared-as-if-jh
- .as-if-jh:rules:prepare-as-if-jh
stage: prepare
needs:
- add-jh-files
script:
- git checkout -b "${AS_IF_JH_BRANCH}"
- git add ${JH_FILES_TO_COMMIT}
- git commit -m 'Add JH files' # TODO: Mark which SHA we add
# Fetch for the history of the branch so it does not cause the following error:
# ! [remote rejected] ref -> ref (shallow update not allowed)
- git fetch --unshallow --filter=tree:0 origin "${CI_COMMIT_REF_NAME}"
- git push -f "${SANDBOX_REPOSITORY}" "${AS_IF_JH_BRANCH}"
start-as-if-jh:
extends:
- .shared-as-if-jh
- .as-if-jh:rules:start-as-if-jh
stage: prepare
needs: ["prepare-as-if-jh-branch"]
inherit:
variables: false
variables:
AS_IF_EDITION: "jh"
FORCE_GITLAB_CI: "true" # TODO: Trigger a merge request pipeline
trigger:
project: gitlab-org-sandbox/gitlab-jh-validation # ${SANDBOX_PROJECT} does not work here
branch: as-if-jh/${CI_COMMIT_REF_NAME} # ${AS_IF_JH_BRANCH} does not work here
strategy: depend

View File

@ -5,13 +5,17 @@
if: '$CI_PROJECT_NAMESPACE !~ /^gitlab(-org)?($|\/)/' if: '$CI_PROJECT_NAMESPACE !~ /^gitlab(-org)?($|\/)/'
.if-not-ee: &if-not-ee .if-not-ee: &if-not-ee
if: '$CI_PROJECT_NAME !~ /^gitlab(-ee)?$/' # Only consider FOSS not EE
if: '$CI_PROJECT_NAME !~ /^gitlab(-ee)?$/ && $CI_PROJECT_NAME !~ /^gitlab-jh/'
.if-not-foss: &if-not-foss .if-not-foss: &if-not-foss
if: '$CI_PROJECT_NAME != "gitlab-foss" && $CI_PROJECT_NAME != "gitlab-ce" && $CI_PROJECT_NAME != "gitlabhq"' if: '$CI_PROJECT_NAME != "gitlab-foss" && $CI_PROJECT_NAME != "gitlab-ce" && $CI_PROJECT_NAME != "gitlabhq"'
.if-jh: &if-jh .if-jh: &if-jh
if: '$CI_PROJECT_PATH =~ /^gitlab-(jh|cn)\/.*/' # Example of these projects:
# https://jihulab.com/gitlab-cn/gitlab
# https://gitlab.com/gitlab-org-sandbox/gitlab-jh-validation
if: '$CI_PROJECT_PATH =~ /^gitlab-(jh|cn)\/.*/ || $CI_PROJECT_NAME =~ /^gitlab-jh/'
.if-force-ci: &if-force-ci .if-force-ci: &if-force-ci
if: '$FORCE_GITLAB_CI' if: '$FORCE_GITLAB_CI'
@ -560,6 +564,13 @@
- <<: *if-jh - <<: *if-jh
when: never when: never
.as-if-jh-default-exclusion-rules:
rules:
- <<: *if-security-merge-request
when: never
- <<: *if-merge-request-targeting-stable-branch
when: never
.rails:rules:minimal-default-rules: .rails:rules:minimal-default-rules:
rules: rules:
- <<: *if-merge-request-approved - <<: *if-merge-request-approved
@ -2024,3 +2035,21 @@
rules: rules:
- <<: *if-default-refs - <<: *if-default-refs
changes: *lint-metrics-yaml-patterns changes: *lint-metrics-yaml-patterns
##################
# as-if-jh rules #
##################
.as-if-jh:rules:prepare-as-if-jh:
rules:
- !reference [".strict-ee-only-rules", rules]
- !reference [".as-if-jh-default-exclusion-rules", rules]
- <<: *if-merge-request-labels-as-if-jh
# This rule should share the same logic with .as-if-jh:rules:prepare-as-if-jh
# Because the jobs using this need jobs using the preparation rules
.as-if-jh:rules:start-as-if-jh:
rules:
- !reference [".strict-ee-only-rules", rules]
- !reference [".as-if-jh-default-exclusion-rules", rules]
- <<: *if-merge-request-labels-as-if-jh
allow_failure: true # See https://gitlab.com/gitlab-org/gitlab/-/issues/351136

View File

@ -590,6 +590,12 @@ Graphql/Descriptions:
- 'app/graphql/**/*' - 'app/graphql/**/*'
- 'ee/app/graphql/**/*' - 'ee/app/graphql/**/*'
Graphql/EnumNames:
Enabled: true
Include:
- 'app/graphql/**/*'
- 'ee/app/graphql/**/*'
# Cops for upgrade to gitlab-styles 3.1.0 # Cops for upgrade to gitlab-styles 3.1.0
RSpec/ImplicitSubject: RSpec/ImplicitSubject:
Enabled: false Enabled: false

View File

@ -0,0 +1,37 @@
---
Graphql/EnumNames:
Details: grace period
Exclude:
- 'app/graphql/types/access_level_enum.rb'
- 'app/graphql/types/availability_enum.rb'
- 'app/graphql/types/ci/pipeline_config_source_enum.rb'
- 'app/graphql/types/ci/pipeline_scope_enum.rb'
- 'app/graphql/types/ci/pipeline_status_enum.rb'
- 'app/graphql/types/container_expiration_policy_cadence_enum.rb'
- 'app/graphql/types/container_expiration_policy_keep_enum.rb'
- 'app/graphql/types/container_expiration_policy_older_than_enum.rb'
- 'app/graphql/types/data_visualization_palette/color_enum.rb'
- 'app/graphql/types/data_visualization_palette/weight_enum.rb'
- 'app/graphql/types/merge_strategy_enum.rb'
- 'app/graphql/types/milestone_state_enum.rb'
- 'app/graphql/types/packages/cleanup/keep_duplicated_package_files_enum.rb'
- 'app/graphql/types/packages/conan/metadatum_file_type_enum.rb'
- 'app/graphql/types/packages/package_type_enum.rb'
- 'app/graphql/types/security/report_type_enum.rb'
- 'app/graphql/types/snippets/blob_action_enum.rb'
- 'app/graphql/types/snippets/type_enum.rb'
- 'app/graphql/types/snippets/visibility_scopes_enum.rb'
- 'app/graphql/types/sort_direction_enum.rb'
- 'app/graphql/types/todo_action_enum.rb'
- 'app/graphql/types/todo_state_enum.rb'
- 'app/graphql/types/todo_target_enum.rb'
- 'app/graphql/types/user_callout_feature_name_enum.rb'
- 'app/graphql/types/visibility_levels_enum.rb'
- 'ee/app/graphql/types/dast_scan_type_enum.rb'
- 'ee/app/graphql/types/dast_site_profile_validation_status_enum.rb'
- 'ee/app/graphql/types/dast_site_validation_status_enum.rb'
- 'ee/app/graphql/types/dast_site_validation_strategy_enum.rb'
- 'ee/app/graphql/types/dast_target_type_enum.rb'
- 'ee/app/graphql/types/geo/replication_state_enum.rb'
- 'ee/app/graphql/types/geo/verification_state_enum.rb'
- 'ee/app/graphql/types/incident_management/oncall_rotation_length_unit_enum.rb'

View File

@ -1 +1 @@
165e1fbd149fd4baec8ce3957e728d3ce3412a15 b55578ec476e8bc8ecd9775ee7e9960b52e0f6e0

View File

@ -1,6 +1,6 @@
<script> <script>
import { GlAlert } from '@gitlab/ui'; import { GlAlert } from '@gitlab/ui';
import { sortBy } from 'lodash'; import { sortBy, throttle } from 'lodash';
import Draggable from 'vuedraggable'; import Draggable from 'vuedraggable';
import { mapState, mapGetters, mapActions } from 'vuex'; import { mapState, mapGetters, mapActions } from 'vuex';
import BoardAddNewColumn from 'ee_else_ce/boards/components/board_add_new_column.vue'; import BoardAddNewColumn from 'ee_else_ce/boards/components/board_add_new_column.vue';
@ -26,6 +26,11 @@ export default {
required: true, required: true,
}, },
}, },
data() {
return {
boardHeight: null,
};
},
computed: { computed: {
...mapState(['boardLists', 'error', 'addColumnForm']), ...mapState(['boardLists', 'error', 'addColumnForm']),
...mapGetters(['isSwimlanesOn', 'isEpicBoard', 'isIssueBoard']), ...mapGetters(['isSwimlanesOn', 'isEpicBoard', 'isIssueBoard']),
@ -55,12 +60,28 @@ export default {
return this.canDragColumns ? options : {}; return this.canDragColumns ? options : {};
}, },
}, },
mounted() {
this.setBoardHeight();
this.resizeObserver = new ResizeObserver(
throttle(() => {
this.setBoardHeight();
}, 150),
);
this.resizeObserver.observe(document.body);
},
unmounted() {
this.resizeObserver.disconnect();
},
methods: { methods: {
...mapActions(['moveList', 'unsetError']), ...mapActions(['moveList', 'unsetError']),
afterFormEnters() { afterFormEnters() {
const el = this.canDragColumns ? this.$refs.list.$el : this.$refs.list; const el = this.canDragColumns ? this.$refs.list.$el : this.$refs.list;
el.scrollTo({ left: el.scrollWidth, behavior: 'smooth' }); el.scrollTo({ left: el.scrollWidth, behavior: 'smooth' });
}, },
setBoardHeight() {
this.boardHeight = `${window.innerHeight - this.$el.getBoundingClientRect().top}px`;
},
}, },
}; };
</script> </script>
@ -76,6 +97,7 @@ export default {
ref="list" ref="list"
v-bind="draggableOptions" v-bind="draggableOptions"
class="boards-list gl-w-full gl-py-5 gl-pr-3 gl-white-space-nowrap gl-overflow-x-scroll" class="boards-list gl-w-full gl-py-5 gl-pr-3 gl-white-space-nowrap gl-overflow-x-scroll"
:style="{ height: boardHeight }"
@end="moveList" @end="moveList"
> >
<board-column <board-column
@ -99,6 +121,7 @@ export default {
:lists="boardListsToUse" :lists="boardListsToUse"
:can-admin-list="canAdminList" :can-admin-list="canAdminList"
:disabled="disabled" :disabled="disabled"
:style="{ height: boardHeight }"
/> />
<board-content-sidebar v-if="isIssueBoard" data-testid="issue-boards-sidebar" /> <board-content-sidebar v-if="isIssueBoard" data-testid="issue-boards-sidebar" />

View File

@ -1,84 +0,0 @@
<script>
import { mapState, mapActions, mapGetters } from 'vuex';
import { s__, sprintf } from '~/locale';
import { componentNames } from '~/reports/components/issue_body';
import ReportSection from '~/reports/components/report_section.vue';
import createStore from './store';
export default {
name: 'GroupedCodequalityReportsApp',
store: createStore(),
components: {
ReportSection,
},
props: {
headBlobPath: {
type: String,
required: true,
},
baseBlobPath: {
type: String,
required: false,
default: null,
},
codequalityReportsPath: {
type: String,
required: false,
default: '',
},
codequalityHelpPath: {
type: String,
required: true,
},
},
componentNames,
computed: {
...mapState(['newIssues', 'resolvedIssues', 'hasError', 'statusReason']),
...mapGetters([
'hasCodequalityIssues',
'codequalityStatus',
'codequalityText',
'codequalityPopover',
]),
},
created() {
this.setPaths({
baseBlobPath: this.baseBlobPath,
headBlobPath: this.headBlobPath,
reportsPath: this.codequalityReportsPath,
helpPath: this.codequalityHelpPath,
});
this.fetchReports();
},
methods: {
...mapActions(['fetchReports', 'setPaths']),
},
loadingText: sprintf(s__('ciReport|Loading %{reportName} report'), {
// eslint-disable-next-line @gitlab/require-i18n-strings
reportName: 'Code quality',
}),
errorText: sprintf(s__('ciReport|Failed to load %{reportName} report'), {
// eslint-disable-next-line @gitlab/require-i18n-strings
reportName: 'Code quality',
}),
};
</script>
<template>
<report-section
:status="codequalityStatus"
:loading-text="$options.loadingText"
:error-text="$options.errorText"
:success-text="codequalityText"
:unresolved-issues="newIssues"
:resolved-issues="resolvedIssues"
:has-issues="hasCodequalityIssues"
:component="$options.componentNames.CodequalityIssueBody"
:popover-options="codequalityPopover"
:show-report-section-status-icon="false"
track-action="users_expanding_testing_code_quality_report"
class="js-codequality-widget mr-widget-border-top mr-report"
>
<template v-if="hasError" #sub-heading>{{ statusReason }}</template>
</report-section>
</template>

View File

@ -6,6 +6,7 @@ import { sprintf, __ } from '~/locale';
import Poll from '~/lib/utils/poll'; import Poll from '~/lib/utils/poll';
import ActionButtons from '../action_buttons.vue'; import ActionButtons from '../action_buttons.vue';
import { EXTENSION_ICONS } from '../../constants'; import { EXTENSION_ICONS } from '../../constants';
import { createTelemetryHub } from '../extensions/telemetry';
import ContentRow from './widget_content_row.vue'; import ContentRow from './widget_content_row.vue';
import DynamicContent from './dynamic_content.vue'; import DynamicContent from './dynamic_content.vue';
import StatusIcon from './status_icon.vue'; import StatusIcon from './status_icon.vue';
@ -89,6 +90,11 @@ export default {
type: String, type: String,
required: true, required: true,
}, },
telemetry: {
type: Boolean,
required: false,
default: true,
},
}, },
data() { data() {
return { return {
@ -98,6 +104,7 @@ export default {
isLoadingExpandedContent: false, isLoadingExpandedContent: false,
summaryError: null, summaryError: null,
contentError: null, contentError: null,
telemetryHub: null,
}; };
}, },
computed: { computed: {
@ -113,8 +120,14 @@ export default {
this.$emit('is-loading', newValue); this.$emit('is-loading', newValue);
}, },
}, },
created() {
if (this.telemetry) {
this.telemetryHub = createTelemetryHub(this.widgetName);
}
},
async mounted() { async mounted() {
this.isLoading = true; this.isLoading = true;
this.telemetryHub?.viewed();
try { try {
await this.fetch(this.fetchCollapsedData, FETCH_TYPE_COLLAPSED); await this.fetch(this.fetchCollapsedData, FETCH_TYPE_COLLAPSED);
@ -125,12 +138,21 @@ export default {
this.isLoading = false; this.isLoading = false;
}, },
methods: { methods: {
onActionClick(action) {
if (action.fullReport) {
this.telemetryHub?.fullReportClicked();
}
},
toggleCollapsed() { toggleCollapsed() {
this.isCollapsed = !this.isCollapsed; this.isCollapsed = !this.isCollapsed;
if (this.isExpandedForTheFirstTime && typeof this.fetchExpandedData === 'function') { if (this.isExpandedForTheFirstTime) {
this.isExpandedForTheFirstTime = false; this.telemetryHub?.expanded({ type: this.summaryStatusIcon });
this.fetchExpandedContent();
if (typeof this.fetchExpandedData === 'function') {
this.isExpandedForTheFirstTime = false;
this.fetchExpandedContent();
}
} }
}, },
async fetchExpandedContent() { async fetchExpandedContent() {
@ -208,6 +230,7 @@ export default {
v-if="actionButtons.length > 0" v-if="actionButtons.length > 0"
:widget="widgetName" :widget="widgetName"
:tertiary-buttons="actionButtons" :tertiary-buttons="actionButtons"
@clickedAction="onActionClick"
/> />
<div <div
v-if="isCollapsible" v-if="isCollapsible"

View File

@ -82,8 +82,6 @@ export default {
MrWidgetAutoMergeFailed: AutoMergeFailed, MrWidgetAutoMergeFailed: AutoMergeFailed,
MrWidgetRebase: RebaseState, MrWidgetRebase: RebaseState,
SourceBranchRemovalStatus, SourceBranchRemovalStatus,
GroupedCodequalityReportsApp: () =>
import('../reports/codequality_report/grouped_codequality_reports_app.vue'),
GroupedTestReportsApp: () => GroupedTestReportsApp: () =>
import('../reports/grouped_test_report/grouped_test_reports_app.vue'), import('../reports/grouped_test_report/grouped_test_reports_app.vue'),
MrWidgetApprovals, MrWidgetApprovals,
@ -218,9 +216,6 @@ export default {
shouldShowSecurityExtension() { shouldShowSecurityExtension() {
return window.gon?.features?.refactorSecurityExtension; return window.gon?.features?.refactorSecurityExtension;
}, },
shouldShowCodeQualityExtension() {
return window.gon?.features?.refactorCodeQualityExtension;
},
shouldShowMergeDetails() { shouldShowMergeDetails() {
if (this.mr.state === 'readyToMerge') return true; if (this.mr.state === 'readyToMerge') return true;
@ -519,7 +514,7 @@ export default {
} }
}, },
registerCodeQualityExtension() { registerCodeQualityExtension() {
if (this.shouldRenderCodeQuality && this.shouldShowCodeQualityExtension) { if (this.shouldRenderCodeQuality) {
registerExtension(codeQualityExtension); registerExtension(codeQualityExtension);
} }
}, },
@ -592,14 +587,6 @@ export default {
<widget-container v-if="mr" :mr="mr" /> <widget-container v-if="mr" :mr="mr" />
<grouped-codequality-reports-app
v-if="shouldRenderCodeQuality && !shouldShowCodeQualityExtension"
:head-blob-path="mr.headBlobPath"
:base-blob-path="mr.baseBlobPath"
:codequality-reports-path="mr.codequalityReportsPath"
:codequality-help-path="mr.codequalityHelpPath"
/>
<security-reports-app <security-reports-app
v-if="shouldRenderSecurityReport && !shouldShowSecurityExtension" v-if="shouldRenderSecurityReport && !shouldShowSecurityExtension"
:pipeline-id="mr.pipeline.id" :pipeline-id="mr.pipeline.id"

View File

@ -299,7 +299,6 @@ export default class MergeRequestStore {
this.headBlobPath = blobPath.head_path || ''; this.headBlobPath = blobPath.head_path || '';
this.baseBlobPath = blobPath.base_path || ''; this.baseBlobPath = blobPath.base_path || '';
this.codequalityReportsPath = data.codequality_reports_path; this.codequalityReportsPath = data.codequality_reports_path;
this.codequalityHelpPath = data.codequality_help_path;
// Security reports // Security reports
this.sastComparisonPath = data.sast_comparison_path; this.sastComparisonPath = data.sast_comparison_path;

View File

@ -674,18 +674,7 @@ $ci-skipped-color: #888;
*/ */
$issue-boards-font-size: 14px; $issue-boards-font-size: 14px;
$issue-boards-card-shadow: rgba(0, 0, 0, 0.1); $issue-boards-card-shadow: rgba(0, 0, 0, 0.1);
/*
The following heights are used in boards.scss and are used for calculation of the board height.
They probably should be derived in a smarter way.
*/
$issue-boards-filter-height: 68px; $issue-boards-filter-height: 68px;
$issue-boards-filter-height-md: 110px;
$issue-boards-filter-height-sm: 299px;
$issue-boards-breadcrumbs-height-xs: 63px;
$issue-board-list-difference-xs: calc(#{$header-height} + #{$issue-boards-breadcrumbs-height-xs});
$issue-board-list-difference-sm: calc(#{$header-height} + #{$breadcrumb-min-height});
$issue-board-list-difference-md: calc(#{$issue-board-list-difference-sm} + #{$issue-boards-filter-height-md});
$issue-board-list-difference-lg: calc(#{$issue-board-list-difference-sm} + #{$issue-boards-filter-height});
/* /*
The following heights are used in environment_logs.scss and are used for calculation of the log viewer height. The following heights are used in environment_logs.scss and are used for calculation of the log viewer height.
*/ */

View File

@ -18,38 +18,9 @@
.boards-list, .boards-list,
.board-swimlanes { .board-swimlanes {
height: calc(100vh - #{$issue-board-list-difference-xs});
overflow-x: scroll; overflow-x: scroll;
min-height: 200px; min-height: 200px;
border-left: 8px solid var(--gray-10, $white); border-left: 8px solid var(--gray-10, $white);
@include media-breakpoint-only(sm) {
height: calc(100vh - #{$issue-board-list-difference-sm});
}
@include media-breakpoint-up(md) {
height: calc(100vh - #{$issue-board-list-difference-md});
}
@include media-breakpoint-up(lg) {
height: calc(100vh - #{$issue-board-list-difference-lg});
}
.with-performance-bar & {
height: calc(100vh - #{$issue-board-list-difference-xs} - #{$performance-bar-height});
@include media-breakpoint-only(sm) {
height: calc(100vh - #{$issue-board-list-difference-sm} - #{$performance-bar-height});
}
@include media-breakpoint-up(md) {
height: calc(100vh - #{$issue-board-list-difference-md} - #{$performance-bar-height});
}
@include media-breakpoint-up(lg) {
height: calc(100vh - #{$issue-board-list-difference-lg} - #{$performance-bar-height});
}
}
} }
.board { .board {

View File

@ -34,7 +34,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
before_action only: [:show] do before_action only: [:show] do
push_frontend_feature_flag(:merge_request_widget_graphql, project) push_frontend_feature_flag(:merge_request_widget_graphql, project)
push_frontend_feature_flag(:core_security_mr_widget_counts, project) push_frontend_feature_flag(:core_security_mr_widget_counts, project)
push_frontend_feature_flag(:refactor_code_quality_extension, project)
push_frontend_feature_flag(:refactor_mr_widget_test_summary, project) push_frontend_feature_flag(:refactor_mr_widget_test_summary, project)
push_frontend_feature_flag(:issue_assignees_widget, @project) push_frontend_feature_flag(:issue_assignees_widget, @project)
push_frontend_feature_flag(:realtime_labels, project) push_frontend_feature_flag(:realtime_labels, project)

View File

@ -25,7 +25,7 @@ module PgFullTextSearchable
TSVECTOR_MAX_LENGTH = 1.megabyte.freeze TSVECTOR_MAX_LENGTH = 1.megabyte.freeze
TEXT_SEARCH_DICTIONARY = 'english' TEXT_SEARCH_DICTIONARY = 'english'
URL_SCHEME_REGEX = %r{(?<=\A|\W)\w+://(?=\w+)}.freeze URL_SCHEME_REGEX = %r{(?<=\A|\W)\w+://(?=\w+)}.freeze
TSQUERY_DISALLOWED_CHARACTERS_REGEX = %r{[^a-zA-Z0-9 .@/\-"]}.freeze TSQUERY_DISALLOWED_CHARACTERS_REGEX = %r{[^a-zA-Z0-9 .@/\-_"]}.freeze
def update_search_data! def update_search_data!
tsvector_sql_nodes = self.class.pg_full_text_searchable_columns.map do |column, weight| tsvector_sql_nodes = self.class.pg_full_text_searchable_columns.map do |column, weight|

View File

@ -10,6 +10,8 @@ module Groups
reject_parent_id! reject_parent_id!
remove_unallowed_params remove_unallowed_params
before_assignment_hook(group, params)
if renaming_group_with_container_registry_images? if renaming_group_with_container_registry_images?
group.errors.add(:base, container_images_error) group.errors.add(:base, container_images_error)
return false return false
@ -25,8 +27,6 @@ module Groups
handle_changes handle_changes
before_assignment_hook(group, params)
handle_namespace_settings handle_namespace_settings
group.assign_attributes(params) group.assign_attributes(params)

View File

@ -52,7 +52,8 @@ module IncidentManagement
def change_severity(incident, user) def change_severity(incident, user)
return if Feature.disabled?(:incident_timeline_events_for_severity, incident.project) return if Feature.disabled?(:incident_timeline_events_for_severity, incident.project)
note = "@#{user.username} changed the incident severity to **#{incident.severity.humanize}**" severity_label = IssuableSeverity::SEVERITY_LABELS[incident.severity.to_sym]
note = "@#{user.username} changed the incident severity to **#{severity_label}**"
occurred_at = incident.updated_at occurred_at = incident.updated_at
action = 'severity' action = 'severity'

View File

@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/342497
milestone: '14.4' milestone: '14.4'
type: development type: development
group: group::source code group: group::source code
default_enabled: false default_enabled: true

View File

@ -1,8 +0,0 @@
---
name: refactor_code_quality_extension
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/88865
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/363845
milestone: '15.1'
type: development
group: group::secure
default_enabled: false

View File

@ -29,6 +29,8 @@ metadata:
description: Operations related to environments description: Operations related to environments
- name: feature_flags_user_lists - name: feature_flags_user_lists
description: Operations related to accessing GitLab feature flag user lists description: Operations related to accessing GitLab feature flag user lists
- name: feature_flags
description: Operations related to feature flags
- name: features - name: features
description: Operations related to managing Flipper-based feature flags description: Operations related to managing Flipper-based feature flags
- name: freeze_periods - name: freeze_periods
@ -39,5 +41,7 @@ metadata:
description: Operations related to metadata of the GitLab instance description: Operations related to metadata of the GitLab instance
- name: release_links - name: release_links
description: Operations related to release assets (links) description: Operations related to release assets (links)
- name: releases
description: Operations related to releases
- name: suggestions - name: suggestions
description: Operations related to suggestions description: Operations related to suggestions

View File

@ -144,7 +144,7 @@ POST /projects/:id/feature_flags
| ------------------- | ---------------- | ---------- | ---------------------------------------------------------------------------------------| | ------------------- | ---------------- | ---------- | ---------------------------------------------------------------------------------------|
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding). | | `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding). |
| `name` | string | yes | The name of the feature flag. | | `name` | string | yes | The name of the feature flag. |
| `version` | string | yes | The version of the feature flag. Must be `new_version_flag`. Omit or set to `legacy_flag` to create a Legacy feature flag. | | `version` | string | yes | The version of the feature flag. Must be `new_version_flag`. Omit to create a Legacy feature flag. |
| `description` | string | no | The description of the feature flag. | | `description` | string | no | The description of the feature flag. |
| `active` | boolean | no | The active state of the flag. Defaults to true. [Supported](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38350) in GitLab 13.3 and later. | | `active` | boolean | no | The active state of the flag. Defaults to true. [Supported](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38350) in GitLab 13.3 and later. |
| `strategies` | JSON | no | The feature flag [strategies](../operations/feature_flags.md#feature-flag-strategies). | | `strategies` | JSON | no | The feature flag [strategies](../operations/feature_flags.md#feature-flag-strategies). |

View File

@ -28,7 +28,7 @@ For authentication, the Releases API accepts either:
> [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72448) to allow for `JOB-TOKEN` in GitLab 14.5. > [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72448) to allow for `JOB-TOKEN` in GitLab 14.5.
Paginated list of Releases, sorted by `released_at`. Returns a paginated list of releases, sorted by `released_at`.
```plaintext ```plaintext
GET /projects/:id/releases GET /projects/:id/releases
@ -235,7 +235,7 @@ Example response:
> [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72448) to allow for `JOB-TOKEN` in GitLab 14.5. > [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72448) to allow for `JOB-TOKEN` in GitLab 14.5.
Get a Release for the given tag. Gets a release for the given tag.
```plaintext ```plaintext
GET /projects/:id/releases/:tag_name GET /projects/:id/releases/:tag_name
@ -366,7 +366,7 @@ Example response:
## Create a release ## Create a release
Create a release. Developer level access to the project is required to create a release. Creates a release. Developer level access to the project is required to create a release.
```plaintext ```plaintext
POST /projects/:id/releases POST /projects/:id/releases
@ -516,7 +516,7 @@ adding milestones for ancestor groups raises an error.
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/199065) in GitLab 12.10. > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/199065) in GitLab 12.10.
> - [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72448) to allow for `JOB-TOKEN` in GitLab 14.5. > - [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72448) to allow for `JOB-TOKEN` in GitLab 14.5.
Create Evidence for an existing Release. Creates an evidence for an existing release.
```plaintext ```plaintext
POST /projects/:id/releases/:tag_name/evidence POST /projects/:id/releases/:tag_name/evidence
@ -543,7 +543,7 @@ Example response:
> [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72448) to allow for `JOB-TOKEN` in GitLab 14.5. > [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72448) to allow for `JOB-TOKEN` in GitLab 14.5.
Update a release. Developer level access to the project is required to update a release. Updates a release. Developer level access to the project is required to update a release.
```plaintext ```plaintext
PUT /projects/:id/releases/:tag_name PUT /projects/:id/releases/:tag_name
@ -652,7 +652,7 @@ Example response:
> [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72448) to allow for `JOB-TOKEN` in GitLab 14.5. > [Changed](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72448) to allow for `JOB-TOKEN` in GitLab 14.5.
Delete a release. Deleting a release doesn't delete the associated tag. Maintainer level access to the project is required to delete a release. Deletes a release. Deleting a release doesn't delete the associated tag. Maintainer level access to the project is required to delete a release.
```plaintext ```plaintext
DELETE /projects/:id/releases/:tag_name DELETE /projects/:id/releases/:tag_name

View File

@ -693,7 +693,7 @@ module EE
prepended do prepended do
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: ::API::API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: ::API::API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
# ... # ...

View File

@ -257,45 +257,141 @@ set and get the `ee/` folder removed before the tests start running.
The intent is to ensure that a change doesn't introduce a failure after `gitlab-org/gitlab` is synced to `gitlab-org/gitlab-foss`. The intent is to ensure that a change doesn't introduce a failure after `gitlab-org/gitlab` is synced to `gitlab-org/gitlab-foss`.
## As-if-JH jobs ## As-if-JH cross project downstream pipeline
NOTE: The `start-as-if-jh` job triggers a cross project downstream pipeline which
This is disabled for now. runs the GitLab test suite "as if JiHu", meaning as if the pipeline would run
in the context of [GitLab JH](../jh_features_review.md). These jobs are only
The `* as-if-jh` jobs run the GitLab test suite "as if JiHu", meaning as if the jobs would run in the context created in the following cases:
of [GitLab JH](../jh_features_review.md). These jobs are only created in the following cases:
- when the `pipeline:run-as-if-jh` label is set on the merge request - when the `pipeline:run-as-if-jh` label is set on the merge request
- when the `pipeline:run-all-rspec` label is set on the merge request
- when any code or backstage file is changed
- when any startup CSS file is changed
The `* as-if-jh` jobs are run in addition to the regular EE-context jobs. The `jh/` folder is added before the tests start running. This pipeline runs under the context of a generated branch in the
[GitLab JH validation](https://gitlab.com/gitlab-org-sandbox/gitlab-jh-validation)
project, which is a mirror of the
[GitLab JH mirror](https://gitlab.com/gitlab-org/gitlab-jh-mirrors/gitlab).
The intent is to ensure that a change doesn't introduce a failure after `gitlab-org/gitlab` is synced to [GitLab JH](https://jihulab.com/gitlab-cn/gitlab). The generated branch name is prefixed with `as-if-jh/` along with the branch
name in the merge request. This generated branch is based on the merge request
branch, additionally adding changes downloaded from the
[corresponding JH branch](#corresponding-jh-branch) on top to turn the whole
pipeline as if JiHu.
The intent is to ensure that a change doesn't introduce a failure after
[GitLab](https://gitlab.com/gitlab-org/gitlab) is synchronized to
[GitLab JH](https://jihulab.com/gitlab-cn/gitlab).
### When to consider applying `pipeline:run-as-if-jh` label ### When to consider applying `pipeline:run-as-if-jh` label
NOTE:
This is disabled for now.
If a Ruby file is renamed and there's a corresponding [`prepend_mod` line](../jh_features_review.md#jh-features-based-on-ce-or-ee-features), If a Ruby file is renamed and there's a corresponding [`prepend_mod` line](../jh_features_review.md#jh-features-based-on-ce-or-ee-features),
it's likely that GitLab JH is relying on it and requires a corresponding it's likely that GitLab JH is relying on it and requires a corresponding
change to rename the module or class it's prepending. change to rename the module or class it's prepending.
### Corresponding JH branch ### Corresponding JH branch
NOTE:
This is disabled for now.
You can create a corresponding JH branch on [GitLab JH](https://jihulab.com/gitlab-cn/gitlab) by You can create a corresponding JH branch on [GitLab JH](https://jihulab.com/gitlab-cn/gitlab) by
appending `-jh` to the branch name. If a corresponding JH branch is found, appending `-jh` to the branch name. If a corresponding JH branch is found,
`* as-if-jh` jobs grab the `jh` folder from the respective branch, as-if-jh pipeline grabs files from the respective branch, rather than from the
rather than from the default branch `main-jh`. default branch `main-jh`.
NOTE: NOTE:
For now, CI will try to fetch the branch on the [GitLab JH mirror](https://gitlab.com/gitlab-org/gitlab-jh-mirrors/gitlab), so it might take some time for the new JH branch to propagate to the mirror. For now, CI will try to fetch the branch on the [GitLab JH mirror](https://gitlab.com/gitlab-org/gitlab-jh-mirrors/gitlab), so it might take some time for the new JH branch to propagate to the mirror.
NOTE:
While [GitLab JH validation](https://gitlab.com/gitlab-org-sandbox/gitlab-jh-validation) is a mirror of
[GitLab JH mirror](https://gitlab.com/gitlab-org/gitlab-jh-mirrors/gitlab),
it does not include any corresponding JH branch beside the default `main-jh`.
This is why when we want to fetch corresponding JH branch we should fetch it
from the main mirror, rather than the validation project.
### How as-if-JH pipeline was configured
The whole process looks like this:
```mermaid
flowchart TD
subgraph "JiHuLab.com"
JH["gitlab-cn/gitlab"]
end
subgraph "GitLab.com"
Mirror["gitlab-org/gitlab-jh-mirrors/gitlab"]
Validation["gitlab-org-sandbox/gitlab-jh-validation"]
subgraph MR["gitlab-org/gitlab merge request"]
Add["add-jh-files job"]
Prepare["prepare-as-if-jh-branch job"]
Add --"download artifacts"--> Prepare
end
Mirror --"pull mirror with master and main-jh"--> Validation
Mirror --"download JiHu files with ADD_JH_FILES_TOKEN"--> Add
Prepare --"push as-if-jh branches with AS_IF_JH_TOKEN"--> Validation
Validation --> Pipeline["as-if-jh pipeline"]
end
JH --"pull mirror with corresponding JH branches"--> Mirror
```
#### Tokens set in the project variables
- `ADD_JH_FILES_TOKEN`: This is a [GitLab JH mirror](https://gitlab.com/gitlab-org/gitlab-jh-mirrors/gitlab)
project token with `read_api` permission, to be able to download JiHu files.
- `AS_IF_JH_TOKEN`: This is a [GitLab JH validation](https://gitlab.com/gitlab-org-sandbox/gitlab-jh-validation)
project token with `write_repository` permission, to push generated `as-if-jh/*` branch.
#### How we generate the as-if-JH branch
First `add-jh-files` job will download the required JiHu files from the
corresponding JH branch, saving in artifacts. Next `prepare-as-if-jh-branch`
job will create a new branch from the merge request branch, commit the
changes, and finally push the branch to the
[validation project](https://gitlab.com/gitlab-org-sandbox/gitlab-jh-validation).
#### How we trigger and run the as-if-JH pipeline
After having the `as-if-jh/*` branch, `start-as-if-jh` job will trigger a pipeline
in the [validation project](https://gitlab.com/gitlab-org-sandbox/gitlab-jh-validation)
to run the cross-project downstream pipeline.
#### How the GitLab JH mirror project is set up
The [GitLab JH mirror](https://gitlab.com/gitlab-org/gitlab-jh-mirrors/gitlab) project is private and CI is disabled.
It's a pull mirror pulling from [GitLab JH](https://jihulab.com/gitlab-cn/gitlab),
mirroring all branches, overriding divergent refs, triggering no pipelines
when mirror is updated.
The pulling user is [`@gitlab-jh-bot`](https://gitlab.com/gitlab-jh-bot), who
is a maintainer in the project. The credentials can be found in the 1password
engineering vault.
No password is used from mirroring because GitLab JH is a public project.
#### How the GitLab JH validation project is set up
This [GitLab JH validation](https://gitlab.com/gitlab-org-sandbox/gitlab-jh-validation) project is public and CI is enabled, without any project variables.
It's a pull mirror pulling from [GitLab JH mirror](https://gitlab.com/gitlab-org/gitlab-jh-mirrors/gitlab),
mirroring only protected branches, `master` and `main-jh`, overriding
divergent refs, triggering no pipelines when mirror is updated.
The pulling user is [`@gitlab-jh-validation-bot`](https://gitlab.com/gitlab-jh-validation-bot), who is a maintainer in the project, and also a
reporter in the
[GitLab JH mirror](https://gitlab.com/gitlab-org/gitlab-jh-mirrors/gitlab).
The credentials can be found in the 1password engineering vault.
A personal access token from `@gitlab-jh-validation-bot` with
`write_repository` permission is used as the password to pull changes from
the GitLab JH mirror. Username is set with `gitlab-jh-validation-bot`.
There is also a [pipeline schedule](https://gitlab.com/gitlab-org-sandbox/gitlab-jh-validation/-/pipeline_schedules)
to run maintenance pipelines with variable `SCHEDULE_TYPE` set to `maintenance`
running every day, updating cache.
The default CI/CD configuration file is also set at `jh/.gitlab-ci.yml` so it
runs exactly like [GitLab JH](https://jihulab.com/gitlab-cn/gitlab/-/blob/main-jh/jh/.gitlab-ci.yml).
## Ruby 3.0 jobs ## Ruby 3.0 jobs
You can add the `pipeline:run-in-ruby3` label to the merge request to switch You can add the `pipeline:run-in-ruby3` label to the merge request to switch

View File

@ -151,7 +151,8 @@ When implementing a service class, consider:
developer's discretion, such as: `issue`, `project`, `merge_request`. developer's discretion, such as: `issue`, `project`, `merge_request`.
1. When service represents an action initiated by a user or executed in the 1. When service represents an action initiated by a user or executed in the
context of a user, the initializer must have the `current_user:` keyword argument. context of a user, the initializer must have the `current_user:` keyword argument.
Services with `current_user:` argument run high-level business logic. Services with the `current_user:` argument run high-level business logic
and must validate user authorization to perform their operations.
1. When service does not have a user context and it's not directly initiated 1. When service does not have a user context and it's not directly initiated
by a user (like background service or side-effects), the `current_user:` by a user (like background service or side-effects), the `current_user:`
argument is not needed. This describes low-level domain logic or instance-wide logic. argument is not needed. This describes low-level domain logic or instance-wide logic.

View File

@ -46,12 +46,12 @@ If the highest number stable branch is unclear, check the [GitLab blog](https://
## Software requirements ## Software requirements
| Software | Minimum version | Notes | | Software | Minimum version | Notes |
| -------- | --------------- | ----- | | ------------------ | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [Ruby](#2-ruby) | `2.7` | From GitLab 13.6, Ruby 2.7 is required. Ruby 3.0 is not supported yet (see [the relevant epic](https://gitlab.com/groups/gitlab-org/-/epics/5149) for the current status). You must use the standard MRI implementation of Ruby. We love [JRuby](https://www.jruby.org/) and [Rubinius](https://github.com/rubinius/rubinius#the-rubinius-language-platform), but GitLab needs several Gems that have native extensions. | | [Ruby](#2-ruby) | `2.7` | From GitLab 13.6, Ruby 2.7 is required. Ruby 3.0 is not supported yet (see [the relevant epic](https://gitlab.com/groups/gitlab-org/-/epics/5149) for the current status). You must use the standard MRI implementation of Ruby. We love [JRuby](https://www.jruby.org/) and [Rubinius](https://github.com/rubinius/rubinius#the-rubinius-language-platform), but GitLab needs several Gems that have native extensions. |
| [Go](#3-go) | `1.17` | From GitLab 15.2, Go 1.17 or later is required. | | [Go](#3-go) | `1.17` | From GitLab 15.2, Go 1.17 or later is required. |
| [Git](#git) | `2.33.x` | From GitLab 14.4, Git 2.33.x and later is required. It's highly recommended that you use the [Git version provided by Gitaly](#git). | | [Git](#git) | `2.37.x` | From GitLab 15.6, Git 2.37.x and later is required. It's highly recommended that you use the [Git version provided by Gitaly](#git). |
| [Node.js](#4-node) | `14.15.0` | GitLab uses [webpack](https://webpack.js.org/) to compile frontend assets. Node.js 16.x is recommended, as it's faster. You can check which version you're running with `node -v`. You must update it to a newer version if needed. | | [Node.js](#4-node) | `14.15.0` | GitLab uses [webpack](https://webpack.js.org/) to compile frontend assets. Node.js 16.x is recommended, as it's faster. You can check which version you're running with `node -v`. You must update it to a newer version if needed. |
## GitLab directory structure ## GitLab directory structure

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -467,6 +467,10 @@ NOTE:
Specific information that follow related to Ruby and Git versions do not apply to [Omnibus installations](https://docs.gitlab.com/omnibus/) Specific information that follow related to Ruby and Git versions do not apply to [Omnibus installations](https://docs.gitlab.com/omnibus/)
and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with appropriate Ruby and Git versions and are not using system binaries for Ruby and Git. There is no need to install Ruby or Git when utilizing these two approaches. and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with appropriate Ruby and Git versions and are not using system binaries for Ruby and Git. There is no need to install Ruby or Git when utilizing these two approaches.
### 15.6.0
- Git 2.37.0 and later is required by Gitaly. For installations from source, we recommend you use the [Git version provided by Gitaly](../install/installation.md#git).
### 15.4.0 ### 15.4.0
- GitLab 15.4.0 includes a [batched background migration](#batched-background-migrations) to [remove incorrect values from `expire_at` in `ci_job_artifacts` table](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/89318). - GitLab 15.4.0 includes a [batched background migration](#batched-background-migrations) to [remove incorrect values from `expire_at` in `ci_job_artifacts` table](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/89318).

View File

@ -78,11 +78,12 @@ Prerequisite:
## Change group visibility ## Change group visibility
Prerequisite: Prerequisites:
- You must have the Owner role for a group. - You must have the Owner role for a group.
- Subgroups and projects must already have visibility settings that are at least as - Subgroups and projects must already have visibility settings that are at least as
restrictive as the new setting of the parent group. restrictive as the new setting of the parent group. For example, you cannot set a group
to private if a subgroup or project in that group is public.
1. On the top bar, select **Main menu > Groups** and find your project. 1. On the top bar, select **Main menu > Groups** and find your project.
1. On the left sidebar, select **Settings > General**. 1. On the left sidebar, select **Settings > General**.

View File

@ -6,7 +6,7 @@ module API
urgency :low urgency :low
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
requires :alert_iid, type: Integer, desc: 'The IID of the Alert' requires :alert_iid, type: Integer, desc: 'The IID of the Alert'
end end

View File

@ -182,11 +182,14 @@ module API
mount ::API::Deployments mount ::API::Deployments
mount ::API::Environments mount ::API::Environments
mount ::API::FeatureFlagsUserLists mount ::API::FeatureFlagsUserLists
mount ::API::FeatureFlags
mount ::API::Features mount ::API::Features
mount ::API::FreezePeriods mount ::API::FreezePeriods
mount ::API::MergeRequestDiffs mount ::API::Keys
mount ::API::Metadata mount ::API::Metadata
mount ::API::MergeRequestDiffs
mount ::API::ProjectRepositoryStorageMoves mount ::API::ProjectRepositoryStorageMoves
mount ::API::Releases
mount ::API::Release::Links mount ::API::Release::Links
mount ::API::ResourceAccessTokens mount ::API::ResourceAccessTokens
mount ::API::ProtectedTags mount ::API::ProtectedTags
@ -238,7 +241,6 @@ module API
mount ::API::ErrorTracking::Collector mount ::API::ErrorTracking::Collector
mount ::API::ErrorTracking::ProjectSettings mount ::API::ErrorTracking::ProjectSettings
mount ::API::Events mount ::API::Events
mount ::API::FeatureFlags
mount ::API::Files mount ::API::Files
mount ::API::GenericPackages mount ::API::GenericPackages
mount ::API::Geo mount ::API::Geo
@ -263,7 +265,6 @@ module API
mount ::API::Invitations mount ::API::Invitations
mount ::API::IssueLinks mount ::API::IssueLinks
mount ::API::Issues mount ::API::Issues
mount ::API::Keys
mount ::API::Labels mount ::API::Labels
mount ::API::Lint mount ::API::Lint
mount ::API::Markdown mount ::API::Markdown
@ -301,7 +302,6 @@ module API
mount ::API::Projects mount ::API::Projects
mount ::API::ProtectedTags mount ::API::ProtectedTags
mount ::API::PypiPackages mount ::API::PypiPackages
mount ::API::Releases
mount ::API::RemoteMirrors mount ::API::RemoteMirrors
mount ::API::Repositories mount ::API::Repositories
mount ::API::ResourceLabelEvents mount ::API::ResourceLabelEvents

View File

@ -19,7 +19,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
segment ':id/boards' do segment ':id/boards' do

View File

@ -29,7 +29,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'Get a project repository branches' do desc 'Get a project repository branches' do

View File

@ -19,7 +19,7 @@ module API
prepend_mod_with('API::Ci::JobArtifacts') # rubocop: disable Cop/InjectEnterpriseEditionModule prepend_mod_with('API::Ci::JobArtifacts') # rubocop: disable Cop/InjectEnterpriseEditionModule
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'Download the artifacts archive from a job' do desc 'Download the artifacts archive from a job' do

View File

@ -11,7 +11,7 @@ module API
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
helpers do helpers do

View File

@ -11,7 +11,7 @@ module API
urgency :low urgency :low
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: ::API::API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: ::API::API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'Get all pipeline schedules' do desc 'Get all pipeline schedules' do

View File

@ -11,7 +11,7 @@ module API
urgency :low urgency :low
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: ::API::API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: ::API::API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'Get all resource groups for this project' do desc 'Get all resource groups for this project' do

View File

@ -256,7 +256,9 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID or URL-encoded path of the project owned by the authenticated user' requires :id,
types: [String, Integer],
desc: 'The ID or URL-encoded path of the project owned by the authenticated user'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
before { authorize_admin_project } before { authorize_admin_project }

View File

@ -16,7 +16,7 @@ module API
default_format :json default_format :json
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do

View File

@ -11,7 +11,7 @@ module API
urgency :low urgency :low
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'Trigger a GitLab project pipeline' do desc 'Trigger a GitLab project pipeline' do

View File

@ -13,7 +13,7 @@ module API
helpers ::API::Helpers::VariablesHelpers helpers ::API::Helpers::VariablesHelpers
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do

View File

@ -10,7 +10,7 @@ module API
feature_category :kubernetes_management feature_category :kubernetes_management
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
params do params do

View File

@ -11,7 +11,7 @@ module API
urgency :low urgency :low
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'List the agents for a project' do desc 'List the agents for a project' do

View File

@ -8,7 +8,7 @@ module API
urgency :low urgency :low
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
include PaginationParams include PaginationParams

View File

@ -27,7 +27,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS, urgency: :low do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS, urgency: :low do
desc 'Get a project repository commits' do desc 'Get a project repository commits' do

View File

@ -14,7 +14,7 @@ module API
namespace 'registry' do namespace 'registry' do
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :repositories, requirements: { id: /[0-9]*/ } do resource :repositories, requirements: { id: /[0-9]*/ } do
desc 'Get a container repository' do desc 'Get a container repository' do

View File

@ -34,7 +34,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
namespace ':id/packages/debian' do namespace ':id/packages/debian' do

View File

@ -5,12 +5,12 @@ module API
class BasicReleaseDetails < Grape::Entity class BasicReleaseDetails < Grape::Entity
include ::API::Helpers::Presentable include ::API::Helpers::Presentable
expose :name expose :name, documentation: { type: 'string', example: 'Release v1.0' }
expose :tag, as: :tag_name expose :tag, documentation: { type: 'string', example: 'v1.0' }, as: :tag_name
expose :description expose :description, documentation: { type: 'string', example: 'Finally released v1.0' }
expose :created_at expose :created_at, documentation: { type: 'dateTime', example: '2019-01-03T01:56:19.539Z' }
expose :released_at expose :released_at, documentation: { type: 'dateTime', example: '2019-01-03T01:56:19.539Z' }
expose :upcoming_release?, as: :upcoming_release expose :upcoming_release?, documentation: { type: 'boolean' }, as: :upcoming_release
end end
end end
end end

View File

@ -3,12 +3,12 @@
module API module API
module Entities module Entities
class FeatureFlag < Grape::Entity class FeatureFlag < Grape::Entity
expose :name expose :name, documentation: { type: 'string', example: 'merge_train' }
expose :description expose :description, documentation: { type: 'string', example: 'merge train feature flag' }
expose :active expose :active, documentation: { type: 'boolean' }
expose :version expose :version, documentation: { type: 'string', example: 'new_version_flag' }
expose :created_at expose :created_at, documentation: { type: 'dateTime', example: '2019-11-04T08:13:51.423Z' }
expose :updated_at expose :updated_at, documentation: { type: 'dateTime', example: '2019-11-04T08:13:51.423Z' }
expose :scopes do |_ff| expose :scopes do |_ff|
[] []
end end

View File

@ -4,8 +4,8 @@ module API
module Entities module Entities
class FeatureFlag < Grape::Entity class FeatureFlag < Grape::Entity
class Scope < Grape::Entity class Scope < Grape::Entity
expose :id expose :id, documentation: { type: 'integer', example: 1 }
expose :environment_scope expose :environment_scope, documentation: { type: 'string', example: 'production' }
end end
end end
end end

View File

@ -4,9 +4,9 @@ module API
module Entities module Entities
class FeatureFlag < Grape::Entity class FeatureFlag < Grape::Entity
class Strategy < Grape::Entity class Strategy < Grape::Entity
expose :id expose :id, documentation: { type: 'integer', example: 1 }
expose :name expose :name, documentation: { type: 'string', example: 'userWithId' }
expose :parameters expose :parameters, documentation: { type: 'string', example: '{"userIds": "user1"}' }
expose :scopes, using: FeatureFlag::Scope expose :scopes, using: FeatureFlag::Scope
end end
end end

View File

@ -16,11 +16,13 @@ module API
release.milestones.order_by_dates_and_title release.milestones.order_by_dates_and_title
end end
expose :commit_path, expose_nil: false expose :commit_path,
expose :tag_path, expose_nil: false documentation: { type: 'string', example: '/root/app/commit/588440f66559714280628a4f9799f0c4eb880a4a' },
expose_nil: false
expose :tag_path, documentation: { type: 'string', example: '/root/app/-/tags/v1.0' }, expose_nil: false
expose :assets do expose :assets do
expose :assets_count, as: :count expose :assets_count, documentation: { type: 'integer', example: 2 }, as: :count
expose :sources, using: Entities::Releases::Source, if: ->(_, _) { can_download_code? } expose :sources, using: Entities::Releases::Source, if: ->(_, _) { can_download_code? }
expose :sorted_links, as: :links, using: Entities::Releases::Link expose :sorted_links, as: :links, using: Entities::Releases::Link
end end

View File

@ -6,9 +6,9 @@ module API
class Evidence < Grape::Entity class Evidence < Grape::Entity
include ::API::Helpers::Presentable include ::API::Helpers::Presentable
expose :sha expose :sha, documentation: { type: 'string', example: '760d6cdfb0879c3ffedec13af470e0f71cf52c6cde4d' }
expose :filepath expose :filepath, documentation: { type: 'string', example: 'https://gitlab.example.com/root/app/-/releases/v1.0/evidence.json' }
expose :collected_at expose :collected_at, documentation: { type: 'dateTime', example: '2019-01-03T01:56:19.539Z' }
end end
end end
end end

View File

@ -4,14 +4,22 @@ module API
module Entities module Entities
module Releases module Releases
class Link < Grape::Entity class Link < Grape::Entity
expose :id expose :id, documentation: { type: 'integer', example: 1 }
expose :name expose :name, documentation: { type: 'string', example: 'app-v1.0.dmg' }
expose :url expose :url, documentation:
expose :direct_asset_url do |link| {
type: 'string',
example: 'https://gitlab.example.com/root/app/-/jobs/688/artifacts/raw/bin/app-v1.0.dmg'
}
expose :direct_asset_url, documentation:
{
type: 'string',
example: 'https://gitlab.example.com/root/app/-/releases/v1.0/downloads/app-v1.0.dmg'
} do |link|
::Releases::LinkPresenter.new(link).direct_asset_url ::Releases::LinkPresenter.new(link).direct_asset_url
end end
expose :external?, as: :external expose :external?, documentation: { type: 'boolean' }, as: :external
expose :link_type expose :link_type, documentation: { type: 'string', example: 'other' }
end end
end end
end end

View File

@ -4,8 +4,8 @@ module API
module Entities module Entities
module Releases module Releases
class Source < Grape::Entity class Source < Grape::Entity
expose :format expose :format, documentation: { type: 'string', example: 'zip' }
expose :url expose :url, documentation: { type: 'string', example: 'https://gitlab.example.com/root/app/-/archive/v1.0/app-v1.0.zip' }
end end
end end
end end

View File

@ -3,8 +3,15 @@
module API module API
module Entities module Entities
class SSHKey < Grape::Entity class SSHKey < Grape::Entity
expose :id, :title, :created_at, :expires_at expose :id, documentation: { type: 'integer', example: 1 }
expose :publishable_key, as: :key expose :title, documentation: { type: 'string', example: 'Sample key 25' }
expose :created_at, documentation: { type: 'dateTime', example: '2015-09-03T07:24:44.627Z' }
expose :expires_at, documentation: { type: 'dateTime', example: '2020-09-03T07:24:44.627Z' }
expose :publishable_key, as: :key, documentation:
{ type: 'string',
example: 'ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt1256k6Yjz\
GGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCdd\
NaP0L+hM7zhFNzjFvpaMgJw0=' }
end end
end end
end end

View File

@ -3,16 +3,16 @@
module API module API
module Entities module Entities
class UserBasic < UserSafe class UserBasic < UserSafe
expose :state expose :state, documentation: { type: 'string', example: 'active' }
expose :avatar_url do |user, options| expose :avatar_url, documentation: { type: 'string', example: 'https://gravatar.com/avatar/1' } do |user, options|
user.avatar_url(only_path: false) user.avatar_url(only_path: false)
end end
expose :avatar_path, if: ->(user, options) { options.fetch(:only_path, false) && user.avatar_path } expose :avatar_path, if: ->(user, options) { options.fetch(:only_path, false) && user.avatar_path }
expose :custom_attributes, using: 'API::Entities::CustomAttribute', if: :with_custom_attributes expose :custom_attributes, using: 'API::Entities::CustomAttribute', if: :with_custom_attributes
expose :web_url do |user, options| expose :web_url, documentation: { type: 'string', example: 'https://gitlab.example.com/root' } do |user, options|
Gitlab::Routing.url_helpers.user_url(user) Gitlab::Routing.url_helpers.user_url(user)
end end
end end

View File

@ -3,17 +3,23 @@
module API module API
module Entities module Entities
class UserPublic < Entities::User class UserPublic < Entities::User
expose :last_sign_in_at expose :last_sign_in_at, documentation: { type: 'dateTime', example: '2015-09-03T07:24:01.670Z' }
expose :confirmed_at expose :confirmed_at, documentation: { type: 'dateTime', example: '2015-09-03T07:24:01.670Z' }
expose :last_activity_on expose :last_activity_on, documentation: { type: 'dateTime', example: '2015-09-03T07:24:01.670Z' }
expose :email expose :email, documentation: { type: 'string', example: 'john@example.com' }
expose :theme_id, :color_scheme_id, :projects_limit, :current_sign_in_at expose :theme_id, documentation: { type: 'integer', example: 2 }
expose :color_scheme_id, documentation: { type: 'integer', example: 1 }
expose :projects_limit, documentation: { type: 'integer', example: 10 }
expose :current_sign_in_at, documentation: { type: 'dateTime', example: '2015-09-03T07:24:01.670Z' }
expose :identities, using: Entities::Identity expose :identities, using: Entities::Identity
expose :can_create_group?, as: :can_create_group expose :can_create_group?, as: :can_create_group, documentation: { type: 'boolean', example: true }
expose :can_create_project?, as: :can_create_project expose :can_create_project?, as: :can_create_project, documentation: { type: 'boolean', example: true }
expose :two_factor_enabled?, as: :two_factor_enabled
expose :external expose :two_factor_enabled?, as: :two_factor_enabled, documentation: { type: 'boolean', example: true }
expose :private_profile
expose :external, documentation: { type: 'boolean', example: false }
expose :private_profile, documentation: { type: 'boolean', example: :null }
expose :commit_email_or_default, as: :commit_email expose :commit_email_or_default, as: :commit_email
end end
end end

View File

@ -5,8 +5,9 @@ module API
class UserSafe < Grape::Entity class UserSafe < Grape::Entity
include RequestAwareEntity include RequestAwareEntity
expose :id, :username expose :id, documentation: { type: 'integer', example: 1 }
expose :name do |user| expose :username, documentation: { type: 'string', example: 'admin' }
expose :name, documentation: { type: 'string', example: 'Administrator' } do |user|
current_user = request.respond_to?(:current_user) ? request.current_user : options.fetch(:current_user, nil) current_user = request.respond_to?(:current_user) ? request.current_user : options.fetch(:current_user, nil)
user.redacted_name(current_user) user.redacted_name(current_user)

View File

@ -8,7 +8,7 @@ module API
urgency :low urgency :low
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do

View File

@ -67,7 +67,7 @@ module API
detail 'This feature was introduced in GitLab 14.1.' detail 'This feature was introduced in GitLab 14.1.'
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
post 'error_tracking/collector/api/:id/envelope' do post 'error_tracking/collector/api/:id/envelope' do
# There is a reason why we have such uncommon path. # There is a reason why we have such uncommon path.
@ -119,7 +119,7 @@ module API
detail 'This feature was introduced in GitLab 14.1.' detail 'This feature was introduced in GitLab 14.1.'
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
post 'error_tracking/collector/api/:id/store' do post 'error_tracking/collector/api/:id/store' do
# There is a reason why we have such uncommon path. # There is a reason why we have such uncommon path.

View File

@ -14,7 +14,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do

View File

@ -15,18 +15,20 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource 'projects/:id', requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource 'projects/:id', requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
resource :feature_flags do resource :feature_flags do
desc 'Get all feature flags of a project' do desc 'List feature flags for a project' do
detail 'This feature was introduced in GitLab 12.5' detail 'Gets all feature flags of the requested project. This feature was introduced in GitLab 12.5.'
success ::API::Entities::FeatureFlag success ::API::Entities::FeatureFlag
is_array true
tags %w[feature_flags]
end end
params do params do
optional :scope, optional :scope,
type: String, type: String,
desc: 'The scope of feature flags', desc: 'The scope of feature flags, one of: `enabled`, `disabled`',
values: %w[enabled disabled] values: %w[enabled disabled]
use :pagination use :pagination
end end
@ -39,22 +41,18 @@ module API
end end
desc 'Create a new feature flag' do desc 'Create a new feature flag' do
detail 'This feature was introduced in GitLab 12.5' detail 'Creates a new feature flag. This feature was introduced in GitLab 12.5.'
success ::API::Entities::FeatureFlag success ::API::Entities::FeatureFlag
tags %w[feature_flags]
end end
params do params do
requires :name, type: String, desc: 'The name of feature flag' requires :name, type: String, desc: 'The name of the feature flag'
optional :description, type: String, desc: 'The description of the feature flag' optional :description, type: String, desc: 'The description of the feature flag'
optional :active, type: Boolean, desc: 'Active/inactive value of the flag' optional :active, type: Boolean, desc: 'The active state of the flag. Defaults to `true`. Supported in GitLab 13.3 and later'
optional :version, type: String, desc: 'The version of the feature flag' optional :version, type: String, desc: 'The version of the feature flag. Must be `new_version_flag`. Omit to create a Legacy feature flag.'
optional :scopes, type: Array do
requires :environment_scope, type: String, desc: 'The environment scope of the scope'
requires :active, type: Boolean, desc: 'Active/inactive of the scope'
requires :strategies, type: JSON, desc: 'The strategies of the scope'
end
optional :strategies, type: Array do optional :strategies, type: Array do
requires :name, type: String, desc: 'The strategy name' requires :name, type: String, desc: 'The strategy name. Can be `default`, `gradualRolloutUserId`, `userWithId`, or `gitlabUserList`. In GitLab 13.5 and later, can be `flexibleRollout`'
requires :parameters, type: JSON, desc: 'The strategy parameters' requires :parameters, type: JSON, desc: 'The strategy parameters as a JSON-formatted string e.g. `{"userIds":"user1"}`', documentation: { type: 'String' }
optional :scopes, type: Array do optional :scopes, type: Array do
requires :environment_scope, type: String, desc: 'The environment scope of the scope' requires :environment_scope, type: String, desc: 'The environment scope of the scope'
end end
@ -87,9 +85,10 @@ module API
requires :feature_flag_name, type: String, desc: 'The name of the feature flag' requires :feature_flag_name, type: String, desc: 'The name of the feature flag'
end end
resource 'feature_flags/:feature_flag_name', requirements: FEATURE_FLAG_ENDPOINT_REQUIREMENTS do resource 'feature_flags/:feature_flag_name', requirements: FEATURE_FLAG_ENDPOINT_REQUIREMENTS do
desc 'Get a feature flag of a project' do desc 'Get a single feature flag' do
detail 'This feature was introduced in GitLab 12.5' detail 'Gets a single feature flag. This feature was introduced in GitLab 12.5.'
success ::API::Entities::FeatureFlag success ::API::Entities::FeatureFlag
tags %w[feature_flags]
end end
get do get do
authorize_read_feature_flag! authorize_read_feature_flag!
@ -99,20 +98,21 @@ module API
end end
desc 'Update a feature flag' do desc 'Update a feature flag' do
detail 'This feature was introduced in GitLab 13.2' detail 'Updates a feature flag. This feature was introduced in GitLab 13.2.'
success ::API::Entities::FeatureFlag success ::API::Entities::FeatureFlag
tags %w[feature_flags]
end end
params do params do
optional :name, type: String, desc: 'The name of the feature flag' optional :name, type: String, desc: 'The new name of the feature flag. Supported in GitLab 13.3 and later'
optional :description, type: String, desc: 'The description of the feature flag' optional :description, type: String, desc: 'The description of the feature flag'
optional :active, type: Boolean, desc: 'Active/inactive value of the flag' optional :active, type: Boolean, desc: 'The active state of the flag. Supported in GitLab 13.3 and later'
optional :strategies, type: Array do optional :strategies, type: Array do
optional :id, type: Integer, desc: 'The strategy id' optional :id, type: Integer, desc: 'The feature flag strategy ID'
optional :name, type: String, desc: 'The strategy type' optional :name, type: String, desc: 'The strategy name'
optional :parameters, type: JSON, desc: 'The strategy parameters' optional :parameters, type: JSON, desc: 'The strategy parameters as a JSON-formatted string e.g. `{"userIds":"user1"}`', documentation: { type: 'String' }
optional :_destroy, type: Boolean, desc: 'Delete the strategy when true' optional :_destroy, type: Boolean, desc: 'Delete the strategy when true'
optional :scopes, type: Array do optional :scopes, type: Array do
optional :id, type: Integer, desc: 'The environment scope id' optional :id, type: Integer, desc: 'The scope id'
optional :environment_scope, type: String, desc: 'The environment scope of the scope' optional :environment_scope, type: String, desc: 'The environment scope of the scope'
optional :_destroy, type: Boolean, desc: 'Delete the scope when true' optional :_destroy, type: Boolean, desc: 'Delete the scope when true'
end end
@ -142,8 +142,9 @@ module API
end end
desc 'Delete a feature flag' do desc 'Delete a feature flag' do
detail 'This feature was introduced in GitLab 12.5' detail 'Deletes a feature flag. This feature was introduced in GitLab 12.5.'
success ::API::Entities::FeatureFlag success ::API::Entities::FeatureFlag
tags %w[feature_flags]
end end
delete do delete do
authorize_destroy_feature_flag! authorize_destroy_feature_flag!

View File

@ -18,7 +18,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do

View File

@ -17,6 +17,10 @@ module API
before { require_packages_enabled! } before { require_packages_enabled! }
helpers do helpers do
def project
user_project(action: :read_package)
end
def case_decode(str) def case_decode(str)
# Converts "github.com/!azure" to "github.com/Azure" # Converts "github.com/!azure" to "github.com/Azure"
# #
@ -32,12 +36,12 @@ module API
end end
def find_module def find_module
not_found! unless Feature.enabled?(:go_proxy, user_project) not_found! unless Feature.enabled?(:go_proxy, project)
module_name = case_decode params[:module_name] module_name = case_decode params[:module_name]
bad_request_missing_attribute!('Module Name') if module_name.blank? bad_request_missing_attribute!('Module Name') if module_name.blank?
mod = ::Packages::Go::ModuleFinder.new(user_project, module_name).execute mod = ::Packages::Go::ModuleFinder.new(project, module_name).execute
not_found! unless mod not_found! unless mod
@ -58,13 +62,13 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
requires :module_name, type: String, desc: 'Module name', coerce_with: ->(val) { CGI.unescape(val) } requires :module_name, type: String, desc: 'Module name', coerce_with: ->(val) { CGI.unescape(val) }
end end
route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true, authenticate_non_public: true route_setting :authentication, job_token_allowed: true, basic_auth_personal_access_token: true, authenticate_non_public: true
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
before do before do
authorize_read_package! authorize_read_package!(project)
end end
namespace ':id/packages/go/*module_name/@v' do namespace ':id/packages/go/*module_name/@v' do

View File

@ -3,6 +3,8 @@
module API module API
module Helpers module Helpers
module PackagesHelpers module PackagesHelpers
extend ::Gitlab::Utils::Override
MAX_PACKAGE_FILE_SIZE = 50.megabytes.freeze MAX_PACKAGE_FILE_SIZE = 50.megabytes.freeze
def require_packages_enabled! def require_packages_enabled!
@ -48,6 +50,34 @@ module API
require_gitlab_workhorse! require_gitlab_workhorse!
end end
override :user_project
def user_project(action: :read_project)
case action
when :read_project
super()
when :read_package
user_project_with_read_package
else
raise ArgumentError, "unexpected action: #{action}"
end
end
# This function is similar to the `find_project!` function, but it considers the `read_package` ability.
def user_project_with_read_package
strong_memoize(:user_project_with_read_package) do
project = find_project(params[:id])
next forbidden! unless authorized_project_scope?(project)
next project if can?(current_user, :read_package, project&.packages_policy_subject)
# guest users can have :read_project but not :read_package
next forbidden! if can?(current_user, :read_project, project)
next unauthorized! if authenticate_non_public?
not_found!('Project')
end
end
def track_package_event(event_name, scope, **args) def track_package_event(event_name, scope, **args)
::Packages::CreateEventService.new(nil, current_user, event_name: event_name, scope: scope).execute ::Packages::CreateEventService.new(nil, current_user, event_name: event_name, scope: scope).execute
category = args.delete(:category) || self.options[:for].name category = args.delete(:category) || self.options[:for].name

View File

@ -65,7 +65,7 @@ module API
# The support for `:id/services` can be dropped if we create an API V5. # The support for `:id/services` can be dropped if we create an API V5.
[':id/services', ':id/integrations'].each do |path| [':id/services', ':id/integrations'].each do |path|
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
before { authenticate! } before { authenticate! }
@ -149,7 +149,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc "Trigger a slash command for #{integration_slug}" do desc "Trigger a slash command for #{integration_slug}" do

View File

@ -10,7 +10,7 @@ module API
urgency :low urgency :low
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
requires :issue_iid, type: Integer, desc: 'The internal ID of a project issue' requires :issue_iid, type: Integer, desc: 'The internal ID of a project issue'
end end
resource :projects, requirements: { id: %r{[^/]+} } do resource :projects, requirements: { id: %r{[^/]+} } do

View File

@ -198,7 +198,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
include TimeTrackingEndpoints include TimeTrackingEndpoints

View File

@ -9,8 +9,13 @@ module API
resource :keys do resource :keys do
desc 'Get single ssh key by id. Only available to admin users' do desc 'Get single ssh key by id. Only available to admin users' do
detail 'Get SSH key with user by ID of an SSH key. Note only administrators can lookup SSH key with user by ID\
of an SSH key'
success Entities::SSHKeyWithUser success Entities::SSHKeyWithUser
end end
params do
requires :id, types: [String, Integer], desc: 'The ID of an SSH key', documentation: { example: '2' }
end
get ":id" do get ":id" do
authenticated_as_admin! authenticated_as_admin!
@ -19,11 +24,14 @@ module API
present key, with: Entities::SSHKeyWithUser, current_user: current_user present key, with: Entities::SSHKeyWithUser, current_user: current_user
end end
desc 'Get SSH Key information' do desc 'Get user by fingerprint of SSH key' do
success Entities::UserWithAdmin success Entities::UserWithAdmin
detail 'You can search for a user that owns a specific SSH key. Note only administrators can lookup SSH key\
with the fingerprint of an SSH key'
end end
params do params do
requires :fingerprint, type: String, desc: 'Search for a SSH fingerprint' requires :fingerprint, type: String, desc: 'The fingerprint of an SSH key',
documentation: { example: 'ba:81:59:68:d7:6c:cd:02:02:bf:6a:9b:55:4e:af:d1' }
end end
get do get do
authenticated_with_can_read_all_resources! authenticated_with_can_read_all_resources!

View File

@ -15,7 +15,7 @@ module API
label_id: API::NO_SLASH_URL_PART_REGEX) label_id: API::NO_SLASH_URL_PART_REGEX)
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: LABEL_ENDPOINT_REQUIREMENTS do resource :projects, requirements: LABEL_ENDPOINT_REQUIREMENTS do
desc 'Get all labels of the project' do desc 'Get all labels of the project' do

View File

@ -220,7 +220,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'Download the maven package file' do desc 'Download the maven package file' do

View File

@ -10,7 +10,7 @@ module API
feature_category :code_review feature_category :code_review
params do params do
requires :id, type: String, desc: 'The ID of the project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'Get a list of merge request diff versions' do desc 'Get a list of merge request diff versions' do

View File

@ -170,7 +170,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
include TimeTrackingEndpoints include TimeTrackingEndpoints

View File

@ -80,7 +80,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'API to interface with MLFlow Client, REST API version 1.28.0' do desc 'API to interface with MLFlow Client, REST API version 1.28.0' do

View File

@ -11,7 +11,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
namespace 'projects/:id/packages/npm' do namespace 'projects/:id/packages/npm' do
desc 'Download the NPM tarball' do desc 'Download the NPM tarball' do

View File

@ -91,7 +91,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project', regexp: ::API::Concerns::Packages::NugetEndpoints::POSITIVE_INTEGER_REGEX requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project', regexp: ::API::Concerns::Packages::NugetEndpoints::POSITIVE_INTEGER_REGEX
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
namespace ':id/packages/nuget' do namespace ':id/packages/nuget' do

View File

@ -14,7 +14,7 @@ module API
helpers ::API::Helpers::PackagesHelpers helpers ::API::Helpers::PackagesHelpers
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
requires :package_id, type: Integer, desc: 'The ID of a package' requires :package_id, type: Integer, desc: 'The ID of a package'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do

View File

@ -10,7 +10,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'Unpublish pages' do desc 'Unpublish pages' do

View File

@ -54,7 +54,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
before do before do

View File

@ -13,7 +13,7 @@ module API
urgency :low urgency :low
params do params do
requires :id, type: String, desc: 'The ID of the project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'Get all clusters from the project' do desc 'Get all clusters from the project' do

View File

@ -16,7 +16,7 @@ module API
urgency :low urgency :low
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
route_setting :authentication, job_token_allowed: true, job_token_scope: :project route_setting :authentication, job_token_allowed: true, job_token_scope: :project
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do

View File

@ -3,7 +3,7 @@
module API module API
class ProjectDebianDistributions < ::API::Base class ProjectDebianDistributions < ::API::Base
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
before do before do

View File

@ -12,7 +12,7 @@ module API
urgency :low urgency :low
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc "List a Project's visible events" do desc "List a Project's visible events" do

View File

@ -11,7 +11,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: { id: %r{[^/]+} } do resource :projects, requirements: { id: %r{[^/]+} } do
desc 'Get export status' do desc 'Get export status' do

View File

@ -37,7 +37,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
namespace ':id/hooks' do namespace ':id/hooks' do

View File

@ -108,7 +108,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
desc 'Get a project import status' do desc 'Get a project import status' do
detail 'This feature was introduced in GitLab 10.6.' detail 'This feature was introduced in GitLab 10.6.'

View File

@ -11,7 +11,7 @@ module API
urgency :low urgency :low
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'Get a list of project milestones' do desc 'Get a list of project milestones' do

View File

@ -14,7 +14,7 @@ module API
helpers ::API::Helpers::PackagesHelpers helpers ::API::Helpers::PackagesHelpers
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'Get all project packages' do desc 'Get all project packages' do

View File

@ -55,7 +55,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'Get a list of all project repository storage moves' do desc 'Get a list of all project repository storage moves' do

View File

@ -9,7 +9,7 @@ module API
feature_category :snippets feature_category :snippets
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
helpers Helpers::SnippetsHelpers helpers Helpers::SnippetsHelpers

View File

@ -10,7 +10,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'Get the list of project fetch statistics for the last 30 days' desc 'Get the list of project fetch statistics for the last 30 days'

View File

@ -15,7 +15,7 @@ module API
feature_category :source_code_management feature_category :source_code_management
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
requires :type, type: String, values: TEMPLATE_TYPES, desc: 'The type (dockerfiles|gitignores|gitlab_ci_ymls|licenses|metrics_dashboard_ymls|issues|merge_requests) of the template' requires :type, type: String, values: TEMPLATE_TYPES, desc: 'The type (dockerfiles|gitignores|gitlab_ci_ymls|licenses|metrics_dashboard_ymls|issues|merge_requests) of the template'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do

View File

@ -336,7 +336,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'Get a single project' do desc 'Get a single project' do

View File

@ -13,7 +13,10 @@ module API
helpers Helpers::ProtectedBranchesHelpers helpers Helpers::ProtectedBranchesHelpers
params do params do
requires :id, type: String, desc: 'The ID of a project', documentation: { example: 'gitlab-org/gitlab' } requires :id,
types: [String, Integer],
desc: 'The ID or URL-encoded path of the project',
documentation: { example: 'gitlab-org/gitlab' }
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc "Get a project's protected branches" do desc "Get a project's protected branches" do

View File

@ -13,7 +13,7 @@ module API
helpers Helpers::ProtectedTagsHelpers helpers Helpers::ProtectedTagsHelpers
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc "Get a project's protected tags" do desc "Get a project's protected tags" do

View File

@ -157,7 +157,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do

View File

@ -4,6 +4,8 @@ module API
class Releases < ::API::Base class Releases < ::API::Base
include PaginationParams include PaginationParams
releases_tags = %w[releases]
RELEASE_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS RELEASE_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS
.merge(tag_name: API::NO_SLASH_URL_PART_REGEX) .merge(tag_name: API::NO_SLASH_URL_PART_REGEX)
RELEASE_CLI_USER_AGENT = 'GitLab-release-cli' RELEASE_CLI_USER_AGENT = 'GitLab-release-cli'
@ -12,20 +14,37 @@ module API
urgency :low urgency :low
params do params do
requires :id, type: String, desc: 'The ID of a group' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the group'
end end
resource :groups, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :groups, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
before { authorize_read_group_releases! } before { authorize_read_group_releases! }
desc 'Get a list of releases for projects in this group.' do desc 'List group releases' do
detail 'Returns a list of group releases.'
success Entities::Release success Entities::Release
failure [
{ code: 400, message: 'Bad request' },
{ code: 403, message: 'Forbidden' },
{ code: 404, message: 'Not found' }
]
is_array true
tags releases_tags
end end
params do params do
requires :id, type: Integer, desc: 'The ID of the group to get releases for' requires :id,
optional :sort, type: String, values: %w[asc desc], default: 'desc', types: [String, Integer],
desc: 'Return projects sorted in ascending and descending order by released_at' desc: 'The ID or URL-encoded path of the group owned by the authenticated user'
optional :simple, type: Boolean, default: false,
desc: 'Return only the ID, URL, name, and path of each project' optional :sort,
type: String,
values: %w[asc desc],
default: 'desc',
desc: 'The direction of the order. Either `desc` (default) for descending order or `asc` for ascending order'
optional :simple,
type: Boolean,
default: false,
desc: 'Return only limited fields for each release'
use :pagination use :pagination
end end
@ -42,26 +61,38 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
before { authorize_read_releases! } before { authorize_read_releases! }
after { track_release_event } after { track_release_event }
desc 'Get a project releases' do desc 'List Releases' do
detail 'This feature was introduced in GitLab 11.7.' detail 'Returns a paginated list of releases. This feature was introduced in GitLab 11.7.'
named 'get_releases' named 'get_releases'
is_array true
success Entities::Release success Entities::Release
tags releases_tags
end end
params do params do
use :pagination use :pagination
optional :order_by, type: String, values: %w[released_at created_at], default: 'released_at',
desc: 'Return releases ordered by `released_at` or `created_at`.' optional :order_by,
optional :sort, type: String, values: %w[asc desc], default: 'desc', type: String,
desc: 'Return releases sorted in `asc` or `desc` order.' values: %w[released_at created_at],
optional :include_html_description, type: Boolean, default: 'released_at',
desc: 'If `true`, a response includes HTML rendered markdown of the release description.' desc: 'The field to use as order. Either `released_at` (default) or `created_at`'
optional :sort,
type: String,
values: %w[asc desc],
default: 'desc',
desc: 'The direction of the order. Either `desc` (default) for descending order or `asc` for ascending order'
optional :include_html_description,
type: Boolean,
desc: 'If `true`, a response includes HTML rendered markdown of the release description'
end end
route_setting :authentication, job_token_allowed: true route_setting :authentication, job_token_allowed: true
get ':id/releases' do get ':id/releases' do
@ -81,15 +112,22 @@ module API
include_html_description: params[:include_html_description] include_html_description: params[:include_html_description]
end end
desc 'Get a single project release' do desc 'Get a release by a tag name' do
detail 'This feature was introduced in GitLab 11.7.' detail 'Gets a release for the given tag. This feature was introduced in GitLab 11.7.'
named 'get_release' named 'get_release'
success Entities::Release success Entities::Release
failure [
{ code: 401, message: 'Unauthorized' },
{ code: 404, message: 'Not found' }
]
tags releases_tags
end end
params do params do
requires :tag_name, type: String, desc: 'The name of the tag', as: :tag requires :tag_name, type: String, desc: 'The Git tag the release is associated with', as: :tag
optional :include_html_description, type: Boolean,
desc: 'If `true`, a response includes HTML rendered markdown of the release description.' optional :include_html_description,
type: Boolean,
desc: 'If `true`, a response includes HTML rendered markdown of the release description'
end end
route_setting :authentication, job_token_allowed: true route_setting :authentication, job_token_allowed: true
get ':id/releases/:tag_name', requirements: RELEASE_ENDPOINT_REQUIREMENTS do get ':id/releases/:tag_name', requirements: RELEASE_ENDPOINT_REQUIREMENTS do
@ -103,13 +141,19 @@ module API
desc 'Download a project release asset file' do desc 'Download a project release asset file' do
detail 'This feature was introduced in GitLab 15.4.' detail 'This feature was introduced in GitLab 15.4.'
named 'download_release_asset_file' named 'download_release_asset_file'
failure [
{ code: 401, message: 'Unauthorized' },
{ code: 404, message: 'Not found' }
]
tags releases_tags
end end
params do params do
requires :tag_name, type: String, requires :tag_name, type: String, desc: 'The Git tag the release is associated with', as: :tag
desc: 'The name of the tag.', as: :tag
requires :file_path, type: String, requires :file_path,
file_path: true, type: String,
desc: 'The path to the file to download, as specified when creating the release asset.' file_path: true,
desc: 'The path to the file to download, as specified when creating the release asset'
end end
route_setting :authentication, job_token_allowed: true route_setting :authentication, job_token_allowed: true
get ':id/releases/:tag_name/downloads/*file_path', format: false, requirements: RELEASE_ENDPOINT_REQUIREMENTS do get ':id/releases/:tag_name/downloads/*file_path', format: false, requirements: RELEASE_ENDPOINT_REQUIREMENTS do
@ -127,9 +171,17 @@ module API
desc 'Get the latest project release' do desc 'Get the latest project release' do
detail 'This feature was introduced in GitLab 15.4.' detail 'This feature was introduced in GitLab 15.4.'
named 'get_latest_release' named 'get_latest_release'
failure [
{ code: 401, message: 'Unauthorized' },
{ code: 404, message: 'Not found' }
]
tags releases_tags
end end
params do params do
requires :suffix_path, type: String, file_path: true, desc: 'The path to be suffixed to the latest release' requires :suffix_path,
type: String,
file_path: true,
desc: 'The path to be suffixed to the latest release'
end end
route_setting :authentication, job_token_allowed: true route_setting :authentication, job_token_allowed: true
get ':id/releases/permalink/latest(/)(*suffix_path)', format: false, requirements: RELEASE_ENDPOINT_REQUIREMENTS do get ':id/releases/permalink/latest(/)(*suffix_path)', format: false, requirements: RELEASE_ENDPOINT_REQUIREMENTS do
@ -156,27 +208,50 @@ module API
redirect redirect_url redirect redirect_url
end end
desc 'Create a new release' do desc 'Create a release' do
detail 'This feature was introduced in GitLab 11.7.' detail 'Creates a release. Developer level access to the project is required to create a release. This feature was introduced in GitLab 11.7.'
named 'create_release' named 'create_release'
success Entities::Release success Entities::Release
failure [
{ code: 400, message: 'Bad request' },
{ code: 401, message: 'Unauthorized' },
{ code: 403, message: 'Forbidden' },
{ code: 404, message: 'Not found' },
{ code: 409, message: 'Conflict' },
{ code: 422, message: 'Unprocessable entity' }
]
tags releases_tags
end end
params do params do
requires :tag_name, type: String, desc: 'The name of the tag', as: :tag requires :tag_name, type: String, desc: 'The tag where the release is created from', as: :tag
optional :tag_message, type: String, desc: 'Message to use if creating a new annotated tag' optional :tag_message, type: String, desc: 'Message to use if creating a new annotated tag'
optional :name, type: String, desc: 'The name of the release' optional :name, type: String, desc: 'The release name'
optional :description, type: String, desc: 'The release notes' optional :description, type: String, desc: 'The description of the release. You can use Markdown'
optional :ref, type: String, desc: 'Commit SHA or branch name to use if creating a new tag'
optional :ref,
type: String,
desc: "If a tag specified in `tag_name` doesn't exist, the release is created from `ref` and tagged " \
"with `tag_name`. It can be a commit SHA, another tag name, or a branch name."
optional :assets, type: Hash do optional :assets, type: Hash do
optional :links, type: Array do optional :links, type: Array do
requires :name, type: String, desc: 'The name of the link' requires :name, type: String, desc: 'The name of the link. Link names must be unique within the release'
requires :url, type: String, desc: 'The URL of the link' requires :url, type: String, desc: 'The URL of the link. Link URLs must be unique within the release'
optional :filepath, type: String, desc: 'The filepath of the link' optional :filepath, type: String, desc: 'Optional path for a direct asset link'
optional :link_type, type: String, desc: 'The link type, one of: "runbook", "image", "package" or "other"' optional :link_type, type: String, desc: 'The type of the link: `other`, `runbook`, `image`, `package`. Defaults to `other`'
end end
end end
optional :milestones, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce, desc: 'The titles of the related milestones', default: []
optional :released_at, type: DateTime, desc: 'The date when the release will be/was ready. Defaults to the current time.' optional :milestones,
type: Array[String],
coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce,
desc: 'The title of each milestone the release is associated with. GitLab Premium customers can specify group milestones',
default: []
optional :released_at,
type: DateTime,
desc: 'Date and time for the release. Defaults to the current time. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`). ' \
'Only provide this field if creating an upcoming or historical release.'
end end
route_setting :authentication, job_token_allowed: true route_setting :authentication, job_token_allowed: true
post ':id/releases' do post ':id/releases' do
@ -196,16 +271,27 @@ module API
end end
desc 'Update a release' do desc 'Update a release' do
detail 'This feature was introduced in GitLab 11.7.' detail 'Updates a release. Developer level access to the project is required to update a release. This feature was introduced in GitLab 11.7.'
named 'update_release' named 'update_release'
success Entities::Release success Entities::Release
failure [
{ code: 400, message: 'Bad request' },
{ code: 401, message: 'Unauthorized' },
{ code: 403, message: 'Forbidden' },
{ code: 404, message: 'Not found' }
]
tags releases_tags
end end
params do params do
requires :tag_name, type: String, desc: 'The name of the tag', as: :tag requires :tag_name, type: String, desc: 'The Git tag the release is associated with', as: :tag
optional :name, type: String, desc: 'The name of the release' optional :name, type: String, desc: 'The release name'
optional :description, type: String, desc: 'Release notes with markdown support' optional :description, type: String, desc: 'The description of the release. You can use Markdown'
optional :released_at, type: DateTime, desc: 'The date when the release will be/was ready.' optional :released_at, type: DateTime, desc: 'The date when the release is/was ready. Expected in ISO 8601 format (`2019-03-15T08:00:00Z`)'
optional :milestones, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce, desc: 'The titles of the related milestones'
optional :milestones,
type: Array[String],
coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce,
desc: 'The title of each milestone to associate with the release. GitLab Premium customers can specify group milestones. To remove all milestones from the release, specify `[]`'
end end
route_setting :authentication, job_token_allowed: true route_setting :authentication, job_token_allowed: true
put ':id/releases/:tag_name', requirements: RELEASE_ENDPOINT_REQUIREMENTS do put ':id/releases/:tag_name', requirements: RELEASE_ENDPOINT_REQUIREMENTS do
@ -226,12 +312,19 @@ module API
end end
desc 'Delete a release' do desc 'Delete a release' do
detail 'This feature was introduced in GitLab 11.7.' detail "Delete a release. Deleting a release doesn't delete the associated tag. Maintainer level access to the project is required to delete a release. This feature was introduced in GitLab 11.7."
named 'delete_release' named 'delete_release'
success Entities::Release success Entities::Release
failure [
{ code: 400, message: 'Bad request' },
{ code: 401, message: 'Unauthorized' },
{ code: 403, message: 'Forbidden' },
{ code: 404, message: 'Not found' }
]
tags releases_tags
end end
params do params do
requires :tag_name, type: String, desc: 'The name of the tag', as: :tag requires :tag_name, type: String, desc: 'The Git tag the release is associated with', as: :tag
end end
route_setting :authentication, job_token_allowed: true route_setting :authentication, job_token_allowed: true
delete ':id/releases/:tag_name', requirements: RELEASE_ENDPOINT_REQUIREMENTS do delete ':id/releases/:tag_name', requirements: RELEASE_ENDPOINT_REQUIREMENTS do

View File

@ -11,7 +11,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc "List the project's remote mirrors" do desc "List the project's remote mirrors" do

View File

@ -41,7 +41,7 @@ module API
feature_category :source_code_management feature_category :source_code_management
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
helpers do helpers do

View File

@ -21,7 +21,7 @@ module API
end end
params do params do
requires :id, type: String, desc: 'The ID of a project' requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
end end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
namespace ':id/packages/rpm' do namespace ':id/packages/rpm' do

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