Commit 223a3c66 authored by Matija Čupić's avatar Matija Čupić

Expand template names when tracking inclusion

Expands template names when tracking their inclusion. This is required
because some templates get automatically resolved to different paths or
redirect to the latest version of the template.

Changelog: fixed
parent 7546a09e
...@@ -34,6 +34,11 @@ RSpec.describe 'Every metric definition' do ...@@ -34,6 +34,11 @@ RSpec.describe 'Every metric definition' do
templates_gitlab_slack_application_active templates_gitlab_slack_application_active
groups_inheriting_gitlab_slack_application_active groups_inheriting_gitlab_slack_application_active
projects_inheriting_gitlab_slack_application_active projects_inheriting_gitlab_slack_application_active
p_ci_templates_5_min_production_app
p_ci_templates_aws_cf_deploy_ec2
p_ci_templates_auto_devops_build
p_ci_templates_auto_devops_deploy
p_ci_templates_auto_devops_deploy_latest
).freeze ).freeze
end end
......
...@@ -5,23 +5,14 @@ module Gitlab::UsageDataCounters ...@@ -5,23 +5,14 @@ module Gitlab::UsageDataCounters
REDIS_SLOT = 'ci_templates' REDIS_SLOT = 'ci_templates'
KNOWN_EVENTS_FILE_PATH = File.expand_path('known_events/ci_templates.yml', __dir__) KNOWN_EVENTS_FILE_PATH = File.expand_path('known_events/ci_templates.yml', __dir__)
# NOTE: Events originating from implicit Auto DevOps pipelines get prefixed with `implicit_`
TEMPLATE_TO_EVENT = {
'5-Minute-Production-App.gitlab-ci.yml' => '5_min_production_app',
'Auto-DevOps.gitlab-ci.yml' => 'auto_devops',
'AWS/CF-Provision-and-Deploy-EC2.gitlab-ci.yml' => 'aws_cf_deploy_ec2',
'AWS/Deploy-ECS.gitlab-ci.yml' => 'aws_deploy_ecs',
'Jobs/Build.gitlab-ci.yml' => 'auto_devops_build',
'Jobs/Deploy.gitlab-ci.yml' => 'auto_devops_deploy',
'Jobs/Deploy.latest.gitlab-ci.yml' => 'auto_devops_deploy_latest',
'Security/SAST.gitlab-ci.yml' => 'security_sast',
'Security/Secret-Detection.gitlab-ci.yml' => 'security_secret_detection',
'Terraform/Base.latest.gitlab-ci.yml' => 'terraform_base_latest'
}.freeze
class << self class << self
def track_unique_project_event(project_id:, template:, config_source:) def track_unique_project_event(project_id:, template:, config_source:)
Gitlab::UsageDataCounters::HLLRedisCounter.track_event(ci_template_event_name(template, config_source), values: project_id) expanded_template_name = expand_template_name(template)
return unless expanded_template_name
Gitlab::UsageDataCounters::HLLRedisCounter.track_event(
ci_template_event_name(expanded_template_name, config_source), values: project_id
)
end end
def ci_templates(relative_base = 'lib/gitlab/ci/templates') def ci_templates(relative_base = 'lib/gitlab/ci/templates')
...@@ -30,9 +21,12 @@ module Gitlab::UsageDataCounters ...@@ -30,9 +21,12 @@ module Gitlab::UsageDataCounters
def ci_template_event_name(template_name, config_source) def ci_template_event_name(template_name, config_source)
prefix = 'implicit_' if config_source.to_s == 'auto_devops_source' prefix = 'implicit_' if config_source.to_s == 'auto_devops_source'
template_event_name = TEMPLATE_TO_EVENT[template_name] || template_to_event_name(template_name)
"p_#{REDIS_SLOT}_#{prefix}#{template_event_name}" "p_#{REDIS_SLOT}_#{prefix}#{template_to_event_name(template_name)}"
end
def expand_template_name(template_name)
Gitlab::Template::GitlabCiYmlTemplate.find(template_name.chomp('.gitlab-ci.yml'))&.full_name
end end
private private
......
# Implicit Auto DevOps pipeline events # This file is generated automatically by
- name: p_ci_templates_implicit_auto_devops
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
# Explicit include:template pipeline events
- name: p_ci_templates_5_min_production_app
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
- name: p_ci_templates_aws_cf_deploy_ec2
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
- name: p_ci_templates_auto_devops_build
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
- name: p_ci_templates_auto_devops_deploy
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
- name: p_ci_templates_auto_devops_deploy_latest
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
# This part of the file is generated automatically by
# bin/rake gitlab:usage_data:generate_ci_template_events # bin/rake gitlab:usage_data:generate_ci_template_events
# #
# Do not edit it manually! # Do not edit it manually!
# ---
# The section above this should be removed once we roll out tracking all ci
# templates
# https://gitlab.com/gitlab-org/gitlab/-/issues/339684
- name: p_ci_templates_terraform_base_latest - name: p_ci_templates_terraform_base_latest
category: ci_templates category: ci_templates
redis_slot: ci_templates redis_slot: ci_templates
...@@ -463,6 +427,10 @@ ...@@ -463,6 +427,10 @@
category: ci_templates category: ci_templates
redis_slot: ci_templates redis_slot: ci_templates
aggregation: weekly aggregation: weekly
- name: p_ci_templates_implicit_auto_devops
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
- name: p_ci_templates_implicit_jobs_dast_default_branch_deploy - name: p_ci_templates_implicit_jobs_dast_default_branch_deploy
category: ci_templates category: ci_templates
redis_slot: ci_templates redis_slot: ci_templates
...@@ -499,11 +467,11 @@ ...@@ -499,11 +467,11 @@
category: ci_templates category: ci_templates
redis_slot: ci_templates redis_slot: ci_templates
aggregation: weekly aggregation: weekly
- name: p_ci_templates_implicit_auto_devops_deploy - name: p_ci_templates_implicit_jobs_deploy
category: ci_templates category: ci_templates
redis_slot: ci_templates redis_slot: ci_templates
aggregation: weekly aggregation: weekly
- name: p_ci_templates_implicit_auto_devops_build - name: p_ci_templates_implicit_jobs_build
category: ci_templates category: ci_templates
redis_slot: ci_templates redis_slot: ci_templates
aggregation: weekly aggregation: weekly
...@@ -515,7 +483,7 @@ ...@@ -515,7 +483,7 @@
category: ci_templates category: ci_templates
redis_slot: ci_templates redis_slot: ci_templates
aggregation: weekly aggregation: weekly
- name: p_ci_templates_implicit_auto_devops_deploy_latest - name: p_ci_templates_implicit_jobs_deploy_latest
category: ci_templates category: ci_templates
redis_slot: ci_templates redis_slot: ci_templates
aggregation: weekly aggregation: weekly
......
...@@ -41,20 +41,32 @@ namespace :gitlab do ...@@ -41,20 +41,32 @@ namespace :gitlab do
repository_includes = ci_template_includes_hash(:repository_source) repository_includes = ci_template_includes_hash(:repository_source)
auto_devops_jobs_includes = ci_template_includes_hash(:auto_devops_source, 'Jobs') auto_devops_jobs_includes = ci_template_includes_hash(:auto_devops_source, 'Jobs')
auto_devops_security_includes = ci_template_includes_hash(:auto_devops_source, 'Security') auto_devops_security_includes = ci_template_includes_hash(:auto_devops_source, 'Security')
all_includes = [*repository_includes, *auto_devops_jobs_includes, *auto_devops_security_includes] all_includes = [
*repository_includes,
ci_template_event('p_ci_templates_implicit_auto_devops'),
*auto_devops_jobs_includes,
*auto_devops_security_includes
]
File.write(Gitlab::UsageDataCounters::CiTemplateUniqueCounter::KNOWN_EVENTS_FILE_PATH, banner + YAML.dump(all_includes).gsub(/ *$/m, '')) File.write(Gitlab::UsageDataCounters::CiTemplateUniqueCounter::KNOWN_EVENTS_FILE_PATH, banner + YAML.dump(all_includes).gsub(/ *$/m, ''))
end end
def ci_template_includes_hash(source, template_directory = nil) def ci_template_includes_hash(source, template_directory = nil)
Gitlab::UsageDataCounters::CiTemplateUniqueCounter.ci_templates("lib/gitlab/ci/templates/#{template_directory}").map do |template| Gitlab::UsageDataCounters::CiTemplateUniqueCounter.ci_templates("lib/gitlab/ci/templates/#{template_directory}").map do |template|
expanded_template_name = Gitlab::UsageDataCounters::CiTemplateUniqueCounter.expand_template_name("#{template_directory}/#{template}")
event_name = Gitlab::UsageDataCounters::CiTemplateUniqueCounter.ci_template_event_name(expanded_template_name, source)
ci_template_event(event_name)
end
end
def ci_template_event(event_name)
{ {
'name' => Gitlab::UsageDataCounters::CiTemplateUniqueCounter.ci_template_event_name("#{template_directory}/#{template}", source), 'name' => event_name,
'category' => 'ci_templates', 'category' => 'ci_templates',
'redis_slot' => Gitlab::UsageDataCounters::CiTemplateUniqueCounter::REDIS_SLOT, 'redis_slot' => Gitlab::UsageDataCounters::CiTemplateUniqueCounter::REDIS_SLOT,
'aggregation' => 'weekly' 'aggregation' => 'weekly'
} }
end end
end end
end
end end
...@@ -6,97 +6,62 @@ RSpec.describe Gitlab::UsageDataCounters::CiTemplateUniqueCounter do ...@@ -6,97 +6,62 @@ RSpec.describe Gitlab::UsageDataCounters::CiTemplateUniqueCounter do
describe '.track_unique_project_event' do describe '.track_unique_project_event' do
using RSpec::Parameterized::TableSyntax using RSpec::Parameterized::TableSyntax
where(:template, :config_source, :expected_event) do let(:project_id) { 1 }
# Implicit Auto DevOps usage
'Auto-DevOps.gitlab-ci.yml' | :auto_devops_source | 'p_ci_templates_implicit_auto_devops' shared_examples 'tracks template' do
'Jobs/Build.gitlab-ci.yml' | :auto_devops_source | 'p_ci_templates_implicit_auto_devops_build' it "has an event defined for template" do
'Jobs/Deploy.gitlab-ci.yml' | :auto_devops_source | 'p_ci_templates_implicit_auto_devops_deploy' expect do
'Security/SAST.gitlab-ci.yml' | :auto_devops_source | 'p_ci_templates_implicit_security_sast' described_class.track_unique_project_event(
'Security/Secret-Detection.gitlab-ci.yml' | :auto_devops_source | 'p_ci_templates_implicit_security_secret_detection' project_id: project_id,
# Explicit include:template usage template: template_path,
'5-Minute-Production-App.gitlab-ci.yml' | :repository_source | 'p_ci_templates_5_min_production_app' config_source: config_source
'Auto-DevOps.gitlab-ci.yml' | :repository_source | 'p_ci_templates_auto_devops' )
'AWS/CF-Provision-and-Deploy-EC2.gitlab-ci.yml' | :repository_source | 'p_ci_templates_aws_cf_deploy_ec2' end.not_to raise_error
'AWS/Deploy-ECS.gitlab-ci.yml' | :repository_source | 'p_ci_templates_aws_deploy_ecs'
'Jobs/Build.gitlab-ci.yml' | :repository_source | 'p_ci_templates_auto_devops_build'
'Jobs/Deploy.gitlab-ci.yml' | :repository_source | 'p_ci_templates_auto_devops_deploy'
'Jobs/Deploy.latest.gitlab-ci.yml' | :repository_source | 'p_ci_templates_auto_devops_deploy_latest'
'Security/SAST.gitlab-ci.yml' | :repository_source | 'p_ci_templates_security_sast'
'Security/Secret-Detection.gitlab-ci.yml' | :repository_source | 'p_ci_templates_security_secret_detection'
'Terraform/Base.latest.gitlab-ci.yml' | :repository_source | 'p_ci_templates_terraform_base_latest'
end end
with_them do it "tracks template" do
it_behaves_like 'tracking unique hll events' do expanded_template_name = described_class.expand_template_name(template_path)
subject(:request) { described_class.track_unique_project_event(project_id: project_id, template: template, config_source: config_source) } expected_template_event_name = described_class.ci_template_event_name(expanded_template_name, config_source)
expect(Gitlab::UsageDataCounters::HLLRedisCounter).to(receive(:track_event)).with(expected_template_event_name, values: project_id)
let(:project_id) { 1 } described_class.track_unique_project_event(project_id: project_id, template: template_path, config_source: config_source)
let(:target_id) { expected_event }
let(:expected_type) { instance_of(Integer) }
end end
end end
context 'known_events coverage tests' do context 'with explicit includes' do
let(:project_id) { 1 }
let(:config_source) { :repository_source } let(:config_source) { :repository_source }
# These tests help guard against missing "explicit" events in known_events/ci_templates.yml (described_class.ci_templates - ['Verify/Browser-Performance.latest.gitlab-ci.yml', 'Verify/Browser-Performance.gitlab-ci.yml']).each do |template|
context 'explicit include:template events' do context "for #{template}" do
described_class::TEMPLATE_TO_EVENT.keys.each do |template| let(:template_path) { template }
it "does not raise error for #{template}" do
expect do include_examples 'tracks template'
described_class.track_unique_project_event(project_id: project_id, template: template, config_source: config_source)
end.not_to raise_error
end end
end end
end end
# This test is to help guard against missing "implicit" events in known_events/ci_templates.yml context 'with implicit includes' do
it 'does not raise error for any template in an implicit Auto DevOps pipeline' do let(:config_source) { :auto_devops_source }
project = create(:project, :auto_devops)
pipeline = double(project: project)
command = double
result = Gitlab::Ci::YamlProcessor.new(
Gitlab::Ci::Pipeline::Chain::Config::Content::AutoDevops.new(pipeline, command).content,
project: project,
user: double,
sha: 'd310cc759caaa20cd05a9e0983d6017896d9c34c'
).execute
config_source = :auto_devops_source [
['', ['Auto-DevOps.gitlab-ci.yml']],
['Jobs', described_class.ci_templates('lib/gitlab/ci/templates/Jobs')],
['Security', described_class.ci_templates('lib/gitlab/ci/templates/Security')]
].each do |directory, templates|
templates.each do |template|
context "for #{template}" do
let(:template_path) { File.join(directory, template) }
result.included_templates.each do |template| include_examples 'tracks template'
expect do end
described_class.track_unique_project_event(project_id: project.id, template: template, config_source: config_source)
end.not_to raise_error
end end
end end
end end
context 'templates outside of TEMPLATE_TO_EVENT' do it 'expands short template names' do
let(:project_id) { 1 }
let(:config_source) { :repository_source }
described_class.ci_templates.each do |template|
next if described_class::TEMPLATE_TO_EVENT.key?(template)
it "has an event defined for #{template}" do
expect do expect do
described_class.track_unique_project_event( described_class.track_unique_project_event(project_id: 1, template: 'Dependency-Scanning.gitlab-ci.yml', config_source: :repository_source)
project_id: project_id,
template: template,
config_source: config_source
)
end.not_to raise_error end.not_to raise_error
end end
it "tracks #{template}" do
expected_template_event_name = described_class.ci_template_event_name(template, :repository_source)
expect(Gitlab::UsageDataCounters::HLLRedisCounter).to(receive(:track_event)).with(expected_template_event_name, values: project_id)
described_class.track_unique_project_event(project_id: project_id, template: template, config_source: config_source)
end
end
end
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment