Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update telemetry to support more anonymized project id #3713

Merged
merged 3 commits into from
Jun 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/strange-laws-kick.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"astro": patch
"@astrojs/telemetry": minor
---

Update telemetry to support a more anonymized project id. `anonymousProjectId` is now hashed based on anonymous git data instead of your git remote URL.
113 changes: 42 additions & 71 deletions packages/astro/src/cli/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import { LogOptions } from '../core/logger/core.js';

import { AstroTelemetry } from '@astrojs/telemetry';
import * as event from '@astrojs/telemetry/events';
import * as event from '../events/index.js';
import * as colors from 'kleur/colors';
import yargs from 'yargs-parser';
import { z } from 'zod';
Expand All @@ -19,6 +19,7 @@ import { createSafeError } from '../core/util.js';
import { check } from './check.js';
import { openInBrowser } from './open.js';
import * as telemetryHandler from './telemetry.js';
import { AstroUserConfig } from '../@types/astro.js';

type Arguments = yargs.Arguments;
type CLICommand =
Expand Down Expand Up @@ -60,12 +61,13 @@ function printAstroHelp() {
});
}

// PACKAGE_VERSION is injected when we build and publish the astro package.
const ASTRO_VERSION = process.env.PACKAGE_VERSION ?? 'development';

/** Display --version flag */
async function printVersion() {
// PACKAGE_VERSION is injected at build time
const version = process.env.PACKAGE_VERSION ?? '';
console.log();
console.log(` ${colors.bgGreen(colors.black(` astro `))} ${colors.green(`v${version}`)}`);
console.log(` ${colors.bgGreen(colors.black(` astro `))} ${colors.green(`v${ASTRO_VERSION}`)}`);
}

/** Determine which command the user requested */
Expand Down Expand Up @@ -109,43 +111,51 @@ export async function cli(args: string[]) {
} else if (flags.silent) {
logging.level = 'silent';
}
const telemetry = new AstroTelemetry({ version: process.env.PACKAGE_VERSION ?? '' });

if (cmd === 'telemetry') {
try {
const subcommand = flags._[3]?.toString();
return await telemetryHandler.update(subcommand, { flags, telemetry });
} catch (err) {
return throwAndExit(err);
}
}
const telemetry = new AstroTelemetry({ version: ASTRO_VERSION });

// Special CLI Commands: "add", "docs", "telemetry"
// These commands run before the user's config is parsed, and may have other special
// conditions that should be handled here, before the others.
//
switch (cmd) {
case 'add': {
try {
telemetry.record(event.eventCliSession({ cliCommand: cmd }));
const packages = flags._.slice(3) as string[];
telemetry.record(
event.eventCliSession({
astroVersion: process.env.PACKAGE_VERSION ?? '',
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this isn't needed, since astroVersion is passed to the AstroTelemetry constructor above.

cliCommand: 'add',
})
);
return await add(packages, { cwd: root, flags, logging, telemetry });
} catch (err) {
return throwAndExit(err);
}
}
case 'docs': {
try {
telemetry.record(event.eventCliSession({ cliCommand: cmd }));
return await openInBrowser('https://docs.astro.build/');
} catch (err) {
return throwAndExit(err);
}
}
case 'telemetry': {
try {
// Do not track session start, since the user may be trying to enable,
// disable, or modify telemetry settings.
const subcommand = flags._[3]?.toString();
return await telemetryHandler.update(subcommand, { flags, telemetry });
} catch (err) {
return throwAndExit(err);
}
}
}

const { astroConfig, userConfig } = await openConfig({ cwd: root, flags, cmd });
telemetry.record(event.eventCliSession({ cliCommand: cmd }, userConfig, flags));

// Common CLI Commands:
// These commands run normally. All commands are assumed to have been handled
// by the end of this switch statement.
switch (cmd) {
case 'dev': {
try {
const { astroConfig, userConfig } = await openConfig({ cwd: root, flags, cmd });

telemetry.record(
event.eventCliSession(
{ astroVersion: process.env.PACKAGE_VERSION ?? '', cliCommand: 'dev' },
userConfig,
flags
)
);
await devServer(astroConfig, { logging, telemetry });
return await new Promise(() => {}); // lives forever
} catch (err) {
Expand All @@ -155,68 +165,29 @@ export async function cli(args: string[]) {

case 'build': {
try {
const { astroConfig, userConfig } = await openConfig({ cwd: root, flags, cmd });
telemetry.record(
event.eventCliSession(
{ astroVersion: process.env.PACKAGE_VERSION ?? '', cliCommand: 'build' },
userConfig,
flags
)
);
return await build(astroConfig, { logging, telemetry });
} catch (err) {
return throwAndExit(err);
}
}

case 'check': {
const { astroConfig, userConfig } = await openConfig({ cwd: root, flags, cmd });
telemetry.record(
event.eventCliSession(
{ astroVersion: process.env.PACKAGE_VERSION ?? '', cliCommand: 'check' },
userConfig,
flags
)
);
const ret = await check(astroConfig);
return process.exit(ret);
}

case 'preview': {
try {
const { astroConfig, userConfig } = await openConfig({ cwd: root, flags, cmd });
telemetry.record(
event.eventCliSession(
{ astroVersion: process.env.PACKAGE_VERSION ?? '', cliCommand: 'preview' },
userConfig,
flags
)
);
const server = await preview(astroConfig, { logging, telemetry });
return await server.closed(); // keep alive until the server is closed
} catch (err) {
return throwAndExit(err);
}
}

case 'docs': {
try {
await telemetry.record(
event.eventCliSession({
astroVersion: process.env.PACKAGE_VERSION ?? '',
cliCommand: 'docs',
})
);
return await openInBrowser('https://docs.astro.build/');
} catch (err) {
return throwAndExit(err);
}
}

default: {
throw new Error(`Error running ${cmd}`);
}
}

// No command handler matched! This is unexpected.
throwAndExit(new Error(`Error running ${cmd} -- no command found.`));
}

/** Display error and exit */
Expand Down
2 changes: 0 additions & 2 deletions packages/astro/src/cli/telemetry.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
/* eslint-disable no-console */
import type { AstroTelemetry } from '@astrojs/telemetry';
import type yargs from 'yargs-parser';

import * as msg from '../core/messages.js';

export interface TelemetryOptions {
flags: yargs.Arguments;
telemetry: AstroTelemetry;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export * from './build.js';
export * from './session.js';
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import { createRequire } from 'node:module';

import type { AstroUserConfig } from '../@types/astro';
const require = createRequire(import.meta.url);

const EVENT_SESSION = 'ASTRO_CLI_SESSION_STARTED';

// :( We can't import the type because of TurboRepo circular dep limitation
type AstroUserConfig = Record<string, any>;

interface EventCliSession {
astroVersion: string;
cliCommand: string;
}

Expand All @@ -25,7 +21,7 @@ interface ConfigInfo {
markdown:
| undefined
| {
mode: undefined | 'md' | 'mdx';
drafts: undefined | boolean;
syntaxHighlight: undefined | 'shiki' | 'prism' | false;
};
}
Expand Down Expand Up @@ -91,15 +87,18 @@ export function eventCliSession(
flags?: Record<string, any>
): { eventName: string; payload: EventCliSessionInternal }[] {
// Filter out falsy integrations
const integrations = userConfig?.integrations?.filter?.(Boolean) ?? [];
const configValues = userConfig
? {
markdownPlugins: [
userConfig?.markdown?.remarkPlugins ?? [],
userConfig?.markdown?.rehypePlugins ?? [],
].flat(1),
...(userConfig?.markdown?.remarkPlugins?.map((p) =>
typeof p === 'string' ? p : typeof p
) ?? []),
...(userConfig?.markdown?.rehypePlugins?.map((p) =>
typeof p === 'string' ? p : typeof p
) ?? []),
] as string[],
adapter: userConfig?.adapter?.name ?? null,
integrations: integrations?.map?.((i: any) => i?.name) ?? [],
integrations: (userConfig?.integrations ?? []).filter(Boolean).map((i: any) => i?.name),
trailingSlash: userConfig?.trailingSlash,
build: userConfig?.build
? {
Expand All @@ -108,7 +107,7 @@ export function eventCliSession(
: undefined,
markdown: userConfig?.markdown
? {
mode: userConfig?.markdown?.mode,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mode is no longer supported but the types were out of date, so this wasn't caught. Removed this and added drafts instead.

drafts: userConfig.markdown?.drafts,
syntaxHighlight: userConfig.markdown?.syntaxHighlight,
}
: undefined,
Expand All @@ -121,15 +120,12 @@ export function eventCliSession(
const payload: EventCliSessionInternal = {
cliCommand: event.cliCommand,
// Versions
astroVersion: event.astroVersion,
viteVersion: getViteVersion(),
nodeVersion: process.version.replace(/^v?/, ''),
configKeys: userConfig ? configKeys(userConfig, '') : undefined,
// Config Values
config: configValues,
flags: cliFlags,
// Optional integrations
optionalIntegrations: userConfig?.integrations?.length - integrations?.length,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was added as a "nice-to-have" in a PR that was fixing a different bug, but I don't think this is actually valuable to us so I removed it.

};
return [{ eventName: EVENT_SESSION, payload }];
}
Loading