Commit 6f0f893b authored by 🤖 GitLab Bot 🤖's avatar 🤖 GitLab Bot 🤖

Add latest changes from gitlab-org/[email protected]

parent 8b1228b0
......@@ -10,5 +10,8 @@ lint-ci-gitlab:
- "**/*.yml"
image: sdesbure/yamllint:latest
dependencies: []
variables:
LINT_PATHS: .gitlab-ci.yml .gitlab/ci lib/gitlab/ci/templates changelogs
script:
- yamllint .gitlab-ci.yml .gitlab/ci lib/gitlab/ci/templates changelogs
- '[[ ! -d "ee/" ]] || export LINT_PATHS="$LINT_PATHS ee/changelogs"'
- yamllint $LINT_PATHS
......@@ -238,7 +238,7 @@ entry.
- Skip updating LFS objects in mirror updates if repository has not changed. !21744
- Add indexes on deployments to improve environments search. !21789
### Added (117 changes, 16 of them are from the community)
### Added (119 changes, 18 of them are from the community)
- Add upvote/downvotes attributes to GraphQL Epic query. !14311
- Delete kubernetes cluster association and resources. !16954
......@@ -357,6 +357,8 @@ entry.
- Added migration which adds service desk username column. !21733
- Add SentryIssue table to store a link between issue and sentry issue. !37026
- Add path based targeting to broadcast messages.
- Add allow failure in pipeline webhook event. !20978 (Gaetan Semet)
- Add runner information in build web hook event. !20709 (Gaetan Semet)
### Other (51 changes, 28 of them are from the community)
......@@ -483,7 +485,7 @@ entry.
- Do not display project labels that are not visible for user accessing group labels.
- Standardize error response when route is missing.
### Fixed (99 changes, 14 of them are from the community)
### Fixed (100 changes, 15 of them are from the community)
- Fix incorrect selection of custom templates. !17205
- Smaller width for design comments layout, truncate image title. !17547
......@@ -584,6 +586,7 @@ entry.
- Only allow confirmed users to run pipelines.
- Fix scroll to bottom with new job log.
- Fixed protected branches flash styling.
- Show tag link whenever it's a tag in chat message integration for push events and pipeline events. !18126 (Mats Estensen)
### Deprecated (2 changes)
......
import axios from '~/lib/utils/axios_utils';
import Poll from './poll';
import httpStatusCodes from './http_status';
/**
* Polls an endpoint until it returns either a 200 OK or a error status.
* The Poll-Interval header in the responses are used to determine how
* frequently to poll.
*
* Once a 200 OK is received, the promise resolves with that response. If an
* error status is received, the promise rejects with the error.
*
* @param {string} url - The URL to poll.
* @param {Object} [config] - The config to provide to axios.get().
* @returns {Promise}
*/
export default (url, config = {}) =>
new Promise((resolve, reject) => {
const eTagPoll = new Poll({
resource: {
axiosGet(data) {
return axios.get(data.url, {
headers: {
'Content-Type': 'application/json',
},
...data.config,
});
},
},
data: { url, config },
method: 'axiosGet',
successCallback: response => {
if (response.status === httpStatusCodes.OK) {
resolve(response);
eTagPoll.stop();
}
},
errorCallback: reject,
});
eTagPoll.makeRequest();
});
......@@ -66,7 +66,7 @@ export default {
:svg-path="illustrationPath"
:description="
__(
'Releases mark specific points in a project\'s development history, communicate information about the type of change, and deliver on prepared, often compiled, versions of the software to be reused elsewhere. Currently, releases can only be created through the API.',
'Releases are based on Git tags and mark specific points in a project\'s development history. They can contain information about the type of changes and can also deliver binaries, like compiled versions of your software.',
)
"
:primary-button-link="documentationLink"
......
......@@ -76,6 +76,9 @@ module Types
field :last_release_short_version, GraphQL::STRING_TYPE,
null: true,
description: "Release version the error was last seen"
field :gitlab_commit, GraphQL::STRING_TYPE,
null: true,
description: "GitLab commit SHA attributed to the Error based on the release version"
def first_seen
DateTime.parse(object.first_seen)
......
# frozen_string_literal: true
module Ci
class Bridge < CommitStatus
include Ci::Processable
class Bridge < Ci::Processable
include Ci::Contextable
include Ci::PipelineDelegator
include Importable
......
# frozen_string_literal: true
module Ci
class Build < CommitStatus
include Ci::Processable
class Build < Ci::Processable
include Ci::Metadatable
include Ci::Contextable
include Ci::PipelineDelegator
......
......@@ -33,8 +33,7 @@ module Ci
has_many :stages, -> { order(position: :asc) }, inverse_of: :pipeline
has_many :statuses, class_name: 'CommitStatus', foreign_key: :commit_id, inverse_of: :pipeline
has_many :latest_statuses_ordered_by_stage, -> { latest.order(:stage_idx, :stage) }, class_name: 'CommitStatus', foreign_key: :commit_id, inverse_of: :pipeline
has_many :processables, -> { processables },
class_name: 'CommitStatus', foreign_key: :commit_id, inverse_of: :pipeline
has_many :processables, class_name: 'Ci::Processable', foreign_key: :commit_id, inverse_of: :pipeline
has_many :builds, foreign_key: :commit_id, inverse_of: :pipeline
has_many :trigger_requests, dependent: :destroy, foreign_key: :commit_id # rubocop:disable Cop/ActiveRecordDependent
has_many :variables, class_name: 'Ci::PipelineVariable'
......
# frozen_string_literal: true
module Ci
##
# This module implements methods that need to be implemented by CI/CD
# entities that are supposed to go through pipeline processing
# services.
#
#
module Processable
extend ActiveSupport::Concern
class Processable < ::CommitStatus
has_many :needs, class_name: 'Ci::BuildNeed', foreign_key: :build_id, inverse_of: :build
included do
has_many :needs, class_name: 'Ci::BuildNeed', foreign_key: :build_id, inverse_of: :build
accepts_nested_attributes_for :needs
accepts_nested_attributes_for :needs
scope :preload_needs, -> { preload(:needs) }
scope :preload_needs, -> { preload(:needs) }
end
validates :type, presence: true
def schedulable?
raise NotImplementedError
......
......@@ -45,7 +45,6 @@ class CommitStatus < ApplicationRecord
scope :before_stage, -> (index) { where('stage_idx < ?', index) }
scope :for_stage, -> (index) { where(stage_idx: index) }
scope :after_stage, -> (index) { where('stage_idx > ?', index) }
scope :processables, -> { where(type: %w[Ci::Build Ci::Bridge]) }
scope :for_ids, -> (ids) { where(id: ids) }
scope :for_ref, -> (ref) { where(ref: ref) }
scope :by_name, -> (name) { where(name: name) }
......
......@@ -113,9 +113,8 @@ module ErrorTracking
when 'list_issues'
sentry_client.list_issues(**opts.symbolize_keys)
when 'issue_details'
{
issue: sentry_client.issue_details(**opts.symbolize_keys)
}
issue = sentry_client.issue_details(**opts.symbolize_keys)
{ issue: add_gitlab_issue_details(issue) }
when 'issue_latest_event'
{
latest_event: sentry_client.issue_latest_event(**opts.symbolize_keys)
......@@ -140,6 +139,20 @@ module ErrorTracking
private
def add_gitlab_issue_details(issue)
issue.gitlab_commit = match_gitlab_commit(issue.first_release_version)
issue
end
def match_gitlab_commit(release_version)
return unless release_version
commit = project.repository.commit(release_version)
commit&.id
end
def handle_exceptions
yield
rescue Sentry::Client::Error => e
......
......@@ -81,6 +81,10 @@ class Release < ApplicationRecord
evidence&.summary || {}
end
def milestone_titles
self.milestones.map {|m| m.title }.sort.join(", ")
end
private
def actual_sha
......
# frozen_string_literal: true
module Ci
class BridgePresenter < CommitStatusPresenter
class BridgePresenter < ProcessablePresenter
def detailed_status
@detailed_status ||= subject.detailed_status(user)
end
......
# frozen_string_literal: true
module Ci
class BuildPresenter < CommitStatusPresenter
class BuildPresenter < ProcessablePresenter
def erased_by_user?
# Build can be erased through API, therefore it does not have
# `erased_by` user assigned in that case.
......
# frozen_string_literal: true
module Ci
class ProcessablePresenter < CommitStatusPresenter
end
end
......@@ -8,6 +8,7 @@ module ErrorTracking
:external_url,
:first_release_last_commit,
:first_release_short_version,
:gitlab_commit,
:first_seen,
:frequency,
:gitlab_issue,
......
......@@ -11,10 +11,13 @@ module Releases
return error('params is empty', 400) if empty_params?
return error("Milestone(s) not found: #{inexistent_milestones.join(', ')}", 400) if inexistent_milestones.any?
params[:milestones] = milestones if param_for_milestone_titles_provided?
if param_for_milestone_titles_provided?
previous_milestones = release.milestones.map(&:title)
params[:milestones] = milestones
end
if release.update(params)
success(tag: existing_tag, release: release)
success(tag: existing_tag, release: release, milestones_updated: milestones_updated?(previous_milestones))
else
error(release.errors.messages || '400 Bad request', 400)
end
......@@ -29,5 +32,11 @@ module Releases
def empty_params?
params.except(:tag).empty?
end
def milestones_updated?(previous_milestones)
return false unless param_for_milestone_titles_provided?
previous_milestones.to_set != release.milestones.map(&:title)
end
end
end
......@@ -188,3 +188,4 @@
- create_evidence
- group_export
- self_monitoring_project_create
- self_monitoring_project_delete
# frozen_string_literal: true
module SelfMonitoringProjectWorker
extend ActiveSupport::Concern
included do
# This worker falls under Self-monitoring with Monitor::APM group. However,
# self-monitoring is not classified as a feature category but rather as
# Other Functionality. Metrics seems to be the closest feature_category for
# this worker.
feature_category :metrics
end
LEASE_TIMEOUT = 15.minutes.to_i
EXCLUSIVE_LEASE_KEY = 'self_monitoring_service_creation_deletion'
class_methods do
# @param job_id [String]
# Job ID that is used to construct the cache keys.
# @return [Hash]
# Returns true if the job is enqueued or in progress and false otherwise.
def in_progress?(job_id)
Gitlab::SidekiqStatus.job_status(Array.wrap(job_id)).first
end
end
private
def lease_key
EXCLUSIVE_LEASE_KEY
end
def lease_timeout
self.class::LEASE_TIMEOUT
end
end
......@@ -3,38 +3,11 @@
class SelfMonitoringProjectCreateWorker
include ApplicationWorker
include ExclusiveLeaseGuard
# This worker falls under Self-monitoring with Monitor::APM group. However,
# self-monitoring is not classified as a feature category but rather as
# Other Functionality. Metrics seems to be the closest feature_category for
# this worker.
feature_category :metrics
LEASE_TIMEOUT = 15.minutes.to_i
EXCLUSIVE_LEASE_KEY = 'self_monitoring_service_creation_deletion'
include SelfMonitoringProjectWorker
def perform
try_obtain_lease do
Gitlab::DatabaseImporters::SelfMonitoring::Project::CreateService.new.execute
end
end
# @param job_id [String]
# Job ID that is used to construct the cache keys.
# @return [Hash]
# Returns true if the job is enqueued or in progress and false otherwise.
def self.in_progress?(job_id)
Gitlab::SidekiqStatus.job_status(Array.wrap(job_id)).first
end
private
def lease_key
EXCLUSIVE_LEASE_KEY
end
def lease_timeout
LEASE_TIMEOUT
end
end
# frozen_string_literal: true
class SelfMonitoringProjectDeleteWorker
include ApplicationWorker
include ExclusiveLeaseGuard
include SelfMonitoringProjectWorker
def perform
try_obtain_lease do
Gitlab::DatabaseImporters::SelfMonitoring::Project::DeleteService.new.execute
end
end
end
---
title: Migrate the database to activate projects prometheus service integration for projects with prometheus installed on shared k8s cluster.
merge_request: 19956
author:
type: fixed
---
title: "Show tag link whenever it's a tag in chat message integration for push events and pipeline events"
merge_request: 18126
author: Mats Estensen
type: fixed
---
title: Add runner information in build web hook event
merge_request: 20709
author: Gaetan Semet
type: added
---
title: |
Add allow failure in pipeline webhook event
merge_request: 20978
author: Gaetan Semet
type: added
---
title: Add GitLab commit to error detail endpoint
merge_request: 22174
author:
type: added
---
title: Add support to export and import award emojis for issues, issue notes, MR, MR notes and snippet notes
merge_request: 22493
author:
type: fixed
---
title: Remove unused index on project_mirror_data
merge_request: 22647
author:
type: performance
......@@ -100,6 +100,7 @@
- [create_evidence, 2]
- [group_export, 1]
- [self_monitoring_project_create, 2]
- [self_monitoring_project_delete, 2]
# EE-specific queues
- [analytics, 1]
......
# frozen_string_literal: true
class AddTimestampSoftwarelicensespolicy < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
def up
add_timestamps_with_timezone(:software_license_policies, null: true)
end
def down
remove_timestamps(:software_license_policies)
end
end
# frozen_string_literal: true
class RemoveIndexProjectMirrorDataOnJid < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
remove_concurrent_index :project_mirror_data, :jid
end
def down
add_concurrent_index :project_mirror_data, :jid
end
end
# frozen_string_literal: true
class PatchPrometheusServicesForSharedClusterApplications < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
MIGRATION = 'ActivatePrometheusServicesForSharedClusterApplications'.freeze
BATCH_SIZE = 500
DELAY = 2.minutes
disable_ddl_transaction!
module Migratable
module Applications
class Prometheus < ActiveRecord::Base
self.table_name = 'clusters_applications_prometheus'
enum status: {
errored: -1,
installed: 3,
updated: 5
}
end
end
class Project < ActiveRecord::Base
self.table_name = 'projects'
include ::EachBatch
scope :with_application_on_group_clusters, -> {
joins("INNER JOIN namespaces ON namespaces.id = projects.namespace_id")
.joins("INNER JOIN cluster_groups ON cluster_groups.group_id = namespaces.id")
.joins("INNER JOIN clusters ON clusters.id = cluster_groups.cluster_id AND clusters.cluster_type = #{Cluster.cluster_types['group_type']}")
.joins("INNER JOIN clusters_applications_prometheus ON clusters_applications_prometheus.cluster_id = clusters.id
AND clusters_applications_prometheus.status IN (#{Applications::Prometheus.statuses[:installed]}, #{Applications::Prometheus.statuses[:updated]})")
}
scope :without_active_prometheus_services, -> {
joins("LEFT JOIN services ON services.project_id = projects.id AND services.type = 'PrometheusService'")
.where("services.id IS NULL OR (services.active = FALSE AND services.properties = '{}')")
}
end
class Cluster < ActiveRecord::Base
self.table_name = 'clusters'
enum cluster_type: {
instance_type: 1,
group_type: 2
}
def self.has_prometheus_application?
joins("INNER JOIN clusters_applications_prometheus ON clusters_applications_prometheus.cluster_id = clusters.id
AND clusters_applications_prometheus.status IN (#{Applications::Prometheus.statuses[:installed]}, #{Applications::Prometheus.statuses[:updated]})").exists?
end
end
end
def up
projects_without_active_prometheus_service.group('projects.id').each_batch(of: BATCH_SIZE) do |batch, index|
bg_migrations_batch = batch.select('projects.id').map { |project| [MIGRATION, project.id] }
delay = index * DELAY
BackgroundMigrationWorker.bulk_perform_in(delay.seconds, bg_migrations_batch)
end
end
def down
# no-op
end
private
def projects_without_active_prometheus_service
scope = Migratable::Project.without_active_prometheus_services
return scope if migrate_instance_cluster?
scope.with_application_on_group_clusters
end
def migrate_instance_cluster?
if instance_variable_defined?('@migrate_instance_cluster')
@migrate_instance_cluster
else
@migrate_instance_cluster = Migratable::Cluster.instance_type.has_prometheus_application?
end
end
end
......@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2020_01_08_155731) do
ActiveRecord::Schema.define(version: 2020_01_08_233040) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_trgm"
......@@ -3199,7 +3199,6 @@ ActiveRecord::Schema.define(version: 2020_01_08_155731) do
t.text "last_error"
t.datetime_with_timezone "last_update_at"
t.datetime_with_timezone "last_successful_update_at"
t.index ["jid"], name: "index_project_mirror_data_on_jid"
t.index ["last_successful_update_at"], name: "index_project_mirror_data_on_last_successful_update_at"
t.index ["last_update_at", "retry_count"], name: "index_project_mirror_data_on_last_update_at_and_retry_count"
t.index ["next_execution_timestamp", "retry_count"], name: "index_mirror_data_on_next_execution_and_retry_count"
......@@ -3824,6 +3823,8 @@ ActiveRecord::Schema.define(version: 2020_01_08_155731) do
t.integer "project_id", null: false
t.integer "software_license_id", null: false
t.integer "classification", default: 0, null: false
t.datetime_with_timezone "created_at"
t.datetime_with_timezone "updated_at"
t.index ["project_id", "software_license_id"], name: "index_software_license_policies_unique_per_project", unique: true
t.index ["software_license_id"], name: "index_software_license_policies_on_software_license_id"
end
......
......@@ -364,6 +364,7 @@ The following documentation relates to the DevOps **Secure** stage:
| [Dependency Scanning](user/application_security/dependency_scanning/index.md) **(ULTIMATE)** | Analyze your dependencies for known vulnerabilities. |
| [Dynamic Application Security Testing (DAST)](user/application_security/dast/index.md) **(ULTIMATE)** | Analyze running web applications for known vulnerabilities. |
| [Group Security Dashboard](user/application_security/security_dashboard/index.md#group-security-dashboard) **(ULTIMATE)** | View vulnerabilities in all the projects in a group and its subgroups. |
| [Instance Security Dashboard](user/application_security/security_dashboard/index.md#instance-security-dashboard) **(ULTIMATE)** | View vulnerabilities in all the projects you're interested in. |
| [License Compliance](user/application_security/license_compliance/index.md) **(ULTIMATE)** | Search your project's dependencies for their licenses. |
| [Pipeline Security Dashboard](user/application_security/security_dashboard/index.md#pipeline-security-dashboard) **(ULTIMATE)** | View the security reports for your project's pipelines. |
| [Project Security Dashboard](user/application_security/security_dashboard/index.md#project-security-dashboard) **(ULTIMATE)** | View the latest security reports for your project. |
......
......@@ -80,6 +80,9 @@ From there, you can see the following actions:
- Project was archived
- Project was unarchived
- Added/removed/updated protected branches
- Release was added to a project
- Release was updated
- Release milestone associations changed
### Instance events **(PREMIUM ONLY)**
......
......@@ -154,7 +154,7 @@ Some basic Ruby runtime metrics are available:
| `ruby_sampler_duration_seconds` | Counter | 11.1 | Time spent collecting stats |
| `ruby_process_cpu_seconds_total` | Gauge | 12.0 | Total amount of CPU time per process |
| `ruby_process_max_fds` | Gauge | 12.0 | Maximum number of open file descriptors per process |
| `ruby_process_resident_memory_bytes` | Gauge | 12.0 | Memory usage by process, measured in bytes |
| `ruby_process_resident_memory_bytes` | Gauge | 12.0 | Memory usage by process |
| `ruby_process_start_time_seconds` | Gauge | 12.0 | UNIX timestamp of process start time |
[GC.stat]: https://ruby-doc.org/core-2.6.5/GC.html#method-c-stat
......
......@@ -5711,6 +5711,11 @@ type SentryDetailedError {
"""
frequency: [SentryErrorFrequency!]!
"""
GitLab commit SHA attributed to the Error based on the release version
"""
gitlabCommit: String