Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
f33d86ffac
commit
0dd9f7b364
|
|
@ -44,10 +44,10 @@ export function createProject(projectData) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function deleteProject(projectId) {
|
export function deleteProject(projectId, params) {
|
||||||
const url = buildApiUrl(PROJECT_PATH).replace(':id', projectId);
|
const url = buildApiUrl(PROJECT_PATH).replace(':id', projectId);
|
||||||
|
|
||||||
return axios.delete(url);
|
return axios.delete(url, { params });
|
||||||
}
|
}
|
||||||
|
|
||||||
export function importProjectMembers(sourceId, targetId) {
|
export function importProjectMembers(sourceId, targetId) {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
export const organizationProjects = [
|
export const organizationProjects = [
|
||||||
{
|
{
|
||||||
id: 'gid://gitlab/Project/8',
|
id: 'gid://gitlab/Project/8',
|
||||||
|
fullPath: 'project/8',
|
||||||
nameWithNamespace: 'Twitter / Typeahead.Js',
|
nameWithNamespace: 'Twitter / Typeahead.Js',
|
||||||
organizationEditPath: '/-/organizations/default/projects/twitter/Typeahead.Js/edit',
|
organizationEditPath: '/-/organizations/default/projects/twitter/Typeahead.Js/edit',
|
||||||
webUrl: 'http://127.0.0.1:3000/twitter/Typeahead.Js',
|
webUrl: 'http://127.0.0.1:3000/twitter/Typeahead.Js',
|
||||||
|
|
@ -40,6 +41,7 @@ export const organizationProjects = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'gid://gitlab/Project/7',
|
id: 'gid://gitlab/Project/7',
|
||||||
|
fullPath: 'project/7',
|
||||||
nameWithNamespace: 'Flightjs / Flight',
|
nameWithNamespace: 'Flightjs / Flight',
|
||||||
organizationEditPath: '/-/organizations/default/projects/flightjs/Flight/edit',
|
organizationEditPath: '/-/organizations/default/projects/flightjs/Flight/edit',
|
||||||
webUrl: 'http://127.0.0.1:3000/flightjs/Flight',
|
webUrl: 'http://127.0.0.1:3000/flightjs/Flight',
|
||||||
|
|
@ -73,6 +75,7 @@ export const organizationProjects = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'gid://gitlab/Project/6',
|
id: 'gid://gitlab/Project/6',
|
||||||
|
fullPath: 'project/6',
|
||||||
nameWithNamespace: 'Jashkenas / Underscore',
|
nameWithNamespace: 'Jashkenas / Underscore',
|
||||||
organizationEditPath: '/-/organizations/default/projects/jashkenas/Underscore/edit',
|
organizationEditPath: '/-/organizations/default/projects/jashkenas/Underscore/edit',
|
||||||
webUrl: 'http://127.0.0.1:3000/jashkenas/Underscore',
|
webUrl: 'http://127.0.0.1:3000/jashkenas/Underscore',
|
||||||
|
|
@ -106,6 +109,7 @@ export const organizationProjects = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'gid://gitlab/Project/5',
|
id: 'gid://gitlab/Project/5',
|
||||||
|
fullPath: 'project/5',
|
||||||
nameWithNamespace: 'Commit451 / Lab Coat',
|
nameWithNamespace: 'Commit451 / Lab Coat',
|
||||||
organizationEditPath: '/-/organizations/default/projects/Commit451/lab-coat/edit',
|
organizationEditPath: '/-/organizations/default/projects/Commit451/lab-coat/edit',
|
||||||
webUrl: 'http://127.0.0.1:3000/Commit451/lab-coat',
|
webUrl: 'http://127.0.0.1:3000/Commit451/lab-coat',
|
||||||
|
|
@ -139,6 +143,7 @@ export const organizationProjects = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'gid://gitlab/Project/1',
|
id: 'gid://gitlab/Project/1',
|
||||||
|
fullPath: 'project/1',
|
||||||
nameWithNamespace: 'Toolbox / Gitlab Smoke Tests',
|
nameWithNamespace: 'Toolbox / Gitlab Smoke Tests',
|
||||||
organizationEditPath: '/-/organizations/default/projects/toolbox/gitlab-smoke-tests/edit',
|
organizationEditPath: '/-/organizations/default/projects/toolbox/gitlab-smoke-tests/edit',
|
||||||
webUrl: 'http://127.0.0.1:3000/toolbox/gitlab-smoke-tests',
|
webUrl: 'http://127.0.0.1:3000/toolbox/gitlab-smoke-tests',
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
fragment BaseProject on Project {
|
fragment BaseProject on Project {
|
||||||
id
|
id
|
||||||
|
fullPath
|
||||||
archived
|
archived
|
||||||
nameWithNamespace
|
nameWithNamespace
|
||||||
organizationEditPath
|
organizationEditPath
|
||||||
|
|
|
||||||
|
|
@ -113,10 +113,7 @@ export default {
|
||||||
<div class="hide-collapsed gl-line-height-20 gl-font-weight-bold">
|
<div class="hide-collapsed gl-line-height-20 gl-font-weight-bold">
|
||||||
{{ contactsLabel }}
|
{{ contactsLabel }}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div v-if="shouldShowContacts" class="hide-collapsed gl-display-flex gl-flex-wrap gl-mt-2">
|
||||||
class="hide-collapsed gl-display-flex gl-flex-wrap"
|
|
||||||
:class="contacts.length > 0 ? 'gl-mt-2' : ''"
|
|
||||||
>
|
|
||||||
<div
|
<div
|
||||||
v-for="(contact, index) in contacts"
|
v-for="(contact, index) in contacts"
|
||||||
:id="`contact_container_${index}`"
|
:id="`contact_container_${index}`"
|
||||||
|
|
@ -137,5 +134,12 @@ export default {
|
||||||
</gl-popover>
|
</gl-popover>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
data-testid="crm-empty-message"
|
||||||
|
class="gl-display-flex gl-align-items-center hide-collapsed gl-text-gray-500"
|
||||||
|
>
|
||||||
|
{{ __('To add active contacts, use /add_contacts.') }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import {
|
||||||
GlSprintf,
|
GlSprintf,
|
||||||
GlModal,
|
GlModal,
|
||||||
GlAlert,
|
GlAlert,
|
||||||
GlLoadingIcon,
|
|
||||||
GlDisclosureDropdown,
|
GlDisclosureDropdown,
|
||||||
GlDisclosureDropdownGroup,
|
GlDisclosureDropdownGroup,
|
||||||
GlDisclosureDropdownItem,
|
GlDisclosureDropdownItem,
|
||||||
|
|
@ -40,7 +39,6 @@ export default {
|
||||||
GlSprintf,
|
GlSprintf,
|
||||||
GlModal,
|
GlModal,
|
||||||
GlAlert,
|
GlAlert,
|
||||||
GlLoadingIcon,
|
|
||||||
GlDisclosureDropdown,
|
GlDisclosureDropdown,
|
||||||
GlDisclosureDropdownGroup,
|
GlDisclosureDropdownGroup,
|
||||||
GlDisclosureDropdownItem,
|
GlDisclosureDropdownItem,
|
||||||
|
|
@ -347,7 +345,6 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<gl-modal
|
<gl-modal
|
||||||
ref="deleteModal"
|
|
||||||
v-model="isDeleteModalVisible"
|
v-model="isDeleteModalVisible"
|
||||||
modal-id="delete-modal"
|
modal-id="delete-modal"
|
||||||
:title="__('Delete snippet modal')"
|
:title="__('Delete snippet modal')"
|
||||||
|
|
@ -374,11 +371,10 @@ export default {
|
||||||
<gl-button
|
<gl-button
|
||||||
variant="danger"
|
variant="danger"
|
||||||
category="primary"
|
category="primary"
|
||||||
:disabled="isLoading"
|
:loading="isLoading"
|
||||||
data-testid="delete-snippet-button"
|
data-testid="delete-snippet-button"
|
||||||
@click="deleteSnippet"
|
@click="deleteSnippet"
|
||||||
>
|
>
|
||||||
<gl-loading-icon v-if="isLoading" size="sm" inline />
|
|
||||||
{{ __('Delete snippet') }}
|
{{ __('Delete snippet') }}
|
||||||
</gl-button>
|
</gl-button>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ export default {
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<span v-else class="gl-text-secondary">
|
<span v-else class="gl-text-secondary">
|
||||||
{{ s__('TimeTracking|Use /spend or /estimate to manage time.') }}
|
{{ s__('TimeTracking|To manage time, use /spend or /estimate.') }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
# Use this template to announce a feature deprecation or other
|
|
||||||
# important planned changes at least three releases prior to removal.
|
|
||||||
# Breaking changes must happen in a major release.
|
|
||||||
#
|
|
||||||
# See the deprecation guidelines to confirm your understanding of GitLab's definitions:
|
|
||||||
# https://docs.gitlab.com/ee/development/deprecation_guidelines/#terminology
|
|
||||||
#
|
|
||||||
# If an End of Support period applies, see the OPTIONAL section below.
|
|
||||||
#
|
|
||||||
# For more information, see the handbook:
|
|
||||||
# https://handbook.gitlab.com/handbook/marketing/blog/release-posts/#deprecations-and-other-planned-breaking-change-announcements
|
|
||||||
|
|
||||||
# ===================
|
|
||||||
# REQUIRED FIELDS
|
|
||||||
# ===================
|
|
||||||
|
|
||||||
# ----- DELETE EVERYTHING ABOVE THIS LINE -----
|
|
||||||
|
|
||||||
- title: "Hosted Runners on Linux operating system upgrade"
|
|
||||||
# The milestones for the deprecation announcement, and the removal.
|
|
||||||
removal_milestone: "17.0"
|
|
||||||
announcement_milestone: "16.10"
|
|
||||||
# Change breaking_change to false if needed.
|
|
||||||
breaking_change: true
|
|
||||||
# The stage and GitLab username of the person reporting the change,
|
|
||||||
# and a link to the deprecation issue
|
|
||||||
reporter: tmaczukin
|
|
||||||
stage: ci
|
|
||||||
issue_url: https://gitlab.com/gitlab-org/ci-cd/shared-runners/infrastructure/-/issues/60
|
|
||||||
impact: low # Can be one of: [critical, high, medium, low]
|
|
||||||
scope: instance # Can be one or a combination of: [instance, group, project]
|
|
||||||
resolution_role: Developer # Can be one of: [Admin, Owner, Maintainer, Developer]
|
|
||||||
manual_task: true # Can be true or false. Use this to denote whether a resolution action must be performed manually (true), or if it can be automated by using the API or other automation (false).
|
|
||||||
body: | # (required) Don't change this line.
|
|
||||||
With GitLab 17.0 we're upgrading the container-optimized operating system ([COS](https://cloud.google.com/container-optimized-os/docs))
|
|
||||||
of the ephemeral VMs used to execute jobs for [Hosted Runners on Linux](https://docs.gitlab.com/ee/ci/runners/saas/linux_saas_runner.html).
|
|
||||||
The COS upgrade includes a Docker Engine upgrade from Version 19.03.15 to Version 23.0.5, which introduced
|
|
||||||
a known compatibility issue.
|
|
||||||
|
|
||||||
GitLab CI/CD jobs [using Docker-in-Docker-based jobs](https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#use-docker-in-docker)
|
|
||||||
with a Docker-in-Docker service version prior to 20.10 and GitLab CI/CD jobs [using Kaniko to build container images](https://docs.gitlab.com/ee/ci/docker/using_kaniko.html)
|
|
||||||
with a Kaniko service version older than `v1.9.0` will start failing.
|
|
||||||
|
|
||||||
To fix these issues, an update of service version in `.gitlab-ci.yml` is required.
|
|
||||||
|
|
||||||
Both issues, including a detailed explanation of how they affect jobs and how to fix
|
|
||||||
the issue, are described
|
|
||||||
[in the announcement blog post](https://about.gitlab.com/blog/2023/10/04/updating-the-os-version-of-saas-runners-on-linux/).
|
|
||||||
|
|
||||||
# ==============================
|
|
||||||
# OPTIONAL END-OF-SUPPORT FIELDS
|
|
||||||
# ==============================
|
|
||||||
#
|
|
||||||
# If an End of Support period applies:
|
|
||||||
# 1) Share this announcement in the `#spt_managers` Support channel in Slack
|
|
||||||
# 2) Mention `@gitlab-com/support` in this merge request.
|
|
||||||
#
|
|
||||||
# When support for this feature ends, in XX.YY milestone format.
|
|
||||||
end_of_support_milestone:
|
|
||||||
# Array of tiers the feature is currently available to,
|
|
||||||
# like [Free, Silver, Gold, Core, Premium, Ultimate]
|
|
||||||
tiers:
|
|
||||||
# Links to documentation and thumbnail image
|
|
||||||
documentation_url:
|
|
||||||
image_url:
|
|
||||||
# Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
|
|
||||||
video_url:
|
|
||||||
|
|
@ -1,10 +1,25 @@
|
||||||
---
|
---
|
||||||
table_name: dependency_proxy_blob_states
|
table_name: dependency_proxy_blob_states
|
||||||
classes:
|
classes:
|
||||||
- Geo::DependencyProxyBlobState
|
- Geo::DependencyProxyBlobState
|
||||||
feature_categories:
|
feature_categories:
|
||||||
- geo_replication
|
- geo_replication
|
||||||
description: Separate table for dependency proxy blob verification states
|
description: Separate table for dependency proxy blob verification states
|
||||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/101429
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/101429
|
||||||
milestone: '15.6'
|
milestone: '15.6'
|
||||||
gitlab_schema: gitlab_main
|
gitlab_schema: gitlab_main_cell
|
||||||
|
allow_cross_joins:
|
||||||
|
- gitlab_main_clusterwide
|
||||||
|
allow_cross_transactions:
|
||||||
|
- gitlab_main_clusterwide
|
||||||
|
allow_cross_foreign_keys:
|
||||||
|
- gitlab_main_clusterwide
|
||||||
|
desired_sharding_key:
|
||||||
|
group_id:
|
||||||
|
references: namespaces
|
||||||
|
backfill_via:
|
||||||
|
parent:
|
||||||
|
foreign_key: dependency_proxy_blob_id
|
||||||
|
table: dependency_proxy_blobs
|
||||||
|
sharding_key: group_id
|
||||||
|
belongs_to: dependency_proxy_blob
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,25 @@
|
||||||
---
|
---
|
||||||
table_name: dependency_proxy_manifest_states
|
table_name: dependency_proxy_manifest_states
|
||||||
classes:
|
classes:
|
||||||
- Geo::DependencyProxyManifestState
|
- Geo::DependencyProxyManifestState
|
||||||
feature_categories:
|
feature_categories:
|
||||||
- geo_replication
|
- geo_replication
|
||||||
description: Separate table for dependency proxy manifest verification states
|
description: Separate table for dependency proxy manifest verification states
|
||||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/102908
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/102908
|
||||||
milestone: '15.6'
|
milestone: '15.6'
|
||||||
gitlab_schema: gitlab_main
|
gitlab_schema: gitlab_main_cell
|
||||||
|
allow_cross_joins:
|
||||||
|
- gitlab_main_clusterwide
|
||||||
|
allow_cross_transactions:
|
||||||
|
- gitlab_main_clusterwide
|
||||||
|
allow_cross_foreign_keys:
|
||||||
|
- gitlab_main_clusterwide
|
||||||
|
desired_sharding_key:
|
||||||
|
group_id:
|
||||||
|
references: namespaces
|
||||||
|
backfill_via:
|
||||||
|
parent:
|
||||||
|
foreign_key: dependency_proxy_manifest_id
|
||||||
|
table: dependency_proxy_manifests
|
||||||
|
sharding_key: group_id
|
||||||
|
belongs_to: dependency_proxy_manifest
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,19 @@ feature_categories:
|
||||||
description: User mentions in epic descriptions
|
description: User mentions in epic descriptions
|
||||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/19009
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/19009
|
||||||
milestone: '12.6'
|
milestone: '12.6'
|
||||||
gitlab_schema: gitlab_main
|
gitlab_schema: gitlab_main_cell
|
||||||
|
allow_cross_joins:
|
||||||
|
- gitlab_main_clusterwide
|
||||||
|
allow_cross_transactions:
|
||||||
|
- gitlab_main_clusterwide
|
||||||
|
allow_cross_foreign_keys:
|
||||||
|
- gitlab_main_clusterwide
|
||||||
|
desired_sharding_key:
|
||||||
|
group_id:
|
||||||
|
references: namespaces
|
||||||
|
backfill_via:
|
||||||
|
parent:
|
||||||
|
foreign_key: epic_id
|
||||||
|
table: epics
|
||||||
|
sharding_key: group_id
|
||||||
|
belongs_to: epic
|
||||||
|
|
|
||||||
|
|
@ -25479,6 +25479,7 @@ Check permissions for the current user on a vulnerability finding.
|
||||||
| <a id="projectid"></a>`id` | [`ID!`](#id) | ID of the project. |
|
| <a id="projectid"></a>`id` | [`ID!`](#id) | ID of the project. |
|
||||||
| <a id="projectimportstatus"></a>`importStatus` | [`String`](#string) | Status of import background job of the project. |
|
| <a id="projectimportstatus"></a>`importStatus` | [`String`](#string) | Status of import background job of the project. |
|
||||||
| <a id="projectincidentmanagementtimelineeventtags"></a>`incidentManagementTimelineEventTags` | [`[TimelineEventTagType!]`](#timelineeventtagtype) | Timeline event tags for the project. |
|
| <a id="projectincidentmanagementtimelineeventtags"></a>`incidentManagementTimelineEventTags` | [`[TimelineEventTagType!]`](#timelineeventtagtype) | Timeline event tags for the project. |
|
||||||
|
| <a id="projectisadjourneddeletionenabled"></a>`isAdjournedDeletionEnabled` **{warning-solid}** | [`Boolean!`](#boolean) | **Introduced** in GitLab 16.11. **Status**: Experiment. Indicates if delayed project deletion is enabled. |
|
||||||
| <a id="projectiscatalogresource"></a>`isCatalogResource` **{warning-solid}** | [`Boolean`](#boolean) | **Introduced** in GitLab 15.11. **Status**: Experiment. Indicates if a project is a catalog resource. |
|
| <a id="projectiscatalogresource"></a>`isCatalogResource` **{warning-solid}** | [`Boolean`](#boolean) | **Introduced** in GitLab 15.11. **Status**: Experiment. Indicates if a project is a catalog resource. |
|
||||||
| <a id="projectisforked"></a>`isForked` | [`Boolean!`](#boolean) | Project is forked. |
|
| <a id="projectisforked"></a>`isForked` | [`Boolean!`](#boolean) | Project is forked. |
|
||||||
| <a id="projectissuesaccesslevel"></a>`issuesAccessLevel` | [`ProjectFeatureAccess`](#projectfeatureaccess) | Access level required for issues access. |
|
| <a id="projectissuesaccesslevel"></a>`issuesAccessLevel` | [`ProjectFeatureAccess`](#projectfeatureaccess) | Access level required for issues access. |
|
||||||
|
|
@ -25509,6 +25510,7 @@ Check permissions for the current user on a vulnerability finding.
|
||||||
| <a id="projectpackagesprotectionrules"></a>`packagesProtectionRules` | [`PackagesProtectionRuleConnection`](#packagesprotectionruleconnection) | Packages protection rules for the project. (see [Connections](#connections)) |
|
| <a id="projectpackagesprotectionrules"></a>`packagesProtectionRules` | [`PackagesProtectionRuleConnection`](#packagesprotectionruleconnection) | Packages protection rules for the project. (see [Connections](#connections)) |
|
||||||
| <a id="projectpath"></a>`path` | [`String!`](#string) | Path of the project. |
|
| <a id="projectpath"></a>`path` | [`String!`](#string) | Path of the project. |
|
||||||
| <a id="projectpathlocks"></a>`pathLocks` | [`PathLockConnection`](#pathlockconnection) | The project's path locks. (see [Connections](#connections)) |
|
| <a id="projectpathlocks"></a>`pathLocks` | [`PathLockConnection`](#pathlockconnection) | The project's path locks. (see [Connections](#connections)) |
|
||||||
|
| <a id="projectpermanentdeletiondate"></a>`permanentDeletionDate` **{warning-solid}** | [`String`](#string) | **Introduced** in GitLab 16.11. **Status**: Experiment. Date when project will be deleted if delayed project deletion is enabled. |
|
||||||
| <a id="projectpipelineanalytics"></a>`pipelineAnalytics` | [`PipelineAnalytics`](#pipelineanalytics) | Pipeline analytics. |
|
| <a id="projectpipelineanalytics"></a>`pipelineAnalytics` | [`PipelineAnalytics`](#pipelineanalytics) | Pipeline analytics. |
|
||||||
| <a id="projectpipelinetriggers"></a>`pipelineTriggers` **{warning-solid}** | [`PipelineTriggerConnection`](#pipelinetriggerconnection) | **Introduced** in GitLab 16.3. **Status**: Experiment. List of pipeline trigger tokens. |
|
| <a id="projectpipelinetriggers"></a>`pipelineTriggers` **{warning-solid}** | [`PipelineTriggerConnection`](#pipelinetriggerconnection) | **Introduced** in GitLab 16.3. **Status**: Experiment. List of pipeline trigger tokens. |
|
||||||
| <a id="projectpreventmergewithoutjiraissueenabled"></a>`preventMergeWithoutJiraIssueEnabled` | [`Boolean!`](#boolean) | Indicates if an associated issue from Jira is required. |
|
| <a id="projectpreventmergewithoutjiraissueenabled"></a>`preventMergeWithoutJiraIssueEnabled` | [`Boolean!`](#boolean) | Indicates if an associated issue from Jira is required. |
|
||||||
|
|
|
||||||
|
|
@ -1241,33 +1241,6 @@ set `AUTO_DEVOPS_BUILD_IMAGE_CNB_BUILDER` to `heroku/builder:20`.
|
||||||
|
|
||||||
<div class="deprecation breaking-change" data-milestone="17.0">
|
<div class="deprecation breaking-change" data-milestone="17.0">
|
||||||
|
|
||||||
### Hosted Runners on Linux operating system upgrade
|
|
||||||
|
|
||||||
<div class="deprecation-notes">
|
|
||||||
- Announced in GitLab <span class="milestone">16.10</span>
|
|
||||||
- Removal in GitLab <span class="milestone">17.0</span> ([breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change))
|
|
||||||
- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/ci-cd/shared-runners/infrastructure/-/issues/60).
|
|
||||||
</div>
|
|
||||||
|
|
||||||
With GitLab 17.0 we're upgrading the container-optimized operating system ([COS](https://cloud.google.com/container-optimized-os/docs))
|
|
||||||
of the ephemeral VMs used to execute jobs for [Hosted Runners on Linux](https://docs.gitlab.com/ee/ci/runners/saas/linux_saas_runner.html).
|
|
||||||
The COS upgrade includes a Docker Engine upgrade from Version 19.03.15 to Version 23.0.5, which introduced
|
|
||||||
a known compatibility issue.
|
|
||||||
|
|
||||||
GitLab CI/CD jobs [using Docker-in-Docker-based jobs](https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#use-docker-in-docker)
|
|
||||||
with a Docker-in-Docker service version prior to 20.10 and GitLab CI/CD jobs [using Kaniko to build container images](https://docs.gitlab.com/ee/ci/docker/using_kaniko.html)
|
|
||||||
with a Kaniko service version older than `v1.9.0` will start failing.
|
|
||||||
|
|
||||||
To fix these issues, an update of service version in `.gitlab-ci.yml` is required.
|
|
||||||
|
|
||||||
Both issues, including a detailed explanation of how they affect jobs and how to fix
|
|
||||||
the issue, are described
|
|
||||||
[in the announcement blog post](https://about.gitlab.com/blog/2023/10/04/updating-the-os-version-of-saas-runners-on-linux/).
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="deprecation breaking-change" data-milestone="17.0">
|
|
||||||
|
|
||||||
### Internal container registry API tag deletion endpoint
|
### Internal container registry API tag deletion endpoint
|
||||||
|
|
||||||
<div class="deprecation-notes">
|
<div class="deprecation-notes">
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ module Gitlab
|
||||||
|
|
||||||
def instance_count_request(amount = 1)
|
def instance_count_request(amount = 1)
|
||||||
@request_counter ||= Gitlab::Metrics.counter(:gitlab_redis_client_requests_total, 'Client side Redis request count, per Redis server')
|
@request_counter ||= Gitlab::Metrics.counter(:gitlab_redis_client_requests_total, 'Client side Redis request count, per Redis server')
|
||||||
@request_counter.increment({ storage: storage_key }, amount)
|
@request_counter.increment(storage_labels, amount)
|
||||||
end
|
end
|
||||||
|
|
||||||
def instance_count_pipelined_request(size)
|
def instance_count_pipelined_request(size)
|
||||||
|
|
@ -132,7 +132,7 @@ module Gitlab
|
||||||
{},
|
{},
|
||||||
[10, 100, 1000, 10_000]
|
[10, 100, 1000, 10_000]
|
||||||
)
|
)
|
||||||
@pipeline_size_histogram.observe({ storage: storage_key, storage_shard: shard_key }, size)
|
@pipeline_size_histogram.observe(storage_labels, size)
|
||||||
end
|
end
|
||||||
|
|
||||||
def instance_count_exception(ex)
|
def instance_count_exception(ex)
|
||||||
|
|
@ -140,12 +140,12 @@ module Gitlab
|
||||||
# server is doing. Redis itself does not expose error counts. This
|
# server is doing. Redis itself does not expose error counts. This
|
||||||
# metric can be used for Redis alerting and service health monitoring.
|
# metric can be used for Redis alerting and service health monitoring.
|
||||||
@exception_counter ||= Gitlab::Metrics.counter(:gitlab_redis_client_exceptions_total, 'Client side Redis exception count, per Redis server, per exception class')
|
@exception_counter ||= Gitlab::Metrics.counter(:gitlab_redis_client_exceptions_total, 'Client side Redis exception count, per Redis server, per exception class')
|
||||||
@exception_counter.increment({ storage: storage_key, storage_shard: shard_key, exception: ex.class.to_s })
|
@exception_counter.increment(storage_labels.merge(exception: ex.class.to_s))
|
||||||
end
|
end
|
||||||
|
|
||||||
def instance_count_connection_exception(ex)
|
def instance_count_connection_exception(ex)
|
||||||
@connection_exception_counter ||= Gitlab::Metrics.counter(:gitlab_redis_client_connection_exceptions_total, 'Client side Redis connection exception count, per Redis server, per exception class')
|
@connection_exception_counter ||= Gitlab::Metrics.counter(:gitlab_redis_client_connection_exceptions_total, 'Client side Redis connection exception count, per Redis server, per exception class')
|
||||||
@connection_exception_counter.increment({ storage: storage_key, storage_shard: shard_key, exception: ex.class.to_s })
|
@connection_exception_counter.increment(storage_labels.merge(exception: ex.class.to_s))
|
||||||
end
|
end
|
||||||
|
|
||||||
def instance_count_cluster_redirection(ex)
|
def instance_count_cluster_redirection(ex)
|
||||||
|
|
@ -153,7 +153,7 @@ module Gitlab
|
||||||
# redirected to the right node, especially during resharding..
|
# redirected to the right node, especially during resharding..
|
||||||
# This metric can be used for Redis alerting and service health monitoring.
|
# This metric can be used for Redis alerting and service health monitoring.
|
||||||
@redirection_counter ||= Gitlab::Metrics.counter(:gitlab_redis_client_redirections_total, 'Client side Redis Cluster redirection count, per Redis node, per slot')
|
@redirection_counter ||= Gitlab::Metrics.counter(:gitlab_redis_client_redirections_total, 'Client side Redis Cluster redirection count, per Redis node, per slot')
|
||||||
@redirection_counter.increment(decompose_redirection_message(ex.message).merge({ storage: storage_key, storage_shard: shard_key }))
|
@redirection_counter.increment(decompose_redirection_message(ex.message).merge(storage_labels))
|
||||||
end
|
end
|
||||||
|
|
||||||
def instance_observe_duration(duration)
|
def instance_observe_duration(duration)
|
||||||
|
|
@ -164,15 +164,19 @@ module Gitlab
|
||||||
[0.1, 0.5, 0.75, 1]
|
[0.1, 0.5, 0.75, 1]
|
||||||
)
|
)
|
||||||
|
|
||||||
@request_latency_histogram.observe({ storage: storage_key, storage_shard: shard_key }, duration)
|
@request_latency_histogram.observe(storage_labels, duration)
|
||||||
end
|
end
|
||||||
|
|
||||||
def log_exception(ex)
|
def log_exception(ex)
|
||||||
::Gitlab::ErrorTracking.log_exception(ex, storage: storage_key, storage_shard: shard_key)
|
::Gitlab::ErrorTracking.log_exception(ex, **storage_labels)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def storage_labels
|
||||||
|
{ storage: storage_key, storage_shard: shard_key }
|
||||||
|
end
|
||||||
|
|
||||||
def request_count_key
|
def request_count_key
|
||||||
strong_memoize(:request_count_key) { build_key(:redis_request_count) }
|
strong_memoize(:request_count_key) { build_key(:redis_request_count) }
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -52758,7 +52758,7 @@ msgstr ""
|
||||||
msgid "TimeTracking|Time remaining: %{timeRemainingHumanReadable}"
|
msgid "TimeTracking|Time remaining: %{timeRemainingHumanReadable}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "TimeTracking|Use /spend or /estimate to manage time."
|
msgid "TimeTracking|To manage time, use /spend or /estimate."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Timeago|%s days ago"
|
msgid "Timeago|%s days ago"
|
||||||
|
|
@ -52999,6 +52999,9 @@ msgstr ""
|
||||||
msgid "To add a custom suffix, set up a Service Desk email address. %{linkStart}Learn more%{linkEnd}."
|
msgid "To add a custom suffix, set up a Service Desk email address. %{linkStart}Learn more%{linkEnd}."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "To add active contacts, use /add_contacts."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "To add the entry manually, provide the following details to the application on your phone."
|
msgid "To add the entry manually, provide the following details to the application on your phone."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,13 +86,27 @@ describe('~/api/projects_api.js', () => {
|
||||||
jest.spyOn(axios, 'delete');
|
jest.spyOn(axios, 'delete');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('deletes to the correct URL', () => {
|
describe('without params', () => {
|
||||||
const expectedUrl = `/api/v7/projects/${projectId}`;
|
it('deletes to the correct URL', () => {
|
||||||
|
const expectedUrl = `/api/v7/projects/${projectId}`;
|
||||||
|
|
||||||
mock.onDelete(expectedUrl).replyOnce(HTTP_STATUS_OK);
|
mock.onDelete(expectedUrl).replyOnce(HTTP_STATUS_OK);
|
||||||
|
|
||||||
return projectsApi.deleteProject(projectId).then(() => {
|
return projectsApi.deleteProject(projectId).then(() => {
|
||||||
expect(axios.delete).toHaveBeenCalledWith(expectedUrl);
|
expect(axios.delete).toHaveBeenCalledWith(expectedUrl, { params: undefined });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('with params', () => {
|
||||||
|
it('deletes to the correct URL with params', () => {
|
||||||
|
const expectedUrl = `/api/v7/projects/${projectId}`;
|
||||||
|
|
||||||
|
mock.onDelete(expectedUrl).replyOnce(HTTP_STATUS_OK);
|
||||||
|
|
||||||
|
return projectsApi.deleteProject(projectId, { testParam: true }).then(() => {
|
||||||
|
expect(axios.delete).toHaveBeenCalledWith(expectedUrl, { params: { testParam: true } });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import getIssueCrmContactsQuery from '~/sidebar/queries/get_issue_crm_contacts.q
|
||||||
import issueCrmContactsSubscription from '~/sidebar/queries/issue_crm_contacts.subscription.graphql';
|
import issueCrmContactsSubscription from '~/sidebar/queries/issue_crm_contacts.subscription.graphql';
|
||||||
import {
|
import {
|
||||||
getIssueCrmContactsQueryResponse,
|
getIssueCrmContactsQueryResponse,
|
||||||
|
getIssueCrmContactsQueryResponseEmpty,
|
||||||
issueCrmContactsUpdateResponse,
|
issueCrmContactsUpdateResponse,
|
||||||
issueCrmContactsUpdateNullResponse,
|
issueCrmContactsUpdateNullResponse,
|
||||||
} from '../mock_data';
|
} from '../mock_data';
|
||||||
|
|
@ -21,6 +22,9 @@ describe('Issue crm contacts component', () => {
|
||||||
let fakeApollo;
|
let fakeApollo;
|
||||||
|
|
||||||
const successQueryHandler = jest.fn().mockResolvedValue(getIssueCrmContactsQueryResponse);
|
const successQueryHandler = jest.fn().mockResolvedValue(getIssueCrmContactsQueryResponse);
|
||||||
|
const emptySuccessQueryHandler = jest
|
||||||
|
.fn()
|
||||||
|
.mockResolvedValue(getIssueCrmContactsQueryResponseEmpty);
|
||||||
const successSubscriptionHandler = jest.fn().mockResolvedValue(issueCrmContactsUpdateResponse);
|
const successSubscriptionHandler = jest.fn().mockResolvedValue(issueCrmContactsUpdateResponse);
|
||||||
const nullSubscriptionHandler = jest.fn().mockResolvedValue(issueCrmContactsUpdateNullResponse);
|
const nullSubscriptionHandler = jest.fn().mockResolvedValue(issueCrmContactsUpdateNullResponse);
|
||||||
|
|
||||||
|
|
@ -80,6 +84,16 @@ describe('Issue crm contacts component', () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('has an empty state', async () => {
|
||||||
|
mountComponent({
|
||||||
|
queryHandler: emptySuccessQueryHandler,
|
||||||
|
subscriptionHandler: nullSubscriptionHandler,
|
||||||
|
});
|
||||||
|
await waitForPromises();
|
||||||
|
|
||||||
|
expect(wrapper.findByTestId('crm-empty-message').exists()).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
it('renders correct results after subscription update', async () => {
|
it('renders correct results after subscription update', async () => {
|
||||||
mountComponent();
|
mountComponent();
|
||||||
await waitForPromises();
|
await waitForPromises();
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,18 @@ export const getIssueCrmContactsQueryResponse = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getIssueCrmContactsQueryResponseEmpty = {
|
||||||
|
data: {
|
||||||
|
issue: {
|
||||||
|
__typename: 'Issue',
|
||||||
|
id: 'gid://gitlab/Issue/123',
|
||||||
|
customerRelationsContacts: {
|
||||||
|
nodes: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
export const issueCrmContactsUpdateNullResponse = {
|
export const issueCrmContactsUpdateNullResponse = {
|
||||||
data: {
|
data: {
|
||||||
issueCrmContactsUpdated: null,
|
issueCrmContactsUpdated: null,
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import { mountExtended } from 'helpers/vue_test_utils_helper';
|
||||||
import createMockApollo from 'helpers/mock_apollo_helper';
|
import createMockApollo from 'helpers/mock_apollo_helper';
|
||||||
import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
|
import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
|
||||||
import waitForPromises from 'helpers/wait_for_promises';
|
import waitForPromises from 'helpers/wait_for_promises';
|
||||||
|
import { stubComponent, RENDER_ALL_SLOTS_TEMPLATE } from 'helpers/stub_component';
|
||||||
import { Blob, BinaryBlob } from 'jest/blob/components/mock_data';
|
import { Blob, BinaryBlob } from 'jest/blob/components/mock_data';
|
||||||
import { differenceInMilliseconds } from '~/lib/utils/datetime_utility';
|
import { differenceInMilliseconds } from '~/lib/utils/datetime_utility';
|
||||||
import SnippetHeader, { i18n } from '~/snippets/components/snippet_header.vue';
|
import SnippetHeader, { i18n } from '~/snippets/components/snippet_header.vue';
|
||||||
|
|
@ -83,6 +84,7 @@ describe('Snippet header component', () => {
|
||||||
GlDisclosureDropdownGroup,
|
GlDisclosureDropdownGroup,
|
||||||
GlDisclosureDropdownItem,
|
GlDisclosureDropdownItem,
|
||||||
GlIcon,
|
GlIcon,
|
||||||
|
GlModal: stubComponent(GlModal, { template: RENDER_ALL_SLOTS_TEMPLATE }),
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
GlTooltip: createMockDirective('gl-tooltip'),
|
GlTooltip: createMockDirective('gl-tooltip'),
|
||||||
|
|
@ -99,9 +101,10 @@ describe('Snippet header component', () => {
|
||||||
const findSpamAction = () => wrapper.findByText('Submit as spam');
|
const findSpamAction = () => wrapper.findByText('Submit as spam');
|
||||||
const findDeleteAction = () => wrapper.findByText('Delete');
|
const findDeleteAction = () => wrapper.findByText('Delete');
|
||||||
const findDeleteModal = () => wrapper.findComponent(GlModal);
|
const findDeleteModal = () => wrapper.findComponent(GlModal);
|
||||||
|
const findDeleteModalDeleteAction = () => wrapper.findByTestId('delete-snippet-button');
|
||||||
const findIcon = () => wrapper.findComponent(GlIcon);
|
const findIcon = () => wrapper.findComponent(GlIcon);
|
||||||
const findTooltip = () => getBinding(findIcon().element, 'gl-tooltip');
|
const findTooltip = () => getBinding(findIcon().element, 'gl-tooltip');
|
||||||
const findSpamIcon = () => wrapper.findComponent('[data-testid="snippets-spam-icon"]');
|
const findSpamIcon = () => wrapper.findByTestId('snippets-spam-icon');
|
||||||
|
|
||||||
const title = 'The property of Thor';
|
const title = 'The property of Thor';
|
||||||
|
|
||||||
|
|
@ -294,17 +297,21 @@ describe('Snippet header component', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Delete mutation', () => {
|
describe('Delete mutation', () => {
|
||||||
const deleteSnippet = async () => {
|
const openDeleteSnippetModal = async () => {
|
||||||
// Click delete action
|
// Click delete action
|
||||||
findDropdown().trigger('click');
|
findDropdown().trigger('click');
|
||||||
findDeleteAction().trigger('click');
|
findDeleteAction().trigger('click');
|
||||||
|
|
||||||
await nextTick();
|
await nextTick();
|
||||||
|
};
|
||||||
|
|
||||||
|
const deleteSnippet = async () => {
|
||||||
|
await openDeleteSnippetModal();
|
||||||
|
|
||||||
expect(findDeleteModal().props().visible).toBe(true);
|
expect(findDeleteModal().props().visible).toBe(true);
|
||||||
|
|
||||||
// Click delete button in delete modal
|
// Click delete button in delete modal
|
||||||
document.querySelector('[data-testid="delete-snippet-button"').click();
|
findDeleteModalDeleteAction().trigger('click');
|
||||||
|
|
||||||
await waitForPromises();
|
await waitForPromises();
|
||||||
};
|
};
|
||||||
|
|
@ -325,9 +332,19 @@ describe('Snippet header component', () => {
|
||||||
|
|
||||||
await deleteSnippet();
|
await deleteSnippet();
|
||||||
|
|
||||||
expect(document.querySelector('[data-testid="delete-alert"').textContent.trim()).toBe(
|
expect(wrapper.findByTestId('delete-alert').text()).toBe(ERROR_MSG);
|
||||||
ERROR_MSG,
|
});
|
||||||
);
|
|
||||||
|
it('puts the `Delete snippet` modal button in the loading state on click', async () => {
|
||||||
|
createComponent();
|
||||||
|
|
||||||
|
expect(findDeleteModalDeleteAction().props('loading')).toBe(false);
|
||||||
|
|
||||||
|
await openDeleteSnippetModal();
|
||||||
|
findDeleteModalDeleteAction().trigger('click');
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
expect(findDeleteModalDeleteAction().props('loading')).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('in case of successful mutation, closes modal and redirects to correct listing', () => {
|
describe('in case of successful mutation, closes modal and redirects to correct listing', () => {
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ describe('WorkItemTimeTracking component', () => {
|
||||||
createComponent({ timeEstimate: 0, totalTimeSpent: 0 });
|
createComponent({ timeEstimate: 0, totalTimeSpent: 0 });
|
||||||
|
|
||||||
expect(findTimeTrackingBody().text()).toMatchInterpolatedText(
|
expect(findTimeTrackingBody().text()).toMatchInterpolatedText(
|
||||||
'Use /spend or /estimate to manage time.',
|
'To manage time, use /spend or /estimate.',
|
||||||
);
|
);
|
||||||
expect(findProgressBar().exists()).toBe(false);
|
expect(findProgressBar().exists()).toBe(false);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue