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

optional telemetry #1092

Merged
merged 41 commits into from
Aug 10, 2022
Merged
Show file tree
Hide file tree
Changes from 37 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
f6ed7bf
Telemetry
DavidGOrtega Jul 9, 2022
d97b0c1
appdirs
DavidGOrtega Jul 9, 2022
ec6b5e3
analytics tested
DavidGOrtega Jul 10, 2022
4e9ac5d
remove analytics
DavidGOrtega Jul 10, 2022
e569c3b
deterministic check
DavidGOrtega Jul 10, 2022
f53673e
remove fake code
DavidGOrtega Jul 10, 2022
e74eda2
fix isCI
DavidGOrtega Jul 10, 2022
e71fec8
cml
DavidGOrtega Jul 10, 2022
271fd5c
integrated
DavidGOrtega Jul 11, 2022
052f68d
endpoint
DavidGOrtega Jul 12, 2022
cef1830
defensive
DavidGOrtega Jul 12, 2022
0b8790c
json spec
DavidGOrtega Jul 12, 2022
e5d0657
Telemetry (#1092) suggestion: don't repeat ourselves (#1094)
0x2b3bfa0 Jul 13, 2022
d818b82
dryer cml
DavidGOrtega Jul 14, 2022
9e1a351
dryer cml
DavidGOrtega Jul 14, 2022
554d909
telemetrySend
DavidGOrtega Jul 14, 2022
41ec815
naming consistency
DavidGOrtega Jul 14, 2022
53f800b
read non json id
DavidGOrtega Jul 14, 2022
977ddd5
gh check repoOptions
DavidGOrtega Jul 15, 2022
dd9dfd5
one error handler
DavidGOrtega Jul 15, 2022
32edb2d
Merge branch 'master' of https://github.com/iterative/cml into telemetry
DavidGOrtega Jul 15, 2022
181ab44
fix tensorboard
DavidGOrtega Jul 18, 2022
34152a7
fix tensorboard and tests
DavidGOrtega Jul 18, 2022
e7b9d9b
cleanup yargs fail handler
DavidGOrtega Jul 21, 2022
1b2a618
unused
DavidGOrtega Jul 21, 2022
1a79b29
RUNNER_SHUTTING_DOWN
DavidGOrtega Jul 21, 2022
ef13e13
remove comments
DavidGOrtega Jul 21, 2022
6f1f931
golantic
DavidGOrtega Jul 21, 2022
2589efa
Merge branch 'master' of https://github.com/iterative/cml into telemetry
DavidGOrtega Jul 28, 2022
006e226
getDriver
DavidGOrtega Jul 28, 2022
17fc89f
fix telemetry
DavidGOrtega Jul 28, 2022
76cfc3d
fix getter
DavidGOrtega Jul 28, 2022
6160b89
merge master
DavidGOrtega Jul 31, 2022
c1349c7
Merge branch 'master' into telemetry
DavidGOrtega Aug 1, 2022
f806b05
merge master
DavidGOrtega Aug 1, 2022
39c6669
Merge branch 'telemetry' of https://github.com/iterative/cml into tel…
DavidGOrtega Aug 1, 2022
d144438
remove report
DavidGOrtega Aug 1, 2022
6271cb8
remove console
DavidGOrtega Aug 4, 2022
a7944f8
fix os release
DavidGOrtega Aug 10, 2022
3b8d1ea
windows release
DavidGOrtega Aug 10, 2022
7e74df6
Merge branch 'master' into telemetry
DavidGOrtega Aug 10, 2022
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
109 changes: 67 additions & 42 deletions bin/cml.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,39 @@ const which = require('which');
const winston = require('winston');
const yargs = require('yargs');

const configureLogger = (level) => {
const CML = require('../src/cml').default;
const { jitsuEventPayload } = require('../src/analytics');
let OPTS;

const setupOpts = (opts) => {
const legacyEnvironmentVariables = {
TB_CREDENTIALS: 'CML_TENSORBOARD_DEV_CREDENTIALS',
DOCKER_MACHINE: 'CML_RUNNER_DOCKER_MACHINE',
RUNNER_IDLE_TIMEOUT: 'CML_RUNNER_IDLE_TIMEOUT',
RUNNER_LABELS: 'CML_RUNNER_LABELS',
RUNNER_SINGLE: 'CML_RUNNER_SINGLE',
RUNNER_REUSE: 'CML_RUNNER_REUSE',
RUNNER_NO_RETRY: 'CML_RUNNER_NO_RETRY',
RUNNER_DRIVER: 'CML_RUNNER_DRIVER',
RUNNER_REPO: 'CML_RUNNER_REPO',
RUNNER_PATH: 'CML_RUNNER_PATH'
};

for (const [oldName, newName] of Object.entries(legacyEnvironmentVariables)) {
if (process.env[oldName]) process.env[newName] = process.env[oldName];
}

const { markdownfile } = opts;
opts.markdownFile = markdownfile;
opts.cmlCommand = opts._[0];
opts.cml = new CML(opts);

OPTS = opts;
};

const setupLogger = (opts) => {
const { log: level } = opts;

winston.configure({
format: process.stdout.isTTY
? winston.format.combine(
Expand All @@ -29,59 +61,52 @@ const configureLogger = (level) => {
});
};

const setupTelemetry = async (opts) => {
const { cml, cmlCommand: action } = opts;
opts.telemetryEvent = await jitsuEventPayload({ action, cml });
};

const runPlugin = async ({ $0: executable, command }) => {
try {
if (command === undefined) throw new Error('no command');
const path = which.sync(`${basename(executable)}-${command}`);
const parameters = process.argv.slice(process.argv.indexOf(command) + 1); // HACK
process.exit(await pseudoexec(path, parameters));
} catch (error) {
yargs.showHelp();
dacbd marked this conversation as resolved.
Show resolved Hide resolved
winston.debug(error);
}
if (command === undefined) throw new Error('no command');
const path = which.sync(`${basename(executable)}-${command}`);
const parameters = process.argv.slice(process.argv.indexOf(command) + 1); // HACK
await pseudoexec(path, parameters);
};

const handleError = (message, error) => {
const handleError = async (message, error, yargs) => {
dacbd marked this conversation as resolved.
Show resolved Hide resolved
if (error) {
winston.error(error);
} else {
yargs.showHelp();
console.error('\n' + message);
const { telemetryEvent, cml } = OPTS;
const event = { ...telemetryEvent, error: error.message };
await cml.telemetrySend({ event });
return;
}
process.exit(1);
};

const options = {
log: {
type: 'string',
description: 'Maximum log level',
coerce: (value) => configureLogger(value) && value,
choices: ['error', 'warn', 'info', 'debug'],
default: 'info'
}
yargs.showHelp();
console.error('\n' + message);
};

const legacyEnvironmentVariables = {
TB_CREDENTIALS: 'CML_TENSORBOARD_DEV_CREDENTIALS',
DOCKER_MACHINE: 'CML_RUNNER_DOCKER_MACHINE',
RUNNER_IDLE_TIMEOUT: 'CML_RUNNER_IDLE_TIMEOUT',
RUNNER_LABELS: 'CML_RUNNER_LABELS',
RUNNER_SINGLE: 'CML_RUNNER_SINGLE',
RUNNER_REUSE: 'CML_RUNNER_REUSE',
RUNNER_NO_RETRY: 'CML_RUNNER_NO_RETRY',
RUNNER_DRIVER: 'CML_RUNNER_DRIVER',
RUNNER_REPO: 'CML_RUNNER_REPO',
RUNNER_PATH: 'CML_RUNNER_PATH'
};
process.on('uncaughtException', async (err) => {
await handleError('', err, yargs);
});

for (const [oldName, newName] of Object.entries(legacyEnvironmentVariables)) {
if (process.env[oldName]) process.env[newName] = process.env[oldName];
}
process.on('unhandledRejection', async (reason) => {
await handleError('', new Error(reason), yargs);
});

yargs
.fail(handleError)
.env('CML')
.options(options)
.options({
log: {
type: 'string',
description: 'Maximum log level',
choices: ['error', 'warn', 'info', 'debug'],
default: 'info'
}
})
.fail(handleError)
.middleware(setupOpts)
.middleware(setupLogger)
.middleware(setupTelemetry)
.commandDir('./cml', { exclude: /\.test\.js$/ })
.command('$0 <command>', false, (builder) => builder.strict(false), runPlugin)
.recommendCommands()
Expand Down
24 changes: 5 additions & 19 deletions bin/cml/ci.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
const kebabcaseKeys = require('kebabcase-keys');

const { GIT_USER_NAME, GIT_USER_EMAIL } = require('../../src/cml');
const CML = require('../../src/cml').default;
const { GIT_USER_NAME, GIT_USER_EMAIL, repoOptions } = require('../../src/cml');

exports.command = 'ci';
exports.description = 'Fixes specific CI setups';

exports.handler = async (opts) => {
const cml = new CML(opts);
console.log((await cml.ci(opts)) || '');
const { cml, telemetryEvent: event } = opts;
await cml.ci(opts);
await cml.telemetrySend({ event });
};

exports.builder = (yargs) =>
yargs.env('CML_CI').options(
kebabcaseKeys({
...repoOptions,
unshallow: {
type: 'boolean',
description:
Expand All @@ -28,21 +29,6 @@ exports.builder = (yargs) =>
type: 'string',
default: GIT_USER_NAME,
description: 'Set Git user name.'
},
repo: {
type: 'string',
description:
'Set repository to be used. If unspecified, inferred from the environment.'
},
token: {
type: 'string',
description:
'Personal access token to be used. If unspecified, inferred from the environment.'
},
driver: {
type: 'string',
choices: ['github', 'gitlab', 'bitbucket'],
description: 'If unspecified, inferred from the environment.'
}
})
);
14 changes: 7 additions & 7 deletions bin/cml/ci.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ describe('CML e2e', () => {
--version Show version number [boolean]
--log Maximum log level
[string] [choices: \\"error\\", \\"warn\\", \\"info\\", \\"debug\\"] [default: \\"info\\"]
--repo Specifies the repo to be used. If not specified is extracted
from the CI ENV. [string]
--token Personal access token to be used. If not specified is extracted
from ENV REPO_TOKEN. [string]
--driver If not specify it infers it from the ENV.
[string] [choices: \\"github\\", \\"gitlab\\", \\"bitbucket\\"]
--unshallow Fetch as much as possible, converting a shallow repository to a
complete one. [boolean]
--user-email Set Git user email. [string] [default: \\"[email protected]\\"]
--user-name Set Git user name. [string] [default: \\"Olivaw[bot]\\"]
--repo Set repository to be used. If unspecified, inferred from the
environment. [string]
--token Personal access token to be used. If unspecified, inferred from
the environment. [string]
--driver If unspecified, inferred from the environment.
[string] [choices: \\"github\\", \\"gitlab\\", \\"bitbucket\\"]"
--user-name Set Git user name. [string] [default: \\"Olivaw[bot]\\"]"
`);
});
});
31 changes: 11 additions & 20 deletions bin/cml/pr.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
const kebabcaseKeys = require('kebabcase-keys');

const { GIT_REMOTE, GIT_USER_NAME, GIT_USER_EMAIL } = require('../../src/cml');
const CML = require('../../src/cml').default;
const {
GIT_REMOTE,
GIT_USER_NAME,
GIT_USER_EMAIL,
repoOptions
} = require('../../src/cml');

exports.command = 'pr <glob path...>';
exports.description = 'Create a pull request with the specified files';

exports.handler = async (opts) => {
const cml = new CML(opts);
const link = await cml.prCreate({ ...opts, globs: opts.globpath });
if (link) console.log(link);
const { cml, telemetryEvent: event, globpath: globs } = opts;
const link = await cml.prCreate({ ...opts, globs });
console.log(link);
await cml.telemetrySend({ event });
};

exports.builder = (yargs) =>
yargs.env('CML_PR').options(
kebabcaseKeys({
...repoOptions,
md: {
type: 'boolean',
description: 'Output in markdown format [](url).'
Expand Down Expand Up @@ -69,21 +75,6 @@ exports.builder = (yargs) =>
type: 'string',
default: GIT_USER_NAME,
description: 'Sets git user name.'
},
repo: {
type: 'string',
description:
'Specifies the repo to be used. If not specified is extracted from the CI ENV.'
},
token: {
type: 'string',
description:
'Personal access token to be used. If not specified in extracted from ENV REPO_TOKEN.'
},
driver: {
type: 'string',
choices: ['github', 'gitlab', 'bitbucket'],
description: 'If not specify it infers it from the ENV.'
}
})
);
14 changes: 7 additions & 7 deletions bin/cml/pr.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ describe('CML e2e', () => {
--version Show version number [boolean]
--log Maximum log level
[string] [choices: \\"error\\", \\"warn\\", \\"info\\", \\"debug\\"] [default: \\"info\\"]
--repo Specifies the repo to be used. If not specified is
extracted from the CI ENV. [string]
--token Personal access token to be used. If not specified is
extracted from ENV REPO_TOKEN. [string]
--driver If not specify it infers it from the ENV.
[string] [choices: \\"github\\", \\"gitlab\\", \\"bitbucket\\"]
--md Output in markdown format [](url). [boolean]
--skip-ci Force skip CI for the created commit (if any) [boolean]
--merge, --auto-merge Try to merge the pull request upon creation. [boolean]
Expand All @@ -28,13 +34,7 @@ describe('CML e2e', () => {
--remote Sets git remote. [string] [default: \\"origin\\"]
--user-email Sets git user email.
[string] [default: \\"[email protected]\\"]
--user-name Sets git user name. [string] [default: \\"Olivaw[bot]\\"]
--repo Specifies the repo to be used. If not specified is
extracted from the CI ENV. [string]
--token Personal access token to be used. If not specified in
extracted from ENV REPO_TOKEN. [string]
--driver If not specify it infers it from the ENV.
[string] [choices: \\"github\\", \\"gitlab\\", \\"bitbucket\\"]"
--user-name Sets git user name. [string] [default: \\"Olivaw[bot]\\"]"
`);
});
});
25 changes: 6 additions & 19 deletions bin/cml/publish.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const fs = require('fs').promises;
const kebabcaseKeys = require('kebabcase-keys');
const winston = require('winston');

const CML = require('../../src/cml').default;
const { CML, repoOptions } = require('../../src/cml');

exports.command = 'publish <asset>';
exports.description = 'Upload an image to build a report';
Expand All @@ -15,23 +15,20 @@ exports.handler = async (opts) => {
opts.native = true;
}

const { file, repo, native } = opts;

const path = opts.asset;
const { file, repo, native, asset: path, telemetryEvent: event } = opts;
const cml = new CML({ ...opts, repo: native ? repo : 'cml' });

const output = await cml.publish({
...opts,
path
});
const output = await cml.publish({ ...opts, path });

if (!file) console.log(output);
else await fs.writeFile(file, output);

await cml.telemetrySend({ event });
};

exports.builder = (yargs) =>
yargs.env('CML_PUBLISH').options(
kebabcaseKeys({
...repoOptions,
url: {
type: 'string',
description: 'Self-Hosted URL',
Expand Down Expand Up @@ -75,16 +72,6 @@ exports.builder = (yargs) =>
type: 'string',
description:
'Specifies the repo to be used. If not specified is extracted from the CI ENV.'
},
token: {
type: 'string',
description:
'Personal access token to be used. If not specified, extracted from ENV REPO_TOKEN, GITLAB_TOKEN, GITHUB_TOKEN, or BITBUCKET_TOKEN.'
},
driver: {
type: 'string',
choices: ['github', 'gitlab', 'bitbucket'],
description: 'If not specify it infers it from the ENV.'
}
})
);
15 changes: 7 additions & 8 deletions bin/cml/publish.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,19 @@ describe('CML e2e', () => {
--version Show version number [boolean]
--log Maximum log level
[string] [choices: \\"error\\", \\"warn\\", \\"info\\", \\"debug\\"] [default: \\"info\\"]
--repo Specifies the repo to be used. If not specified is
extracted from the CI ENV. [string]
--token Personal access token to be used. If not specified is
extracted from ENV REPO_TOKEN. [string]
--driver If not specify it infers it from the ENV.
[string] [choices: \\"github\\", \\"gitlab\\", \\"bitbucket\\"]
--md Output in markdown format [title || name](url). [boolean]
-t, --title Markdown title [title](url) or ![](url title). [string]
--native Uses driver's native capabilities to upload assets instead
of CML's storage. Not available on GitHub. [boolean]
--rm-watermark Avoid CML watermark. [boolean]
--mime-type Specifies the mime-type. If not set guess it from the
content. [string]
--repo Specifies the repo to be used. If not specified is
extracted from the CI ENV. [string]
--token Personal access token to be used. If not specified,
extracted from ENV REPO_TOKEN, GITLAB_TOKEN, GITHUB_TOKEN,
or BITBUCKET_TOKEN. [string]
--driver If not specify it infers it from the ENV.
[string] [choices: \\"github\\", \\"gitlab\\", \\"bitbucket\\"]"
content. [string]"
`);
});

Expand Down
Loading