Add experimentation service to github auth extension

This commit is contained in:
Rachel Macfarlane 2021-04-19 11:20:21 -07:00
parent 008c20865e
commit 94589129a2
No known key found for this signature in database
GPG key ID: D6C324F0F27A078C
6 changed files with 122 additions and 6 deletions

View file

@ -57,7 +57,8 @@
"node-fetch": "2.6.1",
"uuid": "8.1.0",
"vscode-extension-telemetry": "0.1.7",
"vscode-nls": "^4.1.2"
"vscode-nls": "^4.1.2",
"vscode-tas-client": "^0.1.22"
},
"devDependencies": {
"@types/node": "^12.19.9",

View file

@ -0,0 +1,85 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as path from 'path';
import * as vscode from 'vscode';
import TelemetryReporter from 'vscode-extension-telemetry';
import { getExperimentationService, IExperimentationService, IExperimentationTelemetry, TargetPopulation } from 'vscode-tas-client';
export class ExperimentationTelemetry implements IExperimentationTelemetry {
private sharedProperties: Record<string, string> = {};
constructor(private baseReporter: TelemetryReporter) { }
sendTelemetryEvent(eventName: string, properties?: Record<string, string>, measurements?: Record<string, number>) {
this.baseReporter.sendTelemetryEvent(
eventName,
{
...this.sharedProperties,
...properties,
},
measurements,
);
}
sendTelemetryErrorEvent(
eventName: string,
properties?: Record<string, string>,
_measurements?: Record<string, number>,
) {
this.baseReporter.sendTelemetryErrorEvent(eventName, {
...this.sharedProperties,
...properties,
});
}
setSharedProperty(name: string, value: string): void {
this.sharedProperties[name] = value;
}
postEvent(eventName: string, props: Map<string, string>): void {
const event: Record<string, string> = {};
for (const [key, value] of props) {
event[key] = value;
}
this.sendTelemetryEvent(eventName, event);
}
dispose(): Promise<any> {
return this.baseReporter.dispose();
}
}
interface ProductConfiguration {
quality?: 'stable' | 'insider' | 'exploration';
}
async function getProductConfig(appRoot: string): Promise<ProductConfiguration> {
const raw = await vscode.workspace.fs.readFile(vscode.Uri.file(path.join(appRoot, 'product.json')));
return JSON.parse(raw.toString());
}
function getTargetPopulation(product: ProductConfiguration): TargetPopulation {
switch (product.quality) {
case 'stable':
return TargetPopulation.Public;
case 'insider':
return TargetPopulation.Insiders;
case 'exploration':
return TargetPopulation.Internal;
case undefined:
return TargetPopulation.Team;
default:
return TargetPopulation.Public;
}
}
export async function createExperimentationService(context: vscode.ExtensionContext, telemetry: ExperimentationTelemetry): Promise<IExperimentationService> {
const id = context.extension.id;
const version = context.extension.packageJSON.version;
const product = await getProductConfig(vscode.env.appRoot);
const targetPopulation = getTargetPopulation(product);
return getExperimentationService(id, version, targetPopulation, telemetry, context.globalState);
}

View file

@ -8,10 +8,14 @@ import { GitHubAuthenticationProvider, onDidChangeSessions } from './github';
import { uriHandler } from './githubServer';
import Logger from './common/logger';
import TelemetryReporter from 'vscode-extension-telemetry';
import { createExperimentationService, ExperimentationTelemetry } from './experimentationService';
export async function activate(context: vscode.ExtensionContext) {
const { name, version, aiKey } = require('../package.json') as { name: string, version: string, aiKey: string };
const telemetryReporter = new TelemetryReporter(name, version, aiKey);
const telemetryReporter = new ExperimentationTelemetry(new TelemetryReporter(name, version, aiKey));
const experimentationService = await createExperimentationService(context, telemetryReporter);
await experimentationService.initialFetch;
context.subscriptions.push(vscode.window.registerUriHandler(uriHandler));
const loginService = new GitHubAuthenticationProvider(context, telemetryReporter);

View file

@ -9,7 +9,7 @@ import { Keychain } from './common/keychain';
import { GitHubServer, NETWORK_ERROR } from './githubServer';
import Logger from './common/logger';
import { arrayEquals } from './common/utils';
import TelemetryReporter from 'vscode-extension-telemetry';
import { ExperimentationTelemetry } from './experimentationService';
export const onDidChangeSessions = new vscode.EventEmitter<vscode.AuthenticationProviderAuthenticationSessionsChangeEvent>();
@ -30,7 +30,7 @@ export class GitHubAuthenticationProvider {
private _keychain: Keychain;
constructor(context: vscode.ExtensionContext, telemetryReporter: TelemetryReporter) {
constructor(context: vscode.ExtensionContext, telemetryReporter: ExperimentationTelemetry) {
this._keychain = new Keychain(context);
this._githubServer = new GitHubServer(telemetryReporter);
}

View file

@ -9,7 +9,7 @@ import fetch, { Response } from 'node-fetch';
import { v4 as uuid } from 'uuid';
import { PromiseAdapter, promiseFromEvent } from './common/utils';
import Logger from './common/logger';
import TelemetryReporter from 'vscode-extension-telemetry';
import { ExperimentationTelemetry } from './experimentationService';
const localize = nls.loadMessageBundle();
@ -42,7 +42,7 @@ export class GitHubServer {
private _pendingStates = new Map<string, string[]>();
private _codeExchangePromises = new Map<string, { promise: Promise<string>, cancel: vscode.EventEmitter<void> }>();
constructor(private readonly telemetryReporter: TelemetryReporter) { }
constructor(private readonly telemetryReporter: ExperimentationTelemetry) { }
private isTestEnvironment(url: vscode.Uri): boolean {
return /\.azurewebsites\.net$/.test(url.authority) || url.authority.startsWith('localhost:');

View file

@ -55,6 +55,13 @@ asynckit@^0.4.0:
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
axios@^0.21.1:
version "0.21.1"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8"
integrity sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==
dependencies:
follow-redirects "^1.10.0"
cls-hooked@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908"
@ -103,6 +110,11 @@ emitter-listener@^1.0.1, emitter-listener@^1.1.1:
dependencies:
shimmer "^1.2.0"
follow-redirects@^1.10.0:
version "1.13.3"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.3.tgz#e5598ad50174c1bc4e872301e82ac2cd97f90267"
integrity sha512-DUgl6+HDzB0iEptNQEXLx/KhTmDb8tZUHSeLqpnjpknR70H0nC2t9N73BK6fN4hOvJ84pKlIQVQ4k5FFlBedKA==
form-data@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.0.tgz#31b7e39c85f1355b7139ee0c647cf0de7f83c682"
@ -144,6 +156,13 @@ stack-chain@^1.3.7:
resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285"
integrity sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=
tas-client@0.1.21:
version "0.1.21"
resolved "https://registry.yarnpkg.com/tas-client/-/tas-client-0.1.21.tgz#62275d5f75266eaae408f7463364748cb92f220d"
integrity sha512-7UuIwOXarCYoCTrQHY5n7M+63XuwMC0sVUdbPQzxqDB9wMjIW0JF39dnp3yoJnxr4jJUVhPtvkkXZbAD0BxCcA==
dependencies:
axios "^0.21.1"
uuid@8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.1.0.tgz#6f1536eb43249f473abc6bd58ff983da1ca30d8d"
@ -160,3 +179,10 @@ vscode-nls@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.2.tgz#ca8bf8bb82a0987b32801f9fddfdd2fb9fd3c167"
integrity sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw==
vscode-tas-client@^0.1.22:
version "0.1.22"
resolved "https://registry.yarnpkg.com/vscode-tas-client/-/vscode-tas-client-0.1.22.tgz#2dd674b21a94ff4e97db2b6545d9efda8b5f07c3"
integrity sha512-1sYH73nhiSRVQgfZkLQNJW7VzhKM9qNbCe8QyXgiKkLhH4GflDXRPAK4yy4P41jUgula+Fc9G7i5imj1dlKfaw==
dependencies:
tas-client "0.1.21"