Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-01-17 06:07:23 +00:00
parent 4c872af312
commit 172e4a1274
25 changed files with 747 additions and 186 deletions

View File

@ -203,7 +203,7 @@ gem 'seed-fu', '~> 2.3.7' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'elasticsearch-model', '~> 7.2' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'elasticsearch-rails', '~> 7.2', require: 'elasticsearch/rails/instrumentation' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'elasticsearch-api', '7.13.3' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'aws-sdk-core', '~> 3.190.2' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'aws-sdk-core', '~> 3.190.3' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'aws-sdk-cloudformation', '~> 1' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'aws-sdk-s3', '~> 1.142.0' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'faraday_middleware-aws-sigv4', '~>0.3.0' # rubocop:todo Gemfile/MissingFeatureCategory

View File

@ -37,7 +37,7 @@
{"name":"aws-eventstream","version":"1.3.0","platform":"ruby","checksum":"f1434cc03ab2248756eb02cfa45e900e59a061d7fbdc4a9fd82a5dd23d796d3f"},
{"name":"aws-partitions","version":"1.877.0","platform":"ruby","checksum":"9552ed7bbd3700ed1eeb0121c160ceaf64fa5dbaff5a1ff5fe6fd8481ecd9cfd"},
{"name":"aws-sdk-cloudformation","version":"1.41.0","platform":"ruby","checksum":"31e47539719734413671edf9b1a31f8673fbf9688549f50c41affabbcb1c6b26"},
{"name":"aws-sdk-core","version":"3.190.2","platform":"ruby","checksum":"5d97bd8ebfff08b51c38e37dace3d919fa7c708696da01b1d343f2bbaf472e7d"},
{"name":"aws-sdk-core","version":"3.190.3","platform":"ruby","checksum":"f9b66775d79112bcffcd031aa2c97aac2b1819fa2d917b1c72557635260f3d41"},
{"name":"aws-sdk-kms","version":"1.76.0","platform":"ruby","checksum":"e7f75013cba9ba357144f66bbc600631c192e2cda9dd572794be239654e2cf49"},
{"name":"aws-sdk-s3","version":"1.142.0","platform":"ruby","checksum":"79cd888eca66fd2ef3ae8b74d76173a2eccbeff6a1bba62a60b7c7dadc8dd7e9"},
{"name":"aws-sigv4","version":"1.8.0","platform":"ruby","checksum":"84dd99768b91b93b63d1d8e53ee837cfd06ab402812772a7899a78f9f9117cbc"},

View File

@ -301,7 +301,7 @@ GEM
aws-sdk-cloudformation (1.41.0)
aws-sdk-core (~> 3, >= 3.99.0)
aws-sigv4 (~> 1.1)
aws-sdk-core (3.190.2)
aws-sdk-core (3.190.3)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.8)
@ -1815,7 +1815,7 @@ DEPENDENCIES
autoprefixer-rails (= 10.2.5.1)
awesome_print
aws-sdk-cloudformation (~> 1)
aws-sdk-core (~> 3.190.2)
aws-sdk-core (~> 3.190.3)
aws-sdk-s3 (~> 1.142.0)
axe-core-rspec (~> 4.8.0)
babosa (~> 2.0)

View File

@ -199,6 +199,10 @@ module Types
field :stuck, GraphQL::Types::Boolean, method: :stuck?, null: false, description: "If the pipeline is stuck."
field :yaml_errors, GraphQL::Types::Boolean, method: :yaml_errors?, null: false, description: "If the pipeline has YAML errors."
field :trigger, GraphQL::Types::Boolean, method: :trigger?, null: false, description: "If the pipeline was created by a Trigger request."
def commit
BatchLoader::GraphQL.wrap(object.commit)
end

View File

@ -0,0 +1,6 @@
- return unless project.import_in_progress?
- content_for :page_level_alert do
= render Pajamas::AlertComponent.new(variant: :warning, dismissible: false, title: _('Import in progress'), alert_options: { class: 'gl-mb-3' }) do |c|
- c.with_body do
= s_('Import|This project is being imported. Do not make any changes to the project until the import is complete.')

View File

@ -1,8 +0,0 @@
---
name: bitbucket_server_importer_exponential_backoff
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/137974
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/432974
milestone: '16.7'
type: development
group: group::import and integrate
default_enabled: false

View File

@ -79,8 +79,17 @@ repl_backlog_histlen:0
## High CPU usage on Redis instance
High CPU usage on Redis instance can be cause by Sidekiq `BRPOP` calls. The `BRPOP` command is expensive and increases CPU usage on Redis.
Increase the [`SIDEKIQ_SEMI_RELIABLE_FETCH_TIMEOUT` environment variable](../environment_variables.md) to improve CPU usage on Redis.
By default, GitLab uses over 600 Sidekiq queues, each stored as a Redis list. Each Sidekiq thread issues a `BRPOP` command with all the queues listed in a long string.
Redis CPU utilization grows as the number of queues and the rate of `BRPOP` calls increases. If your GitLab instance has many Sidekiq processes, this can cause Redis
CPU utilization to approach 100%. High CPU utilization degrades GitLab performance significantly.
To reduce CPU usage on Redis caused by Sidekiq you can both:
- Use [routing rules](../sidekiq/processing_specific_job_classes.md#routing-rules) to reduce the number of Sidekiq queues.
- If you are using GitLab 16.6 and earlier, increase the [`SIDEKIQ_SEMI_RELIABLE_FETCH_TIMEOUT` environment variable](../environment_variables.md) to improve CPU usage on Redis.
On GitLab 16.7 and later, the [default value is 5](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/139583), which should be sufficient.
The `SIDEKIQ_SEMI_RELIABLE_FETCH_TIMEOUT` option reduces the overhead that tearing down and connecting causes, but increase the shutdown delay of Sidekiq.
## Troubleshooting Sentinel

View File

@ -24052,6 +24052,7 @@ Returns [`UserMergeRequestInteraction`](#usermergerequestinteraction).
| <a id="pipelinestuck"></a>`stuck` | [`Boolean!`](#boolean) | If the pipeline is stuck. |
| <a id="pipelinetestreportsummary"></a>`testReportSummary` | [`TestReportSummary!`](#testreportsummary) | Summary of the test report generated by the pipeline. |
| <a id="pipelinetotaljobs"></a>`totalJobs` | [`Int!`](#int) | The total number of jobs in the pipeline. |
| <a id="pipelinetrigger"></a>`trigger` | [`Boolean!`](#boolean) | If the pipeline was created by a Trigger request. |
| <a id="pipelinetriggeredbypath"></a>`triggeredByPath` | [`String`](#string) | The path that triggered this pipeline. |
| <a id="pipelineupdatedat"></a>`updatedAt` | [`Time!`](#time) | Timestamp of the pipeline's last activity. |
| <a id="pipelineupstream"></a>`upstream` | [`Pipeline`](#pipeline) | Pipeline that triggered the pipeline. |
@ -24060,6 +24061,7 @@ Returns [`UserMergeRequestInteraction`](#usermergerequestinteraction).
| <a id="pipelineusesneeds"></a>`usesNeeds` | [`Boolean`](#boolean) | Indicates if the pipeline has jobs with `needs` dependencies. |
| <a id="pipelinewarningmessages"></a>`warningMessages` | [`[PipelineMessage!]`](#pipelinemessage) | Pipeline warning messages. |
| <a id="pipelinewarnings"></a>`warnings` | [`Boolean!`](#boolean) | Indicates if a pipeline has warnings. |
| <a id="pipelineyamlerrors"></a>`yamlErrors` | [`Boolean!`](#boolean) | If the pipeline has YAML errors. |
#### Fields with arguments

View File

@ -65,6 +65,11 @@ For every issue, a job for the `Gitlab::BitbucketImport::ImportIssueNotesWorker`
This worker completes the import process by performing some housekeeping
such as marking the import as completed.
## Backoff and retry
In order to handle rate limiting, requests are wrapped with `Bitbucket::ExponentialBackoff`.
This wrapper catches rate limit errors and retries after a delay up to three times.
## Set up Bitbucket authentication on GDK
To set up Bitbucket authentication on GDK:

View File

@ -82,3 +82,8 @@ same email does not exist on GitLab, this can lead to incorrect users being tagg
To get around this, we build a cache containing all users who have access to the Bitbucket
project and then convert mentions in pull request descriptions and notes.
## Backoff and retry
In order to handle rate limiting, requests are wrapped with `BitbucketServer::RetryWithDelay`.
This wrapper checks if the response is rate limited and retries once after the delay specified in the response headers.

View File

@ -18,7 +18,7 @@ GitLab is creating AI-assisted features across our DevSecOps platform. These fea
| Assists with quickly getting everyone up to speed on lengthy conversations to help ensure you are all on the same page. | [Discussion summary](#summarize-issue-discussions-with-discussion-summary) | **(ULTIMATE SAAS EXPERIMENT)** |
| Generates issue descriptions. | [Issue description generation](#summarize-an-issue-with-issue-description-generation) | **(ULTIMATE SAAS EXPERIMENT)** |
| Helps you write code more efficiently by viewing code suggestions as you type. <br><br><i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=hCAyCTacdAQ) | [Code Suggestions](project/repository/code_suggestions/index.md) | For SaaS: **(FREE)**<br><br> For self-managed: **(PREMIUM)** |
| Automates repetitive tasks and helps catch bugs early. | [Test generation](gitlab_duo_chat.md#write-tests-in-the-ide) | **(ULTIMATE SAAS EXPERIMENT)** |
| Automates repetitive tasks and helps catch bugs early. | [Test generation](gitlab_duo_chat.md#write-tests-in-the-ide) | **(ULTIMATE BETA)** |
| Generates a description for the merge request based on the contents of the template. | [Merge request template population](project/merge_requests/ai_in_merge_requests.md#fill-in-merge-request-templates) | **(ULTIMATE SAAS EXPERIMENT)** |
| Assists in creating faster and higher-quality reviews by automatically suggesting reviewers for your merge request. <br><br><i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=ivwZQgh4Rxw) | [Suggested Reviewers](project/merge_requests/reviews/index.md#gitlab-duo-suggested-reviewers) | **(ULTIMATE SAAS)** |
| Efficiently communicates the impact of your merge request changes. | [Merge request summary](project/merge_requests/ai_in_merge_requests.md#summarize-merge-request-changes) | **(ULTIMATE SAAS EXPERIMENT)** |
@ -195,7 +195,7 @@ For details about this Beta feature, see [GitLab Duo Chat](gitlab_duo_chat.md).
| [Discussion summary](#summarize-issue-discussions-with-discussion-summary) | Vertex AI Codey [`text-bison`](https://cloud.google.com/vertex-ai/docs/generative-ai/model-reference/text) |
| [Issue description generation](#summarize-an-issue-with-issue-description-generation) | Anthropic [`Claude-2`](https://docs.anthropic.com/claude/reference/selecting-a-model) |
| [Code Suggestions](project/repository/code_suggestions/index.md) | For Code Completion: Vertex AI Codey [`code-gecko`](https://cloud.google.com/vertex-ai/docs/generative-ai/model-reference/code-completion) For Code Generation: Anthropic [`Claude-2`](https://docs.anthropic.com/claude/reference/selecting-a-model) |
| [Test generation](gitlab_duo_chat.md#write-tests-in-the-ide) | Vertex AI Codey [`text-bison`](https://cloud.google.com/vertex-ai/docs/generative-ai/model-reference/text) |
| [Test generation](gitlab_duo_chat.md#write-tests-in-the-ide) | Anthropic [`Claude-2`](https://docs.anthropic.com/claude/reference/selecting-a-model) |
| [Merge request template population](project/merge_requests/ai_in_merge_requests.md#fill-in-merge-request-templates) | Vertex AI Codey [`text-bison`](https://cloud.google.com/vertex-ai/docs/generative-ai/model-reference/text) |
| [Suggested Reviewers](project/merge_requests/reviews/index.md#gitlab-duo-suggested-reviewers) | GitLab creates a machine learning model for each project, which is used to generate reviewers [View the issue](https://gitlab.com/gitlab-org/modelops/applied-ml/applied-ml-updates/-/issues/10) |
| [Merge request summary](project/merge_requests/ai_in_merge_requests.md#summarize-merge-request-changes) | Vertex AI Codey [`text-bison`](https://cloud.google.com/vertex-ai/docs/generative-ai/model-reference/text) |

View File

@ -32,13 +32,9 @@ module BitbucketServer
end
def get(path, extra_query = {})
response = if Feature.enabled?(:bitbucket_server_importer_exponential_backoff)
retry_with_delay do
Gitlab::HTTP.get(build_url(path), basic_auth: auth, headers: accept_headers, query: extra_query)
end
else
Gitlab::HTTP.get(build_url(path), basic_auth: auth, headers: accept_headers, query: extra_query)
end
response = retry_with_delay do
Gitlab::HTTP.get(build_url(path), basic_auth: auth, headers: accept_headers, query: extra_query)
end
check_errors!(response)
@ -48,13 +44,9 @@ module BitbucketServer
end
def post(path, body)
response = if Feature.enabled?(:bitbucket_server_importer_exponential_backoff)
retry_with_delay do
Gitlab::HTTP.post(build_url(path), basic_auth: auth, headers: post_headers, body: body)
end
else
Gitlab::HTTP.post(build_url(path), basic_auth: auth, headers: post_headers, body: body)
end
response = retry_with_delay do
Gitlab::HTTP.post(build_url(path), basic_auth: auth, headers: post_headers, body: body)
end
check_errors!(response)
@ -70,13 +62,9 @@ module BitbucketServer
def delete(resource, path, body)
url = delete_url(resource, path)
response = if Feature.enabled?(:bitbucket_server_importer_exponential_backoff)
retry_with_delay do
Gitlab::HTTP.delete(url, basic_auth: auth, headers: post_headers, body: body)
end
else
Gitlab::HTTP.delete(url, basic_auth: auth, headers: post_headers, body: body)
end
response = retry_with_delay do
Gitlab::HTTP.delete(url, basic_auth: auth, headers: post_headers, body: body)
end
check_errors!(response)

View File

@ -0,0 +1,59 @@
# frozen_string_literal: true
module Gitlab
module Ci
module Parsers
module Sbom
class Component
include Gitlab::Utils::StrongMemoize
TRIVY_SOURCE_PACKAGE_FIELD = 'SrcName'
def initialize(data)
@data = data
end
def parse
::Gitlab::Ci::Reports::Sbom::Component.new(
type: data['type'],
name: data['name'],
purl: purl,
version: data['version'],
properties: properties,
source_package_name: source_package_name
)
end
private
attr_reader :data
def purl
return unless data['purl']
::Sbom::PackageUrl.parse(data['purl'])
end
strong_memoize_attr :purl
def properties
CyclonedxProperties.parse_trivy_source(data['properties'])
end
strong_memoize_attr :properties
def source_package_name
return unless container_scanning_component?
properties&.data&.dig(TRIVY_SOURCE_PACKAGE_FIELD) || data['name']
end
def container_scanning_component?
return false unless data['purl']
Enums::Sbom.container_scanning_purl_type?(purl.type)
end
strong_memoize_attr :container_scanning_component?
end
end
end
end
end

View File

@ -58,15 +58,7 @@ module Gitlab
def parse_components
data['components']&.each_with_index do |component_data, index|
properties = component_data['properties']
component = ::Gitlab::Ci::Reports::Sbom::Component.new(
type: component_data['type'],
name: component_data['name'],
purl: component_data['purl'],
version: component_data['version']
)
component.properties = CyclonedxProperties.parse_trivy_source(properties) if properties
component = Component.new(component_data).parse
report.add_component(component) if component.ingestible?
rescue ::Sbom::PackageUrl::InvalidPackageUrl
report.add_error("/components/#{index}/purl is invalid")

View File

@ -8,14 +8,15 @@ module Gitlab
include Gitlab::Utils::StrongMemoize
attr_reader :component_type, :version, :path
attr_accessor :properties
attr_accessor :properties, :purl, :source_package_name
def initialize(type:, name:, purl:, version:, properties: nil)
def initialize(type:, name:, purl:, version:, properties: nil, source_package_name: nil)
@component_type = type
@name = name
@raw_purl = purl
@purl = purl
@version = version
@properties = properties
@source_package_name = source_package_name
end
def <=>(other)
@ -26,13 +27,6 @@ module Gitlab
supported_component_type? && supported_purl_type?
end
def purl
return unless @raw_purl
::Sbom::PackageUrl.parse(@raw_purl)
end
strong_memoize_attr :purl
def purl_type
purl.type
end

View File

@ -10,6 +10,7 @@ FactoryBot.define do
transient do
purl_type { 'npm' }
namespace { nil }
source_package_name { nil }
end
purl do
@ -18,7 +19,7 @@ FactoryBot.define do
name: name,
namespace: namespace,
version: version
).to_s
)
end
skip_create
@ -28,7 +29,8 @@ FactoryBot.define do
type: type,
name: name,
purl: purl,
version: version
version: version,
source_package_name: source_package_name
)
end
end

View File

@ -16,7 +16,7 @@ RSpec.describe Types::Ci::PipelineType do
upstream path project active user_permissions warnings commit commit_path uses_needs
test_report_summary test_suite ref ref_path warning_messages merge_request_event_type
name total_jobs triggered_by_path child source stuck
latest merge_request ref_text failure_reason
latest merge_request ref_text failure_reason yaml_errors trigger
]
if Gitlab.ee?

View File

@ -22,31 +22,27 @@ RSpec.describe BitbucketServer::Connection, feature_category: :importers do
subject.get(url)
end
shared_examples 'handles get requests' do
it 'returns JSON body' do
expect(subject.get(url, { something: 1 })).to eq(payload)
end
it 'throws an exception if the response is not 200' do
WebMock.stub_request(:get, url).with(headers: { 'Accept' => 'application/json' }).to_return(body: payload.to_json, status: 500, headers: headers)
expect { subject.get(url) }.to raise_error(described_class::ConnectionError)
end
it 'throws an exception if the response is not JSON' do
WebMock.stub_request(:get, url).with(headers: { 'Accept' => 'application/json' }).to_return(body: 'bad data', status: 200, headers: headers)
expect { subject.get(url) }.to raise_error(described_class::ConnectionError)
end
it 'throws an exception upon a network error' do
WebMock.stub_request(:get, url).with(headers: { 'Accept' => 'application/json' }).to_raise(OpenSSL::SSL::SSLError)
expect { subject.get(url) }.to raise_error(described_class::ConnectionError)
end
it 'returns JSON body' do
expect(subject.get(url, { something: 1 })).to eq(payload)
end
it_behaves_like 'handles get requests'
it 'throws an exception if the response is not 200' do
WebMock.stub_request(:get, url).with(headers: { 'Accept' => 'application/json' }).to_return(body: payload.to_json, status: 500, headers: headers)
expect { subject.get(url) }.to raise_error(described_class::ConnectionError)
end
it 'throws an exception if the response is not JSON' do
WebMock.stub_request(:get, url).with(headers: { 'Accept' => 'application/json' }).to_return(body: 'bad data', status: 200, headers: headers)
expect { subject.get(url) }.to raise_error(described_class::ConnectionError)
end
it 'throws an exception upon a network error' do
WebMock.stub_request(:get, url).with(headers: { 'Accept' => 'application/json' }).to_raise(OpenSSL::SSL::SSLError)
expect { subject.get(url) }.to raise_error(described_class::ConnectionError)
end
context 'when the response is a 429 rate limit reached error' do
let(:response) do
@ -65,14 +61,6 @@ RSpec.describe BitbucketServer::Connection, feature_category: :importers do
expect { subject.get(url) }.to raise_error(BitbucketServer::Connection::ConnectionError)
end
end
context 'when the bitbucket_server_importer_exponential_backoff feature flag is disabled' do
before do
stub_feature_flags(bitbucket_server_importer_exponential_backoff: false)
end
it_behaves_like 'handles get requests'
end
end
describe '#post' do
@ -88,38 +76,26 @@ RSpec.describe BitbucketServer::Connection, feature_category: :importers do
subject.post(url, payload)
end
shared_examples 'handles post requests' do
it 'returns JSON body' do
expect(subject.post(url, payload)).to eq(payload)
end
it 'throws an exception if the response is not 200' do
WebMock.stub_request(:post, url).with(headers: headers).to_return(body: payload.to_json, status: 500, headers: headers)
expect { subject.post(url, payload) }.to raise_error(described_class::ConnectionError)
end
it 'throws an exception upon a network error' do
WebMock.stub_request(:post, url).with(headers: { 'Accept' => 'application/json' }).to_raise(OpenSSL::SSL::SSLError)
expect { subject.post(url, payload) }.to raise_error(described_class::ConnectionError)
end
it 'throws an exception if the URI is invalid' do
stub_request(:post, url).with(headers: { 'Accept' => 'application/json' }).to_raise(URI::InvalidURIError)
expect { subject.post(url, payload) }.to raise_error(described_class::ConnectionError)
end
it 'returns JSON body' do
expect(subject.post(url, payload)).to eq(payload)
end
it_behaves_like 'handles post requests'
it 'throws an exception if the response is not 200' do
WebMock.stub_request(:post, url).with(headers: headers).to_return(body: payload.to_json, status: 500, headers: headers)
context 'when the bitbucket_server_importer_exponential_backoff feature flag is disabled' do
before do
stub_feature_flags(bitbucket_server_importer_exponential_backoff: false)
end
expect { subject.post(url, payload) }.to raise_error(described_class::ConnectionError)
end
it_behaves_like 'handles post requests'
it 'throws an exception upon a network error' do
WebMock.stub_request(:post, url).with(headers: { 'Accept' => 'application/json' }).to_raise(OpenSSL::SSL::SSLError)
expect { subject.post(url, payload) }.to raise_error(described_class::ConnectionError)
end
it 'throws an exception if the URI is invalid' do
stub_request(:post, url).with(headers: { 'Accept' => 'application/json' }).to_raise(URI::InvalidURIError)
expect { subject.post(url, payload) }.to raise_error(described_class::ConnectionError)
end
end
@ -141,32 +117,20 @@ RSpec.describe BitbucketServer::Connection, feature_category: :importers do
subject.delete(:branches, branch_path, payload)
end
shared_examples 'handles delete requests' do
it 'returns JSON body' do
expect(subject.delete(:branches, branch_path, payload)).to eq(payload)
end
it 'throws an exception if the response is not 200' do
WebMock.stub_request(:delete, branch_url).with(headers: headers).to_return(body: payload.to_json, status: 500, headers: headers)
expect { subject.delete(:branches, branch_path, payload) }.to raise_error(described_class::ConnectionError)
end
it 'throws an exception upon a network error' do
WebMock.stub_request(:delete, branch_url).with(headers: headers).to_raise(OpenSSL::SSL::SSLError)
expect { subject.delete(:branches, branch_path, payload) }.to raise_error(described_class::ConnectionError)
end
it 'returns JSON body' do
expect(subject.delete(:branches, branch_path, payload)).to eq(payload)
end
it_behaves_like 'handles delete requests'
it 'throws an exception if the response is not 200' do
WebMock.stub_request(:delete, branch_url).with(headers: headers).to_return(body: payload.to_json, status: 500, headers: headers)
context 'with the bitbucket_server_importer_exponential_backoff feature flag disabled' do
before do
stub_feature_flags(bitbucket_server_importer_exponential_backoff: false)
end
expect { subject.delete(:branches, branch_path, payload) }.to raise_error(described_class::ConnectionError)
end
it_behaves_like 'handles delete requests'
it 'throws an exception upon a network error' do
WebMock.stub_request(:delete, branch_url).with(headers: headers).to_raise(OpenSSL::SSL::SSLError)
expect { subject.delete(:branches, branch_path, payload) }.to raise_error(described_class::ConnectionError)
end
end
end

View File

@ -0,0 +1,96 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Ci::Parsers::Sbom::Component, feature_category: :dependency_management do
describe "#parse" do
subject(:component) { described_class.new(data).parse }
context "with dependency scanning component" do
let(:data) do
{
"name" => "activesupport",
"version" => "5.1.4",
"purl" => "pkg:gem/activesupport@5.1.4",
"type" => "library",
"bom-ref" => "pkg:gem/activesupport@5.1.4"
}
end
it "sets the expected values" do
is_expected.to be_kind_of(::Gitlab::Ci::Reports::Sbom::Component)
expect(component.component_type).to eq("library")
expect(component.name).to eq("activesupport")
expect(component.version).to eq("5.1.4")
expect(component.purl).to be_kind_of(::Sbom::PackageUrl)
expect(component.purl.name).to eq("activesupport")
expect(component.properties).to be_nil
expect(component.source_package_name).to be_nil
end
end
context "with container scanning component" do
let(:property_name) { 'aquasecurity:trivy:PkgType' }
let(:property_value) { 'alpine' }
let(:purl) { "pkg:apk/alpine/alpine-baselayout-data@3.4.3-r1?arch=x86_64&distro=3.18.4" }
let(:data) do
{
"name" => "alpine-baselayout-data",
"version" => "3.4.3-r1",
"purl" => purl,
"type" => "library",
"bom-ref" => purl,
"properties" => [
{
"name" => property_name,
"value" => property_value
}
]
}
end
context "with an aquasecurity:trivy:SrcName property" do
let(:property_name) { "aquasecurity:trivy:SrcName" }
let(:property_value) { "alpine-baselayout" }
it "sets properties field with parsed data" do
property_data = component.properties.data
expect(property_data).to match({ "SrcName" => "alpine-baselayout" })
end
it "sets the source_package_name from the aquasecurity:trivy:SrcName property" do
expect(component.source_package_name).to eq(property_value)
end
end
context "without an aquasecurity:trivy:SrcName property" do
it "sets properties field with parsed data" do
property_data = component.properties.data
expect(property_data).to match({ "PkgType" => "alpine" })
end
it "sets the source_package_name from the component name" do
expect(component.source_package_name).to eq("alpine-baselayout-data")
end
end
context "without properties" do
it "sets the source_package_name from the component name" do
data.delete('properties')
expect(component.source_package_name).to eq("alpine-baselayout-data")
end
end
context "with corrupted purl" do
let(:purl) { "unknown:apk/alpine/alpine-baselayout-data@3.4.3-r1?arch=x86_64&distro=3.18.4" }
it "raises an error" do
expect { component }.to raise_error(::Sbom::PackageUrl::InvalidPackageUrl)
end
end
end
end
end

View File

@ -8,7 +8,7 @@ RSpec.describe Gitlab::Ci::Parsers::Sbom::Cyclonedx, feature_category: :dependen
let(:raw_report_data) { report_data.to_json }
let(:report_valid?) { true }
let(:validator_errors) { [] }
let(:properties_parser) { class_double('Gitlab::Ci::Parsers::Sbom::CyclonedxProperties') }
let(:properties_parser) { Gitlab::Ci::Parsers::Sbom::CyclonedxProperties }
let(:uuid) { 'c9d550a3-feb8-483b-a901-5aa892d039f9' }
let(:base_report_data) do
@ -28,8 +28,6 @@ RSpec.describe Gitlab::Ci::Parsers::Sbom::Cyclonedx, feature_category: :dependen
allow(validator).to receive(:errors).and_return(validator_errors)
end
allow(properties_parser).to receive(:parse_source)
stub_const('Gitlab::Ci::Parsers::Sbom::CyclonedxProperties', properties_parser)
allow(SecureRandom).to receive(:uuid).and_return(uuid)
end
@ -65,8 +63,9 @@ RSpec.describe Gitlab::Ci::Parsers::Sbom::Cyclonedx, feature_category: :dependen
end
end
context 'when report has components' do
context 'when report has dependency_scanning components' do
let(:report_data) { base_report_data.merge({ 'components' => components }) }
let(:components) do
[
{
@ -128,8 +127,8 @@ RSpec.describe Gitlab::Ci::Parsers::Sbom::Cyclonedx, feature_category: :dependen
context 'when component is trivy type' do
let(:parsed_properties) do
{
'PkgID' => 'adduser@3.134',
'PkgType' => 'debian'
'PkgID' => 'activesupport@5.1.4',
'PkgType' => 'gem'
}
end
@ -144,28 +143,25 @@ RSpec.describe Gitlab::Ci::Parsers::Sbom::Cyclonedx, feature_category: :dependen
"properties" => [
{
"name" => "aquasecurity:trivy:PkgID",
"value" => "apt@2.6.1"
"value" => "activesupport@5.1.4"
},
{
"name" => "aquasecurity:trivy:PkgType",
"value" => "debian"
"value" => "gem"
}
]
}
]
end
before do
allow(properties_parser).to receive(:parse_trivy_source).and_return(parsed_properties)
stub_const('Gitlab::Ci::Parsers::Sbom::CyclonedxProperties', properties_parser)
end
it 'adds each component, ignoring unused attributes' do
expect(report).to receive(:add_component)
.with(
an_object_having_attributes(
component_type: "library",
properties: parsed_properties,
properties: an_object_having_attributes(
data: parsed_properties
),
purl: an_object_having_attributes(
type: "gem"
)
@ -195,6 +191,74 @@ RSpec.describe Gitlab::Ci::Parsers::Sbom::Cyclonedx, feature_category: :dependen
end
end
context 'when report has container_scanning components' do
let(:report_data) { base_report_data.merge({ 'components' => components }) }
let(:parsed_properties) do
{
'SrcName' => 'alpine-baselayout'
}
end
let(:components) do
[
{
"name" => "alpine",
"version" => "3.4.3-r1",
"purl" => "pkg:apk/alpine/alpine@3.4.3-r1?arch=x86_64&distro=3.18.4",
"type" => "library",
"bom-ref" => "pkg:apk/alpine/alpine@3.4.3-r1?arch=x86_64&distro=3.18.4"
},
{
"name" => "alpine-baselayout-data",
"version" => "3.4.3-r1",
"purl" => "pkg:apk/alpine/alpine-baselayout-data@3.4.3-r1?arch=x86_64&distro=3.18.4",
"type" => "library",
"bom-ref" => "pkg:apk/alpine/alpine-baselayout-data@3.4.3-r1?arch=x86_64&distro=3.18.4",
"properties" => [
{
"name" => "aquasecurity:trivy:SrcName",
"value" => "alpine-baselayout"
}
]
}
]
end
before do
allow(report).to receive(:add_component)
end
it 'adds each component, ignoring unused attributes' do
expect(report).to receive(:add_component)
.with(
an_object_having_attributes(
name: "alpine/alpine",
version: "3.4.3-r1",
component_type: "library",
purl: an_object_having_attributes(type: "apk"),
properties: nil,
source_package_name: 'alpine'
)
)
expect(report).to receive(:add_component)
.with(
an_object_having_attributes(
name: "alpine/alpine-baselayout-data",
version: "3.4.3-r1",
component_type: "library",
purl: an_object_having_attributes(type: "apk"),
properties: an_object_having_attributes(
data: parsed_properties
),
source_package_name: 'alpine-baselayout'
)
)
parse!
end
end
context 'when report has metadata tools, author and properties' do
let(:report_data) { base_report_data.merge(metadata) }

View File

@ -6,15 +6,17 @@ RSpec.describe Gitlab::Ci::Reports::Sbom::Component, feature_category: :dependen
let(:component_type) { 'library' }
let(:name) { 'component-name' }
let(:purl_type) { 'npm' }
let(:purl) { Sbom::PackageUrl.new(type: purl_type, name: name, version: version).to_s }
let(:purl) { Sbom::PackageUrl.new(type: purl_type, name: name, version: version) }
let(:version) { 'v0.0.1' }
let(:source_package_name) { 'source-component' }
subject(:component) do
described_class.new(
type: component_type,
name: name,
purl: purl,
version: version
version: version,
source_package_name: source_package_name
)
end
@ -23,7 +25,8 @@ RSpec.describe Gitlab::Ci::Reports::Sbom::Component, feature_category: :dependen
component_type: component_type,
name: name,
purl: an_object_having_attributes(type: purl_type),
version: version
version: version,
source_package_name: source_package_name
)
end
@ -34,18 +37,10 @@ RSpec.describe Gitlab::Ci::Reports::Sbom::Component, feature_category: :dependen
context 'with namespace' do
let(:purl) do
'pkg:maven/org.NameSpace/Name@v0.0.1'
Sbom::PackageUrl.new(type: 'maven', namespace: 'org.NameSpace', name: 'Name', version: 'v0.0.1')
end
it { is_expected.to eq('org.NameSpace/Name') }
context 'when needing normalization' do
let(:purl) do
'pkg:pypi/org.NameSpace/Name@v0.0.1'
end
it { is_expected.to eq('org.namespace/name') }
end
end
end
@ -63,14 +58,18 @@ RSpec.describe Gitlab::Ci::Reports::Sbom::Component, feature_category: :dependen
describe '#<=>' do
where do
purl_a = Sbom::PackageUrl.new(type: 'npm', name: 'component-a', version: '1.0.0')
purl_b = Sbom::PackageUrl.new(type: 'npm', name: 'component-b', version: '1.0.0')
purl_composer = Sbom::PackageUrl.new(type: 'composer', name: 'component-a', version: '1.0.0')
{
'equal' => {
a_name: 'component-a',
b_name: 'component-a',
a_type: 'library',
b_type: 'library',
a_purl: 'pkg:npm/component-a@1.0.0',
b_purl: 'pkg:npm/component-a@1.0.0',
a_purl: purl_a,
b_purl: purl_a,
a_version: '1.0.0',
b_version: '1.0.0',
expected: 0
@ -80,8 +79,8 @@ RSpec.describe Gitlab::Ci::Reports::Sbom::Component, feature_category: :dependen
b_name: 'component-b',
a_type: 'library',
b_type: 'library',
a_purl: 'pkg:npm/component-a@1.0.0',
b_purl: 'pkg:npm/component-b@1.0.0',
a_purl: purl_a,
b_purl: purl_b,
a_version: '1.0.0',
b_version: '1.0.0',
expected: -1
@ -91,8 +90,8 @@ RSpec.describe Gitlab::Ci::Reports::Sbom::Component, feature_category: :dependen
b_name: 'component-a',
a_type: 'library',
b_type: 'library',
a_purl: 'pkg:npm/component-b@1.0.0',
b_purl: 'pkg:npm/component-a@1.0.0',
a_purl: purl_b,
b_purl: purl_a,
a_version: '1.0.0',
b_version: '1.0.0',
expected: 1
@ -102,8 +101,8 @@ RSpec.describe Gitlab::Ci::Reports::Sbom::Component, feature_category: :dependen
b_name: 'component-a',
a_type: 'library',
b_type: 'library',
a_purl: 'pkg:composer/component-a@1.0.0',
b_purl: 'pkg:npm/component-a@1.0.0',
a_purl: purl_composer,
b_purl: purl_a,
a_version: '1.0.0',
b_version: '1.0.0',
expected: -1
@ -113,8 +112,8 @@ RSpec.describe Gitlab::Ci::Reports::Sbom::Component, feature_category: :dependen
b_name: 'component-a',
a_type: 'library',
b_type: 'library',
a_purl: 'pkg:npm/component-a@1.0.0',
b_purl: 'pkg:composer/component-a@1.0.0',
a_purl: purl_a,
b_purl: purl_composer,
a_version: '1.0.0',
b_version: '1.0.0',
expected: 1
@ -125,7 +124,7 @@ RSpec.describe Gitlab::Ci::Reports::Sbom::Component, feature_category: :dependen
a_type: 'library',
b_type: 'library',
a_purl: nil,
b_purl: 'pkg:npm/component-a@1.0.0',
b_purl: purl_a,
a_version: '1.0.0',
b_version: '1.0.0',
expected: -1
@ -135,8 +134,8 @@ RSpec.describe Gitlab::Ci::Reports::Sbom::Component, feature_category: :dependen
b_name: 'component-a',
a_type: 'library',
b_type: 'library',
a_purl: 'pkg:npm/component-a@1.0.0',
b_purl: 'pkg:npm/component-a@1.0.0',
a_purl: purl_a,
b_purl: purl_a,
a_version: '1.0.0',
b_version: '2.0.0',
expected: -1
@ -146,8 +145,8 @@ RSpec.describe Gitlab::Ci::Reports::Sbom::Component, feature_category: :dependen
b_name: 'component-a',
a_type: 'library',
b_type: 'library',
a_purl: 'pkg:npm/component-a@1.0.0',
b_purl: 'pkg:npm/component-a@1.0.0',
a_purl: purl_a,
b_purl: purl_a,
a_version: '2.0.0',
b_version: '1.0.0',
expected: 1
@ -157,8 +156,8 @@ RSpec.describe Gitlab::Ci::Reports::Sbom::Component, feature_category: :dependen
b_name: 'component-a',
a_type: 'library',
b_type: 'library',
a_purl: 'pkg:npm/component-a@1.0.0',
b_purl: 'pkg:npm/component-a@1.0.0',
a_purl: purl_a,
b_purl: purl_a,
a_version: nil,
b_version: '1.0.0',
expected: -1

View File

@ -11,3 +11,4 @@ coverage.html
cover.out
/*.toml
/gitaly.pid
/_support/bin/golangci-*

366
workhorse/.golangci.yml Normal file
View File

@ -0,0 +1,366 @@
# This file contains all available configuration options
# with their default values.
# options for analysis running
run:
# default concurrency is a available CPU number
# concurrency: 4
# timeout for analysis, e.g. 30s, 5m, default is 1m
timeout: 30m
# exit code when at least one issue was found, default is 1
issues-exit-code: 1
# include test files or not, default is true
tests: true
# list of build tags, all linters use it. Default is empty list.
# build-tags:
# - mytag
# which dirs to skip: issues from them won't be reported;
# can use regexp here: generated.*, regexp is applied on full path;
# default value is empty list, but default dirs are skipped independently
# from this option's value (see skip-dirs-use-default).
# skip-dirs:
# - src/external_libs
# - autogenerated_by_my_lib
# default is true. Enables skipping of directories:
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
skip-dirs-use-default: true
# which files to skip: they will be analyzed, but issues from them
# won't be reported. Default value is empty list, but there is
# no need to include all autogenerated files, we confidently recognize
# autogenerated files. If it's not please let us know.
# skip-files:
# - ".*\\.my\\.go$"
# - lib/bad.go
# by default isn't set. If set we pass it to "go list -mod={option}". From "go help modules":
# If invoked with -mod=readonly, the go command is disallowed from the implicit
# automatic updating of go.mod described above. Instead, it fails when any changes
# to go.mod are needed. This setting is most useful to check that go.mod does
# not need updates, such as in a continuous integration and testing system.
# If invoked with -mod=vendor, the go command assumes that the vendor
# directory holds the correct copies of dependencies and ignores
# the dependency descriptions in go.mod.
# modules-download-mode: readonly|release|vendor
# output configuration options
output:
# colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number"
format: line-number
# print lines of code with issue, default is true
print-issued-lines: true
# print linter name in the end of issue text, default is true
print-linter-name: true
# all available settings of specific linters
linters-settings:
errcheck:
# report about not checking of errors in type assetions: `a := b.(MyStruct)`;
# default is false: such cases aren't reported by default.
check-type-assertions: false
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`;
# default is false: such cases aren't reported by default.
check-blank: false
# [deprecated] comma-separated list of pairs of the form pkg:regex
# the regex is used to ignore names within pkg. (default "fmt:.*").
# see https://github.com/kisielk/errcheck#the-deprecated-method for details
# ignore: fmt:.*,io/ioutil:^Read.*
# path to a file containing a list of functions to exclude from checking
# see https://github.com/kisielk/errcheck#excluding-functions for details
# exclude: /path/to/file.txt
# Disable error checking, as errorcheck detects more errors and is more configurable.
gosec:
exclude:
- "G104"
funlen:
lines: 60
statements: 40
govet:
# report about shadowed variables
check-shadowing: true
# settings per analyzer
settings:
printf: # analyzer name, run `go tool vet help` to see all analyzers
funcs: # run `go tool vet help printf` to see available settings for `printf` analyzer
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf
# enable or disable analyzers by name
# enable:
# - atomicalign
# enable-all: false
# disable:
# - shadow
# disable-all: false
gofmt:
# simplify code: gofmt with `-s` option, true by default
simplify: true
goimports:
# put imports beginning with prefix after 3rd-party packages;
# it's a comma-separated list of prefixes
# local-prefixes: github.com/org/project
gocyclo:
# minimal code complexity to report, 30 by default (but we recommend 10-20)
min-complexity: 30
gocognit:
# minimal code complexity to report, 30 by default (but we recommend 10-20)
min-complexity: 20
maligned:
# print struct with more effective memory layout or not, false by default
suggest-new: true
depguard:
rules:
main:
allow:
- $gostd
- github.com/stretchr/testify
- github.com/alecthomas/chroma/v2
- gitlab.com/gitlab-org/labkit
- gitlab.com/gitlab-org/gitlab/workhorse
- github.com/sirupsen/logrus
- github.com/gorilla/websocket
- github.com/prometheus/client_golang/prometheus
- github.com/johannesboyne/gofakes3
- github.com/aws/aws-sdk-go
- github.com/golang-jwt/jwt
- github.com/redis/go-redis
- github.com/sebest/xff
- gitlab.com/gitlab-org/gitaly
- github.com/Azure/azure-sdk-for-go/sdk
- github.com/getsentry/raven-go
- github.com/disintegration/imaging
- github.com/BurntSushi/toml
- github.com/golang/gddo/httputil
- github.com/grpc-ecosystem/go-grpc-prometheus
- github.com/mitchellh/copystructure
- github.com/jpillora/backoff
dupl:
# tokens count to trigger issue, 150 by default
threshold: 100
goconst:
# minimal length of string constant, 3 by default
min-len: 3
# minimal occurrences count to trigger, 3 by default
min-occurrences: 3
# depguard:
# list-type: blacklist
# include-go-root: false
# packages:
# - github.com/sirupsen/logrus
# packages-with-error-messages:
# # specify an error message to output when a blacklisted package is used
# github.com/sirupsen/logrus: "logging is allowed only by logutils.Log"
misspell:
# Correct spellings using locale preferences for US or UK.
# Default is to use a neutral variety of English.
# Setting locale to US will correct the British spelling of 'colour' to 'color'.
locale: US
ignore-words:
- GitLab
lll:
# max line length, lines longer will be reported. Default is 120.
# '\t' is counted as 1 character by default, and can be changed with the tab-width option
line-length: 120
# tab width in spaces. Default to 1.
tab-width: 1
unused:
# treat code as a program (not a library) and report unused exported identifiers; default is false.
# XXX: if you enable this setting, unused will report a lot of false-positives in text editors:
# if it's called for subdir of a project it can't find funcs usages. All text editor integrations
# with golangci-lint call it on a directory with the changed file.
check-exported: false
unparam:
# Inspect exported functions, default is false. Set to true if no external program/library imports your code.
# XXX: if you enable this setting, unparam will report a lot of false-positives in text editors:
# if it's called for subdir of a project it can't find external interfaces. All text editor integrations
# with golangci-lint call it on a directory with the changed file.
check-exported: false
nakedret:
# make an issue if func has more lines of code than this setting and it has naked returns; default is 30
max-func-lines: 30
prealloc:
# XXX: we don't recommend using this linter before doing performance profiling.
# For most programs usage of prealloc will be a premature optimization.
# Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.
# True by default.
simple: true
range-loops: true # Report preallocation suggestions on range loops, true by default
for-loops: false # Report preallocation suggestions on for loops, false by default
gocritic:
# Which checks should be enabled; can't be combined with 'disabled-checks';
# See https://go-critic.github.io/overview#checks-overview
# To check which checks are enabled run `GL_DEBUG=gocritic golangci-lint run`
# By default list of stable checks is used.
# enabled-checks:
# - rangeValCopy
# Which checks should be disabled; can't be combined with 'enabled-checks'; default is empty
# disabled-checks:
# - regexpMust
# Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.
# Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags".
# enabled-tags:
# - performance
settings: # settings passed to gocritic
captLocal: # must be valid enabled check name
paramsOnly: true
# rangeValCopy:
# sizeThreshold: 32
godox:
# report any comments starting with keywords, this is useful for TODO or FIXME comments that
# might be left in the code accidentally and should be resolved before merging
keywords: # default keywords are TODO, BUG, and FIXME, these can be overwritten by this setting
- TODO
- BUG
- FIXME
- NOTE
- OPTIMIZE # marks code that should be optimized before merging
- HACK # marks hack-arounds that should be removed before merging
dogsled:
# checks assignments with too many blank identifiers; default is 2
max-blank-identifiers: 2
whitespace:
multi-if: false # Enforces newlines (or comments) after every multi-line if statement
multi-func: false # Enforces newlines (or comments) after every multi-line function signature
wsl:
# If true append is only allowed to be cuddled if appending value is
# matching variables, fields or types on line above. Default is true.
strict-append: true
# Allow calls and assignments to be cuddled as long as the lines have any
# matching variables, fields or types. Default is true.
allow-assign-and-call: true
# Allow multiline assignments to be cuddled. Default is true.
allow-multiline-assign: true
# Allow declarations (var) to be cuddled.
allow-cuddle-declarations: false
# Allow trailing comments in ending of blocks
allow-trailing-comment: false
# Force newlines in end of case at this limit (0 = never).
force-case-trailing-whitespace: 0
linters:
# please, do not use `enable-all`: it's deprecated and will be removed soon.
# inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint
disable-all: true
enable:
- bodyclose
- depguard
- dogsled
- dupl
- errcheck
- exportloopref
- funlen
- gocognit
- goconst
- gocritic
- godox
- gofmt
- goimports
- gosec
- gosimple
- govet
- ineffassign
- misspell
- nakedret
- revive
- staticcheck
- stylecheck
- testifylint
- typecheck
- unconvert
- unparam
- unused
- whitespace
# don't enable:
# - deadcode
# - gochecknoglobals
# - gochecknoinits
# - gocyclo
# - lll
# - maligned
# - prealloc
# - varcheck
issues:
# List of regexps of issue texts to exclude, empty list by default.
# But independently from this option we use default exclude patterns,
# it can be disabled by `exclude-use-default: false`. To list all
# excluded by default patterns execute `golangci-lint run --help`
# exclude:
# - abcdef
# Excluding configuration per-path, per-linter, per-text and per-source
exclude-rules:
# Exclude some linters from running on tests files.
- path: _test\.go
linters:
- gocyclo
- errcheck
- dupl
- gosec
- funlen
# Exclude known linters from partially hard-vendored code,
# which is impossible to exclude via "nolint" comments.
# - path: internal/hmac/
# text: "weak cryptographic primitive"
# linters:
# - gosec
# Exclude some staticcheck messages
# - linters:
# - staticcheck
# text: "SA9003:"
# Exclude lll issues for long lines with go:generate
- linters:
- lll
source: "^//go:generate "
# Independently from option `exclude` we use default exclude patterns,
# it can be disabled by this option. To list all
# excluded by default patterns execute `golangci-lint run --help`.
# Default value for this option is true.
exclude-use-default: false
# Maximum issues count per one linter. Set to 0 to disable. Default is 50.
max-issues-per-linter: 0
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
max-same-issues: 0
# Show only new issues: if there are unstaged changes or untracked files,
# only those changes are analyzed, else only changes in HEAD~ are analyzed.
# It's a super-useful option for integration of golangci-lint into existing
# large codebase. It's not practical to fix all existing issues at the moment
# of integration: much better don't allow issues in new code.
# Default is false.
new: false
# Show only new issues created after git revision `REV`
# This should be passed as flag during individual CI jobs.
# new-from-rev: REV
# Show only new issues created in git patch with set file path.
# new-from-patch: path/to/patch/file

View File

@ -21,6 +21,13 @@ EXE_ALL := gitlab-resize-image gitlab-zip-cat gitlab-zip-metadata gitlab-workhor
INSTALL := install
BUILD_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver
OS := $(shell uname | tr A-Z a-z)
ARCH ?= $(shell uname -m | sed -e 's/x86_64/amd64/' | sed -e 's/aarch64/arm64/')
GOLANGCI_LINT_VERSION := 1.55.2
GOLANGCI_LINT_ARCH ?= ${ARCH}
GOLANGCI_LINT_FILE := _support/bin/golangci-lint-${GOLANGCI_LINT_VERSION}
ifeq (${FIPS_MODE}, 1)
# boringcrypto tag is added automatically by golang-fips compiler
BUILD_TAGS += fips
@ -155,6 +162,14 @@ lint:
go install golang.org/x/lint/golint
@_support/lint.sh ./...
.PHONY: golangci
golangci: ${GOLANGCI_LINT_FILE}
${GOLANGCI_LINT_FILE} run --issues-exit-code 0 --print-issued-lines=false ${GOLANGCI_LINT_ARGS}
${GOLANGCI_LINT_FILE}:
mkdir -p $(shell dirname ${GOLANGCI_LINT_FILE})
curl -L https://github.com/golangci/golangci-lint/releases/download/v${GOLANGCI_LINT_VERSION}/golangci-lint-${GOLANGCI_LINT_VERSION}-${OS}-${GOLANGCI_LINT_ARCH}.tar.gz | tar --strip-components 1 -zOxf - golangci-lint-${GOLANGCI_LINT_VERSION}-${OS}-${GOLANGCI_LINT_ARCH}/golangci-lint > ${GOLANGCI_LINT_FILE} && chmod +x ${GOLANGCI_LINT_FILE}
.PHONY: vet
vet:
$(call message,Verify: $@)

View File

@ -1,7 +1,6 @@
package config
import (
"os"
"path/filepath"
"testing"
@ -150,8 +149,7 @@ func TestRegisterGoCloudGoogleURLOpenersWithApplicationDefault(t *testing.T) {
path, err := filepath.Abs("../../testdata/google_dummy_credentials.json")
require.NoError(t, err)
os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", path)
defer os.Unsetenv("GOOGLE_APPLICATION_CREDENTIALS")
t.Setenv("GOOGLE_APPLICATION_CREDENTIALS", path)
testRegisterGoCloudURLOpener(t, cfg, "gs")
}