Commit 27a18afc authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent 71c9d577
...@@ -92,7 +92,10 @@ module Clusters ...@@ -92,7 +92,10 @@ module Clusters
def calculate_reactive_cache_for(environment) def calculate_reactive_cache_for(environment)
return unless enabled? return unless enabled?
{ pods: read_pods(environment.deployment_namespace) } pods = read_pods(environment.deployment_namespace)
# extract_relevant_pod_data avoids uploading all the pod info into ReactiveCaching
{ pods: extract_relevant_pod_data(pods) }
end end
def terminals(environment, data) def terminals(environment, data)
...@@ -203,6 +206,21 @@ module Clusters ...@@ -203,6 +206,21 @@ module Clusters
def nullify_blank_namespace def nullify_blank_namespace
self.namespace = nil if namespace.blank? self.namespace = nil if namespace.blank?
end end
def extract_relevant_pod_data(pods)
pods.map do |pod|
{
'metadata' => pod.fetch('metadata', {})
.slice('name', 'generateName', 'labels', 'annotations', 'creationTimestamp'),
'status' => pod.fetch('status', {}).slice('phase'),
'spec' => {
'containers' => pod.fetch('spec', {})
.fetch('containers', [])
.map { |c| c.slice('name') }
}
}
end
end
end end
end end
end end
......
...@@ -128,10 +128,6 @@ module ErrorTracking ...@@ -128,10 +128,6 @@ module ErrorTracking
end end
end end
def expire_issues_cache
Rails.cache.delete_matched(expand_cache_key('list_issues'))
end
# http://HOST/api/0/projects/ORG/PROJECT # http://HOST/api/0/projects/ORG/PROJECT
# -> # ->
# http://HOST/ORG/PROJECT # http://HOST/ORG/PROJECT
...@@ -148,12 +144,6 @@ module ErrorTracking ...@@ -148,12 +144,6 @@ module ErrorTracking
private private
def expand_cache_key(resource_prefix)
klass_key = self.class.reactive_cache_key.call(self).join(':')
"#{klass_key}:#{resource_prefix}*"
end
def add_gitlab_issue_details(issue) def add_gitlab_issue_details(issue)
issue.gitlab_commit = match_gitlab_commit(issue.first_release_version) issue.gitlab_commit = match_gitlab_commit(issue.first_release_version)
issue.gitlab_commit_path = project_commit_path(project, issue.gitlab_commit) if issue.gitlab_commit issue.gitlab_commit_path = project_commit_path(project, issue.gitlab_commit) if issue.gitlab_commit
......
...@@ -2,12 +2,35 @@ ...@@ -2,12 +2,35 @@
module ErrorTracking module ErrorTracking
class IssueDetailsService < ErrorTracking::BaseService class IssueDetailsService < ErrorTracking::BaseService
include Gitlab::Routing
include Gitlab::Utils::StrongMemoize
private private
def perform def perform
response = project_error_tracking_setting.issue_details(issue_id: params[:issue_id]) response = project_error_tracking_setting.issue_details(issue_id: params[:issue_id])
compose_response(response) compose_response(response) do
# The gitlab_issue attribute can contain an absolute GitLab url from the Sentry Client
# here we overwrite that in favor of our own data if we have it
response[:issue].gitlab_issue = gitlab_issue_url if gitlab_issue_url
end
end
def gitlab_issue_url
strong_memoize(:gitlab_issue_url) do
# Use the absolute url to match the GitLab issue url that the Sentry api provides
project_issue_url(project, gitlab_issue.iid) if gitlab_issue
end
end
def gitlab_issue
strong_memoize(:gitlab_issue) do
SentryIssueFinder
.new(project, current_user: current_user)
.execute(params[:issue_id])
&.issue
end
end end
def parse_response(response) def parse_response(response)
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
module ErrorTracking module ErrorTracking
class IssueUpdateService < ErrorTracking::BaseService class IssueUpdateService < ErrorTracking::BaseService
include ::Gitlab::Utils::StrongMemoize
private private
def perform def perform
...@@ -14,14 +12,14 @@ module ErrorTracking ...@@ -14,14 +12,14 @@ module ErrorTracking
compose_response(response) do compose_response(response) do
response[:closed_issue_iid] = update_related_issue&.iid response[:closed_issue_iid] = update_related_issue&.iid
project_error_tracking_setting.expire_issues_cache
end end
end end
def update_related_issue def update_related_issue
return if related_issue.nil? issue = related_issue
return unless issue
close_and_create_note(related_issue) close_and_create_note(issue)
end end
def close_and_create_note(issue) def close_and_create_note(issue)
...@@ -45,12 +43,10 @@ module ErrorTracking ...@@ -45,12 +43,10 @@ module ErrorTracking
end end
def related_issue def related_issue
strong_memoize(:related_issue) do SentryIssueFinder
SentryIssueFinder .new(project, current_user: current_user)
.new(project, current_user: current_user) .execute(params[:issue_id])
.execute(params[:issue_id]) &.issue
&.issue
end
end end
def resolving? def resolving?
......
---
title: Include issues created in GitLab on error tracking details page
merge_request: 23605
author:
type: changed
...@@ -61,9 +61,9 @@ By default, a **Create issue** button is displayed: ...@@ -61,9 +61,9 @@ By default, a **Create issue** button is displayed:
![Error Details without Issue Link](img/error_details_v12_7.png) ![Error Details without Issue Link](img/error_details_v12_7.png)
If you create a GitLab issue from the error, the **Create issue** button will change to a **View issue** button: If you create a GitLab issue from the error, the **Create issue** button will change to a **View issue** button and a link to the GitLab issue will surface within the error detail section:
![Error Details with Issue Link](img/error_details_with_issue_v12_7.png) ![Error Details with Issue Link](img/error_details_with_issue_v12_8.png)
## Taking Action on errors ## Taking Action on errors
......
...@@ -107,6 +107,16 @@ For private projects, the number of Releases is displayed to users with Reporter ...@@ -107,6 +107,16 @@ For private projects, the number of Releases is displayed to users with Reporter
[permissions](../../permissions.md#releases-permissions) or higher. For public projects, [permissions](../../permissions.md#releases-permissions) or higher. For public projects,
it is displayed to every user regardless of their permission level. it is displayed to every user regardless of their permission level.
### Upcoming Releases
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/issues/38105) in GitLab 12.1.
A Release may be created ahead of time by specifying a future `released_at` date. Until
the `released_at` date and time is reached, an **Upcoming Release** badge will appear next to the
Release tag. Once the `released_at` date and time has passed, the badge is automatically removed.
![An upcoming release](img/upcoming_release_v12_7.png)
## Editing a release ## Editing a release
> [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/26016) in GitLab 12.6. > [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/26016) in GitLab 12.6.
...@@ -245,6 +255,19 @@ Please note that Release Evidence's data is collected regardless of this ...@@ -245,6 +255,19 @@ Please note that Release Evidence's data is collected regardless of this
feature flag, which only enables or disables the display of the data on the feature flag, which only enables or disables the display of the data on the
Releases page. Releases page.
### Scheduled Evidence creation
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23697) in GitLab 12.8.
When the `released_at` date and time is not provided, the date and time of Release
creation is used. The Evidence collection background job is immediately executed.
If a future `released_at` is specified, the Release becomes an **Upcoming Release**. In this
case, the Evidence is scheduled to be collected at the `released_at` date and time, via a
background job.
If a past `released_at` is used, no Evidence is collected for the Release.
<!-- ## Troubleshooting <!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues Include any troubleshooting steps that you can foresee. If you know beforehand what issues
......
...@@ -5,60 +5,56 @@ disqus_identifier: 'https://docs.gitlab.com/ee/workflow/forking_workflow.html' ...@@ -5,60 +5,56 @@ disqus_identifier: 'https://docs.gitlab.com/ee/workflow/forking_workflow.html'
# Project forking workflow # Project forking workflow
Forking a project to your own namespace is useful if you have no write Forking a project to your own namespace is useful if you have no write
access to the project you want to contribute to. If you do have write access to the project you want to contribute to. Even if you do have write
access or can request it, we recommend working together in the same access or can request it, we recommend working together in the same
repository since it is simpler. See our [GitLab Flow](../../../topics/gitlab_flow.md) repository since it is simpler. See our [GitLab Flow](../../../topics/gitlab_flow.md)
document more information about using branches to work together. document more information about using branches to work together.
## Creating a fork ## Creating a fork
Forking a project is in most cases a two-step process. Forking a project is, in most cases, a two-step process.
1. Click on the fork button located in between the star and clone buttons on the project's home page. 1. On the project's home page, in the top right, click the **Fork** button.
![Fork button](img/forking_workflow_fork_button.png) ![Fork button](img/forking_workflow_fork_button.png)
1. Once you do that, you'll be presented with a screen where you can choose 1. Click a namespace to fork to. Only namespaces you have Developer and higher [permissions](../../permissions.md) for are shown.
the namespace to fork to. Only namespaces (groups and your own
namespace) where you have write access to, will be shown. Click on the NOTE: **Note:**
namespace to create your fork there. The project path must be unique within the namespace.
![Choose namespace](img/forking_workflow_choose_namespace.png) ![Choose namespace](img/forking_workflow_choose_namespace.png)
**Note:** The fork is created. The permissions you have in the namespace are the permissions you will have in the fork.
If the namespace you chose to fork the project to has another project with
the same path name, you will be presented with a warning that the forking CAUTION: **CAUTION:**
could not be completed. Try to resolve the error before repeating the forking In GitLab 12.6 and later, when project owners [reduce a project's visibility](../../../public_access/public_access.md#reducing-visibility),
process. it **removes the relationship** between a project and all its forks.
![Path taken error](img/forking_workflow_path_taken_error.png) ## Repository mirroring
After the forking is done, you can start working on the newly created You can use [repository mirroring](repository_mirroring.md) to keep your fork synced with the original repository. You can also use `git remote add upstream` to achieve the same result.
repository. There, you will have full [Owner](../../permissions.md)
access, so you can set it up as you please.
CAUTION: **CAUTION:** The main difference is that with repository mirroring your remote fork will be automatically kept up-to-date.
From GitLab 12.6 onward, if the [visibility of an upstream project is reduced](../../../public_access/public_access.md#reducing-visibility)
in any way, the fork relationship with all its forks will be removed. Without mirroring, to work locally you'll have to user `git pull` to update your local repo with the fork on GitLab. You'll have to fetch locally and push it back to the remote repo to update it.
CAUTION: **Caution:** CAUTION: **Caution:**
[Repository mirroring](repository_mirroring.md) will help to keep your fork synced with the original repository. With mirroring, before approving a merge request you'll likely to be asked to sync, hence automating it is recommend.
Before approving a merge request you'll likely to be asked to sync before getting approval, hence automating it is recommend.
Read more about [How to keep your fork up to date with its origin](https://about.gitlab.com/blog/2016/12/01/how-to-keep-your-fork-up-to-date-with-its-origin/).
## Merging upstream ## Merging upstream
Once you are ready to send your code back to the main project, you need When you are ready to send your code back to the upstream project,
to create a merge request. Choose your forked project's main branch as [create a merge request](../merge_requests/creating_merge_requests.md). For **Source branch**,
the source and the original project's main branch as the destination and choose your forked project's branch. For **Target branch**, choose the original project's branch.
create the [merge request](../merge_requests/index.md).
![Selecting branches](img/forking_workflow_branch_select.png) ![Selecting branches](img/forking_workflow_branch_select.png)
You can then assign the merge request to someone to have them review Then you can add labels, a milestone, and assign the merge request to someone who can review
your changes. Upon pressing the 'Submit Merge Request' button, your your changes. Then click **Submit merge request** to conclude the process. When successfully merged, your
changes will be added to the repository and branch you're merging into. changes are added to the repository and branch you're merging into.
![New merge request](img/forking_workflow_merge_request.png)
## Removing a fork relationship ## Removing a fork relationship
......
...@@ -6,7 +6,7 @@ module Gitlab ...@@ -6,7 +6,7 @@ module Gitlab
module Graphql module Graphql
module QueryAnalyzers module QueryAnalyzers
class RecursionAnalyzer class RecursionAnalyzer
IGNORED_FIELDS = %w(node edges ofType).freeze IGNORED_FIELDS = %w(node edges nodes ofType).freeze
RECURSION_THRESHOLD = 2 RECURSION_THRESHOLD = 2
def initial_value(query) def initial_value(query)
......
#!/bin/sh #!/bin/sh
output=`git grep -En '^<<<<<<< ' -- . ':(exclude)spec/lib/gitlab/conflict/file_spec.rb' ':(exclude)spec/lib/gitlab/git/conflict/parser_spec.rb'` output=`git grep -En '^<<<<<<< '`
echo $output echo $output
test -z "$output" test -z "$output"
...@@ -240,28 +240,30 @@ describe 'Task Lists' do ...@@ -240,28 +240,30 @@ describe 'Task Lists' do
end end
shared_examples 'multiple tasks' do shared_examples 'multiple tasks' do
it 'renders for description' do it 'renders for description', :js do
visit_merge_request(project, merge) visit_merge_request(project, merge)
wait_for_requests
expect(page).to have_selector('ul.task-list', count: 1) expect(page).to have_selector('ul.task-list', count: 1)
expect(page).to have_selector('li.task-list-item', count: 6) expect(page).to have_selector('li.task-list-item', count: 6)
expect(page).to have_selector('ul input[checked]', count: 2) expect(page).to have_selector('ul input[checked]', count: 2)
end end
it 'contains the required selectors' do it 'contains the required selectors', :js do
visit_merge_request(project, merge) visit_merge_request(project, merge)
wait_for_requests
container = '.detail-page-description .description.js-task-list-container' container = '.detail-page-description .description.js-task-list-container'
expect(page).to have_selector(container) expect(page).to have_selector(container)
expect(page).to have_selector("#{container} .md .task-list .task-list-item .task-list-item-checkbox") expect(page).to have_selector("#{container} .md .task-list .task-list-item .task-list-item-checkbox")
expect(page).to have_selector("#{container} .js-task-list-field") expect(page).to have_selector("#{container} .js-task-list-field", visible: false)
expect(page).to have_selector('form.js-issuable-update') expect(page).to have_selector('form.js-issuable-update')
expect(page).to have_selector('a.btn-close')
end end
it 'is only editable by author', :js do it 'is only editable by author', :js do
visit_merge_request(project, merge) visit_merge_request(project, merge)
wait_for_requests
expect(page).to have_selector('.js-task-list-container') expect(page).to have_selector('.js-task-list-container')
expect(page).to have_selector('li.task-list-item.enabled', count: 6) expect(page).to have_selector('li.task-list-item.enabled', count: 6)
...@@ -269,6 +271,7 @@ describe 'Task Lists' do ...@@ -269,6 +271,7 @@ describe 'Task Lists' do
logout(:user) logout(:user)
login_as(user2) login_as(user2)
visit current_path visit current_path
wait_for_requests
expect(page).not_to have_selector('.js-task-list-container') expect(page).not_to have_selector('.js-task-list-container')
expect(page).to have_selector('li.task-list-item.enabled', count: 0) expect(page).to have_selector('li.task-list-item.enabled', count: 0)
...@@ -297,8 +300,9 @@ describe 'Task Lists' do ...@@ -297,8 +300,9 @@ describe 'Task Lists' do
describe 'single incomplete task' do describe 'single incomplete task' do
let!(:merge) { create(:merge_request, :simple, description: singleIncompleteMarkdown, author: user, source_project: project) } let!(:merge) { create(:merge_request, :simple, description: singleIncompleteMarkdown, author: user, source_project: project) }
it 'renders for description' do it 'renders for description', :js do
visit_merge_request(project, merge) visit_merge_request(project, merge)
wait_for_requests
expect(page).to have_selector('ul.task-list', count: 1) expect(page).to have_selector('ul.task-list', count: 1)
expect(page).to have_selector('li.task-list-item', count: 1) expect(page).to have_selector('li.task-list-item', count: 1)
...@@ -315,8 +319,9 @@ describe 'Task Lists' do ...@@ -315,8 +319,9 @@ describe 'Task Lists' do
describe 'single complete task' do describe 'single complete task' do
let!(:merge) { create(:merge_request, :simple, description: singleCompleteMarkdown, author: user, source_project: project) } let!(:merge) { create(:merge_request, :simple, description: singleCompleteMarkdown, author: user, source_project: project) }
it 'renders for description' do it 'renders for description', :js do
visit_merge_request(project, merge) visit_merge_request(project, merge)
wait_for_requests
expect(page).to have_selector('ul.task-list', count: 1) expect(page).to have_selector('ul.task-list', count: 1)
expect(page).to have_selector('li.task-list-item', count: 1) expect(page).to have_selector('li.task-list-item', count: 1)
...@@ -325,6 +330,7 @@ describe 'Task Lists' do ...@@ -325,6 +330,7 @@ describe 'Task Lists' do
it 'provides a summary on MergeRequests#index' do it 'provides a summary on MergeRequests#index' do
visit project_merge_requests_path(project) visit project_merge_requests_path(project)
expect(page).to have_content("1 of 1 task completed") expect(page).to have_content("1 of 1 task completed")
end end
end end
......
...@@ -2,51 +2,11 @@ query allSchemaTypes { ...@@ -2,51 +2,11 @@ query allSchemaTypes {
__schema { __schema {
types { types {
fields { fields {
type{ type {
fields { fields {
type { type {
fields { fields {
type { name
fields {
type {
fields {
type {
fields {
type {
fields {
type {
fields {
type {
fields {
type {
fields {
type {
fields {
type {
fields {
type {
fields {
name
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
} }
} }
} }
...@@ -54,4 +14,4 @@ query allSchemaTypes { ...@@ -54,4 +14,4 @@ query allSchemaTypes {
} }
} }
} }
} }
\ No newline at end of file
{
project(fullPath: "gitlab-org/gitlab") {
group {
projects {
edges {
node {
group {
projects {
edges {
node {
group {
description
}
}
}
}
}
}
}
}
}
}
}
{
project(fullPath: "gitlab-org/gitlab") {
group {
projects {
nodes {
group {
projects {
nodes {
group {
description
}
}
}
}
}
}
}
}
}
{
project(fullPath: "gitlab-org/gitlab-ce") {
group {
projects {
edges {
node {
group {
projects {
edges {
node {
group {
projects {
edges {
node {
group {
projects {
edges {
node {
group {
projects {
edges {
node {
group {
description
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
...@@ -153,79 +153,79 @@ describe Gitlab::Conflict::File do ...@@ -153,79 +153,79 @@ describe Gitlab::Conflict::File do
context 'with an example file' do context 'with an example file' do
let(:raw_conflict_content) do let(:raw_conflict_content) do
<<FILE <<~FILE
# Ensure there is no match line header here # Ensure there is no match line header here
def username_regexp def username_regexp
default_regexp default_regexp
end end
<<<<<<< files/ruby/regex.rb <<<<<<< files/ruby/regex.rb
def project_name_regexp def project_name_regexp
/\A[a-zA-Z0-9][a-zA-Z0-9_\-\. ]*\z/ /\A[a-zA-Z0-9][a-zA-Z0-9_\-\. ]*\z/
end end
def name_regexp def name_regexp
/\A[a-zA-Z0-9_\-\. ]*\z/ /\A[a-zA-Z0-9_\-\. ]*\z/
======= =======
def project_name_regex def project_name_regex
%r{\A[a-zA-Z0-9][a-zA-Z0-9_\-\. ]*\z} %r{\A[a-zA-Z0-9][a-zA-Z0-9_\-\. ]*\z}
end end
def name_regex def name_regex
%r{\A[a-zA-Z0-9_\-\. ]*\z} %r{\A[a-zA-Z0-9_\-\. ]*\z}
>>>>>>> files/ruby/regex.rb >>>>>>> files/ruby/regex.rb
end end
# Some extra lines # Some extra lines
# To force a match line # To force a match line
# To be created # To be created
def path_regexp def path_regexp
default_regexp default_regexp
end end
<<<<<<< files/ruby/regex.rb <<<<<<< files/ruby/regex.rb
def archive_formats_regexp def archive_formats_regexp
/(zip|tar|7z|tar\.gz|tgz|gz|tar\.bz2|tbz|tbz2|tb2|bz2)/ /(zip|tar|7z|tar\.gz|tgz|gz|tar\.bz2|tbz|tbz2|tb2|bz2)/
======= =======
def archive_formats_regex def archive_formats_regex
%r{(zip|tar|7z|tar\.gz|tgz|gz|tar\.bz2|tbz|tbz2|tb2|bz2)} %r{(zip|tar|7z|tar\.gz|tgz|gz|tar\.bz2|tbz|tbz2|tb2|bz2)}
>>>>>>> files/ruby/regex.rb >>>>>>> files/ruby/regex.rb
end end
def git_reference_regexp def git_reference_regexp
# Valid git ref regexp, see: # Valid git ref regexp, see:
# https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html # https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html
%r{ %r{
(?! (?!
(?# doesn't begins with) (?# doesn't begins with)
\/| (?# rule #6) \/| (?# rule #6)
(?# doesn't contain) (?# doesn't contain)
.*(?: .*(?:
[\/.]\.| (?# rule #1,3) [\/.]\.| (?# rule #1,3)
\/\/| (?# rule #6) \/\/| (?# rule #6)
@\{| (?# rule #8) @\{| (?# rule #8)
\\ (?# rule #9) \\ (?# rule #9)
) )
) )
[^\000-\040\177~^:?*\[]+ (?# rule #4-5) [^\000-\040\177~^:?*\[]+ (?# rule #4-5)
(?# doesn't end with) (?# doesn't end with)
(?<!\.lock) (?# rule #1) (?<!\.lock) (?# rule #1)
(?<![\/.]) (?# rule #6-7) (?<![\/.]) (?# rule #6-7)
}x }x
end end
protected protected
<<<<<<< files/ruby/regex.rb <<<<<<< files/ruby/regex.rb
def default_regexp def default_regexp
/\A[.?]?[a-zA-Z0-9][a-zA-Z0-9_\-\.]*(?<!\.git)\z/ /\A[.?]?[a-zA-Z0-9][a-zA-Z0-9_\-\.]*(?<!\.git)\z/
======= =======
def default_regex def default_regex
%r{\A[.?]?[a-zA-Z0-9][a-zA-Z0-9_\-\.]*(?<!\.git)\z} %r{\A[.?]?[a-zA-Z0-9][a-zA-Z0-9_\-\.]*(?<!\.git)\z}
>>>>>>> files/ruby/regex.rb >>>>>>> files/ruby/regex.rb
end end
FILE FILE
end end
let(:sections) { conflict_file.sections } let(:sections) { conflict_file.sections }
......
...@@ -10,80 +10,80 @@ describe Gitlab::Git::Conflict::Parser do ...@@ -10,80 +10,80 @@ describe Gitlab::Git::Conflict::Parser do
context 'when the file has valid conflicts' do context 'when the file has valid conflicts' do
let(:text) do let(:text) do
<<CONFLICT <<~CONFLICT
module Gitlab module Gitlab
module Regexp module Regexp
extend self extend self
def username_regexp def username_regexp
default_regexp default_regexp
end end
<<<<<<< files/ruby/regex.rb <<<<<<< files/ruby/regex.rb
def project_name_regexp def project_name_regexp
/\A[a-zA-Z0-9][a-zA-Z0-9_\-\. ]*\z/ /\A[a-zA-Z0-9][a-zA-Z0-9_\-\. ]*\z/
end end
def name_regexp def name_regexp
/\A[a-zA-Z0-9_\-\. ]*\z/ /\A[a-zA-Z0-9_\-\. ]*\z/
======= =======
def project_name_regex def project_name_regex
%r{\A[a-zA-Z0-9][a-zA-Z0-9_\-\. ]*\z} %r{\A[a-zA-Z0-9][a-zA-Z0-9_\-\. ]*\z}
end end
def name_regex def name_regex
%r{\A[a-zA-Z0-9_\-\. ]*\z} %r{\A[a-zA-Z0-9_\-\. ]*\z}
>>>>>>> files/ruby/regex.rb >>>>>>> files/ruby/regex.rb
end end
def path_regexp def path_regexp
default_regexp default_regexp
end end
<<<<<<< files/ruby/regex.rb <<<<<<< files/ruby/regex.rb
def archive_formats_regexp def archive_formats_regexp
/(zip|tar|7z|tar\.gz|tgz|gz|tar\.bz2|tbz|tbz2|tb2|bz2)/ /(zip|tar|7z|tar\.gz|tgz|gz|tar\.bz2|tbz|tbz2|tb2|bz2)/
======= =======
def archive_formats_regex def archive_formats_regex
%r{(zip|tar|7z|tar\.gz|tgz|gz|tar\.bz2|tbz|tbz2|tb2|bz2)} %r{(zip|tar|7z|tar\.gz|tgz|gz|tar\.bz2|tbz|tbz2|tb2|bz2)}
>>>>>>> files/ruby/regex.rb >>>>>>> files/ruby/regex.rb
end end
def git_reference_regexp def git_reference_regexp
# Valid git ref regexp, see: # Valid git ref regexp, see:
# https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html # https://www.kernel.org/pub/software/scm/git/docs/git-check-ref-format.html
%r{ %r{
(?! (?!
(?# doesn't begins with) (?# doesn't begins with)
\/| (?# rule #6) \/| (?# rule #6)
(?# doesn't contain) (?# doesn't contain)
.*(?: .*(?:
[\/.]\.| (?# rule #1,3) [\/.]\.| (?# rule #1,3)
\/\/| (?# rule #6) \/\/| (?# rule #6)
@\{| (?# rule #8) @\{| (?# rule #8)
\\ (?# rule #9) \\ (?# rule #9)
) )
) )
[^\000-\040\177~^:?*\[]+ (?# rule #4-5) [^\000-\040\177~^:?*\[]+ (?# rule #4-5)
(?# doesn't end with) (?# doesn't end with)
(?<!\.lock) (?# rule #1) (?<!\.lock) (?# rule #1)
(?<![\/.]) (?# rule #6-7) (?<![\/.]) (?# rule #6-7)
}x }x
end end
protected protected
<<<<<<< files/ruby/regex.rb <<<<<<< files/ruby/regex.rb
def default_regexp def default_regexp
/\A[.?]?[a-zA-Z0-9][a-zA-Z0-9_\-\.]*(?<!\.git)\z/ /\A[.?]?[a-zA-Z0-9][a-zA-Z0-9_\-\.]*(?<!\.git)\z/
======= =======
def default_regex def default_regex
%r{\A[.?]?[a-zA-Z0-9][a-zA-Z0-9_\-\.]*(?<!\.git)\z} %r{\A[.?]?[a-zA-Z0-9][a-zA-Z0-9_\-\.]*(?<!\.git)\z}
>>>>>>> files/ruby/regex.rb >>>>>>> files/ruby/regex.rb
end end
end end
end end
CONFLICT CONFLICT
end end
let(:lines) do let(:lines) do
......
...@@ -361,8 +361,10 @@ describe Clusters::Platforms::Kubernetes do ...@@ -361,8 +361,10 @@ describe Clusters::Platforms::Kubernetes do
describe '#calculate_reactive_cache_for' do describe '#calculate_reactive_cache_for' do
let(:service) { create(:cluster_platform_kubernetes, :configured) } let(:service) { create(:cluster_platform_kubernetes, :configured) }
let(:pod) { kube_pod } let(:expected_pod_cached_data) do
let(:namespace) { pod["metadata"]["namespace"] } kube_pod.tap { |kp| kp['metadata'].delete('namespace') }
end
let(:namespace) { "project-namespace" }
let(:environment) { instance_double(Environment, deployment_namespace: namespace) } let(:environment) { instance_double(Environment, deployment_namespace: namespace) }
subject { service.calculate_reactive_cache_for(environment) } subject { service.calculate_reactive_cache_for(environment) }
...@@ -381,7 +383,7 @@ describe Clusters::Platforms::Kubernetes do ...@@ -381,7 +383,7 @@ describe Clusters::Platforms::Kubernetes do
stub_kubeclient_deployments(namespace) stub_kubeclient_deployments(namespace)
end end
it { is_expected.to include(pods: [pod]) } it { is_expected.to include(pods: [expected_pod_cached_data]) }
end end
context 'when kubernetes responds with 500s' do context 'when kubernetes responds with 500s' do
......
...@@ -440,18 +440,4 @@ describe ErrorTracking::ProjectErrorTrackingSetting do ...@@ -440,18 +440,4 @@ describe ErrorTracking::ProjectErrorTrackingSetting do
end end
end end
end end
describe '#expire_issues_cache', :use_clean_rails_memory_store_caching do
it 'clears the cache' do
klass_key = subject.class.reactive_cache_key.call(subject).join(':')
key = "#{klass_key}:list_issues:some_suffix"
Rails.cache.write(key, 1)
expect(Rails.cache.exist?(key)).to eq(true)
subject.expire_issues_cache
expect(Rails.cache.exist?(key)).to eq(false)
end
end
end end
...@@ -67,24 +67,45 @@ describe 'GitlabSchema configurations' do ...@@ -67,24 +67,45 @@ describe 'GitlabSchema configurations' do
end end
end end
context 'a deep but simple recursive introspective query' do context 'failing queries' do
it 'fails due to recursion' do before do
query = File.read(Rails.root.join('spec/fixtures/api/graphql/recursive-introspection.graphql')) allow(GitlabSchema).to receive(:max_query_recursion).and_return 1
end
post_graphql(query, current_user: nil) context 'a recursive introspective query' do
it 'fails due to recursion' do
query = File.read(Rails.root.join('spec/fixtures/api/graphql/recursive-introspection.graphql'))
expect_graphql_errors_to_include [/Recursive query/] post_graphql(query, current_user: nil)
expect_graphql_errors_to_include [/Recursive query/]
end
end end
end
context 'a deep recursive non-introspective query' do context 'a recursive non-introspective query' do
it 'fails due to recursion, complexity and depth' do before do
allow(GitlabSchema).to receive(:max_query_complexity).and_return 1 allow(GitlabSchema).to receive(:max_query_complexity).and_return 1
query = File.read(Rails.root.join('spec/fixtures/api/graphql/recursive-query.graphql')) allow(GitlabSchema).to receive(:max_query_depth).and_return 1
allow(GitlabSchema).to receive(:max_query_complexity).and_return 1
end
post_graphql(query, current_user: nil) shared_examples 'fails due to recursion, complexity and depth' do |fixture_file|
it 'fails due to recursion, complexity and depth' do
query = File.read(Rails.root.join(fixture_file))
post_graphql(query, current_user: nil)
expect_graphql_errors_to_include [/Recursive query/, /exceeds max complexity/, /exceeds max depth/]
end
end
expect_graphql_errors_to_include [/Recursive query/, /exceeds max complexity/, /exceeds max depth/] context 'using `nodes` notation' do
it_behaves_like 'fails due to recursion, complexity and depth', 'spec/fixtures/api/graphql/recursive-query-nodes.graphql'
end
context 'using `edges -> node` notation' do
it_behaves_like 'fails due to recursion, complexity and depth', 'spec/fixtures/api/graphql/recursive-query-edges-node.graphql'
end
end end
end end
end end
......
...@@ -9,6 +9,7 @@ describe ErrorTracking::IssueDetailsService do ...@@ -9,6 +9,7 @@ describe ErrorTracking::IssueDetailsService do
context 'with authorized user' do context 'with authorized user' do
context 'when issue_details returns a detailed error' do context 'when issue_details returns a detailed error' do
let(:detailed_error) { build(:detailed_error_tracking_error) } let(:detailed_error) { build(:detailed_error_tracking_error) }
let(:params) { { issue_id: detailed_error.id } }
before do before do
expect(error_tracking_setting) expect(error_tracking_setting)
...@@ -18,6 +19,19 @@ describe ErrorTracking::IssueDetailsService do ...@@ -18,6 +19,19 @@ describe ErrorTracking::IssueDetailsService do
it 'returns the detailed error' do it 'returns the detailed error' do
expect(result).to eq(status: :success, issue: detailed_error) expect(result).to eq(status: :success, issue: detailed_error)
end end
it 'returns the gitlab_issue when the error has a sentry_issue' do
gitlab_issue = create(:issue, project: project)
create(:sentry_issue, issue: gitlab_issue, sentry_issue_identifier: detailed_error.id)
expect(result[:issue].gitlab_issue).to include(
"http", "/#{project.full_path}/issues/#{gitlab_issue.iid}"
)
end
it 'returns the gitlab_issue path from sentry when the error has no sentry_issue' do
expect(result[:issue].gitlab_issue).to eq(detailed_error.gitlab_issue)
end
end end
include_examples 'error tracking service data not ready', :issue_details include_examples 'error tracking service data not ready', :issue_details
......
...@@ -40,16 +40,6 @@ describe ErrorTracking::IssueUpdateService do ...@@ -40,16 +40,6 @@ describe ErrorTracking::IssueUpdateService do
result result
end end
it 'clears the reactive cache' do
allow(error_tracking_setting)
.to receive(:expire_issues_cache)
result
expect(error_tracking_setting)
.to have_received(:expire_issues_cache)
end
context 'related issue and resolving' do context 'related issue and resolving' do
let(:issue) { create(:issue, project: project) } let(:issue) { create(:issue, project: project) }
let(:sentry_issue) { create(:sentry_issue, issue: issue) } let(:sentry_issue) { create(:sentry_issue, issue: issue) }
......
...@@ -494,7 +494,7 @@ module KubernetesHelpers ...@@ -494,7 +494,7 @@ module KubernetesHelpers
"metadata" => { "metadata" => {
"name" => name, "name" => name,
"namespace" => namespace, "namespace" => namespace,
"generate_name" => "generated-name-with-suffix", "generateName" => "generated-name-with-suffix",
"creationTimestamp" => "2016-11-25T19:55:19Z", "creationTimestamp" => "2016-11-25T19:55:19Z",
"annotations" => { "annotations" => {
"app.gitlab.com/env" => environment_slug, "app.gitlab.com/env" => environment_slug,
...@@ -520,7 +520,7 @@ module KubernetesHelpers ...@@ -520,7 +520,7 @@ module KubernetesHelpers
"metadata" => { "metadata" => {
"name" => name, "name" => name,
"namespace" => namespace, "namespace" => namespace,
"generate_name" => "generated-name-with-suffix", "generateName" => "generated-name-with-suffix",
"creationTimestamp" => "2016-11-25T19:55:19Z", "creationTimestamp" => "2016-11-25T19:55:19Z",
"labels" => { "labels" => {
"serving.knative.dev/service" => name "serving.knative.dev/service" => name
...@@ -551,10 +551,7 @@ module KubernetesHelpers ...@@ -551,10 +551,7 @@ module KubernetesHelpers
}, },
"spec" => { "replicas" => 3 }, "spec" => { "replicas" => 3 },
"status" => { "status" => {
"observedGeneration" => 4, "observedGeneration" => 4
"replicas" => 3,
"updatedReplicas" => 3,
"availableReplicas" => 3
} }
} }
end end
......
...@@ -6,9 +6,10 @@ shared_context 'sentry error tracking context' do ...@@ -6,9 +6,10 @@ shared_context 'sentry error tracking context' do
let(:sentry_url) { 'https://sentrytest.gitlab.com/api/0/projects/sentry-org/sentry-project' } let(:sentry_url) { 'https://sentrytest.gitlab.com/api/0/projects/sentry-org/sentry-project' }
let(:token) { 'test-token' } let(:token) { 'test-token' }
let(:params) { {} }
let(:result) { subject.execute } let(:result) { subject.execute }
subject { described_class.new(project, user) } subject { described_class.new(project, user, params) }
let(:error_tracking_setting) do let(:error_tracking_setting) do
create(:project_error_tracking_setting, api_url: sentry_url, token: token, project: project) create(:project_error_tracking_setting, api_url: sentry_url, token: token, project: project)
......
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