Commit e20baee8 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent 71c5863d
<!--Please answer the below questions to the best of your ability.-->
#### What's this issue all about? (Background and context)
#### What hypotheses and/or assumptions do you have?
#### What questions are you trying to answer?
#### What research methodology do you intend to use?
<!-- What needs to be answered to move work forward? If you have a completed Opportunity Canvas include a link.-->
#### What persona, persona segment, or customer type experiences the problem most acutely?
#### What business decisions will be made based on this information?
#### What, if any, relevant prior research already exists?
<!-- Have a look at our UXR_Insights repo: https://gitlab.com/gitlab-org/uxr_insights -->
#### Who will be leading the research?
#### What timescales do you have in mind for the research?
#### Relevant links (problem validation issue, design issue, script, prototype, notes, etc.)
<!-- #### TODO Checklist
Consider adding a checklist in order to keep track of what stage the research is up to. Some possible checklist templates are here:
https://about.gitlab.com/handbook/engineering/ux/ux-research-training/templates-resources-for-research-studies/#checklists
-->
/label ~"workflow::solution validation"
\ No newline at end of file
......@@ -204,7 +204,6 @@ Gitlab/DuplicateSpecLocation:
Exclude:
- ee/spec/helpers/auth_helper_spec.rb
- ee/spec/lib/gitlab/gl_repository_spec.rb
- ee/spec/lib/gitlab/usage_data_spec.rb
- ee/spec/models/namespace_spec.rb
- ee/spec/models/note_spec.rb
- ee/spec/serializers/environment_entity_spec.rb
......@@ -215,7 +214,6 @@ Gitlab/DuplicateSpecLocation:
- ee/spec/services/system_hooks_service_spec.rb
- ee/spec/helpers/ee/auth_helper_spec.rb
- ee/spec/lib/ee/gitlab/gl_repository_spec.rb
- ee/spec/lib/ee/gitlab/usage_data_spec.rb
- ee/spec/models/ee/namespace_spec.rb
- ee/spec/models/ee/note_spec.rb
- ee/spec/serializers/ee/environment_entity_spec.rb
......@@ -382,3 +380,6 @@ Style/FloatDivision:
Cop/BanCatchThrow:
Enabled: true
Performance/ReadlinesEach:
Enabled: true
......@@ -8,13 +8,20 @@ import Flash from '../flash';
import Poll from '../lib/utils/poll';
import initSettingsPanels from '../settings_panels';
import eventHub from './event_hub';
import { APPLICATION_STATUS, INGRESS, INGRESS_DOMAIN_SUFFIX, CROSSPLANE } from './constants';
import {
APPLICATION_STATUS,
INGRESS,
INGRESS_DOMAIN_SUFFIX,
CROSSPLANE,
KNATIVE,
} from './constants';
import ClustersService from './services/clusters_service';
import ClustersStore from './stores/clusters_store';
import Applications from './components/applications.vue';
import RemoveClusterConfirmation from './components/remove_cluster_confirmation.vue';
import setupToggleButtons from '../toggle_buttons';
import initProjectSelectDropdown from '~/project_select';
import initServerlessSurveyBanner from '~/serverless/survey_banner';
const Environments = () => import('ee_component/clusters/components/environments.vue');
......@@ -326,6 +333,10 @@ export default class Clusters {
this.store.state.applications[INGRESS],
);
}
if (this.store.state.applications[KNATIVE]?.status === APPLICATION_STATUS.INSTALLED) {
initServerlessSurveyBanner();
}
}
showToken() {
......
import ServerlessBundle from '~/serverless/serverless_bundle';
import initServerlessSurveyBanner from '~/serverless/survey_banner';
document.addEventListener('DOMContentLoaded', () => {
initServerlessSurveyBanner();
new ServerlessBundle(); // eslint-disable-line no-new
});
import Vue from 'vue';
import { setUrlParams } from '~/lib/utils/url_utility';
import SurveyBanner from './survey_banner.vue';
let bannerInstance;
const SURVEY_URL_BASE = 'https://gitlab.fra1.qualtrics.com/jfe/form/SV_00PfofFfY9s8Shf';
export default function initServerlessSurveyBanner() {
const el = document.querySelector('.js-serverless-survey-banner');
if (el && !bannerInstance) {
const { userName, userEmail } = el.dataset;
// pre-populate survey fields
const surveyUrl = setUrlParams(
{
Q_PopulateResponse: JSON.stringify({
QID1: userEmail,
QID2: userName,
QID16: '1', // selects "yes" to "do you currently use GitLab?"
}),
},
SURVEY_URL_BASE,
);
bannerInstance = new Vue({
el,
render(createElement) {
return createElement(SurveyBanner, {
props: {
surveyUrl,
},
});
},
});
}
}
<script>
import Cookies from 'js-cookie';
import { parseBoolean } from '~/lib/utils/common_utils';
import { GlBanner } from '@gitlab/ui';
export default {
components: {
GlBanner,
},
props: {
surveyUrl: {
type: String,
required: true,
},
},
data() {
return {
visible: true,
};
},
created() {
if (parseBoolean(Cookies.get('hide_serverless_survey'))) {
this.visible = false;
}
},
methods: {
handleClose() {
Cookies.set('hide_serverless_survey', 'true', { expires: 365 * 10 });
this.visible = false;
},
},
};
</script>
<template>
<gl-banner
v-if="visible"
class="mt-4"
:title="s__('Serverless|Help shape the future of Serverless at GitLab')"
:button-text="s__('Serverless|Sign up for First Look')"
:button-link="surveyUrl"
@close="handleClose"
>
<p>
{{
s__(
'Serverless|We are continually striving to improve our Serverless functionality. As a Knative user, we would love to hear how we can make this experience better for you. Sign up for GitLab First Look today and we will be in touch shortly.',
)
}}
</p>
</gl-banner>
</template>
......@@ -8,7 +8,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
# ApplicationSetting model uses Gitlab::ThreadMemoryCache for caching and the
# cache might be stale immediately after an update.
# https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/30233
before_action :set_application_setting
before_action :set_application_setting, except: :integrations
before_action :whitelist_query_limiting, only: [:usage_data]
......@@ -29,13 +29,12 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
def integrations
if Feature.enabled?(:instance_level_integrations)
# TODO: Update this with actual integrations
# To be fixed with https://gitlab.com/gitlab-org/gitlab/-/issues/199388
@integrations = []
end
@integrations = Service.find_or_initialize_instances.sort_by(&:title)
else
set_application_setting
perform_update if submitted?
end
end
def update
perform_update
......
......@@ -9,6 +9,11 @@ class Admin::ProjectsController < Admin::ApplicationController
def index
params[:sort] ||= 'latest_activity_desc'
@sort = params[:sort]
if params[:last_repository_check_failed].present? && params[:archived].nil?
params[:archived] = true
end
@projects = Admin::ProjectsFinder.new(params: params, current_user: current_user).execute
respond_to do |format|
......
......@@ -6,7 +6,7 @@ class Admin::ServicesController < Admin::ApplicationController
before_action :service, only: [:edit, :update]
def index
@services = Service.find_or_create_templates
@services = Service.find_or_create_templates.sort_by(&:title)
end
def edit
......
......@@ -12,5 +12,8 @@ module Types
field :id, GraphQL::ID_TYPE, null: false,
description: 'ID of the environment'
field :state, GraphQL::STRING_TYPE, null: false,
description: 'State of the environment, for example: available/stopped'
end
end
......@@ -160,9 +160,7 @@ module BulkInsertSafe
attributes = {}
column_names.each do |name|
value = item.read_attribute(name)
value = item.type_for_attribute(name).serialize(value) # rubocop:disable Cop/ActiveRecordSerialize
attributes[name] = value
attributes[name] = item.read_attribute(name)
end
_bulk_insert_reject_primary_key!(attributes, item.class.primary_key)
......
......@@ -47,6 +47,7 @@ class Service < ApplicationRecord
scope :without_defaults, -> { where(default: false) }
scope :by_type, -> (type) { where(type: type) }
scope :templates, -> { where(template: true, type: available_services_types) }
scope :instances, -> { where(instance: true, type: available_services_types) }
scope :push_hooks, -> { where(push_events: true, active: true) }
scope :tag_push_hooks, -> { where(tag_push_events: true, active: true) }
......@@ -260,17 +261,16 @@ class Service < ApplicationRecord
self.category == :issue_tracker
end
# Find all service templates; if some of them do not exist, create them
# within a transaction to perform the lowest possible SQL queries.
def self.find_or_create_templates
create_nonexistent_templates
templates
end
private_class_method def self.create_nonexistent_templates
nonexistent_services = available_services_types - templates.map(&:type)
nonexistent_services = list_nonexistent_services_for(templates)
return if nonexistent_services.empty?
# Create within a transaction to perform the lowest possible SQL queries.
transaction do
nonexistent_services.each do |service_type|
service_type.constantize.create(template: true)
......@@ -278,6 +278,20 @@ class Service < ApplicationRecord
end
end
def self.find_or_initialize_instances
instances + build_nonexistent_instances
end
private_class_method def self.build_nonexistent_instances
list_nonexistent_services_for(instances).map do |service_type|
service_type.constantize.new
end
end
private_class_method def self.list_nonexistent_services_for(scope)
available_services_types - scope.map(&:type)
end
def self.available_services_names
service_names = %w[
alerts
......
......@@ -10,7 +10,7 @@
%th Service
%th Description
%th Last edit
- @services.sort_by(&:title).each do |service|
- @services.each do |service|
%tr
%td
= boolean_to_icon service.activated?
......
......@@ -39,6 +39,8 @@
.js-cluster-application-notice
.flash-container
.js-serverless-survey-banner{ data: { user_name: current_user.name, user_email: current_user.email } }
%h4= @cluster.name
= render 'banner'
......
......@@ -10,6 +10,8 @@
help_path: help_page_path('user/project/clusters/serverless/index') } }
%div{ class: [('limit-container-width' unless fluid_layout)] }
.js-serverless-survey-banner{ data: { user_name: current_user.name, user_email: current_user.email } }
.js-serverless-functions-notice
.flash-container
......
......@@ -12,7 +12,7 @@
%th{ role: 'columnheader', scope: 'col', 'aria-colindex': 4 }= _('Last updated')
%tbody{ role: 'rowgroup' }
- @integrations&.each do |integration|
- @integrations.each do |integration|
%tr{ role: 'row' }
%td{ role: 'cell', 'aria-colindex': 1 }
= boolean_to_icon integration.activated?
......
---
title: Fix archived corrupted projects not displaying in admin
merge_request: 25171
author: erickcspice
type: fixed
---
title: Provide link to a survey for Knative users
merge_request: 23025
author:
type: other
# frozen_string_literal: true
# This fix is needed to properly support
# columns that perform data mutation to a SQL datatype
# ex. would be `jsonb` and `enum`
#
# This is covered by tests in `BulkInsertSafe`
# that validates handling of different data types
if Rails.gem_version > Gem::Version.new("6.0.2")
raise Gem::DependencyError,
"Remove patch once the https://github.com/rails/rails/pull/38763 is included"
end
module ActiveRecordInsertAllBuilderMixin
def extract_types_from_columns_on(table_name, keys:)
columns = connection.schema_cache.columns_hash(table_name)
unknown_column = (keys - columns.keys).first
raise UnknownAttributeError.new(model.new, unknown_column) if unknown_column
keys.index_with { |key| model.type_for_attribute(key) }
end
end
ActiveRecord::InsertAll::Builder.prepend(ActiveRecordInsertAllBuilderMixin)
......@@ -2,19 +2,28 @@
require_relative File.expand_path('../../lib/gitlab/danger/commit_linter', __dir__)
URL_GIT_COMMIT = "https://chris.beams.io/posts/git-commit/"
COMMIT_MESSAGE_GUIDELINES = "https://docs.gitlab.com/ee/development/contributing/merge_request_workflow.html#commit-messages-guidelines"
MORE_INFO = "For more information, take a look at our [Commit message guidelines](#{COMMIT_MESSAGE_GUIDELINES})."
THE_DANGER_JOB_TEXT = "the `danger-review` job"
MAX_COMMITS_COUNT = 10
def gitlab_danger
@gitlab_danger ||= GitlabDanger.new(helper.gitlab_helper)
end
def fail_commit(commit, message)
self.fail("#{commit.sha}: #{message}")
def fail_commit(commit, message, more_info: true)
self.fail(build_message(commit, message, more_info: more_info))
end
def warn_commit(commit, message)
self.warn("#{commit.sha}: #{message}")
def warn_commit(commit, message, more_info: true)
self.warn(build_message(commit, message, more_info: more_info))
end
def build_message(commit, message, more_info: true)
[message].tap do |full_message|
full_message << ". #{MORE_INFO}" if more_info
full_message.unshift("#{commit.sha}: ") if commit.sha
end.join
end
def squash_mr?
......@@ -25,6 +34,10 @@ def wip_mr?
gitlab_danger.ci? ? gitlab.mr_json['work_in_progress'] : false
end
def danger_job_link
gitlab_danger.ci? ? "[#{THE_DANGER_JOB_TEXT}](#{ENV['CI_JOB_URL']})" : THE_DANGER_JOB_TEXT
end
# Perform various checks against commits. We're not using
# https://github.com/jonallured/danger-commit_lint because its output is not
# very helpful, and it doesn't offer the means of ignoring merge commits.
......@@ -42,11 +55,11 @@ def lint_commit(commit)
return linter if linter.fixup? && squash_mr?
if linter.fixup?
msg = 'Squash or fixup commits must be squashed before merge, or enable squash merge option'
msg = "Squash or fixup commits must be squashed before merge, or enable squash merge option and re-run #{danger_job_link}."
if wip_mr? || squash_mr?
warn_commit(commit, msg)
warn_commit(commit, msg, more_info: false)
else
fail_commit(commit, msg)
fail_commit(commit, msg, more_info: false)
end
# Makes no sense to process other rules for fixup commits, they trigger just more noise
......@@ -56,7 +69,7 @@ def lint_commit(commit)
# Fail if a suggestion commit is used and squash is not enabled
if linter.suggestion?
unless squash_mr?
fail_commit(commit, "If you are applying suggestions, enable squash in the merge request and re-run the `danger-review` job")
fail_commit(commit, "If you are applying suggestions, enable squash in the merge request and re-run #{danger_job_link}.", more_info: false)
end
return linter
......@@ -93,17 +106,11 @@ def lint_commits(commits)
if multi_line_commit_linter && multi_line_commit_linter.failed?
warn_or_fail_commits(multi_line_commit_linter)
fail_message('The commit message that will be used in the squash commit does not meet our Git commit message standards.')
else
title_linter = lint_mr_title(gitlab.mr_json['title'])
if title_linter.failed?
warn_or_fail_commits(title_linter)
fail_message('The merge request title that will be used in the squash commit does not meet our Git commit message standards.')
end
end
else
if failed_commit_linters.any?
fail_message('One or more commit messages do not meet our Git commit message standards.')
end
end
end
......@@ -123,40 +130,4 @@ def warn_or_fail_commits(failed_linters, default_to_fail: true)
end
end
def fail_message(intro)
markdown(<<~MARKDOWN)
## Commit message standards
#{intro}
For more information on how to write a good commit message, take a look at
[How to Write a Git Commit Message](#{URL_GIT_COMMIT}).
Here is an example of a good commit message:
Reject ruby interpolation in externalized strings
When using ruby interpolation in externalized strings, they can't be
detected. Which means they will never be presented to be translated.
To mix variables into translations we need to use `sprintf`
instead.
Instead of:
_("Hello \#{subject}")
Use:
_("Hello %{subject}") % { subject: 'world' }
This is an example of a bad commit message:
updated README.md
This commit message is bad because although it tells us that README.md is
updated, it doesn't tell us why or how it was updated.
MARKDOWN
end
lint_commits(git.commits)
......@@ -96,7 +96,5 @@ they will receive a `Connection failed` message.
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/8413) in GitLab 8.17.
Terminal sessions use long-lived connections; by default, these may last
forever. You can configure a maximum session time in the Admin Area of your
GitLab instance if you find this undesirable from a scalability or security
point of view.
Terminal sessions, by default, do not expire.
You can limit terminal session lifetime in your GitLab instance. To do so, navigate to **{admin}** [**Admin Area > Settings > Web terminal**](../../user/admin_area/settings/index.md#general), and set a `max session time`.
......@@ -21,10 +21,7 @@ This project will be used for self monitoring your GitLab instance.
1. Navigate to **Admin Area > Settings > Metrics and profiling**, and expand the **Self monitoring** section.
1. Toggle the **Create Project** button on.
1. It can take a few seconds for the project to be created. After the project is
created, GitLab displays a message with a link to the project. The project
will also be linked in the help text above the **Create Project** button. You can also
find the project under **Projects > Your projects**.
1. Once your GitLab instance creates the project, you'll see a link to the project in the text above the **Create Project** toggle. You can also find it under **Projects > Your projects**.
## Deleting the self monitoring project
......
......@@ -1869,6 +1869,11 @@ type Environment {
Human-readable name of the environment
"""
name: String!
"""
State of the environment, for example: available/stopped
"""
state: String!
}
"""
......
......@@ -5530,6 +5530,24 @@
"description": "Human-readable name of the environment",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "state",
"description": "State of the environment, for example: available/stopped",
"args": [
],
"type": {
"kind": "NON_NULL",
......
......@@ -318,6 +318,7 @@ Describes where code is deployed for a project
| --- | ---- | ---------- |
| `id` | ID! | ID of the environment |
| `name` | String! | Human-readable name of the environment |
| `state` | String! | State of the environment, for example: available/stopped |
## Epic
......
......@@ -73,6 +73,10 @@ GET /groups/:id/packages
curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/groups/:id/packages?exclude_subgroups=true
```
CAUTION: **Deprecation**
> The `build_info` attribute in the response is deprecated in favour of `pipeline`.
> Introduced [GitLab 12.10](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28040).
Example response:
```json
......@@ -87,7 +91,6 @@ Example response:
"delete_api_path": "/namespace1/project1/-/packages/1"
},
"created_at": "2019-11-27T03:37:38.711Z",
"build_info": {
"pipeline": {
"id": 123,
"status": "pending",
......@@ -96,6 +99,9 @@ Example response:
"web_url": "https://example.com/foo/bar/pipelines/47",
"created_at": "2016-08-11T11:28:34.085Z",
"updated_at": "2016-08-11T11:32:35.169Z",
"user": {
"name": "Administrator",
"avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon"
}
}
},
......@@ -109,7 +115,6 @@ Example response:
"delete_api_path": "/namespace1/project1/-/packages/1"
},
"created_at": "2019-11-27T03:37:38.711Z",
"build_info": {
"pipeline": {
"id": 123,
"status": "pending",
......@@ -118,6 +123,9 @@ Example response:
"web_url": "https://example.com/foo/bar/pipelines/47",
"created_at": "2016-08-11T11:28:34.085Z",
"updated_at": "2016-08-11T11:32:35.169Z",
"user": {
"name": "Administrator",
"avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon"
}
}
}
......@@ -150,6 +158,10 @@ GET /projects/:id/packages/:package_id
curl --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/:id/packages/:package_id
```
CAUTION: **Deprecation**
> The `build_info` attribute in the response is deprecated in favour of `pipeline`.
> Introduced [GitLab 12.10](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/28040).
Example response:
```json
......@@ -163,7 +175,6 @@ Example response:
"delete_api_path": "/namespace1/project1/-/packages/1"
},
"created_at": "2019-11-27T03:37:38.711Z",
"build_info": {
"pipeline": {
"id": 123,
"status": "pending",
......@@ -172,6 +183,9 @@ Example response:
"web_url": "https://example.com/foo/bar/pipelines/47",
"created_at": "2016-08-11T11:28:34.085Z",
"updated_at": "2016-08-11T11:32:35.169Z",
"user": {
"name": "Administrator",
"avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon"
}
}
}
......
......@@ -81,7 +81,7 @@ Complementary reads:
- [Working with Merge Request diffs](diffs.md)
- [Kubernetes integration guidelines](kubernetes.md)
- [Permissions](permissions.md)
- [Prometheus metrics](prometheus_metrics.md)
- [Prometheus](prometheus.md)
- [Guidelines for reusing abstractions](reusing_abstractions.md)
- [DeclarativePolicy framework](policies.md)
- [How Git object deduplication works in GitLab](git_object_deduplication.md)
......
# Working with Prometheus
For more information on working with [Prometheus metrics](prometheus_metrics.md), see
the documentation.
## Access the UI of a Prometheus managed application in Kubernetes
You can connect directly to Prometheus, and view the Prometheus user interface, when
using a Prometheus managed application in Kubernetes:
1. Find the name of the Prometheus pod in the user interface of your Kubernetes
provider, such as GKE, or by running the following `kubectl` command in your
terminal:
```shell
kubectl get pods -n gitlab-managed-apps | grep 'prometheus-prometheus-server'
```
The command should return a result like the following example, where
`prometheus-prometheus-server-55b4bd64c9-dpc6b` is the name of the Prometheus pod:
```plaintext
gitlab-managed-apps prometheus-prometheus-server-55b4bd64c9-dpc6b 2/2 Running 0 71d
```
1. Run a `kubectl port-forward` command. In the following example, `9090` is the
Prometheus server's listening port:
```shell
kubectl port-forward prometheus-prometheus-server-55b4bd64c9-dpc6b 9090:9090 -n gitlab-managed-apps
```
The `port-forward` command forwards all requests sent to your system's `9090` port
to the `9090` port of the Prometheus pod. If the `9090` port on your system is used
by another application, you can change the port number before the colon to your
desired port. For example, to forward port `8080` of your local system, change the
command to:
```shell
kubectl port-forward prometheus-prometheus-server-55b4bd64c9-dpc6b 8080:9090 -n gitlab-managed-apps
```
1. Open `localhost:9090` in your browser to display the Prometheus user interface.
......@@ -122,6 +122,19 @@ RDS instances as well:
| `gitlab-public-10.0.2.0` | public | `us-west-2b` | `10.0.2.0` |
| `gitlab-private-10.0.3.0` | private | `us-west-2b` | `10.0.3.0` |
### Create NAT Gateways
Instances deployed in our private subnets need to connect to the internet for updates, but should not be reachable from the public internet. To achieve this, we'll make use of [NAT Gateways](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html) deployed in each of our public subnets:
1. Navigate to the VPC dashboard and click on **NAT Gateways** in the left menu bar.
1. Click **Create NAT Gateway** and complete the following:
1. **Subnet**: Select `gitlab-public-10.0.0.0` from the dropdown.
1. **Elastic IP Allocation ID**: Enter an existing Elastic IP or click **Allocate Elastic IP address** to allocate a new IP to your NAT gateway.
1. Add tags if needed.
1. Click **Create NAT Gateway**.
Create a second NAT gateway but this time place it in the second public subnet, `gitlab-public-10.0.2.0`.
### Route Table
Up to now all our subnets are private. We need to create a Route Table
......
......@@ -16,3 +16,4 @@ comments: false
- [Rebuild authorized_keys file](../administration/raketasks/maintenance.md#rebuild-authorized_keys-file) task for administrators
- [Uploads Migrate](../administration/raketasks/uploads/migrate.md)
- [Uploads Sanitize](../administration/raketasks/uploads/sanitize.md)
- [Importing large GitLab project exports](../development/import_project.md#importing-via-a-rake-task)
......@@ -535,18 +535,14 @@ in the first place, and thus not realize that it needs to re-apply the old confi
> Introduced in [GitLab Ultimate][ee] 10.4.
This is an optional step, since it requires a [review app](#auto-review-apps).
If that requirement is not met, the job will be silently skipped.
Dynamic Application Security Testing (DAST) uses the
popular open source tool [OWASP ZAProxy](https://github.com/zaproxy/zaproxy)
to perform an analysis on the current code and checks for potential security
issues. The Auto DAST stage will be skipped on licenses other than Ultimate.
Once the report is created, it's uploaded as an artifact which you can
later download and check out.
Any security warnings are also shown in the merge request widget. Read how
Once the DAST scan is complete, any security warnings are shown
on the [Security Dashboard](../../user/application_security/security_dashboard/index.md)
and the Merge Request Widget. Read how
[DAST works](../../user/application_security/dast/index.md).
On your default branch, DAST scans an app deployed specifically for that purpose.
......
......@@ -4,35 +4,110 @@ type: index
# Admin Area settings **(CORE ONLY)**
In the Admin Area **Settings** page, you can find various options for your GitLab
instance like sign-up restrictions, account limits and quota, metrics, etc.
Navigate to it by going to **Admin Area > Settings**. Some of the settings
include:
- [Account and limit settings](account_and_limit_settings.md) **(STARTER)**
- [Continuous Integration and Deployment](continuous_integration.md)
- [Email](email.md)
- [Sign up restrictions](sign_up_restrictions.md)
- [Sign in restrictions](sign_in_restrictions.md)
- [Terms](terms.md)
- [Third party offers](third_party_offers.md)
- [Usage statistics](usage_statistics.md)
- [Visibility and access controls](visibility_and_access_controls.md)
- [User and IP rate limits](user_and_ip_rate_limits.md)
- [Custom templates repository](instance_template_repository.md) **(PREMIUM)**
- [Protected paths](protected_paths.md) **(CORE ONLY)**
- [Help messages for the `/help` page and the login page](help_page.md)
- [Push event activities limit and bulk push events](push_event_activities_limit.md)
- [Gitaly timeouts](gitaly_timeouts.md)
As an administrator of a GitLab self-managed instance, you can manage the behavior of your deployment. To do so, select **{admin}** **Admin Area > Settings**.
NOTE: **Note:**
You can change the [first day of the week](../../profile/preferences.md) for the entire GitLab instance
in the **Localization** section of **Admin Area > Settings > Preferences**.
The admin area is not accessible on GitLab.com, and settings can only be changed by the
GitLab.com administrators. See the [GitLab.com settings](../../gitlab_com/index.md)
documentation for all current settings and limits on the GitLab.com instance.
## General
Access the default page for admin area settings by navigating to
**{admin}** **Admin Area > Settings > General**:
| Option | Description |
| ------ | ----------- |
| [Visibility and access controls](visibility_and_access_controls.md) | Set default and restrict visibility levels. Configure import sources and Git access protocol. |
| [Account and limit](account_and_limit_settings.md) **(STARTER)** | Set projects and maximum size limits, session duration, user options, and check feature availability for namespace plan. |
| [Diff limits](../diff_limits.md) | Diff content limits. |
| [Sign-up restrictions](sign_up_restrictions.md) | Configure the way a user creates a new account. |
| [Sign in restrictions](sign_in_restrictions.md) | Set requirements for a user to sign-in. Enable mandatory two-factor authentication. |
| [Terms of Service and Privacy Policy](terms.md) | Include a Terms of Service agreement and Privacy Policy that all users must accept. |
| [External Authentication](external_authorization.md#configuration) | External Classification Policy Authorization |
| [Web terminal](../../../administration/integration/terminal.md#limiting-websocket-connection-time) | Set max session time for web terminal. |
| [Web IDE](../../project/web_ide/index.md#enabling-client-side-evaluation) | Manage Web IDE Features. |
## Integrations
| Option | Description |
| ------ | ----------- |
| [Elasticsearch](../../../integration/elasticsearch.md#enabling-elasticsearch) | Elasticsearch integration. Elasticsearch AWS IAM. |
| [PlantUML](../../../administration/integration/plantuml.md#gitlab) | Allow rendering of PlantUML diagrams in Asciidoc documents. |
| [Slack application](../../../user/project/integrations/gitlab_slack_application.md#configuration) **(FREE ONLY)** | Slack integration allows you to interact with GitLab via slash commands in a chat window. This option is only available on GitLab.com, though it may be [available for self-managed instances in the future](https://gitlab.com/gitlab-org/gitlab/-/issues/28164). |
| [Third party offers](third_party_offers.md) | Control the display of third party offers. |
| [Snowplow](../../../telemetry/index.md#enabling-tracking) | Configure the Snowplow integration. |
| [Amazon EKS](../../project/clusters/add_remove_clusters.md#additional-requirements-for-self-managed-instances-core-only) | Amazon EKS integration allows you to provision EKS clusters from GitLab. |
## Repository
| Option | Description |
| ------ | ----------- |
| [Repository mirror](visibility_and_access_controls.md#allow-mirrors-to-be-set-up-for-projects) | Configure repository mirroring. |
| [Repository storage](../../../administration/repository_storage_types.md#how-to-migrate-to-hashed-storage) | Configure storage path settings. |
| Repository maintenance | ([Repository checks](../../../administration/repository_checks.md) and [Housekeeping](../../../administration/housekeeping.md)). Configure automatic Git checks and housekeeping on repositories. |
| [Repository static objects](../../../administration/static_objects_external_storage.md) | Serve repository static objects (e.g. archives, blobs, ...) from an external storage (e.g. a CDN). |
## Templates **(PREMIUM ONLY)**
| Option | Description |
| ------ | ----------- |
| [Templates](instance_template_repository.md#configuration) | Set instance-wide template repository. |
| [Custom project templates](../custom_project_templates.md) | Select the custom project template source group. |
## CI/CD
## GitLab.com Admin Area settings
| Option | Description |
| ------ | ----------- |
| [Continuous Integration and Deployment](continuous_integration.md) | Auto DevOps, runners and job artifacts. |
| [Required pipeline configuration](continuous_integration.md#required-pipeline-configuration-premium-only) **(PREMIUM ONLY)** | Set an instance-wide auto included [pipeline configuration](../../../ci/yaml/README.md). This pipeline configuration will be run after the project's own configuration. |
| [Package Registry](continuous_integration.md#package-registry-configuration-premium-only) **(PREMIUM ONLY)**| Settings related to the use and experience of using GitLab's Package Registry. |
Most of the settings under the Admin Area change the behavior of the whole
GitLab instance. For GitLab.com, the admin settings are available only for the
GitLab.com administrators, and the parameters can be found on the
[GitLab.com settings](../../gitlab_com/index.md) documentation.
## Reporting
| Option | Description |
| ------ | ----------- |
| [Spam and Anti-bot Protection](../../../integration/recaptcha.md) | Enable reCAPTCHA or Akismet and set IP limits. For reCAPTCHA, we currently only support [v2](https://developers.google.com/recaptcha/docs/versions). |
| [Abuse reports](../abuse_reports.md) | Set notification email for abuse reports. |
## Metrics and profiling
| Option | Description |
| ------ | ----------- |
| [Metrics - Influx](../../../administration/monitoring/performance/gitlab_configuration.md) | Enable and configure InfluxDB metrics. |
| [Metrics - Prometheus](../../../administration/monitoring/prometheus/gitlab_metrics.md) | Enable and configure Prometheus metrics. |
| [Metrics - Grafana](../../../administration/monitoring/performance/grafana_configuration.md#integration-with-gitlab-ui) | Enable and configure Grafana. |
| [Profiling - Performance bar](../../../administration/monitoring/performance/performance_bar.md#enable-the-performance-bar-via-the-admin-panel) | Enable access to the Performance Bar for a given group. |
| [Self monitoring](../../../administration/monitoring/gitlab_self_monitoring_project/index.md#creating-the-self-monitoring-project) | Enable or disable instance self monitoring. |
| [Usage statistics](usage_statistics.md) | Enable or disable version check and usage ping. |
| [Pseudonymizer data collection](../../../administration/pseudonymizer.md) **(ULTIMATE)** | Enable or disable the Pseudonymizer data collection. |
## Network
| Option | Description |
| ------ | ----------- |
| Performance optimization | [Write to "authorized_keys" file](../../../administration/operations/fast_ssh_key_lookup.md#setting-up-fast-lookup-via-gitlab-shell) and [Push event activities limit and bulk push events](push_event_activities_limit.md). Various settings that affect GitLab performance. |
| [User and IP rate limits](user_and_ip_rate_limits.md) | Configure limits for web and API requests. |
| [Outbound requests](../../../security/webhooks.md) | Allow requests to the local network from hooks and services. |
| [Protected Paths](protected_paths.md) | Configure paths to be protected by Rack Attack. |
| [Incident Management](../../incident_management/index.md) Limits | Configure limits on the number of inbound alerts able to be sent to a project. |
## Geo
| Option | Description |
| ------ | ----------- |
| Geo | Geo allows you to replicate your GitLab instance to other geographical locations. Redirects to **{admin}** **Admin Area >** **{location-dot}** **Geo >** **{settings}** **Settings**, and will no longer be available at **{admin}** **Admin Area >** **{settings}** **Settings >** **{location-dot}** **Geo** in [GitLab 13.0](https://gitlab.com/gitlab-org/gitlab/-/issues/36896). |
## Preferences
| Option | Description |
| ------ | ----------- |
| [Email](email.md) | Various email settings. |
| [Help page](../../../customization/help_message.md) | Help page text and support page url. |
| [Pages](../../../administration/pages/index.md#custom-domain-verification) | Size and domain settings for static websites |
| [Real-time features](../../../administration/polling.md) | Change this value to influence how frequently the GitLab UI polls for updates. |
| [Gitaly timeouts](gitaly_timeouts.md) | Configure Gitaly timeouts. |
| Localization | [Default first day of the week](../../profile/preferences.md) and [Time tracking](../../project/time_tracking.md#limit-displayed-units-to-hours-core-only). |
NOTE: **Note:**
You can change the [Default first day of the week](../../profile/preferences.md) for the entire GitLab instance
in the **Localization** section of **Admin Area > Settings > Preferences**.
# Analytics workspace
# Analytics
## Analytics workspace
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/12077) in GitLab 12.2.
......@@ -6,27 +8,30 @@ The Analytics workspace will make it possible to aggregate analytics across
GitLab, so that users can view information across multiple projects and groups
in one place.
To access the centralized analytics workspace, enable at least
[one of the features](#available-analytics) under the workspace.
To access the Analytics workspace, click on **More > Analytics** in the top navigation bar.
Once enabled, click on **Analytics** from the top navigation bar.
## Group-level analytics
## Available analytics
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/195979) in GitLab 12.8.
From the centralized analytics workspace, the following analytics are available:
The following analytics features are available at the group level:
- [Code Review Analytics](code_review_analytics.md). **(STARTER)**
- [Value Stream Analytics](value_stream_analytics.md), enabled with the `cycle_analytics`
- [Contribution](../group/contribution_analytics/index.md). **(STARTER)**
- [Insights](../group/insights/index.md). **(ULTIMATE)**
- [Issues](../group/issues_analytics/index.md). **(PREMIUM)**
- [Productivity](productivity_analytics.md), enabled with the `productivity_analytics`
[feature flag](../../development/feature_flags/development.md#enabling-a-feature-flag-in-development). **(PREMIUM)**
- [Productivity Analytics](productivity_analytics.md), enabled with the `productivity_analytics`
- [Value Stream](value_stream_analytics.md), enabled with the `cycle_analytics`
[feature flag](../../development/feature_flags/development.md#enabling-a-feature-flag-in-development). **(PREMIUM)**
NOTE: **Note:**
Project-level Value Stream Analytics are still available at a project's **Project > Value Stream Analytics**.
## Other analytics tools
## Project-level analytics
In addition to the tools available in the Analytics workspace, GitLab provides:
The following analytics features are available at the project level:
- [Contribution analytics](../group/contribution_analytics/index.md). **(STARTER)**
- [Issue analytics](../group/issues_analytics/index.md). **(PREMIUM)**
- [CI/CD](../../ci/pipelines/index.md#pipeline-success-and-duration-charts). **(STARTER)**
- [Code Review](code_review_analytics.md). **(STARTER)**
- [Insights](../group/insights/index.md). **(ULTIMATE)**
- [Issues](../group/issues_analytics/index.md). **(PREMIUM)**
- Repository. **(STARTER)**
- [Value Stream](value_stream_analytics.md), enabled with the `cycle_analytics`
[feature flag](../../development/feature_flags/development.md#enabling-a-feature-flag-in-development). **(STARTER)**
......@@ -2,48 +2,62 @@
type: reference, howto
---
# Offline deployments
# Air-gapped (or offline) environment deployments
This document describes how to operate Secure scanners offline.
It is possible to run most of the GitLab security scanners when not
connected to the internet.
## Overview
This document describes how to operate Secure scanners in an air-gapped or offline envionment. These instructions also apply to
self-managed installations that are secured, have security policies (e.g., firewall policies), or otherwise restricted from
accessing the full internet. These instructions are designed for physically disconnected networks,
but can also be followed in these other use cases.
It is possible to run most of the GitLab security scanners when not
connected to the internet, in what is sometimes known as an offline,
limited connectivity, Local Area Network (LAN), Intranet, or "air-gap"
environment.
## Air-gapped (or offline) environments
In this situation, the GitLab instance can be one or more servers and services that can communicate
on a local network, but with no or very restricted access to the internet. Assume anything within
the GitLab instance and supporting infrastructure (for example, a private Maven repository) can be
accessed through a local network connection. Assume any files from the internet must come in through
physical media (USB drive, hard drive, writeable DVD, etc.).
In this situation, the GitLab instance can be one, or more, servers and services running in a network that can talk to one another, but have zero, or perhaps very restricted access to the internet. Assume anything within the GitLab instance and supporting infrastructure (private Maven repository for example) can be accessed via local network connection. Assume any files from the internet must come in via physical media (USB drive, hard drive).
## Overview
GitLab scanners generally will connect to the internet to download the
latest sets of signatures, rules, and patches. A few extra steps are necessary
to configure the tools to not do this and to still function properly.
to configure the tools to function properly by using resources available on your local network.
### Container registries and package repositories
At a high-level, each of the security analyzers are delivered as Docker
containers and reference various package repositories. When you run a job on
At a high-level, the security analyzers are delivered as Docker images and
may leverage various package repositories. When you run a job on
an internet-connected GitLab installation, GitLab checks the GitLab.com-hosted
container registry and package repositories to ensure that you have
the latest versions.
container registry to check that you have the latest versions of these Docker images
and possibly connect to package repositories to install necessary dependencies.
In an air-gapped environment, this must be disabled so that GitLab.com is not
In an air-gapped environment, these checks must be disabled so that GitLab.com is not
queried. Because the GitLab.com registry and repositories are not available,
you must update each of the scanners to either reference a different,
internally-hosted registry or provide access to the individual scanner images.
You must also ensure that your app has access to common package repos
You must also ensure that your app has access to common package repositories
that are not hosted on GitLab.com, such as npm, yarn, or rubygems. Packages
from these repos can be obtained by temporarily connecting to a network or by
mirroring the packages inside your own offline network.
### Interacting with the vulnerabilities
Once a vulnerability is found, you can interact with it. Read more on how to [interact with the vulnerabilities](../index.md#interacting-with-the-vulnerabilities).
Please note that in some cases the reported vulnerabilities provide metadata that can contain external links exposed in the UI. These links might not be accessible within an air-gapped (or offline) environment.
### Scanner signature and rule updates
When connected to the internet, some scanners will reference public databases
for the latest sets of signatures and rules to check against. Without connectivity,
this is not possible. Depending on the scanner, you must therefore disable
these automatic update checks and either use the databases that they came
with or manually update those databases.
with and manually update those databases or provide access to your own copies
hosted within your network.
## Specific scanner instructions
......
......@@ -18,9 +18,9 @@ that is provided by [Auto DevOps](../../../topics/autodevops/index.md).
GitLab checks the License Compliance report, compares the licenses between the
source and target branches, and shows the information right on the merge request.
Blacklisted licenses will be clearly visible with an `x` red icon next to them
Denied licenses will be clearly visible with an `x` red icon next to them
as well as new licenses which need a decision from you. In addition, you can
[manually approve or blacklist](#project-policies-for-license-compliance)
[manually allow or deny](#project-policies-for-license-compliance)
licenses in your project's settings.
NOTE: **Note:**
......@@ -33,7 +33,7 @@ compliance report will be shown properly.
![License Compliance Widget](img/license_compliance.png)
If you are a project or group Maintainer, you can click on a license to be given
the choice to approve it or blacklist it.
the choice to allow it or deny it.
![License approval decision](img/license_compliance_decision.png)
......@@ -282,9 +282,9 @@ license_scanning:
From the project's settings:
- The list of licenses and their status can be managed.
- Licenses can be manually approved or blacklisted.
- Licenses can be manually allowed or denied.
To approve or blacklist a license:
To allow or deny a license:
1. Either use the **Manage licenses** button in the merge request widget, or
navigate to the project's **Settings > CI/CD** and expand the
......@@ -298,12 +298,12 @@ To approve or blacklist a license:
at the top of the list.
- Enter arbitrary text in the field at the top of the list. This will cause the text to be
added as a license name to the list.
1. Select the **Approve** or **Blacklist** radio button to approve or blacklist respectively
1. Select the **Allow** or **Deny** radio button to allow or deny respectively
the selected license.
To modify an existing license:
1. In the **License Compliance** list, click the **Approved/Declined** dropdown to change it to the desired status.
1. In the **License Compliance** list, click the **Allow/Deny** dropdown to change it to the desired status.
![License Compliance Settings](img/license_compliance_settings_v12_3.png)
......
......@@ -837,6 +837,11 @@ Prerequisites for embedding from a Grafana instance:
## Troubleshooting
When troubleshooting issues with a managed Prometheus app, it is often useful to
[view the Prometheus UI](../../../development/prometheus.md#access-the-ui-of-a-prometheus-managed-application-in-kubernetes).
### "No data found" error on Metrics dashboard page
If the "No data found" screen continues to appear, it could be due to:
- No successful deployments have occurred to this environment.
......
......@@ -6,7 +6,7 @@ module Gitlab
module StageEvents
class ProductionStageEnd < StageEvent
def self.name
PlanStageStart.name
_("Issue first depoloyed to production")
end
def self.identifier
......
......@@ -173,7 +173,7 @@ module Gitlab
end
def details
message_parts[2]
message_parts[2]&.gsub(/^Signed-off-by.*$/, '')
end
def line_too_long?(line)
......
......@@ -36,6 +36,8 @@ excluded_attributes:
- :runners_token_encrypted
- :saml_discovery_token
- :visibility_level
epics:
- :state_id
methods:
labels:
......@@ -50,6 +52,8 @@ methods:
- :action
lists:
- :list_type
epics:
- :state
preloads:
......
......@@ -6127,19 +6127,19 @@ msgstr ""
msgid "CycleAnalyticsEvent|Issue last edited"
msgstr ""
msgid "CycleAnalyticsEvent|Merge Request label was added"
msgid "CycleAnalyticsEvent|Merge request closed"
msgstr ""
msgid "CycleAnalyticsEvent|Merge Request label was removed"
msgid "CycleAnalyticsEvent|Merge request created"
msgstr ""
msgid "CycleAnalyticsEvent|Merge request closed"
msgid "CycleAnalyticsEvent|Merge request first deployed to production"
msgstr ""
msgid "CycleAnalyticsEvent|Merge request created"
msgid "CycleAnalyticsEvent|Merge request label was added"
msgstr ""
msgid "CycleAnalyticsEvent|Merge request first deployed to production"
msgid "CycleAnalyticsEvent|Merge request label was removed"
msgstr ""
msgid "CycleAnalyticsEvent|Merge request last build finish time"
......@@ -11161,6 +11161,9 @@ msgstr ""
msgid "Issue events"
msgstr ""
msgid "Issue first depoloyed to production"
msgstr ""
msgid "Issue or Merge Request ID is required"
msgstr ""
......@@ -17972,6 +17975,9 @@ msgstr ""
msgid "Serverless|Getting started with serverless"
msgstr ""
msgid "Serverless|Help shape the future of Serverless at GitLab"
msgstr ""
msgid "Serverless|If you believe none of these apply, please check back later as the function data may be in the process of becoming available."
msgstr ""
......@@ -17984,6 +17990,9 @@ msgstr ""
msgid "Serverless|No functions available"
msgstr ""
msgid "Serverless|Sign up for First Look"
msgstr ""
msgid "Serverless|The deploy job has not finished."
msgstr ""
......@@ -17993,6 +18002,9 @@ msgstr ""
msgid "Serverless|There is currently no function data available from Knative. This could be for a variety of reasons including:"
msgstr ""
msgid "Serverless|We are continually striving to improve our Serverless functionality. As a Knative user, we would love to hear how we can make this experience better for you. Sign up for GitLab First Look today and we will be in touch shortly."
msgstr ""
msgid "Serverless|Your %{startTag}.gitlab-ci.yml%{endTag} file is not properly configured."
msgstr ""
......
# frozen_string_literal: true
module RuboCop
module Cop
module Performance
class ReadlinesEach < RuboCop::Cop::Cop
MESSAGE = 'Avoid `IO.readlines.each`, since it reads contents into memory in full. ' \
'Use `IO.each_line` or `IO.each` instead.'
def_node_matcher :full_file_read_via_class?, <<~PATTERN
(send
(send (const nil? {:IO :File}) :readlines _) :each)
PATTERN
def_node_matcher :full_file_read_via_instance?, <<~PATTERN
(... (... :readlines) :each)
PATTERN
def on_send(node)
full_file_read_via_class?(node) { add_offense(node, location: :selector, message: MESSAGE) }
full_file_read_via_instance?(node) { add_offense(node, location: :selector, message: MESSAGE) }
end
def autocorrect(node)
lambda do |corrector|
corrector.replace(node.loc.expression, node.source.gsub('readlines.each', 'each_line'))
end
end
end
end
end
end
......@@ -127,6 +127,10 @@ describe Admin::ApplicationSettingsController do
end
describe 'verify panel actions' do
before do
stub_feature_flags(instance_level_integrations: false)
end
Admin::ApplicationSettingsController::VALID_SETTING_PANELS.each do |valid_action|
it_behaves_like 'renders correct panels' do
let(:action) { valid_action }
......
......@@ -24,6 +24,18 @@ describe Admin::ProjectsController do
expect(response.body).not_to match(project.name)
end
it 'retrieves archived and non archived corrupted projects when last_repository_check_failed is true' do
archived_corrupted_project = create(:project, :public, :archived, :last_repository_check_failed, name: 'CorruptedArchived', path: 'A')
corrupted_project = create(:project, :public, :last_repository_check_failed, name: 'CorruptedOnly', path: 'C')
get :index, params: { last_repository_check_failed: true }
expect(response).to have_gitlab_http_status(:ok)
expect(response.body).not_to match(project.name)
expect(response.body).to match(archived_corrupted_project.name)
expect(response.body).to match(corrupted_project.name)
end
it 'does not respond with projects pending deletion' do
pending_delete_project = create(:project, pending_delete: true)
......
......@@ -114,6 +114,10 @@ FactoryBot.define do
archived { true }
end
trait :last_repository_check_failed do
last_repository_check_failed { true }
end
storage_version { Project::LATEST_STORAGE_VERSION }
trait :legacy_storage do
......
......@@ -194,6 +194,13 @@ describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_not_moc
expect(page).to have_content "Application settings saved successfully"
expect(current_settings.terminal_max_session_time).to eq(15)
end
end
context 'Integrations page' do
before do
stub_feature_flags(instance_level_integrations: false)
visit integrations_admin_application_settings_path
end
it 'Enable hiding third party offers' do
page.within('.as-third-party-offers') do
......
......@@ -205,10 +205,11 @@ describe 'Gcp Cluster', :js, :do_not_mock_admin_mode do
let(:admin) { create(:admin) }
before do
stub_feature_flags(instance_level_integrations: false)
stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
visit general_admin_application_settings_path
visit integrations_admin_application_settings_path
end
it 'user does not see the offer' do
......
......@@ -1492,7 +1492,7 @@
"closed_at": null,
"parent_id": null,
"relative_position": null,
"state_id": "opened",
"state": "opened",
"start_date_sourcing_epic_id": null,
"due_date_sourcing_epic_id": null,
"notes": []
......@@ -1524,7 +1524,7 @@
"closed_at": null,
"parent_id": null,
"relative_position": null,
"state_id": "opened",
"state": "closed",
"start_date_sourcing_epic_id": null,
"due_date_sourcing_epic_id": null,
"notes": []
......@@ -1556,7 +1556,7 @@
"closed_at": null,
"parent_id": null,
"relative_position": null,
"state_id": "opened",
"state": "opened",
"start_date_sourcing_epic_id": null,
"due_date_sourcing_epic_id": null,
"notes": []
......@@ -1588,7 +1588,7 @@
"closed_at": null,
"parent_id": null,
"relative_position": null,
"state_id": "opened",
"state": "closed",
"start_date_sourcing_epic_id": null,
"due_date_sourcing_epic_id": null,
"notes": []
......@@ -1620,7 +1620,7 @@
"closed_at": null,
"parent_id": null,
"relative_position": null,
"state_id": "opened",
"state": "opened",
"start_date_sourcing_epic_id": null,
"due_date_sourcing_epic_id": null,
"notes": []
......
import { shallowMount } from '@vue/test-utils';
import Cookies from 'js-cookie';
import SurveyBanner from '~/serverless/survey_banner.vue';
import { GlBanner } from '@gitlab/ui';
describe('Knative survey banner', () => {
let wrapper;
function mountBanner() {
wrapper = shallowMount(SurveyBanner, {
propsData: {
surveyUrl: 'http://somesurvey.com/',
},
});
}
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
it('should render the banner when the cookie is absent', () => {
jest.spyOn(Cookies, 'get').mockReturnValue(undefined);
mountBanner();
expect(Cookies.get).toHaveBeenCalled();
expect(wrapper.find(GlBanner).exists()).toBe(true);
});
it('should close the banner and set a cookie when close button is clicked', () => {
jest.spyOn(Cookies, 'get').mockReturnValue(undefined);
jest.spyOn(Cookies, 'set');
mountBanner();
expect(wrapper.find(GlBanner).exists()).toBe(true);
wrapper.find(GlBanner).vm.$emit('close');
return wrapper.vm.$nextTick().then(() => {
expect(Cookies.set).toHaveBeenCalledWith('hide_serverless_survey', 'true', { expires: 3650 });
expect(wrapper.find(GlBanner).exists()).toBe(false);
});
});
it('should not render the banner when the cookie is set', () => {
jest.spyOn(Cookies, 'get').mockReturnValue('true');
mountBanner();
expect(Cookies.get).toHaveBeenCalled();
expect(wrapper.find(GlBanner).exists()).toBe(false);
});
});
......@@ -7,7 +7,7 @@ describe GitlabSchema.types['Environment'] do
it 'has the expected fields' do
expected_fields = %w[
name id
name id state
]
expect(described_class).to have_graphql_fields(*expected_fields)
......
......@@ -86,6 +86,7 @@ describe Gitlab::Danger::CommitLinter do
"A commit message" | false
"A commit message\n" | false
"A commit message\n\n" | false
"A commit message\n\nSigned-off-by: User Name <user@name.me>" | false
"A commit message\n\nWith details" | true
end
......
......@@ -7,7 +7,7 @@ describe BulkInsertSafe do
include BulkInsertSafe
include ShaAttribute
validates :name, :enum_value, :secret_value, :sha_value, presence: true
validates :name, :enum_value, :secret_value, :sha_value, :jsonb_value, presence: true
ENUM_VALUES = {
case_1: 1
......@@ -26,6 +26,7 @@ describe BulkInsertSafe do
default_value_for :enum_value, 'case_1'
default_value_for :secret_value, 'my-secret'
default_value_for :sha_value, '2fd4e1c67a2d28fced849ee1bb76e7391b93eb12'
default_value_for :jsonb_value, { "key" => "value" }
def self.valid_list(count)
Array.new(count) { |n| new(name: "item-#{n}") }
......@@ -60,6 +61,7 @@ describe BulkInsertSafe do
t.text :encrypted_secret_value, null: false
t.string :encrypted_secret_value_iv, null: false
t.binary :sha_value, null: false, limit: 20
t.jsonb :jsonb_value, null: false
t.index :name, unique: true
end
......@@ -114,7 +116,7 @@ describe BulkInsertSafe do
described_class.bulk_insert!(items)
attribute_names = described_class.attribute_names - %w[id]
attribute_names = described_class.attribute_names - %w[id created_at updated_at]
expect(described_class.last(items.size).pluck(*attribute_names)).to eq(
items.pluck(*attribute_names))
end
......
......@@ -64,7 +64,7 @@ describe IrkerService do
irker.execute(sample_data)
conn = @irker_server.accept
conn.readlines.each do |line|
conn.each_line do |line|
msg = JSON.parse(line.chomp("\n"))
expect(msg.keys).to match_array(%w(to privmsg))
expect(msg['to']).to match_array(["irc://chat.freenode.net/#commits",
......
......@@ -149,6 +149,47 @@ describe Service do
end
end
describe '.find_or_initialize_instances' do
shared_examples 'service instances' do
it 'returns the available service instances' do
expect(Service.find_or_initialize_instances.pluck(:type)).to match_array(Service.available_services_types)
end
it 'does not create service instances' do
expect { Service.find_or_initialize_instances }.not_to change { Service.count }
end
end
it_behaves_like 'service instances'
context 'with all existing instances' do
before do
Service.insert_all(
Service.available_services_types.map { |type| { instance: true, type: type } }
)
end
it_behaves_like 'service instances'
context 'with a previous existing service (Previous) and a new service (Asana)' do
before do
Service.insert(type: 'PreviousService', instance: true)
Service.delete_by(type: 'AsanaService', instance: true)
end
it_behaves_like 'service instances'
end
end
context 'with a few existing instances' do
before do
create(:jira_service, :instance)
end
it_behaves_like 'service instances'
end
end
describe 'template' do
let(:project) { create(:project) }
......@@ -173,7 +214,7 @@ describe Service do
end
it 'does not create service templates' do
expect { Service.find_or_create_templates }.to change { Service.count }.by(0)
expect { Service.find_or_create_templates }.not_to change { Service.count }
end
it_behaves_like 'retrieves service templates'
......
# frozen_string_literal: true
require 'fast_spec_helper'
require_relative '../../../support/helpers/expect_offense'
require_relative '../../../../rubocop/cop/performance/readlines_each'
describe RuboCop::Cop::Performance::ReadlinesEach do
include CopHelper
include ExpectOffense
subject(:cop) { described_class.new }
let(:message) { 'Avoid `IO.readlines.each`, since it reads contents into memory in full. Use `IO.each_line` or `IO.each` instead.' }
shared_examples_for(:class_read) do |klass|
context "and it is called as a class method on #{klass}" do
# We can't use `expect_offense` here because indentation changes based on `klass`
it 'flags it as an offense' do
inspect_source "#{klass}.readlines(file_path).each { |line| puts line }"
expect(cop.offenses.map(&:cop_name)).to contain_exactly('Performance/ReadlinesEach')
end
end
context 'when just using readlines without each' do
it 'does not flag it as an offense' do
expect_no_offenses "contents = #{klass}.readlines(file_path)"
end
end
end
context 'when reading all lines using IO.readlines.each' do
%w(IO File).each do |klass|
it_behaves_like(:class_read, klass)
end
context 'and it is called as an instance method on a return value' do
it 'flags it as an offense' do
expect_offense <<~SOURCE
get_file.readlines.each { |line| puts line }
^^^^ #{message}
SOURCE
end
end
context 'and it is called as an instance method on an assigned variable' do
it 'flags it as an offense' do
expect_offense <<~SOURCE
file = File.new(path)
file.readlines.each { |line| puts line }
^^^^ #{message}
SOURCE
end
end
context 'and it is called as an instance method on a new object' do
it 'flags it as an offense' do
expect_offense <<~SOURCE
File.new(path).readlines.each { |line| puts line }
^^^^ #{message}
SOURCE
end
end
it 'autocorrects `readlines.each` to `each_line`' do
expect(autocorrect_source('obj.readlines.each { |line| line }')).to(
eq('obj.each_line { |line| line }')
)
end
end
context 'when just using readlines without each' do
it 'does not flag it as an offense' do
expect_no_offenses 'contents = my_file.readlines'
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment