Skip to content
Snippets Groups Projects
Commit 1c8fa70f authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent 736d36d8
No related branches found
No related tags found
No related merge requests found
Showing
with 234 additions and 147 deletions
---
title: Remove Puma notices from AdminArea banner
merge_request: 26137
author:
type: changed
Loading
Loading
@@ -29,6 +29,7 @@ constraints(::Constraints::GroupUrlConstrainer.new) do
resource :ci_cd, only: [:show, :update], controller: 'ci_cd' do
put :reset_registration_token
patch :update_auto_devops
post :create_deploy_token, path: 'deploy_token/create'
end
end
 
Loading
Loading
@@ -49,6 +50,12 @@ constraints(::Constraints::GroupUrlConstrainer.new) do
end
end
 
resources :deploy_tokens, constraints: { id: /\d+/ }, only: [] do
member do
put :revoke
end
end
resource :avatar, only: [:destroy]
 
concerns :clusterable
Loading
Loading
Loading
Loading
@@ -79,7 +79,9 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
resource :integrations, only: [:show]
 
resource :repository, only: [:show], controller: :repository do
post :create_deploy_token, path: 'deploy_token/create'
# TODO: Move 'create_deploy_token' here to the ':ci_cd' resource above during 12.9.
# More details here: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/24102#note_287572556
post :create_deploy_token, path: 'deploy_token/create', to: 'ci_cd#create_deploy_token'
post :cleanup
end
end
Loading
Loading
Loading
Loading
@@ -64,6 +64,63 @@ the extra jobs will take resources away from jobs from workers that were already
there, if the resources available to the Sidekiq process handling the namespace
are not adjusted appropriately.
 
## Idempotent Jobs
It's known that a job can fail for multiple reasons, for example, network outages or bugs.
In order to address this, Sidekiq has a built-in retry mechanism that is
used by default by most workers within GitLab.
It's expected that a job can run again after a failure without major side-effects for the
application or users, which is why Sidekiq encourages
jobs to be [idempotent and transactional](https://github.com/mperham/sidekiq/wiki/Best-Practices#2-make-your-job-idempotent-and-transactional).
As a general rule, a worker can be considered idempotent if:
- It can safely run multiple times with the same arguments.
- Application side-effects are expected to happen only once
(or side-effects of a second run are not impactful).
A good example of that would be a cache expiration worker.
### Ensuring a worker is idempotent
Make sure the worker tests pass using the following shared example:
```ruby
include_examples 'an idempotent worker' do
it 'marks the MR as merged' do
# Using subject inside this block will process the job multiple times
subject
expect(merge_request.state).to eq('merged')
end
end
```
Use the `perform_multiple` method directly instead of `job.perform` (this
helper method is automatically included for workers).
### Declaring a worker as idempotent
```ruby
class IdempotentWorker
include ApplicationWorker
# Declares a worker is idempotent and can
# safely run multiple times.
idempotent!
# ...
end
```
It's encouraged to only have the `idempotent!` call in the top-most worker class, even if
the `perform` method is defined in another class or module.
NOTE: **Note:**
Note that a cop will fail if the worker class is not marked as idempotent.
Consider skipping the cop if you're not confident your job can safely run multiple times.
## Latency Sensitive Jobs
 
If a large number of background jobs get scheduled at once, queueing of jobs may
Loading
Loading
Loading
Loading
@@ -61,6 +61,7 @@ bugsCharts:
title: "Charts for bugs"
charts:
- title: "Monthly bugs created"
description: "Open bugs created per month"
type: bar
query:
issuable_type: issue
Loading
Loading
@@ -77,6 +78,7 @@ For example, here's single chart definition:
 
```yaml
- title: "Monthly bugs created"
description: "Open bugs created per month"
type: bar
query:
issuable_type: issue
Loading
Loading
@@ -96,6 +98,7 @@ The following table lists available parameters for charts:
| Keyword | Description |
|:---------------------------------------------------|:------------|
| [`title`](#title) | The title of the chart. This will displayed on the Insights page. |
| [`description`](#description) | A description for the individual chart. This will be displayed above the relevant chart. |
| [`type`](#type) | The type of chart: `bar`, `line` or `stacked-bar`. |
| [`query`](#query) | A hash that defines the conditions for issues / merge requests to be part of the chart. |
 
Loading
Loading
@@ -114,6 +117,17 @@ monthlyBugsCreated:
title: "Monthly bugs created"
```
 
### `description`
The `description` text is displayed above the chart, but below the title. It's used
to give extra details regarding the chart, for example:
```yaml
monthlyBugsCreated:
title: "Monthly bugs created"
description: "Open bugs created per month"
```
### `type`
 
`type` is the chart type.
Loading
Loading
@@ -145,6 +159,7 @@ Example:
```yaml
monthlyBugsCreated:
title: "Monthly bugs created"
description: "Open bugs created per month"
type: bar
query:
issuable_type: issue
Loading
Loading
@@ -283,6 +298,7 @@ a group's insights:
```yaml
monthlyBugsCreated:
title: "Monthly bugs created"
description: "Open bugs created per month"
type: bar
query:
issuable_type: issue
Loading
Loading
@@ -311,6 +327,7 @@ bugsCharts:
title: "Charts for bugs"
charts:
- title: "Monthly bugs created"
description: "Open bugs created per month"
type: bar
<<: *projectsOnly
query:
Loading
Loading
Loading
Loading
@@ -33,17 +33,19 @@ defined in that template.
Add the following to your `.gitlab-ci.yml` file:
 
```yaml
include:
template: Verify/Accessibility.gitlab-ci.yml
variables:
a11y_urls: "https://about.gitlab.com"
 
a11y:
variables:
a11y_urls: https://example.com https://example.com/another-page
include:
- remote: "https://gitlab.com/gitlab-org/gitlab/-/raw/master/lib/gitlab/ci/templates/Verify/Accessibility.gitlab-ci.yml"
```
 
The example above will create an `a11y` job in your CI/CD pipeline and will run
Pa11y against the webpage you defined in `a11y_urls` to build a report.
 
NOTE: **Note:**
Only one URL may be currently passed into `a11y_urls`.
The full HTML Pa11y report will be saved as an artifact that can be [viewed directly in your browser](../pipelines/job_artifacts.md#browsing-artifacts).
 
NOTE: **Note:**
Loading
Loading
Loading
Loading
@@ -7,36 +7,14 @@ module Gitlab
extend Gitlab::Git::RuggedImpl::UseRugged
 
def check
return [] unless Gitlab::Runtime.puma?
notices = []
 
link_start = '<a href="https://docs.gitlab.com/ee/administration/operations/puma.html">'
link_end = '</a>'
notices << {
type: 'info',
message: _('You are running Puma, which is currently experimental. '\
'More information is available in our '\
'%{link_start}documentation%{link_end}.') % { link_start: link_start, link_end: link_end }
}
if running_puma_with_multiple_threads?
link_start = '<a href="https://docs.gitlab.com/ee/administration/operations/puma.html">'
link_end = '</a>'
notices << {
type: 'info',
message: _('Puma is running with a thread count above 1. '\
'Information on deprecated GitLab features in this configuration is available in the '\
'%{link_start}documentation%{link_end}.') % { link_start: link_start, link_end: link_end }
}
end
if running_puma_with_multiple_threads? && rugged_enabled_through_feature_flag?
link_start = '<a href="https://docs.gitlab.com/ee/administration/operations/puma.html#performance-caveat-when-using-puma-with-rugged">'
link_end = '</a>'
notices << {
type: 'warning',
message: _('Puma is running with a thread count above 1 and the rugged '\
message: _('Puma is running with a thread count above 1 and the Rugged '\
'service is enabled. This may decrease performance in some environments. '\
'See our %{link_start}documentation%{link_end} '\
'for details of this issue.') % { link_start: link_start, link_end: link_end }
Loading
Loading
Loading
Loading
@@ -6507,6 +6507,9 @@ msgstr ""
msgid "DeployTokens|Expires"
msgstr ""
 
msgid "DeployTokens|Group deploy tokens allow read-only access to the repositories and registry images within the group."
msgstr ""
msgid "DeployTokens|Name"
msgstr ""
 
Loading
Loading
@@ -6516,16 +6519,19 @@ msgstr ""
msgid "DeployTokens|Revoke"
msgstr ""
 
msgid "DeployTokens|Revoke %{b_start}%{name}%{b_end}?"
msgstr ""
msgid "DeployTokens|Revoke %{name}"
msgstr ""
 
msgid "DeployTokens|Scopes"
msgstr ""
 
msgid "DeployTokens|This action cannot be undone."
msgid "DeployTokens|This %{entity_type} has no active Deploy Tokens."
msgstr ""
 
msgid "DeployTokens|This project has no active Deploy Tokens."
msgid "DeployTokens|This action cannot be undone."
msgstr ""
 
msgid "DeployTokens|Use this token as a password. Make sure you save it - you won't be able to access it again."
Loading
Loading
@@ -6537,12 +6543,15 @@ msgstr ""
msgid "DeployTokens|Username"
msgstr ""
 
msgid "DeployTokens|You are about to revoke"
msgid "DeployTokens|You are about to revoke %{b_start}%{name}%{b_end}."
msgstr ""
 
msgid "DeployTokens|Your New Deploy Token"
msgstr ""
 
msgid "DeployTokens|Your new group deploy token has been created."
msgstr ""
msgid "DeployTokens|Your new project deploy token has been created."
msgstr ""
 
Loading
Loading
@@ -15735,10 +15744,7 @@ msgstr ""
msgid "Pull"
msgstr ""
 
msgid "Puma is running with a thread count above 1 and the rugged service is enabled. This may decrease performance in some environments. See our %{link_start}documentation%{link_end} for details of this issue."
msgstr ""
msgid "Puma is running with a thread count above 1. Information on deprecated GitLab features in this configuration is available in the %{link_start}documentation%{link_end}."
msgid "Puma is running with a thread count above 1 and the Rugged service is enabled. This may decrease performance in some environments. See our %{link_start}documentation%{link_end} for details of this issue."
msgstr ""
 
msgid "Purchase more minutes"
Loading
Loading
@@ -22324,9 +22330,6 @@ msgstr ""
msgid "You are receiving this message because you are a GitLab administrator for %{url}."
msgstr ""
 
msgid "You are running Puma, which is currently experimental. More information is available in our %{link_start}documentation%{link_end}."
msgstr ""
msgid "You can %{linkStart}view the blob%{linkEnd} instead."
msgstr ""
 
Loading
Loading
Loading
Loading
@@ -13,6 +13,16 @@ module QA
element :variables_settings_content
end
 
view 'app/views/shared/deploy_tokens/_index.html.haml' do
element :deploy_tokens_settings
end
def expand_deploy_tokens(&block)
expand_section(:deploy_tokens_settings) do
Settings::DeployTokens.perform(&block)
end
end
def expand_runners_settings(&block)
expand_section(:runners_settings_content) do
Settings::Runners.perform(&block)
Loading
Loading
Loading
Loading
@@ -5,7 +5,7 @@ module QA
module Project
module Settings
class DeployTokens < Page::Base
view 'app/views/projects/deploy_tokens/_form.html.haml' do
view 'app/views/shared/deploy_tokens/_form.html.haml' do
element :deploy_token_name
element :deploy_token_expires_at
element :deploy_token_read_repository
Loading
Loading
@@ -13,7 +13,7 @@ module QA
element :create_deploy_token
end
 
view 'app/views/projects/deploy_tokens/_new_deploy_token.html.haml' do
view 'app/views/shared/deploy_tokens/_new_deploy_token.html.haml' do
element :created_deploy_token_section
element :deploy_token_user
element :deploy_token
Loading
Loading
Loading
Loading
@@ -31,12 +31,6 @@ module QA
end
end
 
def expand_deploy_tokens(&block)
expand_section(:deploy_tokens_settings) do
DeployTokens.perform(&block)
end
end
def expand_mirroring_repositories(&block)
expand_section(:mirroring_repositories_settings_section) do
MirroringRepositories.perform(&block)
Loading
Loading
Loading
Loading
@@ -6,16 +6,16 @@ module QA
attr_accessor :name, :expires_at
 
attribute :username do
Page::Project::Settings::Repository.perform do |repository_page|
repository_page.expand_deploy_tokens do |token|
Page::Project::Settings::CICD.perform do |cicd_page|
cicd_page.expand_deploy_tokens do |token|
token.token_username
end
end
end
 
attribute :password do
Page::Project::Settings::Repository.perform do |repository_page|
repository_page.expand_deploy_tokens do |token|
Page::Project::Settings::CICD.perform do |cicd_page|
cicd_page.expand_deploy_tokens do |token|
token.token_password
end
end
Loading
Loading
@@ -31,12 +31,10 @@ module QA
def fabricate!
project.visit!
 
Page::Project::Menu.act do
go_to_repository_settings
end
Page::Project::Menu.perform(&:go_to_ci_cd_settings)
 
Page::Project::Settings::Repository.perform do |setting|
setting.expand_deploy_tokens do |page|
Page::Project::Settings::CICD.perform do |cicd|
cicd.expand_deploy_tokens do |page|
page.fill_token_name(name)
page.fill_token_expires_at(expires_at)
page.fill_scopes(read_repository: true, read_registry: false)
Loading
Loading
Loading
Loading
@@ -210,4 +210,16 @@ describe Groups::Settings::CiCdController do
end
end
end
describe 'POST create_deploy_token' do
it_behaves_like 'a created deploy token' do
let(:entity) { group }
let(:create_entity_params) { { group_id: group } }
let(:deploy_token_type) { DeployToken.deploy_token_types[:group_type] }
before do
entity.add_owner(user)
end
end
end
end
Loading
Loading
@@ -247,4 +247,12 @@ describe Projects::Settings::CiCdController do
end
end
end
describe 'POST create_deploy_token' do
it_behaves_like 'a created deploy token' do
let(:entity) { project }
let(:create_entity_params) { { namespace_id: project.namespace, project_id: project } }
let(:deploy_token_type) { DeployToken.deploy_token_types[:project_type] }
end
end
end
Loading
Loading
@@ -32,24 +32,4 @@ describe Projects::Settings::RepositoryController do
expect(RepositoryCleanupWorker).to have_received(:perform_async).once
end
end
describe 'POST create_deploy_token' do
let(:deploy_token_params) do
{
name: 'deployer_token',
expires_at: 1.month.from_now.to_date.to_s,
username: 'deployer',
read_repository: '1'
}
end
subject(:create_deploy_token) { post :create_deploy_token, params: { namespace_id: project.namespace, project_id: project, deploy_token: deploy_token_params } }
it 'creates deploy token' do
expect { create_deploy_token }.to change { DeployToken.active.count }.by(1)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:show)
end
end
end
Loading
Loading
@@ -37,6 +37,19 @@ describe 'Group CI/CD settings' do
end
end
 
context 'Deploy tokens' do
let!(:deploy_token) { create(:deploy_token, :group, groups: [group]) }
before do
stub_container_registry_config(enabled: true)
visit group_settings_ci_cd_path(group)
end
it_behaves_like 'a deploy token in ci/cd settings' do
let(:entity_type) { 'group' }
end
end
describe 'Auto DevOps form' do
before do
stub_application_setting(auto_devops_enabled: true)
Loading
Loading
# frozen_string_literal: true
require 'spec_helper'
describe 'Projects > Settings > CI/CD settings' do
let(:project) { create(:project_empty_repo) }
let(:user) { create(:user) }
let(:role) { :maintainer }
context 'Deploy tokens' do
let!(:deploy_token) { create(:deploy_token, projects: [project]) }
before do
project.add_role(user, role)
sign_in(user)
stub_container_registry_config(enabled: true)
visit project_settings_ci_cd_path(project)
end
it_behaves_like 'a deploy token in ci/cd settings' do
let(:entity_type) { 'project' }
end
end
end
Loading
Loading
@@ -108,39 +108,6 @@ describe 'Projects > Settings > Repository settings' do
end
end
 
context 'Deploy tokens' do
let!(:deploy_token) { create(:deploy_token, projects: [project]) }
before do
stub_container_registry_config(enabled: true)
visit project_settings_repository_path(project)
end
it 'view deploy tokens' do
within('.deploy-tokens') do
expect(page).to have_content(deploy_token.name)
expect(page).to have_content('read_repository')
expect(page).to have_content('read_registry')
end
end
it 'add a new deploy token' do
fill_in 'deploy_token_name', with: 'new_deploy_key'
fill_in 'deploy_token_expires_at', with: (Date.today + 1.month).to_s
fill_in 'deploy_token_username', with: 'deployer'
check 'deploy_token_read_repository'
check 'deploy_token_read_registry'
click_button 'Create deploy token'
expect(page).to have_content('Your new project deploy token has been created')
within('.created-deploy-token-container') do
expect(page).to have_selector("input[name='deploy-token-user'][value='deployer']")
expect(page).to have_selector("input[name='deploy-token'][readonly='readonly']")
end
end
end
context 'remote mirror settings' do
let(:user2) { create(:user) }
 
Loading
Loading
Loading
Loading
@@ -11,7 +11,7 @@ describe 'Repository Settings > User sees revoke deploy token modal', :js do
before do
project.add_role(user, role)
sign_in(user)
visit(project_settings_repository_path(project))
visit(project_settings_ci_cd_path(project))
click_link('Revoke')
end
 
Loading
Loading
import $ from 'jquery';
import '~/behaviors/quick_submit';
 
describe('Quick Submit behavior', function() {
describe('Quick Submit behavior', () => {
let testContext;
const keydownEvent = (options = { keyCode: 13, metaKey: true }) => $.Event('keydown', options);
 
preloadFixtures('snippets/show.html');
 
beforeEach(() => {
loadFixtures('snippets/show.html');
testContext = {};
testContext.spies = {
submit: jest.fn(),
};
$('form').submit(e => {
// Prevent a form submit from moving us off the testing page
e.preventDefault();
// Explicitly call the spie to know this function get's not called
testContext.spies.submit();
});
this.spies = {
submit: spyOnEvent('form', 'submit'),
};
this.textarea = $('.js-quick-submit textarea').first();
});
afterEach(() => {
// Undo what we did to the shared <body>
$('body').removeAttr('data-page');
testContext.textarea = $('.js-quick-submit textarea').first();
});
 
it('does not respond to other keyCodes', () => {
this.textarea.trigger(
testContext.textarea.trigger(
keydownEvent({
keyCode: 32,
}),
);
 
expect(this.spies.submit).not.toHaveBeenTriggered();
expect(testContext.spies.submit).not.toHaveBeenCalled();
});
 
it('does not respond to Enter alone', () => {
this.textarea.trigger(
testContext.textarea.trigger(
keydownEvent({
ctrlKey: false,
metaKey: false,
}),
);
 
expect(this.spies.submit).not.toHaveBeenTriggered();
expect(testContext.spies.submit).not.toHaveBeenCalled();
});
 
it('does not respond to repeated events', () => {
this.textarea.trigger(
testContext.textarea.trigger(
keydownEvent({
repeat: true,
}),
);
 
expect(this.spies.submit).not.toHaveBeenTriggered();
expect(testContext.spies.submit).not.toHaveBeenCalled();
});
 
it('disables input of type submit', () => {
const submitButton = $('.js-quick-submit input[type=submit]');
this.textarea.trigger(keydownEvent());
testContext.textarea.trigger(keydownEvent());
 
expect(submitButton).toBeDisabled();
});
 
it('disables button of type submit', () => {
const submitButton = $('.js-quick-submit input[type=submit]');
this.textarea.trigger(keydownEvent());
testContext.textarea.trigger(keydownEvent());
 
expect(submitButton).toBeDisabled();
});
Loading
Loading
@@ -73,71 +75,79 @@ describe('Quick Submit behavior', function() {
const existingSubmit = $('.js-quick-submit input[type=submit]');
// Add an extra submit button
const newSubmit = $('<button type="submit">Submit it</button>');
newSubmit.insertAfter(this.textarea);
newSubmit.insertAfter(testContext.textarea);
 
const oldClick = spyOnEvent(existingSubmit, 'click');
const newClick = spyOnEvent(newSubmit, 'click');
const spies = {
oldClickSpy: jest.fn(),
newClickSpy: jest.fn(),
};
existingSubmit.on('click', () => {
spies.oldClickSpy();
});
newSubmit.on('click', () => {
spies.newClickSpy();
});
 
this.textarea.trigger(keydownEvent());
testContext.textarea.trigger(keydownEvent());
 
expect(oldClick).not.toHaveBeenTriggered();
expect(newClick).toHaveBeenTriggered();
expect(spies.oldClickSpy).not.toHaveBeenCalled();
expect(spies.newClickSpy).toHaveBeenCalled();
});
// We cannot stub `navigator.userAgent` for CI's `rake karma` task, so we'll
// only run the tests that apply to the current platform
if (navigator.userAgent.match(/Macintosh/)) {
describe('In Macintosh', () => {
it('responds to Meta+Enter', () => {
this.textarea.trigger(keydownEvent());
testContext.textarea.trigger(keydownEvent());
 
expect(this.spies.submit).toHaveBeenTriggered();
expect(testContext.spies.submit).toHaveBeenCalled();
});
 
it('excludes other modifier keys', () => {
this.textarea.trigger(
testContext.textarea.trigger(
keydownEvent({
altKey: true,
}),
);
this.textarea.trigger(
testContext.textarea.trigger(
keydownEvent({
ctrlKey: true,
}),
);
this.textarea.trigger(
testContext.textarea.trigger(
keydownEvent({
shiftKey: true,
}),
);
 
expect(this.spies.submit).not.toHaveBeenTriggered();
expect(testContext.spies.submit).not.toHaveBeenCalled();
});
});
} else {
it('responds to Ctrl+Enter', () => {
this.textarea.trigger(keydownEvent());
testContext.textarea.trigger(keydownEvent());
 
expect(this.spies.submit).toHaveBeenTriggered();
expect(testContext.spies.submit).toHaveBeenCalled();
});
 
it('excludes other modifier keys', () => {
this.textarea.trigger(
testContext.textarea.trigger(
keydownEvent({
altKey: true,
}),
);
this.textarea.trigger(
testContext.textarea.trigger(
keydownEvent({
metaKey: true,
}),
);
this.textarea.trigger(
testContext.textarea.trigger(
keydownEvent({
shiftKey: true,
}),
);
 
expect(this.spies.submit).not.toHaveBeenTriggered();
expect(testContext.spies.submit).not.toHaveBeenCalled();
});
}
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment