summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/gitlab/ci/pipeline/chain/config/content/auto_devops.rb18
-rw-r--r--lib/gitlab/ci/pipeline/chain/config/content/legacy_auto_devops.rb18
-rw-r--r--lib/gitlab/ci/templates/Beta/Auto-DevOps.gitlab-ci.yml163
-rw-r--r--lib/gitlab/dependency_linker.rb3
-rw-r--r--lib/gitlab/dependency_linker/cargo_toml_linker.rb46
-rw-r--r--lib/gitlab/file_detector.rb1
-rw-r--r--lib/sentry/client.rb54
-rw-r--r--lib/sentry/client/issue.rb62
8 files changed, 309 insertions, 56 deletions
diff --git a/lib/gitlab/ci/pipeline/chain/config/content/auto_devops.rb b/lib/gitlab/ci/pipeline/chain/config/content/auto_devops.rb
index e9bcc67de9c..54be789988c 100644
--- a/lib/gitlab/ci/pipeline/chain/config/content/auto_devops.rb
+++ b/lib/gitlab/ci/pipeline/chain/config/content/auto_devops.rb
@@ -11,7 +11,7 @@ module Gitlab
strong_memoize(:content) do
next unless project&.auto_devops_enabled?
- template = Gitlab::Template::GitlabCiYmlTemplate.find('Auto-DevOps')
+ template = Gitlab::Template::GitlabCiYmlTemplate.find(template_name)
YAML.dump('include' => [{ 'template' => template.full_name }])
end
end
@@ -19,6 +19,22 @@ module Gitlab
def source
:auto_devops_source
end
+
+ private
+
+ def template_name
+ if beta_enabled?
+ 'Beta/Auto-DevOps'
+ else
+ 'Auto-DevOps'
+ end
+ end
+
+ def beta_enabled?
+ Feature.enabled?(:auto_devops_beta, project, default_enabled: true) &&
+ # workflow:rules are required by `Beta/Auto-DevOps.gitlab-ci.yml`
+ Feature.enabled?(:workflow_rules, project, default_enabled: true)
+ end
end
end
end
diff --git a/lib/gitlab/ci/pipeline/chain/config/content/legacy_auto_devops.rb b/lib/gitlab/ci/pipeline/chain/config/content/legacy_auto_devops.rb
index c4cef356628..b282886a56f 100644
--- a/lib/gitlab/ci/pipeline/chain/config/content/legacy_auto_devops.rb
+++ b/lib/gitlab/ci/pipeline/chain/config/content/legacy_auto_devops.rb
@@ -11,7 +11,7 @@ module Gitlab
strong_memoize(:content) do
next unless project&.auto_devops_enabled?
- template = Gitlab::Template::GitlabCiYmlTemplate.find('Auto-DevOps')
+ template = Gitlab::Template::GitlabCiYmlTemplate.find(template_name)
template.content
end
end
@@ -19,6 +19,22 @@ module Gitlab
def source
:auto_devops_source
end
+
+ private
+
+ def template_name
+ if beta_enabled?
+ 'Beta/Auto-DevOps'
+ else
+ 'Auto-DevOps'
+ end
+ end
+
+ def beta_enabled?
+ Feature.enabled?(:auto_devops_beta, project, default_enabled: true) &&
+ # workflow:rules are required by `Beta/Auto-DevOps.gitlab-ci.yml`
+ Feature.enabled?(:workflow_rules, project, default_enabled: true)
+ end
end
end
end
diff --git a/lib/gitlab/ci/templates/Beta/Auto-DevOps.gitlab-ci.yml b/lib/gitlab/ci/templates/Beta/Auto-DevOps.gitlab-ci.yml
new file mode 100644
index 00000000000..2c5035705ac
--- /dev/null
+++ b/lib/gitlab/ci/templates/Beta/Auto-DevOps.gitlab-ci.yml
@@ -0,0 +1,163 @@
+# Auto DevOps - BETA do not use
+# This CI/CD configuration provides a standard pipeline for
+# * building a Docker image (using a buildpack if necessary),
+# * storing the image in the container registry,
+# * running tests from a buildpack,
+# * running code quality analysis,
+# * creating a review app for each topic branch,
+# * and continuous deployment to production
+#
+# Test jobs may be disabled by setting environment variables:
+# * test: TEST_DISABLED
+# * code_quality: CODE_QUALITY_DISABLED
+# * license_management: LICENSE_MANAGEMENT_DISABLED
+# * performance: PERFORMANCE_DISABLED
+# * sast: SAST_DISABLED
+# * dependency_scanning: DEPENDENCY_SCANNING_DISABLED
+# * container_scanning: CONTAINER_SCANNING_DISABLED
+# * dast: DAST_DISABLED
+# * review: REVIEW_DISABLED
+# * stop_review: REVIEW_DISABLED
+#
+# In order to deploy, you must have a Kubernetes cluster configured either
+# via a project integration, or via group/project variables.
+# KUBE_INGRESS_BASE_DOMAIN must also be set on the cluster settings,
+# as a variable at the group or project level, or manually added below.
+#
+# Continuous deployment to production is enabled by default.
+# If you want to deploy to staging first, set STAGING_ENABLED environment variable.
+# If you want to enable incremental rollout, either manual or time based,
+# set INCREMENTAL_ROLLOUT_MODE environment variable to "manual" or "timed".
+# If you want to use canary deployments, set CANARY_ENABLED environment variable.
+#
+# If Auto DevOps fails to detect the proper buildpack, or if you want to
+# specify a custom buildpack, set a project variable `BUILDPACK_URL` to the
+# repository URL of the buildpack.
+# e.g. BUILDPACK_URL=https://github.com/heroku/heroku-buildpack-ruby.git#v142
+# If you need multiple buildpacks, add a file to your project called
+# `.buildpacks` that contains the URLs, one on each line, in order.
+# Note: Auto CI does not work with multiple buildpacks yet
+
+image: alpine:latest
+
+variables:
+ # KUBE_INGRESS_BASE_DOMAIN is the application deployment domain and should be set as a variable at the group or project level.
+ # KUBE_INGRESS_BASE_DOMAIN: domain.example.com
+
+ POSTGRES_USER: user
+ POSTGRES_PASSWORD: testing-password
+ POSTGRES_ENABLED: "true"
+ POSTGRES_DB: $CI_ENVIRONMENT_SLUG
+ POSTGRES_VERSION: 9.6.2
+
+ DOCKER_DRIVER: overlay2
+
+ ROLLOUT_RESOURCE_TYPE: deployment
+
+ DOCKER_TLS_CERTDIR: "" # https://gitlab.com/gitlab-org/gitlab-runner/issues/4501
+
+stages:
+ - build
+ - test
+ - deploy # dummy stage to follow the template guidelines
+ - review
+ - dast
+ - staging
+ - canary
+ - production
+ - incremental rollout 10%
+ - incremental rollout 25%
+ - incremental rollout 50%
+ - incremental rollout 100%
+ - performance
+ - cleanup
+
+workflow:
+ rules:
+ - if: '$BUILDPACK_URL || $AUTO_DEVOPS_EXPLICITLY_ENABLED == "1"'
+
+ - exists:
+ - Dockerfile
+
+ # https://github.com/heroku/heroku-buildpack-clojure
+ - exists:
+ - project.clj
+
+ # https://github.com/heroku/heroku-buildpack-go
+ - exists:
+ - go.mod
+ - Gopkg.mod
+ - Godeps/Godeps.json
+ - vendor/vendor.json
+ - glide.yaml
+ - src/**/*.go
+
+ # https://github.com/heroku/heroku-buildpack-gradle
+ - exists:
+ - gradlew
+ - build.gradle
+ - settings.gradle
+
+ # https://github.com/heroku/heroku-buildpack-java
+ - exists:
+ - pom.xml
+ - pom.atom
+ - pom.clj
+ - pom.groovy
+ - pom.rb
+ - pom.scala
+ - pom.yaml
+ - pom.yml
+
+ # https://github.com/heroku/heroku-buildpack-multi
+ - exists:
+ - .buildpacks
+
+ # https://github.com/heroku/heroku-buildpack-nodejs
+ - exists:
+ - package.json
+
+ # https://github.com/heroku/heroku-buildpack-php
+ - exists:
+ - composer.json
+ - index.php
+
+ # https://github.com/heroku/heroku-buildpack-play
+ # TODO: detect script excludes some scala files
+ - exists:
+ - '**/conf/application.conf'
+
+ # https://github.com/heroku/heroku-buildpack-python
+ # TODO: detect script checks that all of these exist, not any
+ - exists:
+ - requirements.txt
+ - setup.py
+ - Pipfile
+
+ # https://github.com/heroku/heroku-buildpack-ruby
+ - exists:
+ - Gemfile
+
+ # https://github.com/heroku/heroku-buildpack-scala
+ - exists:
+ - '*.sbt'
+ - project/*.scala
+ - .sbt/*.scala
+ - project/build.properties
+
+ # https://github.com/dokku/buildpack-nginx
+ - exists:
+ - .static
+
+include:
+ - template: Jobs/Build.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml
+ - template: Jobs/Test.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Jobs/Test.gitlab-ci.yml
+ - template: Jobs/Code-Quality.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Jobs/Code-Quality.gitlab-ci.yml
+ - template: Jobs/Deploy.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Jobs/Deploy.gitlab-ci.yml
+ - template: Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml
+ - template: Jobs/Browser-Performance-Testing.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Jobs/Browser-Performance-Testing.gitlab-ci.yml
+ - template: Security/DAST.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Security/DAST.gitlab-ci.yml
+ - template: Security/Container-Scanning.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Security/Container-Scanning.gitlab-ci.yml
+ - template: Security/Dependency-Scanning.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml
+ - template: Security/License-Management.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Security/License-Management.gitlab-ci.yml
+ - template: Security/SAST.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab-foss/blob/master/lib/gitlab/ci/templates/Security/SAST.gitlab-ci.yml
diff --git a/lib/gitlab/dependency_linker.rb b/lib/gitlab/dependency_linker.rb
index c63d9e5bb71..7af380689d5 100644
--- a/lib/gitlab/dependency_linker.rb
+++ b/lib/gitlab/dependency_linker.rb
@@ -12,7 +12,8 @@ module Gitlab
PodspecJsonLinker,
CartfileLinker,
GodepsJsonLinker,
- RequirementsTxtLinker
+ RequirementsTxtLinker,
+ CargoTomlLinker
].freeze
def self.linker(blob_name)
diff --git a/lib/gitlab/dependency_linker/cargo_toml_linker.rb b/lib/gitlab/dependency_linker/cargo_toml_linker.rb
new file mode 100644
index 00000000000..57e0a5f4699
--- /dev/null
+++ b/lib/gitlab/dependency_linker/cargo_toml_linker.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module DependencyLinker
+ class CargoTomlLinker < BaseLinker
+ self.file_type = :cargo_toml
+
+ def link
+ return highlighted_text unless toml
+
+ super
+ end
+
+ private
+
+ def link_dependencies
+ link_dependencies_at("dependencies")
+ link_dependencies_at("dev-dependencies")
+ link_dependencies_at("build-dependencies")
+ end
+
+ def link_dependencies_at(type)
+ dependencies = toml[type]
+ return unless dependencies
+
+ dependencies.each do |name, value|
+ link_toml(name, value, type) do |name|
+ "https://crates.io/crates/#{name}"
+ end
+ end
+ end
+
+ def link_toml(key, value, type, &url_proc)
+ if value.is_a? String
+ link_regex(/^(?<name>#{key})\s*=\s*"#{value}"/, &url_proc)
+ else
+ link_regex(/^\[#{type}\.(?<name>#{key})]/, &url_proc)
+ end
+ end
+
+ def toml
+ @toml ||= TomlRB.parse(plain_text) rescue nil
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/file_detector.rb b/lib/gitlab/file_detector.rb
index a386c21983d..234c834a83a 100644
--- a/lib/gitlab/file_detector.rb
+++ b/lib/gitlab/file_detector.rb
@@ -25,6 +25,7 @@ module Gitlab
route_map: '.gitlab/route-map.yml',
# Dependency files
+ cargo_toml: 'Cargo.toml',
cartfile: %r{\ACartfile[^/]*\z},
composer_json: 'composer.json',
gemfile: /\A(Gemfile|gems\.rb)\z/,
diff --git a/lib/sentry/client.rb b/lib/sentry/client.rb
index 3df688a1fda..dd589b6194d 100644
--- a/lib/sentry/client.rb
+++ b/lib/sentry/client.rb
@@ -3,6 +3,7 @@
module Sentry
class Client
include Sentry::Client::Projects
+ include Sentry::Client::Issue
Error = Class.new(StandardError)
MissingKeysError = Class.new(StandardError)
@@ -23,12 +24,6 @@ module Sentry
@token = token
end
- def issue_details(issue_id:)
- issue = get_issue(issue_id: issue_id)
-
- map_to_detailed_error(issue)
- end
-
def issue_latest_event(issue_id:)
latest_event = get_issue_latest_event(issue_id: issue_id)
@@ -107,10 +102,6 @@ module Sentry
}.compact
end
- def get_issue(issue_id:)
- http_get(issue_api_url(issue_id))[:body]
- end
-
def get_issue_latest_event(issue_id:)
http_get(issue_latest_event_api_url(issue_id))[:body]
end
@@ -145,13 +136,6 @@ module Sentry
raise Client::Error, message
end
- def issue_api_url(issue_id)
- issue_url = URI(@url)
- issue_url.path = "/api/0/issues/#{issue_id}/"
-
- issue_url
- end
-
def issue_latest_event_api_url(issue_id)
latest_event_url = URI(@url)
latest_event_url.path = "/api/0/issues/#{issue_id}/events/latest/"
@@ -212,42 +196,6 @@ module Sentry
stack_trace_entry.dig('stacktrace', 'frames')
end
- def parse_gitlab_issue(plugin_issues)
- return unless plugin_issues
-
- gitlab_plugin = plugin_issues.detect { |item| item['id'] == 'gitlab' }
- return unless gitlab_plugin
-
- gitlab_plugin.dig('issue', 'url')
- end
-
- def map_to_detailed_error(issue)
- Gitlab::ErrorTracking::DetailedError.new(
- id: issue.fetch('id'),
- first_seen: issue.fetch('firstSeen', nil),
- last_seen: issue.fetch('lastSeen', nil),
- title: issue.fetch('title', nil),
- type: issue.fetch('type', nil),
- user_count: issue.fetch('userCount', nil),
- count: issue.fetch('count', nil),
- message: issue.dig('metadata', 'value'),
- culprit: issue.fetch('culprit', nil),
- external_url: issue_url(issue.fetch('id')),
- external_base_url: project_url,
- short_id: issue.fetch('shortId', nil),
- status: issue.fetch('status', nil),
- frequency: issue.dig('stats', '24h'),
- project_id: issue.dig('project', 'id'),
- project_name: issue.dig('project', 'name'),
- project_slug: issue.dig('project', 'slug'),
- gitlab_issue: parse_gitlab_issue(issue.fetch('pluginIssues', nil)),
- first_release_last_commit: issue.dig('firstRelease', 'lastCommit'),
- last_release_last_commit: issue.dig('lastRelease', 'lastCommit'),
- first_release_short_version: issue.dig('firstRelease', 'shortVersion'),
- last_release_short_version: issue.dig('lastRelease', 'shortVersion')
- )
- end
-
def map_to_error(issue)
Gitlab::ErrorTracking::Error.new(
id: issue.fetch('id'),
diff --git a/lib/sentry/client/issue.rb b/lib/sentry/client/issue.rb
new file mode 100644
index 00000000000..08ed5392a11
--- /dev/null
+++ b/lib/sentry/client/issue.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+module Sentry
+ class Client
+ module Issue
+ def issue_details(issue_id:)
+ issue = get_issue(issue_id: issue_id)
+
+ map_to_detailed_error(issue)
+ end
+
+ private
+
+ def get_issue(issue_id:)
+ http_get(issue_api_url(issue_id))[:body]
+ end
+
+ def issue_api_url(issue_id)
+ issue_url = URI(url)
+ issue_url.path = "/api/0/issues/#{CGI.escape(issue_id.to_s)}/"
+
+ issue_url
+ end
+
+ def parse_gitlab_issue(plugin_issues)
+ return unless plugin_issues
+
+ gitlab_plugin = plugin_issues.detect { |item| item['id'] == 'gitlab' }
+ return unless gitlab_plugin
+
+ gitlab_plugin.dig('issue', 'url')
+ end
+
+ def map_to_detailed_error(issue)
+ Gitlab::ErrorTracking::DetailedError.new(
+ id: issue.fetch('id'),
+ first_seen: issue.fetch('firstSeen', nil),
+ last_seen: issue.fetch('lastSeen', nil),
+ title: issue.fetch('title', nil),
+ type: issue.fetch('type', nil),
+ user_count: issue.fetch('userCount', nil),
+ count: issue.fetch('count', nil),
+ message: issue.dig('metadata', 'value'),
+ culprit: issue.fetch('culprit', nil),
+ external_url: issue_url(issue.fetch('id')),
+ external_base_url: project_url,
+ short_id: issue.fetch('shortId', nil),
+ status: issue.fetch('status', nil),
+ frequency: issue.dig('stats', '24h'),
+ project_id: issue.dig('project', 'id'),
+ project_name: issue.dig('project', 'name'),
+ project_slug: issue.dig('project', 'slug'),
+ gitlab_issue: parse_gitlab_issue(issue.fetch('pluginIssues', nil)),
+ first_release_last_commit: issue.dig('firstRelease', 'lastCommit'),
+ last_release_last_commit: issue.dig('lastRelease', 'lastCommit'),
+ first_release_short_version: issue.dig('firstRelease', 'shortVersion'),
+ last_release_short_version: issue.dig('lastRelease', 'shortVersion')
+ )
+ end
+ end
+ end
+end