Commit 9ba77091 authored by Alishan Ladhani's avatar Alishan Ladhani Committed by Mikołaj Wawrzyniak

Create generator for Snowplow event definitions

parent 12393cb8
{
"type": "object",
"required": [],
"properties": {
"description": {
"type": "string"
},
"category": {
"type": "string"
},
"action": {
"type": "string"
},
"label_description": {
"type": ["string", "null"]
},
"property_description": {
"type": ["string", "null"]
},
"value_description": {
"type": ["string", "null"]
},
"extra_properties": {
"type": ["object", "null"]
},
"identifiers": {
"type": ["array", "null"],
"items": {
"type": "string",
"enum": ["project", "user", "namespace"]
}
},
"iglu_schema_url": {
"type": ["string", "null"]
},
"product_section": {
"type": "string"
},
"product_stage": {
"type": ["string", "null"]
},
"product_group": {
"type": "string"
},
"product_category": {
"type": ["string", "null"]
},
"introduced_by_url": {
"type": ["uri", "null"]
},
"milestone": {
"type": ["string", "null"],
"pattern": "^[0-9]+\\.[0-9]+$"
},
"distributions": {
"type": "array",
"items": {
"type": "string",
"enum": ["ee", "ce"]
}
},
"tiers": {
"type": "array",
"items": {
"type": "string",
"enum": ["free", "premium", "ultimate"]
}
}
}
}
---
stage: Growth
group: Product Intelligence
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Event dictionary guide
NOTE:
The event dictionary is a work in progress, and this process is subject to change.
This guide describes the event dictionary and how it's implemented.
## Event definition and validation
This process is meant to document all Snowplow events and ensure consistency. Event definitions must comply with the [JSON Schema](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/events/schema.json).
All event definitions are stored in the following directories:
- [`config/events`](https://gitlab.com/gitlab-org/gitlab/-/tree/master/config/events)
- [`ee/config/events`](https://gitlab.com/gitlab-org/gitlab/-/tree/master/ee/config/events)
Each event is defined in a separate YAML file consisting of the following fields:
| Field | Required | Additional information |
|------------------------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `description` | yes | A description of the event. |
| `category` | yes | The event category (see [Structured event taxonomy](index.md#structured-event-taxonomy)). |
| `action` | yes | The event action (see [Structured event taxonomy](index.md#structured-event-taxonomy)). |
| `label_description` | no | A description of the event label (see [Structured event taxonomy](index.md#structured-event-taxonomy)). |
| `property_description` | no | A description of the event property (see [Structured event taxonomy](index.md#structured-event-taxonomy)). |
| `value_description` | no | A description of the event value (see [Structured event taxonomy](index.md#structured-event-taxonomy)). |
| `extra_properties` | no | The type and description of each extra property sent with the event. |
| `identifiers` | no | A list of identifiers sent with the event. Can be set to one or more of `project`, `user`, or `namespace`. |
| `iglu_schema_url` | no | The URL to the custom schema sent with the event, for example, `iglu:com.gitlab/gitlab_experiment/jsonschema/1-0-0`. |
| `product_section` | yes | The [section](https://gitlab.com/gitlab-com/www-gitlab-com/-/blob/master/data/sections.yml). |
| `product_stage` | no | The [stage](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/stages.yml) for the event. |
| `product_group` | yes | The [group](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/stages.yml) that owns the event. |
| `product_category` | no | The [product category](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/data/categories.yml) for the event. |
| `milestone` | no | The milestone when the event is introduced. |
| `introduced_by_url` | no | The URL to the merge request that introduced the event. |
| `distributions` | yes | The [distributions](https://about.gitlab.com/handbook/marketing/strategic-marketing/tiers/#definitions) where the tracked feature is available. Can be set to one or more of `ce` or `ee`. |
| `tiers` | yes | The [tiers]( https://about.gitlab.com/handbook/marketing/strategic-marketing/tiers/) where the tracked feature is available. Can be set to one or more of `free`, `premium`, or `ultimate`. |
### Example event definition
The linked [`uuid`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/events/epics_promote.yml)
YAML file includes an example event definition.
```yaml
description: Issue promoted to epic
category: epics
action: promote
property_description: The string "issue_id"
value_description: ID of the issue
extra_properties:
weight:
type: integer
description: Weight of the issue
identifiers:
- project
- user
- namespace
product_section: dev
product_stage: plan
product_group: group::product planning
product_category: epics
milestone: "11.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/10537
distributions:
- ee
tiers:
- premium
- ultimate
```
## Create a new event definition
Use the dedicated [event definition generator](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/generators/gitlab/snowplow_event_definition_generator.rb)
to create new event definitions.
The `category` and `action` of each event are included in the filename to enforce uniqueness.
The generator takes three options:
- `--ee`: Indicates if the event is for EE.
- `--category=CATEGORY`: Indicates the `category` of the event.
- `--action=ACTION`: Indicates the `action` of the event.
```shell
bundle exec rails generate gitlab:snowplow_event_definition --category Groups::EmailCampaignsController --action click
create create config/events/groups__email_campaigns_controller_click.yml
```
---
description: Issue promoted to epic
category: epics
action: promote
property_description: The string "issue_id"
value_description: ID of the issue
extra_properties:
weight:
type: integer
description: Weight of the issue
identifiers:
- project
- user
- namespace
product_section: dev
product_stage: plan
product_group: group::product planning
product_category: epics
milestone: "11.10"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/10537
distributions:
- ee
tiers:
- premium
- ultimate
---
description:
category: <%= event_category %>
action: <%= event_action %>
label_description:
property_description:
value_description:
extra_properties:
identifiers:
#- project
#- user
#- namespace
product_section:
product_stage:
product_group:
product_category:
milestone: "<%= milestone %>"
introduced_by_url:
distributions:
<%= distributions %>
tiers: <% if ee? %>
#- premium
- ultimate
<% else %>
- free
- premium
- ultimate
<% end %>
# frozen_string_literal: true
require 'rails/generators'
module Gitlab
class SnowplowEventDefinitionGenerator < Rails::Generators::Base
CE_DIR = 'config/events'
EE_DIR = 'ee/config/events'
source_root File.expand_path('../../../generator_templates/snowplow_event_definition', __dir__)
desc 'Generates an event definition yml file'
class_option :ee, type: :boolean, optional: true, default: false, desc: 'Indicates if event is for ee'
class_option :category, type: :string, optional: false, desc: 'Category of the event'
class_option :action, type: :string, optional: false, desc: 'Action of the event'
def create_event_file
raise 'Event definition already exists' if definition_exists?
template "event_definition.yml", file_path
end
def distributions
(ee? ? ['- ee'] : ['- ce', '- ee']).join("\n")
end
def event_category
options[:category]
end
def event_action
options[:action]
end
def milestone
Gitlab::VERSION.match('(\d+\.\d+)').captures.first
end
def ee?
options[:ee]
end
private
def definition_exists?
File.exist?(ce_file_path) || File.exist?(ee_file_path)
end
def file_path
ee? ? ee_file_path : ce_file_path
end
def ce_file_path
File.join(CE_DIR, file_name)
end
def ee_file_path
File.join(EE_DIR, file_name)
end
def file_name
"#{event_category}_#{event_action}.yml".underscore.gsub("/", "__")
end
end
end
---
description:
category: Groups::EmailCampaignsController
action: click
label_description:
property_description:
value_description:
extra_properties:
identifiers:
#- project
#- user
#- namespace
product_section:
product_stage:
product_group:
product_category:
milestone: "13.11"
introduced_by_url:
distributions:
- ce
- ee
tiers:
- free
- premium
- ultimate
---
description:
category: Groups::EmailCampaignsController
action: click
label_description:
property_description:
value_description:
extra_properties:
identifiers:
#- project
#- user
#- namespace
product_section:
product_stage:
product_group:
product_category:
milestone: "13.11"
introduced_by_url:
distributions:
- ee
tiers:
#- premium
- ultimate
# frozen_string_literal: true
require 'generator_helper'
RSpec.describe Gitlab::SnowplowEventDefinitionGenerator do
let(:ce_temp_dir) { Dir.mktmpdir }
let(:ee_temp_dir) { Dir.mktmpdir }
let(:generator_options) { { 'category' => 'Groups::EmailCampaignsController', 'action' => 'click' } }
before do
stub_const("#{described_class}::CE_DIR", ce_temp_dir)
stub_const("#{described_class}::EE_DIR", ee_temp_dir)
end
after do
FileUtils.rm_rf([ce_temp_dir, ee_temp_dir])
end
describe 'Creating event definition file' do
before do
stub_const('Gitlab::VERSION', '13.11.0-pre')
end
let(:sample_event_dir) { 'lib/generators/gitlab/snowplow_event_definition_generator' }
it 'creates CE event definition file using the template' do
sample_event = ::Gitlab::Config::Loader::Yaml.new(fixture_file(File.join(sample_event_dir, 'sample_event.yml'))).load_raw!
described_class.new([], generator_options).invoke_all
event_definition_path = File.join(ce_temp_dir, 'groups__email_campaigns_controller_click.yml')
expect(::Gitlab::Config::Loader::Yaml.new(File.read(event_definition_path)).load_raw!).to eq(sample_event)
end
it 'creates EE event definition file using the template' do
sample_event = ::Gitlab::Config::Loader::Yaml.new(fixture_file(File.join(sample_event_dir, 'sample_event_ee.yml'))).load_raw!
described_class.new([], generator_options.merge('ee' => true)).invoke_all
event_definition_path = File.join(ee_temp_dir, 'groups__email_campaigns_controller_click.yml')
expect(::Gitlab::Config::Loader::Yaml.new(File.read(event_definition_path)).load_raw!).to eq(sample_event)
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