Skip to content

Instantly share code, notes, and snippets.

@josephschmitt
Last active July 6, 2022 20:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save josephschmitt/0fc2b5a7fdf60b3b08d2074fcf794139 to your computer and use it in GitHub Desktop.
Save josephschmitt/0fc2b5a7fdf60b3b08d2074fcf794139 to your computer and use it in GitHub Desktop.
Brainstorming Thrift source code that generates Segment event definitions and client SDK's
namespace go tech_infra.ci.step
// CI Step has started
struct Started {
// Name of the CI step being run
1: required string name;
} (
analytics.method = "track"
)
// CI Step has finished
struct Finished {
// Name of the CI step that completed
1: required string name;
} (
analytics.method = "track"
)
// CI job page information
struct Job {
// Name of the job
1: required string name;
// CI build number
1: optional string buildNum;
// GitHub repository name
1: optional string repo;
// SHA of the commit the job is running on
1: optional string sha1;
} (
analytics.method = "page"
)
import Analytics from 'analytics-node';
/**
* Either a userId or an anonymousId, but not both
*/
export type User = {userId: string} | {anonymousId: string};
/**
* CI Step has started
*
* @param name - Name of the CI step being run
*/
export interface Started {
name: string;
};
/**
* CI Step has finished
*
* @param name - Name of the CI step that completed
*/
export interface Finished {
name: string;
};
const client = new Analytics(process.env.ANALYTICS_WRITE_KEY);
/**
* Track: CI Step has started
*
* @param properties - Optional properties to send with the tracking event.
* @param user - Object containing either a userId or an anonymousId
*/
export function trackStepStarted(properties: Started, user: User) {
return client.track({
event: 'step_started',
properties: properties,
...{user},
});
}
/**
* Track: CI Step has finished
*
* @param properties - Optional properties to send with the tracking event.
* @param user - Object containing either a userId or an anonymousId
*/
export function trackStepFinished(properties: Finished, user: User) {
return client.track({
event: 'step_finished',
properties: properties,
...{user},
});
}
/**
* CI job page information
*
* @param name - Name of the job
* @param buildNum - CI build number
* @param repo - GitHub repository name
* @param sha1 - SHA of the commit the job is running on
*/
export type Job = {
name: string;
buildNum?: string;
repo?: string;
sha1?: string;
}
/**
* Page: CI job page information
*
* @param properties - Optional properties to send with the page event.
* @param user - Object containing either a userId or an anonymousId
*/
export function pageCiJob(properties: Job, user: User) {
return client.page({
name: 'ci_job',
properties: properties,
...{user},
})
}
package analytics_thrift_sdk
import (
"os"
"github.com/fatih/structs"
"github.com/segmentio/analytics-go/v3"
)
type User struct {
UserId string `structs:"userId,omitempty"`
AnonymousId string `structs:"anonymousId,omitempty"`
}
// CI Step has started
type Started struct {
// Name of the CI step being run
Name string `structs:"name"`
}
// CI Step has finished
type Finished struct {
// Name of the CI step that completed
Name string `structs:"name"`
}
// CI job page information
type CiJob struct {
// Name of the job
Name string `structs:"name"`
// CI build number
BuildNum string `structs:"buildNum,omitempty"`
// GitHub repository name
Repo string `structs:"repo,omitempty"`
// SHA of the commit the job is running on
Sha1 string `structs:"sha1,omitempty"`
}
type CiStepAnalytics struct{ client analytics.Client }
func NewCiStepAnalytics(client *analytics.Client) {
if client == nil {
return &CiStepAnalytics{
client: analytics.New(os.Getenv("ANALYTICS_WRITE_KEY")),
}
}
return &CiStepAnalytics{
client: *client,
}
}
// Track: CI Step has was started
func (acl *CiStepAnalytics) TrackCiStepStarted(properties Started, user User) error {
return acl.enqueueWithUser(analytics.Track{
Event: "ci_step_started",
Properties: structs.Map(properties),
}, user)
}
// Track: CI Step has finished
func (acl *CiStepAnalytics) TrackCiStepFinished(properties Finished, user User) error {
return acl.enqueueWithUser(analytics.Track{
Event: "ci_step_finished",
Properties: structs.Map(properties),
}, user)
}
// Page: CI job page information
func (acl *CiStepAnalytics) PageCiJob(properties CiJob, user User) error {
return acl.enqueueWithUser(analytics.Page{
Name: "ci_step_home",
Properties: structs.Map(properties),
}, user)
}
func (acl *CiStepAnalytics) Close() {
return acl.client.Close()
}
func (acl *CiStepAnalytics) enqueueWithUser(message analytics.Message, user User) error {
if user.UserId != "" {
message.UserId = user.UserId
} else if user.AnonymousId != "" {
message.AnonymousId = user.AnonymousId
}
return acl.client.Enqueue(message)
}
package step
import (
"compass_analytics/analytics_thrift_sdk"
"github.com/alecthomas/kong"
)
type CiStep struct {
Track TrackCiStepCmd `kong:"cmd,help='Send analytics track commands to Segment'"`
Page PageCiJobCmd `kong:"cmd,help='Send analytics page commands to Segment'"`
}
func (m *CiStep) AfterApply(ctx *kong.Context) error {
ctx.Bind(analytics_thrift_sdk.NewStepAnalytics(nil))
return nil
}
type TrackCiStepCmd struct {
Started TrackCiStepStartedCmd `kong:"cmd,help='CI Step has started'"`
Finished TrackCiStepFinishedCmd `kong:"cmd,help='CI Step has finished'"`
}
type TrackCiStepStartedCmd struct {
Name string `kong:"required"`
}
func (t *TrackCiStepStartedCmd) Run(ctx *kong.Context, acl *analytics_thrift_sdk.StepAnalytics) error {
defer acl.Close()
return acl.TrackCiStepStarted(analytics_thrift_sdk.Started{
Name: t.Name,
}, analytics_thrift_sdk.User{})
return nil
}
type TrackCiStepFinishedCmd struct {
Name string `kong:"required"`
}
func (t *TrackCiStepFinishedCmd) Run(ctx *kong.Context, acl *analytics_thrift_sdk.StepAnalytics) error {
defer acl.Close()
return acl.TrackCiStepFinished(analytics_thrift_sdk.Finished{
Name: t.Name,
}, analytics_thrift_sdk.User{})
return nil
}
type PageCiJobCmd struct {
Name string `kong:"required"`
}
func (p *PageCiJobCmd) Run(ctx *kong.Context) error {
defer acl.Close()
return acl.TrackCiStepFinished(analytics_thrift_sdk.CiJob{
Name: t.Name,
BuildNum t.BuildNum,
Repo t.Repo,
Sha1 t.Sha1,
}, analytics_thrift_sdk.User{})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment