Commit c6a33b29 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent c52b81f4
......@@ -25,7 +25,7 @@ export default {
return Promise.resolve(file.content);
}
if (file.raw) {
if (file.raw || !file.rawPath) {
return Promise.resolve(file.raw);
}
......
......@@ -13,8 +13,6 @@
class LicenseTemplateFinder
include Gitlab::Utils::StrongMemoize
prepend_if_ee('::EE::LicenseTemplateFinder') # rubocop: disable Cop/InjectEnterpriseEditionModule
attr_reader :project, :params
def initialize(project, params = {})
......@@ -52,3 +50,5 @@ class LicenseTemplateFinder
params.fetch(:popular, nil)
end
end
LicenseTemplateFinder.prepend_if_ee('::EE::LicenseTemplateFinder')
......@@ -27,8 +27,6 @@
class ProjectsFinder < UnionFinder
include CustomAttributesFilter
prepend_if_ee('::EE::ProjectsFinder') # rubocop: disable Cop/InjectEnterpriseEditionModule
attr_accessor :params
attr_reader :current_user, :project_ids_relation
......@@ -225,3 +223,5 @@ class ProjectsFinder < UnionFinder
{ min_access_level: params[:min_access_level] }
end
end
ProjectsFinder.prepend_if_ee('::EE::ProjectsFinder')
......@@ -3,8 +3,6 @@
class TemplateFinder
include Gitlab::Utils::StrongMemoize
prepend_if_ee('::EE::TemplateFinder') # rubocop: disable Cop/InjectEnterpriseEditionModule
VENDORED_TEMPLATES = HashWithIndifferentAccess.new(
dockerfiles: ::Gitlab::Template::DockerfileTemplate,
gitignores: ::Gitlab::Template::GitignoreTemplate,
......@@ -42,3 +40,5 @@ class TemplateFinder
end
end
end
TemplateFinder.prepend_if_ee('::EE::TemplateFinder')
......@@ -2,6 +2,7 @@
class ContainerExpirationPolicy < ApplicationRecord
include Schedulable
include UsageStatistics
belongs_to :project, inverse_of: :container_expiration_policy
......
......@@ -787,7 +787,7 @@ class Project < ApplicationRecord
end
def jira_issues_import_feature_flag_enabled?
Feature.enabled?(:jira_issue_import, self)
Feature.enabled?(:jira_issue_import, self, default_enabled: true)
end
def team
......
......@@ -89,3 +89,5 @@ module Clusters
end
end
end
Clusters::ClusterPresenter.prepend_if_ee('EE::Clusters::ClusterPresenter')
---
title: Make "Value Stream" the default page that appears when clicking the project-level "Analytics" sidebar item.
merge_request: 27279
author: Gilang Gumilar
type: added
---
title: Fix incorrect content returned on empty dotfile
merge_request: 28144
author:
type: fixed
---
title: Add jira issues import feature
merge_request:
author:
type: added
---
title: Move prepend to last line in finders files
merge_request: 29274
author: Rajendra Kadam
type: fixed
# frozen_string_literal: true
# See https://docs.gitlab.com/ee/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AddJsonbToGeoNodeStatusTable < ActiveRecord::Migration[6.0]
DOWNTIME = false
def change
change_table :geo_node_statuses do |t|
t.jsonb :status, null: false, default: {}
end
end
end
......@@ -2650,7 +2650,8 @@ CREATE TABLE public.geo_node_statuses (
design_repositories_count integer,
design_repositories_synced_count integer,
design_repositories_failed_count integer,
design_repositories_registry_count integer
design_repositories_registry_count integer,
status jsonb DEFAULT '{}'::jsonb NOT NULL
);
CREATE SEQUENCE public.geo_node_statuses_id_seq
......@@ -13076,6 +13077,7 @@ COPY "schema_migrations" (version) FROM STDIN;
20200331132103
20200331195952
20200331220930
20200401095430
20200401211005
20200402123926
20200402124802
......
......@@ -8353,15 +8353,20 @@ scalar Time
type Timelog {
"""
The date when the time tracked was spent at
Timestamp of when the time tracked was spent at. Deprecated in 12.10: Use `spentAt`
"""
date: Time!
date: Time! @deprecated(reason: "Use `spentAt`. Deprecated in 12.10")
"""
The issue that logged time was added to
"""
issue: Issue
"""
Timestamp of when the time tracked was spent at
"""
spentAt: Time
"""
The time spent displayed in seconds
"""
......
......@@ -25299,7 +25299,7 @@
"fields": [
{
"name": "date",
"description": "The date when the time tracked was spent at",
"description": "Timestamp of when the time tracked was spent at. Deprecated in 12.10: Use `spentAt`",
"args": [
],
......@@ -25312,8 +25312,8 @@
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
"isDeprecated": true,
"deprecationReason": "Use `spentAt`. Deprecated in 12.10"
},
{
"name": "issue",
......@@ -25329,6 +25329,20 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "spentAt",
"description": "Timestamp of when the time tracked was spent at",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "Time",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "timeSpent",
"description": "The time spent displayed in seconds",
......
......@@ -1306,8 +1306,9 @@ Completion status of tasks
| Name | Type | Description |
| --- | ---- | ---------- |
| `date` | Time! | The date when the time tracked was spent at |
| `date` **{warning-solid}** | Time! | **Deprecated:** Use `spentAt`. Deprecated in 12.10 |
| `issue` | Issue | The issue that logged time was added to |
| `spentAt` | Time | Timestamp of when the time tracked was spent at |
| `timeSpent` | Int! | The time spent displayed in seconds |
| `user` | User! | The user that logged the time |
......
# GitLab Status Page
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2479) in GitLab 12.10.
GitLab Status Page allows you to create and deploy a static website to communicate efficiently to users during an incident.
## How to set up
NOTE: **Note:**
Only AWS S3 is supported as a deploy target.
```mermaid
graph TB
subgraph GitLab Instance
issues(issue updates) -- trigger --> middleware(Background job: JSON generation)
end
subgraph Cloud Provider
middleware --saves data --> c1(Cloud Bucket stores JSON file)
end
subgraph Status Page
d(Static Site on CDN) -- fetches data --> c1
end
```
Setting up a Status Page is pretty painless but there are a few things you need to do.
### Cloud account set up
To use GitLab Status Page you first need to set up your account details for your cloud provider in the operations settings page. Today, only AWS is supported.
1. Within your AWS account, create an AWS access key.
1. Add the following permissions policies:
- [Create bucket](https://gitlab.com/gitlab-org/status-page/-/blob/master/deploy/etc/s3_create_policy.json).
- [Update bucket contents](https://gitlab.com/gitlab-org/status-page/-/blob/master/deploy/etc/s3_update_bucket_policy.json) (Remember replace `S3_BUCKET_NAME` with your bucket name).
### Status Page project
To deploy the status page to AWS S3 you need to add the Status Page project & configure the necessary CI variables.
1. Fork the [Status Page](https://gitlab.com/gitlab-org/status-page) project. This can also be done via [Repository Mirroring](https://gitlab.com/gitlab-org/status-page#repository-mirroring) which will ensure you get the up-to-date Status Page features.
1. Add the following variables in **Settings > CI/CD > Variables**. (To get these variables from Amazon, use your Amazon Console):
- `S3_BUCKET_NAME` - name of the Amazon S3 bucket
- `AWS_DEFAULT_REGION` - the AWS region
- `AWS_ACCESS_KEY_ID` - the AWS access key ID
- `AWS_SECRET_ACCESS_KEY` - the AWS secret
1. Run the pipeline to deploy the status page to S3.
### Syncing incidents to the Status Page
Once the CI/CD variables are set, you'll need to set up the Project you want to use for Incident issues:
1. Navigate to **Settings > Operations > Status Page**.
1. Fill in your cloud provider's credentials and make sure the **Active** checkbox is checked.
1. Click **Save changes**.
## Status Page UI
The Status page landing page shows you an overview of the recent incidents. Clicking on an incident will take you to the incident's detail page.
![Status Page landing page](../img/status_page_incidents_v12_10.png)
### Incident detail page
The incident detail page shows detailed information about a particular incident. For example:
- Status on the incident, including when the incident was last updated.
- The incident title.
- The description of the incident.
- A chronological ordered list of updates to the incident.
![Status Page detail](../img/status_page_detail_v12_10.png)
## How it works
### Publishing Incidents
To publish an Incident, you first need to create an issue in the Project you enabled the Status Page settings in.
Once this issue is created, a background worker will publish the issue onto the status page using the credentials you provided during setup.
### Publishing updates
To publish an update to the Incident, update the incident issue's description.
### Adding comments
To add comments to the Status Page Incident, create a comment on the incident issue.
When you're ready to publish the comment, add a microphone [award emoji](../../../user/award_emojis.md) reaction (`:microphone` 🎤) to the comment. This marks the comment as one which should be deployed to the Status Page.
CAUTION: **Caution:**
Anyone with access to view the Issue can add an Emoji Award to a comment, so you may want to keep your Issues limited to team members only.
### Changing the Incident status
To change the incident status from `open` to `closed`, close the incident issue within GitLab. This will then be updated shortly on the Status page website.
......@@ -163,8 +163,31 @@ module Gitlab
signup_enabled: alt_usage_data { Gitlab::CurrentSettings.allow_signup? },
web_ide_clientside_preview_enabled: alt_usage_data { Gitlab::CurrentSettings.web_ide_clientside_preview_enabled? },
ingress_modsecurity_enabled: Feature.enabled?(:ingress_modsecurity)
}
}.merge(features_usage_data_container_expiration_policies)
end
# rubocop: disable CodeReuse/ActiveRecord
def features_usage_data_container_expiration_policies
results = {}
start = ::Project.minimum(:id)
finish = ::Project.maximum(:id)
results[:projects_with_expiration_policy_disabled] = distinct_count(::ContainerExpirationPolicy.where(enabled: false), :project_id, start: start, finish: finish)
base = ::ContainerExpirationPolicy.active
results[:projects_with_expiration_policy_enabled] = distinct_count(base, :project_id, start: start, finish: finish)
%i[keep_n cadence older_than].each do |option|
::ContainerExpirationPolicy.public_send("#{option}_options").keys.each do |value| # rubocop: disable GitlabSecurity/PublicSend
results["projects_with_expiration_policy_enabled_with_#{option}_set_to_#{value}".to_sym] = distinct_count(base.where(option => value), :project_id, start: start, finish: finish)
end
end
results[:projects_with_expiration_policy_enabled_with_keep_n_unset] = distinct_count(base.where(keep_n: nil), :project_id, start: start, finish: finish)
results[:projects_with_expiration_policy_enabled_with_older_than_unset] = distinct_count(base.where(older_than: nil), :project_id, start: start, finish: finish)
results
end
# rubocop: enable CodeReuse/ActiveRecord
# @return [Hash<Symbol, Integer>]
def usage_counters
......
......@@ -4,6 +4,7 @@ require 'spec_helper'
describe 'Project navbar' do
include NavbarStructureHelper
include WaitForRequests
include_context 'project navbar structure'
......@@ -21,6 +22,22 @@ describe 'Project navbar' do
end
end
context 'when value stream is available' do
before do
visit project_path(project)
end
it 'redirects to value stream when Analytics item is clicked' do
page.within('.sidebar-top-level-items') do
find('[data-qa-selector=analytics_anchor]').click
end
wait_for_requests
expect(page).to have_current_path(project_cycle_analytics_path(project))
end
end
context 'when pages are available' do
before do
allow(Gitlab.config.pages).to receive(:enabled).and_return(true)
......
......@@ -42,6 +42,87 @@ describe('IDE services', () => {
});
});
describe('getRawFileData', () => {
it("resolves with a file's content if its a tempfile and it isn't renamed", () => {
const file = {
path: 'file',
tempFile: true,
content: 'content',
raw: 'raw content',
};
return services.getRawFileData(file).then(raw => {
expect(raw).toBe('content');
});
});
it('resolves with file.raw if the file is renamed', () => {
const file = {
path: 'file',
tempFile: true,
content: 'content',
prevPath: 'old_path',
raw: 'raw content',
};
return services.getRawFileData(file).then(raw => {
expect(raw).toBe('raw content');
});
});
it('returns file.raw if it exists', () => {
const file = {
path: 'file',
content: 'content',
raw: 'raw content',
};
return services.getRawFileData(file).then(raw => {
expect(raw).toBe('raw content');
});
});
it("returns file.raw if file.raw is empty but file.rawPath doesn't exist", () => {
const file = {
path: 'file',
content: 'content',
raw: '',
};
return services.getRawFileData(file).then(raw => {
expect(raw).toBe('');
});
});
describe("if file.rawPath exists but file.raw doesn't exist", () => {
let file;
let mock;
beforeEach(() => {
file = {
path: 'file',
content: 'content',
raw: '',
rawPath: 'some_raw_path',
};
mock = new MockAdapter(axios);
mock.onGet(file.rawPath).reply(200, 'raw content');
jest.spyOn(axios, 'get');
});
afterEach(() => {
mock.restore();
});
it('sends a request to file.rawPath', () => {
return services.getRawFileData(file).then(raw => {
expect(raw).toEqual('raw content');
});
});
});
});
describe('getBaseRawFileData', () => {
let file;
let mock;
......
......@@ -408,7 +408,7 @@ describe('IDE store file actions', () => {
beforeEach(() => {
jest.spyOn(service, 'getRawFileData');
tmpFile = file('tmpFile');
tmpFile = { ...file('tmpFile'), rawPath: 'raw_path' };
store.state.entries[tmpFile.path] = tmpFile;
});
......
......@@ -144,6 +144,43 @@ describe Gitlab::UsageData, :aggregate_failures do
expect(subject[:gitlab_shared_runners_enabled]).to eq(Gitlab.config.gitlab_ci.shared_runners_enabled)
expect(subject[:web_ide_clientside_preview_enabled]).to eq(Gitlab::CurrentSettings.web_ide_clientside_preview_enabled?)
end
context 'with existing container expiration policies' do
let_it_be(:disabled) { create(:container_expiration_policy, enabled: false) }
let_it_be(:enabled) { create(:container_expiration_policy, enabled: true) }
%i[keep_n cadence older_than].each do |attribute|
ContainerExpirationPolicy.send("#{attribute}_options").keys.each do |value|
let_it_be("container_expiration_policy_with_#{attribute}_set_to_#{value}") { create(:container_expiration_policy, attribute => value) }
end
end
let(:inactive_policies) { ::ContainerExpirationPolicy.where(enabled: false) }
let(:active_policies) { ::ContainerExpirationPolicy.active }
it 'gathers usage data' do
expect(subject[:projects_with_expiration_policy_enabled]).to eq 16
expect(subject[:projects_with_expiration_policy_disabled]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_unset]).to eq 10
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_1]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_5]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_10]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_25]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_keep_n_set_to_50]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_unset]).to eq 12
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_7d]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_14d]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_30d]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_older_than_set_to_90d]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_1d]).to eq 12
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_7d]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_14d]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_1month]).to eq 1
expect(subject[:projects_with_expiration_policy_enabled_with_cadence_set_to_3month]).to eq 1
end
end
end
describe '#components_usage_data' do
......
......@@ -134,5 +134,24 @@ module UsageDataHelpers
prometheus_metrics_enabled
web_ide_clientside_preview_enabled
ingress_modsecurity_enabled
projects_with_expiration_policy_disabled
projects_with_expiration_policy_enabled
projects_with_expiration_policy_enabled_with_keep_n_unset
projects_with_expiration_policy_enabled_with_older_than_unset
projects_with_expiration_policy_enabled_with_keep_n_set_to_1
projects_with_expiration_policy_enabled_with_keep_n_set_to_5
projects_with_expiration_policy_enabled_with_keep_n_set_to_10
projects_with_expiration_policy_enabled_with_keep_n_set_to_25
projects_with_expiration_policy_enabled_with_keep_n_set_to_50
projects_with_expiration_policy_enabled_with_keep_n_set_to_100
projects_with_expiration_policy_enabled_with_cadence_set_to_1d
projects_with_expiration_policy_enabled_with_cadence_set_to_7d
projects_with_expiration_policy_enabled_with_cadence_set_to_14d
projects_with_expiration_policy_enabled_with_cadence_set_to_1month
projects_with_expiration_policy_enabled_with_cadence_set_to_3month
projects_with_expiration_policy_enabled_with_older_than_set_to_7d
projects_with_expiration_policy_enabled_with_older_than_set_to_14d
projects_with_expiration_policy_enabled_with_older_than_set_to_30d
projects_with_expiration_policy_enabled_with_older_than_set_to_90d
).freeze
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