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
templates_gitlab_slack_application_active
groups_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
end
......
......@@ -5,23 +5,14 @@ module Gitlab::UsageDataCounters
REDIS_SLOT = 'ci_templates'
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
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
def ci_templates(relative_base = 'lib/gitlab/ci/templates')
......@@ -30,9 +21,12 @@ module Gitlab::UsageDataCounters
def ci_template_event_name(template_name, config_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
private
......
# Implicit Auto DevOps pipeline events
- 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
# This file is generated automatically by
# bin/rake gitlab:usage_data:generate_ci_template_events
#
# 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
category: ci_templates
redis_slot: ci_templates
......@@ -463,6 +427,10 @@
category: ci_templates
redis_slot: ci_templates
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
category: ci_templates
redis_slot: ci_templates
......@@ -499,11 +467,11 @@
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
- name: p_ci_templates_implicit_auto_devops_deploy
- name: p_ci_templates_implicit_jobs_deploy
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
- name: p_ci_templates_implicit_auto_devops_build
- name: p_ci_templates_implicit_jobs_build
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
......@@ -515,7 +483,7 @@
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
- name: p_ci_templates_implicit_auto_devops_deploy_latest
- name: p_ci_templates_implicit_jobs_deploy_latest
category: ci_templates
redis_slot: ci_templates
aggregation: weekly
......
......@@ -41,20 +41,32 @@ namespace :gitlab do
repository_includes = ci_template_includes_hash(:repository_source)
auto_devops_jobs_includes = ci_template_includes_hash(:auto_devops_source, 'Jobs')
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, ''))
end
def ci_template_includes_hash(source, template_directory = nil)
Gitlab::UsageDataCounters::CiTemplateUniqueCounter.ci_templates("lib/gitlab/ci/templates/#{template_directory}").map do |template|
{
'name' => Gitlab::UsageDataCounters::CiTemplateUniqueCounter.ci_template_event_name("#{template_directory}/#{template}", source),
'category' => 'ci_templates',
'redis_slot' => Gitlab::UsageDataCounters::CiTemplateUniqueCounter::REDIS_SLOT,
'aggregation' => 'weekly'
}
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' => event_name,
'category' => 'ci_templates',
'redis_slot' => Gitlab::UsageDataCounters::CiTemplateUniqueCounter::REDIS_SLOT,
'aggregation' => 'weekly'
}
end
end
end
......@@ -6,97 +6,62 @@ RSpec.describe Gitlab::UsageDataCounters::CiTemplateUniqueCounter do
describe '.track_unique_project_event' do
using RSpec::Parameterized::TableSyntax
where(:template, :config_source, :expected_event) do
# Implicit Auto DevOps usage
'Auto-DevOps.gitlab-ci.yml' | :auto_devops_source | 'p_ci_templates_implicit_auto_devops'
'Jobs/Build.gitlab-ci.yml' | :auto_devops_source | 'p_ci_templates_implicit_auto_devops_build'
'Jobs/Deploy.gitlab-ci.yml' | :auto_devops_source | 'p_ci_templates_implicit_auto_devops_deploy'
'Security/SAST.gitlab-ci.yml' | :auto_devops_source | 'p_ci_templates_implicit_security_sast'
'Security/Secret-Detection.gitlab-ci.yml' | :auto_devops_source | 'p_ci_templates_implicit_security_secret_detection'
# Explicit include:template usage
'5-Minute-Production-App.gitlab-ci.yml' | :repository_source | 'p_ci_templates_5_min_production_app'
'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'
'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
with_them do
it_behaves_like 'tracking unique hll events' do
subject(:request) { described_class.track_unique_project_event(project_id: project_id, template: template, config_source: config_source) }
let(:project_id) { 1 }
let(:project_id) { 1 }
let(:target_id) { expected_event }
let(:expected_type) { instance_of(Integer) }
shared_examples 'tracks template' do
it "has an event defined for template" do
expect do
described_class.track_unique_project_event(
project_id: project_id,
template: template_path,
config_source: config_source
)
end.not_to raise_error
end
end
context 'known_events coverage tests' do
let(:project_id) { 1 }
let(:config_source) { :repository_source }
it "tracks template" do
expanded_template_name = described_class.expand_template_name(template_path)
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)
# These tests help guard against missing "explicit" events in known_events/ci_templates.yml
context 'explicit include:template events' do
described_class::TEMPLATE_TO_EVENT.keys.each do |template|
it "does not raise error for #{template}" do
expect do
described_class.track_unique_project_event(project_id: project_id, template: template, config_source: config_source)
end.not_to raise_error
end
end
described_class.track_unique_project_event(project_id: project_id, template: template_path, config_source: config_source)
end
end
# This test is to help guard against missing "implicit" events in known_events/ci_templates.yml
it 'does not raise error for any template in an implicit Auto DevOps pipeline' do
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
context 'with explicit includes' do
let(:config_source) { :repository_source }
config_source = :auto_devops_source
(described_class.ci_templates - ['Verify/Browser-Performance.latest.gitlab-ci.yml', 'Verify/Browser-Performance.gitlab-ci.yml']).each do |template|
context "for #{template}" do
let(:template_path) { template }
result.included_templates.each do |template|
expect do
described_class.track_unique_project_event(project_id: project.id, template: template, config_source: config_source)
end.not_to raise_error
include_examples 'tracks template'
end
end
end
context 'templates outside of TEMPLATE_TO_EVENT' 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
described_class.track_unique_project_event(
project_id: project_id,
template: template,
config_source: config_source
)
end.not_to raise_error
end
context 'with implicit includes' do
let(:config_source) { :auto_devops_source }
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)
[
['', ['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) }
described_class.track_unique_project_event(project_id: project_id, template: template, config_source: config_source)
include_examples 'tracks template'
end
end
end
end
it 'expands short template names' do
expect do
described_class.track_unique_project_event(project_id: 1, template: 'Dependency-Scanning.gitlab-ci.yml', config_source: :repository_source)
end.not_to raise_error
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