Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-10-09 21:08:38 +00:00
parent 1f794fa428
commit ba2d791767
9 changed files with 111 additions and 51 deletions

View File

@ -7,6 +7,12 @@ import { s__ } from '~/locale';
import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue';
import { RUNNER_TAG_BG_CLASS } from '../../constants';
// TODO This should be implemented via a GraphQL API
// The API should
// 1) scope to the rights of the user
// 2) stay up to date to the removal of old tags
// 3) consider the scope of search, like searching within the tags of a group
// See: https://gitlab.com/gitlab-org/gitlab/-/issues/333796
export const TAG_SUGGESTIONS_PATH = '/admin/runners/tag_list.json';
export default {
@ -29,12 +35,6 @@ export default {
},
methods: {
getTagsOptions(search) {
// TODO This should be implemented via a GraphQL API
// The API should
// 1) scope to the rights of the user
// 2) stay up to date to the removal of old tags
// 3) consider the scope of search, like searching within the tags of a group
// See: https://gitlab.com/gitlab-org/gitlab/-/issues/333796
return axios
.get(TAG_SUGGESTIONS_PATH, {
params: {
@ -46,6 +46,12 @@ export default {
});
},
async fetchTags(searchTerm) {
// Note: Suggestions should only be enabled for admin users
if (this.config.suggestionsDisabled) {
this.tags = [];
return;
}
this.loading = true;
try {
this.tags = await this.getTagsOptions(searchTerm);

View File

@ -10,6 +10,7 @@ query getGroupRunners(
$paused: Boolean
$status: CiRunnerStatus
$type: CiRunnerType
$tagList: [String!]
$search: String
$sort: CiRunnerSort
) {
@ -24,6 +25,7 @@ query getGroupRunners(
paused: $paused
status: $status
type: $type
tagList: $tagList
search: $search
sort: $sort
) {

View File

@ -27,6 +27,7 @@ import RunnerMembershipToggle from '../components/runner_membership_toggle.vue';
import { pausedTokenConfig } from '../components/search_tokens/paused_token_config';
import { statusTokenConfig } from '../components/search_tokens/status_token_config';
import { tagTokenConfig } from '../components/search_tokens/tag_token_config';
import {
GROUP_FILTERED_SEARCH_NAMESPACE,
GROUP_TYPE,
@ -131,12 +132,20 @@ export default {
noRunnersFound() {
return !this.runnersLoading && !this.runners.items.length;
},
searchTokens() {
return [pausedTokenConfig, statusTokenConfig, upgradeStatusTokenConfig];
},
filteredSearchNamespace() {
return `${GROUP_FILTERED_SEARCH_NAMESPACE}/${this.groupFullPath}`;
},
searchTokens() {
return [
pausedTokenConfig,
statusTokenConfig,
{
...tagTokenConfig,
suggestionsDisabled: true,
},
upgradeStatusTokenConfig,
];
},
isSearchFiltered() {
return isSearchFiltered(this.search);
},

View File

@ -19,7 +19,7 @@ Terraform to define resources that you can version, reuse, and share:
## Integrate your project with Terraform
> SAST test was [introduced](https://gitlab.com/groups/gitlab-org/-/epics/6655) in GitLab 14.6.
> IaC Scanning was [introduced](https://gitlab.com/groups/gitlab-org/-/epics/6655) in GitLab 14.6.
The integration with GitLab and Terraform happens through GitLab CI/CD.
Use an `include` attribute to add the Terraform template to your project and
@ -35,7 +35,7 @@ All templates:
- Use the [GitLab-managed Terraform state](terraform_state.md) as the Terraform state storage backend.
- Trigger four pipeline stages: `test`, `validate`, `build`, and `deploy`.
- Run Terraform commands: `test`, `validate`, `plan`, and `plan-json`. It also runs the `apply` only on the default branch.
- Run the [Terraform SAST scanner](../../application_security/iac_scanning/index.md#configure-iac-scanning-manually).
- Check for security problems using [IaC Scanning](../../application_security/iac_scanning/index.md#configure-iac-scanning-manually).
### Latest Terraform template

View File

@ -351,14 +351,15 @@ RSpec.describe "Admin Runners" do
end
describe 'filter by tag' do
before_all do
create(:ci_runner, :instance, description: 'runner-blue', tag_list: ['blue'])
create(:ci_runner, :instance, description: 'runner-red', tag_list: ['red'])
let_it_be(:runner_1) { create(:ci_runner, :instance, description: 'runner-blue', tag_list: ['blue']) }
let_it_be(:runner_2) { create(:ci_runner, :instance, description: 'runner-2-blue', tag_list: ['blue']) }
let_it_be(:runner_3) { create(:ci_runner, :instance, description: 'runner-red', tag_list: ['red']) }
before do
visit admin_runners_path
end
it 'shows tags suggestions' do
visit admin_runners_path
open_filtered_search_suggestions('Tags')
page.within(search_bar_selector) do
@ -367,23 +368,25 @@ RSpec.describe "Admin Runners" do
end
end
it 'shows correct runner when tag matches' do
visit admin_runners_path
it_behaves_like 'filters by tag' do
let(:tag) { 'blue' }
let(:found_runner) { runner_1.description }
let(:missing_runner) { runner_3.description }
end
expect(page).to have_content 'runner-blue'
expect(page).to have_content 'runner-red'
context 'when tag does not match' do
before do
input_filtered_search_filter_is_only('Tags', 'green')
end
input_filtered_search_filter_is_only('Tags', 'blue')
it_behaves_like 'shows no runners found'
expect(page).to have_content 'runner-blue'
expect(page).not_to have_content 'runner-red'
it 'shows no runner' do
expect(page).not_to have_content 'runner-blue'
end
end
it 'shows correct runner when tag is selected and search term is entered' do
create(:ci_runner, :instance, description: 'runner-2-blue', tag_list: ['blue'])
visit admin_runners_path
input_filtered_search_filter_is_only('Tags', 'blue')
expect(page).to have_content 'runner-blue'
@ -396,19 +399,6 @@ RSpec.describe "Admin Runners" do
expect(page).not_to have_content 'runner-blue'
expect(page).not_to have_content 'runner-red'
end
context 'when tag does not match' do
before do
visit admin_runners_path
input_filtered_search_filter_is_only('Tags', 'green')
end
it_behaves_like 'shows no runners found'
it 'shows no runner' do
expect(page).not_to have_content 'runner-blue'
end
end
end
it 'sorts by last contact date' do

View File

@ -189,6 +189,21 @@ RSpec.describe "Group Runners" do
end
end
end
describe 'filter by tag' do
let!(:runner_1) { create(:ci_runner, :group, groups: [group], description: 'runner-blue', tag_list: ['blue']) }
let!(:runner_2) { create(:ci_runner, :group, groups: [group], description: 'runner-red', tag_list: ['red']) }
before do
visit group_runners_path(group)
end
it_behaves_like 'filters by tag' do
let(:tag) { 'blue' }
let(:found_runner) { runner_1.description }
let(:missing_runner) { runner_2.description }
end
end
end
describe "Group runner show page", :js do

View File

@ -77,7 +77,7 @@ describe('TagToken', () => {
const findToken = () => wrapper.findComponent(GlToken);
const findGlLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
beforeEach(async () => {
beforeEach(() => {
mock = new MockAdapter(axios);
mock.onGet(TAG_SUGGESTIONS_PATH, { params: { search: '' } }).reply(200, mockTags);
@ -86,9 +86,6 @@ describe('TagToken', () => {
.reply(200, mockTagsFiltered);
getRecentlyUsedSuggestions.mockReturnValue([]);
createComponent();
await waitForPromises();
});
afterEach(() => {
@ -97,11 +94,17 @@ describe('TagToken', () => {
});
describe('when the tags token is displayed', () => {
beforeEach(() => {
createComponent();
});
it('requests tags suggestions', () => {
expect(mock.history.get[0].params).toEqual({ search: '' });
});
it('displays tags suggestions', () => {
it('displays tags suggestions', async () => {
await waitForPromises();
mockTags.forEach(({ name }, i) => {
expect(findGlFilteredSearchSuggestions().at(i).text()).toBe(name);
});
@ -132,13 +135,13 @@ describe('TagToken', () => {
});
describe('when the users filters suggestions', () => {
beforeEach(async () => {
beforeEach(() => {
createComponent();
findGlFilteredSearchToken().vm.$emit('input', { data: mockSearchTerm });
});
it('requests filtered tags suggestions', async () => {
await waitForPromises();
it('requests filtered tags suggestions', () => {
expect(mock.history.get[1].params).toEqual({ search: mockSearchTerm });
});
@ -166,7 +169,7 @@ describe('TagToken', () => {
await waitForPromises();
});
it('error is shown', async () => {
it('error is shown', () => {
expect(createAlert).toHaveBeenCalledTimes(1);
expect(createAlert).toHaveBeenCalledWith({ message: expect.any(String) });
});
@ -180,8 +183,26 @@ describe('TagToken', () => {
await waitForPromises();
});
it('selected tag is displayed', async () => {
it('selected tag is displayed', () => {
expect(findToken().exists()).toBe(true);
});
});
describe('when suggestions are disabled', () => {
beforeEach(async () => {
createComponent({
config: {
...mockTagTokenConfig,
suggestionsDisabled: true,
},
});
await waitForPromises();
});
it('displays no suggestions', () => {
expect(findGlFilteredSearchSuggestions()).toHaveLength(0);
expect(mock.history.get).toHaveLength(0);
});
});
});

View File

@ -37,6 +37,7 @@ import {
GROUP_TYPE,
PARAM_KEY_PAUSED,
PARAM_KEY_STATUS,
PARAM_KEY_TAG,
STATUS_ONLINE,
STATUS_OFFLINE,
STATUS_STALE,
@ -269,6 +270,10 @@ describe('GroupRunnersApp', () => {
type: PARAM_KEY_STATUS,
options: expect.any(Array),
}),
expect.objectContaining({
type: PARAM_KEY_TAG,
suggestionsDisabled: true,
}),
upgradeStatusTokenConfig,
]);
});

View File

@ -146,6 +146,18 @@ RSpec.shared_examples 'pauses, resumes and deletes a runner' do
end
end
RSpec.shared_examples 'filters by tag' do
it 'shows correct runner when tag matches' do
expect(page).to have_content found_runner
expect(page).to have_content missing_runner
input_filtered_search_filter_is_only('Tags', tag)
expect(page).to have_content found_runner
expect(page).not_to have_content missing_runner
end
end
RSpec.shared_examples 'submits edit runner form' do
it 'breadcrumb contains runner id and token' do
page.within '[data-testid="breadcrumb-links"]' do