Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
25ceb3dc1c
commit
8f177b09d2
|
@ -1 +1 @@
|
|||
e0008a95a16980e0e3c06068982e4093c695738c
|
||||
7bb80f713fccac70cd4f17211f1f5435b5014c7a
|
||||
|
|
|
@ -51,16 +51,7 @@ export default {
|
|||
TokenTable,
|
||||
ActivityEvents,
|
||||
},
|
||||
props: {
|
||||
agentName: {
|
||||
required: true,
|
||||
type: String,
|
||||
},
|
||||
projectPath: {
|
||||
required: true,
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
inject: ['agentName', 'projectPath'],
|
||||
data() {
|
||||
return {
|
||||
cursor: {
|
||||
|
@ -131,12 +122,12 @@ export default {
|
|||
</p>
|
||||
|
||||
<gl-tabs sync-active-tab-with-query-params lazy>
|
||||
<slot name="ee-security-tab"></slot>
|
||||
|
||||
<gl-tab :title="$options.i18n.activity" query-param-value="activity">
|
||||
<activity-events :agent-name="agentName" :project-path="projectPath" />
|
||||
</gl-tab>
|
||||
|
||||
<slot name="ee-security-tab"></slot>
|
||||
|
||||
<gl-tab query-param-value="tokens">
|
||||
<template #title>
|
||||
<span data-testid="cluster-agent-token-count">
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
import { IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
|
||||
import Vue from 'vue';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import createDefaultClient from '~/lib/graphql';
|
||||
import { vulnerabilityLocationTypes } from '~/graphql_shared/fragment_types/vulnerability_location_types';
|
||||
|
||||
Vue.use(VueApollo);
|
||||
|
||||
// We create a fragment matcher so that we can create a fragment from an interface
|
||||
// Without this, Apollo throws a heuristic fragment matcher warning
|
||||
const fragmentMatcher = new IntrospectionFragmentMatcher({
|
||||
introspectionQueryResultData: vulnerabilityLocationTypes,
|
||||
});
|
||||
|
||||
const defaultClient = createDefaultClient(
|
||||
{},
|
||||
{
|
||||
cacheConfig: {
|
||||
fragmentMatcher,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
export default new VueApollo({
|
||||
defaultClient,
|
||||
});
|
|
@ -1,9 +1,6 @@
|
|||
import Vue from 'vue';
|
||||
import VueApollo from 'vue-apollo';
|
||||
import createDefaultClient from '~/lib/graphql';
|
||||
import AgentShowPage from 'ee_else_ce/clusters/agents/components/show.vue';
|
||||
|
||||
Vue.use(VueApollo);
|
||||
import apolloProvider from './graphql/provider';
|
||||
|
||||
export default () => {
|
||||
const el = document.querySelector('#js-cluster-agent-details');
|
||||
|
@ -12,20 +9,19 @@ export default () => {
|
|||
return null;
|
||||
}
|
||||
|
||||
const defaultClient = createDefaultClient();
|
||||
const { agentName, projectPath, activityEmptyStateImage } = el.dataset;
|
||||
const { activityEmptyStateImage, agentName, emptyStateSvgPath, projectPath } = el.dataset;
|
||||
|
||||
return new Vue({
|
||||
el,
|
||||
apolloProvider: new VueApollo({ defaultClient }),
|
||||
provide: { agentName, projectPath, activityEmptyStateImage },
|
||||
apolloProvider,
|
||||
provide: {
|
||||
activityEmptyStateImage,
|
||||
agentName,
|
||||
emptyStateSvgPath,
|
||||
projectPath,
|
||||
},
|
||||
render(createElement) {
|
||||
return createElement(AgentShowPage, {
|
||||
props: {
|
||||
agentName,
|
||||
projectPath,
|
||||
},
|
||||
});
|
||||
return createElement(AgentShowPage);
|
||||
},
|
||||
});
|
||||
};
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
export const vulnerabilityLocationTypes = {
|
||||
__schema: {
|
||||
types: [
|
||||
{
|
||||
kind: 'UNION',
|
||||
name: 'VulnerabilityLocation',
|
||||
possibleTypes: [
|
||||
{ name: 'VulnerabilityLocationContainerScanning' },
|
||||
{ name: 'VulnerabilityLocationDast' },
|
||||
{ name: 'VulnerabilityLocationDependencyScanning' },
|
||||
{ name: 'VulnerabilityLocationSast' },
|
||||
{ name: 'VulnerabilityLocationSecretDetection' },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
|
@ -107,11 +107,8 @@ export default {
|
|||
isInvalidTag() {
|
||||
return !this.tag.digest;
|
||||
},
|
||||
isCheckboxDisabled() {
|
||||
return this.isInvalidTag || this.disabled;
|
||||
},
|
||||
isDeleteDisabled() {
|
||||
return this.isInvalidTag || this.disabled || !this.tag.canDelete;
|
||||
return this.disabled || !this.tag.canDelete;
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -122,7 +119,7 @@ export default {
|
|||
<template #left-action>
|
||||
<gl-form-checkbox
|
||||
v-if="tag.canDelete"
|
||||
:disabled="isCheckboxDisabled"
|
||||
:disabled="disabled"
|
||||
class="gl-m-0"
|
||||
:checked="selected"
|
||||
@change="$emit('select')"
|
||||
|
|
|
@ -420,12 +420,12 @@
|
|||
list-style-type: none;
|
||||
position: relative;
|
||||
min-height: 22px;
|
||||
padding-left: 28px;
|
||||
margin-left: 0 !important;
|
||||
padding-inline-start: 28px;
|
||||
margin-inline-start: 0 !important;
|
||||
|
||||
> input.task-list-item-checkbox {
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
inset-inline-start: 8px;
|
||||
top: 5px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@ module Nav
|
|||
if dashboard_nav_link?(:milestones)
|
||||
builder.add_primary_menu_item_with_shortcut(
|
||||
id: 'milestones',
|
||||
title: 'Milestones',
|
||||
title: _('Milestones'),
|
||||
href: dashboard_milestones_path,
|
||||
active: active_nav_link?(controller: 'dashboard/milestones'),
|
||||
icon: 'clock',
|
||||
|
@ -144,7 +144,7 @@ module Nav
|
|||
if dashboard_nav_link?(:activity)
|
||||
builder.add_primary_menu_item_with_shortcut(
|
||||
id: 'activity',
|
||||
title: 'Activity',
|
||||
title: _('Activity'),
|
||||
href: activity_dashboard_path,
|
||||
active: active_nav_link?(path: 'dashboard#activity'),
|
||||
icon: 'history',
|
||||
|
@ -212,7 +212,7 @@ module Nav
|
|||
def groups_menu_item_attrs
|
||||
{
|
||||
id: 'groups',
|
||||
title: 'Groups',
|
||||
title: _('Groups'),
|
||||
icon: 'group',
|
||||
shortcut_class: 'dashboard-shortcuts-groups'
|
||||
}
|
||||
|
|
|
@ -3,9 +3,10 @@
|
|||
module Projects::ClusterAgentsHelper
|
||||
def js_cluster_agent_details_data(agent_name, project)
|
||||
{
|
||||
activity_empty_state_image: image_path('illustrations/empty-state/empty-state-agents.svg'),
|
||||
agent_name: agent_name,
|
||||
project_path: project.full_path,
|
||||
activity_empty_state_image: image_path('illustrations/empty-state/empty-state-agents.svg')
|
||||
empty_state_svg_path: image_path('illustrations/operations-dashboard_empty.svg'),
|
||||
project_path: project.full_path
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveForeignKeyCiGroupVariablesGroupId < Gitlab::Database::Migration[1.0]
|
||||
disable_ddl_transaction!
|
||||
|
||||
CONSTRAINT_NAME = 'fk_33ae4d58d8'
|
||||
|
||||
def up
|
||||
with_lock_retries do
|
||||
remove_foreign_key_if_exists(:ci_group_variables, :namespaces, name: CONSTRAINT_NAME)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
add_concurrent_foreign_key :ci_group_variables, :namespaces, column: :group_id, on_delete: :cascade, name: CONSTRAINT_NAME
|
||||
end
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
fa87b087b576d320f94028444a082b920870a2554209808849f9f3f42ead83c4
|
|
@ -29179,9 +29179,6 @@ ALTER TABLE ONLY approvals
|
|||
ALTER TABLE ONLY namespaces
|
||||
ADD CONSTRAINT fk_319256d87a FOREIGN KEY (file_template_project_id) REFERENCES projects(id) ON DELETE SET NULL;
|
||||
|
||||
ALTER TABLE ONLY ci_group_variables
|
||||
ADD CONSTRAINT fk_33ae4d58d8 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY namespaces
|
||||
ADD CONSTRAINT fk_3448c97865 FOREIGN KEY (push_rule_id) REFERENCES push_rules(id) ON DELETE SET NULL;
|
||||
|
||||
|
|
|
@ -83,7 +83,41 @@ where:
|
|||
- Configuration imported with [`include`](../yaml/index.md#include) is copied into the view.
|
||||
- Jobs that use [`extends`](../yaml/index.md#extends) display with the
|
||||
[extended configuration merged into the job](../yaml/yaml_optimization.md#merge-details).
|
||||
- YAML anchors are [replaced with the linked configuration](../yaml/yaml_optimization.md#anchors).
|
||||
- [YAML anchors](../yaml/yaml_optimization.md#anchors) are replaced with the linked configuration.
|
||||
- [YAML `!reference` tags](../yaml/yaml_optimization.md#reference-tags) are also replaced
|
||||
with the linked configuration.
|
||||
|
||||
Using `!refence` tags can cause nested configuration that display with
|
||||
multiple hyphens (`-`) in the expanded view. This behavior is expected, and the extra
|
||||
hyphens do not affect the job's execution. For example, this configuration and
|
||||
fully expanded version are both valid:
|
||||
|
||||
- `.gitlab-ci.yml` file:
|
||||
|
||||
```yaml
|
||||
.python-req:
|
||||
script:
|
||||
- pip install pyflakes
|
||||
|
||||
lint-python:
|
||||
image: python:latest
|
||||
script:
|
||||
- !reference [.python-req, script]
|
||||
- pyflakes python/
|
||||
```
|
||||
|
||||
- Expanded configuration in **View merged YAML** tab:
|
||||
|
||||
```yaml
|
||||
".python-req":
|
||||
script:
|
||||
- pip install pyflakes
|
||||
lint-python:
|
||||
script:
|
||||
- - pip install pyflakes # <- The extra hyphens do not affect the job's execution.
|
||||
- pyflakes python/
|
||||
image: python:latest
|
||||
```
|
||||
|
||||
## Commit changes to CI configuration
|
||||
|
||||
|
|
|
@ -89,9 +89,10 @@ ci_pipelines:
|
|||
|
||||
### Track record changes
|
||||
|
||||
To know about deletions in the `projects` table, configure a `DELETE` trigger using a database
|
||||
migration (post-migration). The trigger needs to be configured only once. If the model already has
|
||||
at least one `loose_foreign_key` definition, then this step can be skipped:
|
||||
To know about deletions in the `projects` table, configure a `DELETE` trigger
|
||||
using a [post-deployment migration](../post_deployment_migrations.md). The
|
||||
trigger needs to be configured only once. If the model already has at least one
|
||||
`loose_foreign_key` definition, then this step can be skipped:
|
||||
|
||||
```ruby
|
||||
class TrackProjectRecordChanges < Gitlab::Database::Migration[1.0]
|
||||
|
@ -122,15 +123,20 @@ REFERENCES projects(id)
|
|||
ON DELETE CASCADE;
|
||||
```
|
||||
|
||||
The migration should run after the `DELETE` trigger is installed. If the foreign key is deleted
|
||||
earlier, there is a good chance of introducing data inconsistency which needs manual cleanup:
|
||||
The migration must run after the `DELETE` trigger is installed and the loose
|
||||
foreign key definition is deployed. As such, it must be a [post-deployment
|
||||
migration](../post_deployment_migrations.md) dated after the migration for the
|
||||
trigger. If the foreign key is deleted earlier, there is a good chance of
|
||||
introducing data inconsistency which needs manual cleanup:
|
||||
|
||||
```ruby
|
||||
class RemoveProjectsCiPipelineFk < Gitlab::Database::Migration[1.0]
|
||||
enable_lock_retries!
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
remove_foreign_key_if_exists(:ci_pipelines, :projects, name: "fk_86635dbd80")
|
||||
with_lock_retries do
|
||||
remove_foreign_key_if_exists(:ci_pipelines, :projects, name: "fk_86635dbd80")
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
|
|
|
@ -535,9 +535,9 @@ API requests to add a new user to a project are not possible.
|
|||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/287940) in GitLab 14.2.
|
||||
> - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/336520) in GitLab 14.5.
|
||||
|
||||
You can export a list of members in a group as a CSV.
|
||||
You can export a list of members in a group or subgroup as a CSV.
|
||||
|
||||
1. Go to your project and select **Project information > Members**.
|
||||
1. Go to your group or subgroup and select either **Group information > Members** or **Subgroup information > Members**.
|
||||
1. Select **Export as CSV**.
|
||||
1. Once the CSV file has been generated, it is emailed as an attachment to the user that requested it.
|
||||
|
||||
|
|
|
@ -394,6 +394,8 @@ stages:
|
|||
production:
|
||||
stage: deploy
|
||||
before_script:
|
||||
- apt-get update
|
||||
- apt-get install -y python3-pip
|
||||
- pip3 install awscli --upgrade
|
||||
- pip3 install aws-sam-cli --upgrade
|
||||
script:
|
||||
|
|
|
@ -123,7 +123,6 @@ module API
|
|||
end
|
||||
delete ':id/registry/repositories/:repository_id/tags/:tag_name', requirements: REPOSITORY_ENDPOINT_REQUIREMENTS do
|
||||
authorize_destroy_container_image!
|
||||
validate_tag!
|
||||
|
||||
result = ::Projects::ContainerRepository::DeleteTagsService
|
||||
.new(repository.project, current_user, tags: [declared_params[:tag_name]])
|
||||
|
|
|
@ -33,6 +33,7 @@ coverage_fuzzing_unlicensed:
|
|||
before_script:
|
||||
- export COVFUZZ_JOB_TOKEN=$CI_JOB_TOKEN
|
||||
- export COVFUZZ_PRIVATE_TOKEN=$CI_PRIVATE_TOKEN
|
||||
- export COVFUZZ_PROJECT_PATH=$CI_PROJECT_PATH
|
||||
- export COVFUZZ_PROJECT_ID=$CI_PROJECT_ID
|
||||
- if [ -x "$(command -v apt-get)" ] ; then apt-get update && apt-get install -y wget; fi
|
||||
- wget -O gitlab-cov-fuzz "${COVFUZZ_URL_PREFIX}"/"${COVFUZZ_VERSION}"/binaries/gitlab-cov-fuzz_Linux_x86_64
|
||||
|
|
|
@ -24905,6 +24905,9 @@ msgstr ""
|
|||
msgid "Operation timed out. Check pod logs for %{pod_name} for more details."
|
||||
msgstr ""
|
||||
|
||||
msgid "Operations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Operations Dashboard"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -57,7 +57,11 @@ module QA
|
|||
puts "Creating report".colorize(:green)
|
||||
response = post(
|
||||
"#{gitlab_api_url}/projects/#{PROJECT_ID}/issues",
|
||||
{ title: "Reliable spec report", description: report_issue_body, labels: "Quality,test" },
|
||||
{
|
||||
title: "Reliable e2e test report",
|
||||
description: report_issue_body,
|
||||
labels: "Quality,test,type::maintenance,reliable test report"
|
||||
},
|
||||
headers: { "PRIVATE-TOKEN" => gitlab_access_token }
|
||||
)
|
||||
web_url = parse_body(response)[:web_url]
|
||||
|
|
|
@ -165,9 +165,9 @@ describe QA::Tools::ReliableReport do
|
|||
verify_ssl: false,
|
||||
headers: { "PRIVATE-TOKEN" => "gitlab_token" },
|
||||
payload: {
|
||||
title: "Reliable spec report",
|
||||
title: "Reliable e2e test report",
|
||||
description: issue_body,
|
||||
labels: "Quality,test"
|
||||
labels: "Quality,test,type::maintenance,reliable test report"
|
||||
}
|
||||
)
|
||||
expect(slack_notifier).to have_received(:post).with(
|
||||
|
|
|
@ -19,7 +19,7 @@ describe('ClusterAgentShow', () => {
|
|||
let wrapper;
|
||||
useFakeDate([2021, 2, 15]);
|
||||
|
||||
const propsData = {
|
||||
const provide = {
|
||||
agentName: 'cluster-agent',
|
||||
projectPath: 'path/to/project',
|
||||
};
|
||||
|
@ -49,7 +49,7 @@ describe('ClusterAgentShow', () => {
|
|||
shallowMount(ClusterAgentShow, {
|
||||
localVue,
|
||||
apolloProvider,
|
||||
propsData,
|
||||
provide,
|
||||
stubs: { GlSprintf, TimeAgoTooltip, GlTab },
|
||||
}),
|
||||
);
|
||||
|
@ -60,7 +60,7 @@ describe('ClusterAgentShow', () => {
|
|||
|
||||
wrapper = extendedWrapper(
|
||||
shallowMount(ClusterAgentShow, {
|
||||
propsData,
|
||||
provide,
|
||||
mocks: { $apollo, clusterAgent },
|
||||
slots,
|
||||
stubs: { GlTab },
|
||||
|
@ -85,7 +85,7 @@ describe('ClusterAgentShow', () => {
|
|||
});
|
||||
|
||||
it('displays the agent name', () => {
|
||||
expect(wrapper.text()).toContain(propsData.agentName);
|
||||
expect(wrapper.text()).toContain(provide.agentName);
|
||||
});
|
||||
|
||||
it('displays agent create information', () => {
|
||||
|
|
|
@ -75,16 +75,19 @@ describe('tags list row', () => {
|
|||
});
|
||||
|
||||
it.each`
|
||||
digest | disabled
|
||||
${'foo'} | ${true}
|
||||
${null} | ${false}
|
||||
${null} | ${true}
|
||||
${'foo'} | ${true}
|
||||
`('is disabled when the digest $digest and disabled is $disabled', ({ digest, disabled }) => {
|
||||
mountComponent({ tag: { ...tag, digest }, disabled });
|
||||
digest | disabled | isDisabled
|
||||
${'foo'} | ${true} | ${'true'}
|
||||
${null} | ${true} | ${'true'}
|
||||
${null} | ${false} | ${undefined}
|
||||
${'foo'} | ${false} | ${undefined}
|
||||
`(
|
||||
'disabled attribute is set to $isDisabled when the digest $digest and disabled is $disabled',
|
||||
({ digest, disabled, isDisabled }) => {
|
||||
mountComponent({ tag: { ...tag, digest }, disabled });
|
||||
|
||||
expect(findCheckbox().attributes('disabled')).toBe('true');
|
||||
});
|
||||
expect(findCheckbox().attributes('disabled')).toBe(isDisabled);
|
||||
},
|
||||
);
|
||||
|
||||
it('is wired to the selected prop', () => {
|
||||
mountComponent({ ...defaultProps, selected: true });
|
||||
|
|
|
@ -17,5 +17,10 @@ RSpec.describe Projects::ClusterAgentsHelper do
|
|||
it 'returns project path' do
|
||||
expect(subject[:project_path]).to eq(project.full_path)
|
||||
end
|
||||
|
||||
it 'returns string contants' do
|
||||
expect(subject[:activity_empty_state_image]).to be_kind_of(String)
|
||||
expect(subject[:empty_state_svg_path]).to be_kind_of(String)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -42,4 +42,10 @@ RSpec.describe Ci::GroupVariable do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'cleanup by a loose foreign key' do
|
||||
let!(:model) { create(:ci_group_variable) }
|
||||
|
||||
let!(:parent) { model.group }
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue