Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
967b999f2e
commit
3c33a3d566
|
@ -6,7 +6,6 @@ import MarkdownField from '~/vue_shared/components/markdown/field.vue';
|
|||
import { BACK_URL_PARAM } from '~/releases/constants';
|
||||
import { getParameterByName } from '~/lib/utils/common_utils';
|
||||
import AssetLinksForm from './asset_links_form.vue';
|
||||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import MilestoneCombobox from '~/milestones/project_milestone_combobox.vue';
|
||||
import TagField from './tag_field.vue';
|
||||
|
||||
|
@ -22,7 +21,6 @@ export default {
|
|||
MilestoneCombobox,
|
||||
TagField,
|
||||
},
|
||||
mixins: [glFeatureFlagsMixin()],
|
||||
computed: {
|
||||
...mapState('detail', [
|
||||
'isFetchingRelease',
|
||||
|
@ -68,9 +66,6 @@ export default {
|
|||
cancelPath() {
|
||||
return getParameterByName(BACK_URL_PARAM) || this.releasesPagePath;
|
||||
},
|
||||
showAssetLinksForm() {
|
||||
return this.glFeatures.releaseAssetLinkEditing;
|
||||
},
|
||||
saveButtonLabel() {
|
||||
return this.isExistingRelease ? __('Save changes') : __('Create release');
|
||||
},
|
||||
|
@ -176,7 +171,7 @@ export default {
|
|||
</div>
|
||||
</gl-form-group>
|
||||
|
||||
<asset-links-form v-if="showAssetLinksForm" />
|
||||
<asset-links-form />
|
||||
|
||||
<div class="d-flex pt-3">
|
||||
<gl-button
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<script>
|
||||
import { GlButton } from '@gitlab/ui';
|
||||
import statusIcon from '../mr_widget_status_icon.vue';
|
||||
|
||||
export default {
|
||||
name: 'MRWidgetArchived',
|
||||
components: {
|
||||
GlButton,
|
||||
statusIcon,
|
||||
},
|
||||
};
|
||||
|
@ -12,9 +14,9 @@ export default {
|
|||
<div class="mr-widget-body media">
|
||||
<div class="space-children">
|
||||
<status-icon status="warning" />
|
||||
<button type="button" class="btn btn-success btn-sm" disabled="true">
|
||||
<gl-button category="secondary" variant="success" :disabled="true">
|
||||
{{ s__('mrWidget|Merge') }}
|
||||
</button>
|
||||
</gl-button>
|
||||
</div>
|
||||
<div class="media-body">
|
||||
<span class="bold">
|
||||
|
|
|
@ -7,7 +7,6 @@ class Projects::ReleasesController < Projects::ApplicationController
|
|||
before_action :authorize_read_release!
|
||||
before_action do
|
||||
push_frontend_feature_flag(:release_evidence_collection, project, default_enabled: true)
|
||||
push_frontend_feature_flag(:release_asset_link_editing, project, default_enabled: true)
|
||||
push_frontend_feature_flag(:graphql_release_data, project, default_enabled: true)
|
||||
push_frontend_feature_flag(:graphql_milestone_stats, project, default_enabled: true)
|
||||
push_frontend_feature_flag(:graphql_releases_page, project, default_enabled: true)
|
||||
|
|
|
@ -78,6 +78,20 @@ class DeployToken < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
def group
|
||||
strong_memoize(:group) do
|
||||
groups.first
|
||||
end
|
||||
end
|
||||
|
||||
def accessible_projects
|
||||
if project_type?
|
||||
projects
|
||||
elsif group_type?
|
||||
group.all_projects
|
||||
end
|
||||
end
|
||||
|
||||
def holder
|
||||
strong_memoize(:holder) do
|
||||
if project_type?
|
||||
|
|
|
@ -604,7 +604,7 @@ class Project < ApplicationRecord
|
|||
return public_to_user unless user
|
||||
|
||||
if user.is_a?(DeployToken)
|
||||
user.projects
|
||||
user.accessible_projects
|
||||
else
|
||||
where('EXISTS (?) OR projects.visibility_level IN (?)',
|
||||
user.authorizations_for_projects(min_access_level: min_access_level),
|
||||
|
|
|
@ -4,7 +4,6 @@ module Projects
|
|||
module ContainerRepository
|
||||
class CleanupTagsService < BaseService
|
||||
def execute(container_repository)
|
||||
return error('feature disabled') unless can_use?
|
||||
return error('access denied') unless can_destroy?
|
||||
return error('invalid regex') unless valid_regex?
|
||||
|
||||
|
@ -74,10 +73,6 @@ module Projects
|
|||
can?(current_user, :destroy_container_image, project)
|
||||
end
|
||||
|
||||
def can_use?
|
||||
Feature.enabled?(:container_registry_cleanup, project, default_enabled: true)
|
||||
end
|
||||
|
||||
def valid_regex?
|
||||
%w(name_regex_delete name_regex name_regex_keep).each do |param_name|
|
||||
regex = params[param_name]
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: Fix group deploy tokens to return all projects and work with the Maven group
|
||||
endpoint
|
||||
merge_request: 43628
|
||||
author:
|
||||
type: fixed
|
|
@ -1,7 +0,0 @@
|
|||
---
|
||||
name: container_registry_cleanup
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
type: development
|
||||
default_enabled: true
|
|
@ -1,7 +0,0 @@
|
|||
---
|
||||
name: epics_search
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/42456
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/250317
|
||||
group: group::global search
|
||||
type: development
|
||||
default_enabled: false
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
name: json_limited_encoder
|
||||
introduced_by_url:
|
||||
rollout_issue_url:
|
||||
group:
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38687
|
||||
rollout_issue_url:
|
||||
group: group::source code
|
||||
type: development
|
||||
default_enabled: false
|
||||
|
|
|
@ -184,6 +184,16 @@ The message `Successfully connected` indicates a successful TLS handshake.
|
|||
If there are problems, the Java TLS library generates errors that you can
|
||||
look up for more detail.
|
||||
|
||||
##### Scope error when connecting Jira via DVCS
|
||||
|
||||
```plaintext
|
||||
The requested scope is invalid, unknown, or malformed.
|
||||
```
|
||||
|
||||
Potential resolutions:
|
||||
|
||||
- Verify the URL includes `scope=api` on the end of the URL.
|
||||
|
||||
##### Jira error adding account and no repositories listed
|
||||
|
||||
```plaintext
|
||||
|
|
|
@ -38,7 +38,7 @@ To run Secret Detection jobs, by default, you need GitLab Runner with the
|
|||
If you're using the shared runners on GitLab.com, this is enabled by default.
|
||||
|
||||
CAUTION: **Caution:**
|
||||
Our Secret Detection jobs currently expect a Linux container type. Windows containers are not yet supported.
|
||||
Our Secret Detection jobs expect a Linux container type. Windows containers are not supported.
|
||||
|
||||
CAUTION: **Caution:**
|
||||
If you use your own runners, make sure the Docker version installed
|
||||
|
@ -139,7 +139,7 @@ Secret Detection can be customized by defining available variables:
|
|||
|-------------------------|---------------|-------------|
|
||||
| `SECRET_DETECTION_COMMIT_FROM` | - | The commit a Gitleaks scan starts at. |
|
||||
| `SECRET_DETECTION_COMMIT_TO` | - | The commit a Gitleaks scan ends at. |
|
||||
| `SECRET_DETECTION_EXCLUDED_PATHS` | "" | Exclude vulnerabilities from output based on the paths. This is a comma-separated list of patterns. Patterns can be globs, or file or folder paths (for example, `doc,spec` ). Parent directories will also match patterns. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/225273) in GitLab 13.3. |
|
||||
| `SECRET_DETECTION_EXCLUDED_PATHS` | "" | Exclude vulnerabilities from output based on the paths. This is a comma-separated list of patterns. Patterns can be globs, or file or folder paths (for example, `doc,spec` ). Parent directories also match patterns. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/225273) in GitLab 13.3. |
|
||||
| `SECRET_DETECTION_HISTORIC_SCAN` | false | Flag to enable a historic Gitleaks scan. |
|
||||
|
||||
### Logging level
|
||||
|
|
|
@ -223,6 +223,7 @@ backed by the database and allows searching in:
|
|||
- Merge requests
|
||||
- Milestones
|
||||
- Users
|
||||
- Epics (Group only)
|
||||
- Code (Project only)
|
||||
- Comments (Project only)
|
||||
- Commits (Project only)
|
||||
|
|
|
@ -20,7 +20,7 @@ describe('Release edit/new component', () => {
|
|||
let state;
|
||||
let mock;
|
||||
|
||||
const factory = ({ featureFlags = {}, store: storeUpdates = {} } = {}) => {
|
||||
const factory = async ({ featureFlags = {}, store: storeUpdates = {} } = {}) => {
|
||||
state = {
|
||||
release,
|
||||
markdownDocsPath: 'path/to/markdown/docs',
|
||||
|
@ -68,6 +68,8 @@ describe('Release edit/new component', () => {
|
|||
},
|
||||
});
|
||||
|
||||
await wrapper.vm.$nextTick();
|
||||
|
||||
wrapper.element.querySelectorAll('input').forEach(input => jest.spyOn(input, 'focus'));
|
||||
};
|
||||
|
||||
|
@ -89,7 +91,9 @@ describe('Release edit/new component', () => {
|
|||
const findForm = () => wrapper.find('form');
|
||||
|
||||
describe(`basic functionality tests: all tests unrelated to the "${BACK_URL_PARAM}" parameter`, () => {
|
||||
beforeEach(factory);
|
||||
beforeEach(async () => {
|
||||
await factory();
|
||||
});
|
||||
|
||||
it('calls initializeRelease when the component is created', () => {
|
||||
expect(actions.initializeRelease).toHaveBeenCalledTimes(1);
|
||||
|
@ -131,7 +135,9 @@ describe('Release edit/new component', () => {
|
|||
});
|
||||
|
||||
describe(`when the URL does not contain a "${BACK_URL_PARAM}" parameter`, () => {
|
||||
beforeEach(factory);
|
||||
beforeEach(async () => {
|
||||
await factory();
|
||||
});
|
||||
|
||||
it(`renders a "Cancel" button with an href pointing to "${BACK_URL_PARAM}"`, () => {
|
||||
const cancelButton = wrapper.find('.js-cancel-button');
|
||||
|
@ -142,12 +148,12 @@ describe('Release edit/new component', () => {
|
|||
describe(`when the URL contains a "${BACK_URL_PARAM}" parameter`, () => {
|
||||
const backUrl = 'https://example.gitlab.com/back/url';
|
||||
|
||||
beforeEach(() => {
|
||||
beforeEach(async () => {
|
||||
commonUtils.getParameterByName = jest
|
||||
.fn()
|
||||
.mockImplementation(paramToGet => ({ [BACK_URL_PARAM]: backUrl }[paramToGet]));
|
||||
|
||||
factory();
|
||||
await factory();
|
||||
});
|
||||
|
||||
it('renders a "Cancel" button with an href pointing to the main Releases page', () => {
|
||||
|
@ -157,8 +163,8 @@ describe('Release edit/new component', () => {
|
|||
});
|
||||
|
||||
describe('when creating a new release', () => {
|
||||
beforeEach(() => {
|
||||
factory({
|
||||
beforeEach(async () => {
|
||||
await factory({
|
||||
store: {
|
||||
modules: {
|
||||
detail: {
|
||||
|
@ -177,7 +183,9 @@ describe('Release edit/new component', () => {
|
|||
});
|
||||
|
||||
describe('when editing an existing release', () => {
|
||||
beforeEach(factory);
|
||||
beforeEach(async () => {
|
||||
await factory();
|
||||
});
|
||||
|
||||
it('renders the submit button with the text "Save changes"', () => {
|
||||
expect(findSubmitButton().text()).toBe('Save changes');
|
||||
|
@ -185,33 +193,17 @@ describe('Release edit/new component', () => {
|
|||
});
|
||||
|
||||
describe('asset links form', () => {
|
||||
const findAssetLinksForm = () => wrapper.find(AssetLinksForm);
|
||||
beforeEach(factory);
|
||||
|
||||
describe('when the release_asset_link_editing feature flag is disabled', () => {
|
||||
beforeEach(() => {
|
||||
factory({ featureFlags: { releaseAssetLinkEditing: false } });
|
||||
});
|
||||
|
||||
it('does not render the asset links portion of the form', () => {
|
||||
expect(findAssetLinksForm().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the release_asset_link_editing feature flag is enabled', () => {
|
||||
beforeEach(() => {
|
||||
factory({ featureFlags: { releaseAssetLinkEditing: true } });
|
||||
});
|
||||
|
||||
it('renders the asset links portion of the form', () => {
|
||||
expect(findAssetLinksForm().exists()).toBe(true);
|
||||
});
|
||||
it('renders the asset links portion of the form', () => {
|
||||
expect(wrapper.find(AssetLinksForm).exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('validation', () => {
|
||||
describe('when the form is valid', () => {
|
||||
beforeEach(() => {
|
||||
factory({
|
||||
beforeEach(async () => {
|
||||
await factory({
|
||||
store: {
|
||||
modules: {
|
||||
detail: {
|
||||
|
@ -230,8 +222,8 @@ describe('Release edit/new component', () => {
|
|||
});
|
||||
|
||||
describe('when the form is invalid', () => {
|
||||
beforeEach(() => {
|
||||
factory({
|
||||
beforeEach(async () => {
|
||||
await factory({
|
||||
store: {
|
||||
modules: {
|
||||
detail: {
|
||||
|
|
|
@ -353,4 +353,29 @@ RSpec.describe DeployToken do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#accessible_projects' do
|
||||
subject { deploy_token.accessible_projects }
|
||||
|
||||
context 'when a deploy token is associated to a project' do
|
||||
let_it_be(:deploy_token) { create(:deploy_token, :project) }
|
||||
|
||||
it 'returns only projects directly associated with the token' do
|
||||
expect(deploy_token).to receive(:projects)
|
||||
|
||||
subject
|
||||
end
|
||||
end
|
||||
|
||||
context 'when a deploy token is associated to a group' do
|
||||
let_it_be(:group) { create(:group) }
|
||||
let_it_be(:deploy_token) { create(:deploy_token, :group, groups: [group]) }
|
||||
|
||||
it 'returns all projects from the group' do
|
||||
expect(group).to receive(:all_projects)
|
||||
|
||||
subject
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,10 +15,13 @@ RSpec.describe API::MavenPackages do
|
|||
let_it_be(:job, reload: true) { create(:ci_build, user: user, status: :running) }
|
||||
let_it_be(:deploy_token) { create(:deploy_token, read_package_registry: true, write_package_registry: true) }
|
||||
let_it_be(:project_deploy_token) { create(:project_deploy_token, deploy_token: deploy_token, project: project) }
|
||||
let_it_be(:deploy_token_for_group) { create(:deploy_token, :group, read_package_registry: true, write_package_registry: true) }
|
||||
let_it_be(:group_deploy_token) { create(:group_deploy_token, deploy_token: deploy_token_for_group, group: group) }
|
||||
|
||||
let(:workhorse_token) { JWT.encode({ 'iss' => 'gitlab-workhorse' }, Gitlab::Workhorse.secret, 'HS256') }
|
||||
let(:headers) { { 'GitLab-Workhorse' => '1.0', Gitlab::Workhorse::INTERNAL_API_REQUEST_HEADER => workhorse_token } }
|
||||
let(:headers_with_token) { headers.merge('Private-Token' => personal_access_token.token) }
|
||||
let(:group_deploy_token_headers) { { Gitlab::Auth::AuthFinders::DEPLOY_TOKEN_HEADER => deploy_token_for_group.token } }
|
||||
|
||||
let(:headers_with_deploy_token) do
|
||||
headers.merge(
|
||||
|
@ -342,6 +345,17 @@ RSpec.describe API::MavenPackages do
|
|||
it_behaves_like 'downloads with a job token'
|
||||
|
||||
it_behaves_like 'downloads with a deploy token'
|
||||
|
||||
context 'with group deploy token' do
|
||||
subject { download_file_with_token(package_file.file_name, {}, group_deploy_token_headers) }
|
||||
|
||||
it 'returns the file' do
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response.media_type).to eq('application/octet-stream')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def download_file(file_name, params = {}, request_headers = headers)
|
||||
|
|
|
@ -12,8 +12,6 @@ RSpec.describe Projects::ContainerRepository::CleanupTagsService do
|
|||
before do
|
||||
project.add_maintainer(user)
|
||||
|
||||
stub_feature_flags(container_registry_cleanup: true)
|
||||
|
||||
stub_container_registry_config(enabled: true)
|
||||
|
||||
stub_container_registry_tags(
|
||||
|
|
Loading…
Reference in New Issue