From 72106b77d6f8a906da169c2e5a364dbcd4f3a820 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Wed, 14 Oct 2020 19:01:49 +0200 Subject: [PATCH 01/66] [wip] CML contexts --- bin/cml-cloud-runner-entrypoint.js | 27 ++--- bin/cml-cloud-runner.js | 17 ++- bin/cml-publish.js | 32 ++---- bin/cml-send-comment.js | 13 ++- bin/cml-send-comment.test.js | 27 +++-- bin/cml-send-github-check.js | 21 ++-- bin/cml-send-github-check.test.js | 25 ++--- bin/cml-tensorboard-dev.js | 10 +- src/GithubClient.js | 131 ++++++++++++++++++++++ src/GithubClient.test.js | 112 +++++++++++++++++++ src/GitlabClient.js | 111 +++++++++++++++++++ src/GitlabClient.test.js | 102 +++++++++++++++++ src/cml.js | 74 +++++++++++++ src/cml.test.js | 171 +++++++++++++++++++++++++++++ src/github.js | 112 ------------------- src/gitlab.js | 115 ------------------- src/report.js | 22 ---- src/report.test.js | 35 ------ src/utils.js | 6 + 19 files changed, 787 insertions(+), 376 deletions(-) create mode 100644 src/GithubClient.js create mode 100644 src/GithubClient.test.js create mode 100644 src/GitlabClient.js create mode 100644 src/GitlabClient.test.js create mode 100644 src/cml.js create mode 100644 src/cml.test.js delete mode 100644 src/github.js delete mode 100644 src/gitlab.js delete mode 100644 src/report.js delete mode 100644 src/report.test.js diff --git a/bin/cml-cloud-runner-entrypoint.js b/bin/cml-cloud-runner-entrypoint.js index 31e26d0b5..d0f0ae650 100755 --- a/bin/cml-cloud-runner-entrypoint.js +++ b/bin/cml-cloud-runner-entrypoint.js @@ -1,8 +1,9 @@ #!/usr/bin/env node const { spawn } = require('child_process'); + const { exec, randid } = require('../src/utils'); -const { URL } = require('url'); +const CML = require('../src/cml'); const { DOCKER_MACHINE, // DEPRECATED @@ -14,27 +15,21 @@ const { RUNNER_NAME = randid(), RUNNER_EXECUTOR = 'shell', RUNNER_RUNTIME = '', - RUNNER_IMAGE = 'dvcorg/cml:latest' + RUNNER_IMAGE = 'dvcorg/cml:latest', + + repo_token } = process.env; -const { protocol, host, pathname } = new URL(RUNNER_REPO); +const { protocol, host } = new URL(RUNNER_REPO); const RUNNER_REPO_ORIGIN = `${protocol}//${host}`; -process.env.CI_API_V4_URL = `${RUNNER_REPO_ORIGIN}/api/v4/`; -process.env.GITHUB_REPOSITORY = process.env.CI_PROJECT_PATH = pathname.substring( - 1, - pathname.length - (pathname.endsWith('/') ? 1 : 0) -); +const IS_GITHUB = RUNNER_REPO.startsWith('https://github.com'); +const cml = new CML({ driver: 'github', repo: RUNNER_REPO, token: repo_token }); -const IS_GITHUB = RUNNER_REPO_ORIGIN === 'https://github.com'; let TIMEOUT_TIMER = 0; let JOB_RUNNING = false; let RUNNER_TOKEN; let GITLAB_CI_TOKEN; -const { get_runner_token, register_runner } = IS_GITHUB - ? require('../src/github') - : require('../src/gitlab'); - const shutdown_docker_machine = async () => { console.log('Shutting down docker machine'); try { @@ -98,7 +93,7 @@ process.on('SIGTERM', shutdown); process.on('SIGINT', shutdown); process.on('SIGQUIT', shutdown); const run = async () => { - RUNNER_TOKEN = await get_runner_token(); + RUNNER_TOKEN = await cml.runner_token(); if (!RUNNER_TOKEN) { throw new Error( @@ -124,7 +119,7 @@ const run = async () => { command = `${RUNNER_PATH}/run.sh`; } else { console.log('Registering Gitlab runner'); - const runner = await register_runner({ + const runner = await cml.client.register_runner({ tags: RUNNER_LABELS, token: RUNNER_TOKEN }); @@ -132,8 +127,8 @@ const run = async () => { GITLAB_CI_TOKEN = runner.token; command = `gitlab-runner --log-format="json" run-single \ - --url "${RUNNER_REPO_ORIGIN}" \ --token "${runner.token}" \ + --url "${RUNNER_REPO_ORIGIN}" \ --executor "${RUNNER_EXECUTOR}" \ --docker-runtime "${RUNNER_RUNTIME}" \ --docker-image "${RUNNER_IMAGE}" \ diff --git a/bin/cml-cloud-runner.js b/bin/cml-cloud-runner.js index 66c249d8a..ce6a09f5f 100644 --- a/bin/cml-cloud-runner.js +++ b/bin/cml-cloud-runner.js @@ -5,6 +5,7 @@ const NodeSSH = require('node-ssh').NodeSSH; const fss = require('fs'); const fs = fss.promises; const path = require('path'); + const { exec, sleep, @@ -12,9 +13,10 @@ const { parse_param_newline } = require('../src/utils'); -const { handle_error, repo: REPO, token: TOKEN } = process.env.GITHUB_ACTIONS - ? require('../src/github') - : require('../src/gitlab'); +const CML = require('../src/cml'); + +let REPO; +let TOKEN; const TF_FOLDER = '.cml'; const TF_NO_LOCAL = '.nolocal'; @@ -208,6 +210,10 @@ const shutdown = async () => { }; const run = async (opts) => { + const cml = new CML(); + REPO = cml.client.env_repo(); + TOKEN = cml.client.env_token(); + try { const terraform_state = await run_terraform(opts); await setup_runners({ terraform_state, ...opts }); @@ -268,4 +274,7 @@ const argv = yargs .describe('attached', 'Runs the runner in the foreground.') .coerce('rsa-private-key', parse_param_newline) .help('h').argv; -run(argv).catch((e) => handle_error(e)); +run(argv).catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/bin/cml-publish.js b/bin/cml-publish.js index 0f0b9cbea..8904f00b5 100644 --- a/bin/cml-publish.js +++ b/bin/cml-publish.js @@ -6,33 +6,18 @@ console.log = console.error; const fs = require('fs').promises; const pipe_args = require('../src/pipe-args'); const yargs = require('yargs'); -const { publish_file } = require('../src/report'); -const { GITHUB_ACTIONS } = process.env; - -const { handle_error } = GITHUB_ACTIONS - ? require('../src/github') - : require('../src/gitlab'); +const CML = require('../src/cml'); const run = async (opts) => { - const { data, file } = opts; - let { 'gitlab-uploads': gitlab_uploads } = opts; - const path = opts._[0]; + const { data, file, 'gitlab-uploads': gitlab_uploads } = opts; + const path = opts._[0]; let buffer; if (data) buffer = Buffer.from(data, 'binary'); - if (GITHUB_ACTIONS && gitlab_uploads) { - console.error(` - ********************************************* - * gitlab-uploads option is only for gitlab! * - * ******************************************* - `); - - gitlab_uploads = false; - } - - const output = await publish_file({ buffer, path, gitlab_uploads, ...opts }); + const cml = new CML(opts); + const output = await cml.publish({ buffer, path, gitlab_uploads, ...opts }); if (!file) print(output); else await fs.writeFile(file, output); @@ -42,6 +27,7 @@ pipe_args.load('binary'); const data = pipe_args.piped_arg(); const argv = yargs .usage(`Usage: $0 `) + .describe('md', 'Output in markdown format [title || name](url).') .boolean('md') .describe('md', 'Output in markdown format [title || name](url).') .default('title') @@ -60,4 +46,8 @@ const argv = yargs .alias('file', 'f') .help('h') .demand(data ? 0 : 1).argv; -run({ ...argv, data }).catch((e) => handle_error(e)); + +run({ ...argv, data }).catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/bin/cml-send-comment.js b/bin/cml-send-comment.js index c80f396dc..654c80412 100644 --- a/bin/cml-send-comment.js +++ b/bin/cml-send-comment.js @@ -5,16 +5,15 @@ console.log = console.error; const fs = require('fs').promises; const yargs = require('yargs'); -const { head_sha: HEAD_SHA, handle_error, comment } = process.env.GITHUB_ACTIONS - ? require('../src/github') - : require('../src/gitlab'); +const CML = require('../src/cml'); const run = async (opts) => { const { 'commit-sha': sha, 'head-sha': head_sha } = opts; const path = opts._[0]; const report = await fs.readFile(path, 'utf-8'); - await comment({ commit_sha: sha || head_sha || HEAD_SHA, report }); + const cml = new CML(opts); + await cml.comment_create({ report, commit_sha: sha || head_sha }); }; const argv = yargs @@ -29,4 +28,8 @@ const argv = yargs .deprecateOption('head-sha', 'Use commit-sha instead') .help('h') .demand(1).argv; -run(argv).catch((e) => handle_error(e)); + +run(argv).catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/bin/cml-send-comment.test.js b/bin/cml-send-comment.test.js index 9dd737ae1..7fee4bfa1 100644 --- a/bin/cml-send-comment.test.js +++ b/bin/cml-send-comment.test.js @@ -2,22 +2,14 @@ jest.setTimeout(200000); const { exec } = require('../src/utils'); const fs = require('fs').promises; -const { publish_file } = require('../src/report'); -describe('CML e2e', () => { - test('cml-send-comment', async () => { - const path = 'comment.md'; - const img = await publish_file({ - path: 'assets/logo.png', - md: true, - title: 'logo' - }); - - const report = `## Test Comment Report \n ${img}`; +describe('Comment integration tests', () => { + const path = 'comment.md'; - await fs.writeFile(path, report); - await exec(`node ./bin/cml-send-comment.js ${path}`); - await fs.unlink(path); + afterEach(async () => { + try { + await fs.unlink(path); + } catch (err) {} }); test('cml-send-comment -h', async () => { @@ -34,4 +26,11 @@ describe('CML e2e', () => { -h Show help [boolean]" `); }); + + test('cml-send-comment', async () => { + const report = `## Test Comment Report`; + + await fs.writeFile(path, report); + await exec(`node ./bin/cml-send-comment.js ${path}`); + }); }); diff --git a/bin/cml-send-github-check.js b/bin/cml-send-github-check.js index 2d96fcaf6..df31e4158 100644 --- a/bin/cml-send-github-check.js +++ b/bin/cml-send-github-check.js @@ -5,21 +5,16 @@ console.log = console.error; const fs = require('fs').promises; const yargs = require('yargs'); -const { - head_sha: HEAD_SHA, - handle_error, - create_check_report, - CHECK_TITLE -} = process.env.GITHUB_ACTIONS - ? require('../src/github') - : require('../src/gitlab'); +const CML = require('../src/cml'); +const CHECK_TITLE = 'CML Report'; const run = async (opts) => { - const { 'head-sha': head_sha = HEAD_SHA, conclusion, title } = opts; + const { 'head-sha': head_sha, conclusion, title } = opts; const path = opts._[0]; const report = await fs.readFile(path, 'utf-8'); - await create_check_report({ head_sha, report, conclusion, title }); + const cml = new CML(opts); + await cml.check_create({ head_sha, report, conclusion, title }); }; const argv = yargs @@ -42,4 +37,8 @@ const argv = yargs .describe('title', 'Sets title of the check.') .help('h') .demand(1).argv; -run(argv).catch((e) => handle_error(e)); + +run(argv).catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/bin/cml-send-github-check.test.js b/bin/cml-send-github-check.test.js index 837defa19..a9ac62ec1 100644 --- a/bin/cml-send-github-check.test.js +++ b/bin/cml-send-github-check.test.js @@ -2,31 +2,25 @@ jest.setTimeout(200000); const { exec } = require('../src/utils'); const fs = require('fs').promises; -const { publish_file } = require('../src/report'); describe('CML e2e', () => { + const path = 'check.md'; + + afterEach(async () => { + try { + await fs.unlink(path); + } catch (err) {} + }); + test('cml-send-github-check', async () => { - const path = 'check.md'; - const img = await publish_file({ - path: 'assets/logo.png', - md: true, - title: 'logo' - }); - const pdf = await publish_file({ - path: 'assets/logo.pdf', - md: true, - title: 'logo' - }); - const report = `## Test Check Report \n ${img} \n ${pdf}`; + const report = `## Test Check Report`; await fs.writeFile(path, report); process.env.GITHUB_ACTIONS && (await exec(`node ./bin/cml-send-github-check.js ${path}`)); - await fs.unlink(path); }); test('cml-send-github-check failure with tile "CML neutral test"', async () => { - const path = 'check.md'; const report = `## Hi this check should be neutral`; const title = 'CML neutral test'; const conclusion = 'neutral'; @@ -36,7 +30,6 @@ describe('CML e2e', () => { (await exec( `node ./bin/cml-send-github-check.js ${path} --title "${title}" --conclusion "${conclusion}"` )); - await fs.unlink(path); }); test('cml-send-github-check -h', async () => { diff --git a/bin/cml-tensorboard-dev.js b/bin/cml-tensorboard-dev.js index 7e9bb0c21..b9134e3b4 100644 --- a/bin/cml-tensorboard-dev.js +++ b/bin/cml-tensorboard-dev.js @@ -8,11 +8,8 @@ const fs = require('fs').promises; const { spawn } = require('child_process'); const { homedir } = require('os'); const tempy = require('tempy'); -const { exec } = require('../src/utils'); -const { handle_error } = process.env.GITHUB_ACTIONS - ? require('../src/github') - : require('../src/gitlab'); +const { exec } = require('../src/utils'); const { TB_CREDENTIALS } = process.env; @@ -125,4 +122,7 @@ const argv = yargs .alias('file', 'f') .help('h').argv; -run(argv).catch((e) => handle_error(e)); +run(argv).catch((e) => { + console.error(e); + process.exit(1); +}); diff --git a/src/GithubClient.js b/src/GithubClient.js new file mode 100644 index 000000000..e61e7aada --- /dev/null +++ b/src/GithubClient.js @@ -0,0 +1,131 @@ +const github = require('@actions/github'); + +const { strip_last_chars } = require('./utils'); + +const GITHUB_HOST = 'https://github.com/'; +const CHECK_TITLE = 'CML Report'; + +const owner_repo = (opts) => { + let owner, repo; + const { uri } = opts; + + if (uri) { + const { pathname } = new URL(uri); + [owner, repo] = pathname.substr(1).split('/'); + } + + const { GITHUB_REPOSITORY } = process.env; + if (GITHUB_REPOSITORY) { + [owner, repo] = GITHUB_REPOSITORY.split('/'); + } + + return { owner, repo }; +}; + +class GithubClient { + constructor(opts = {}) { + const { repo = this.env_repo(), token = this.env_token() } = opts; + + if (!repo) throw new Error('repo not found'); + if (!token) throw new Error('token not found'); + + this.repo = repo.endsWith('/') ? strip_last_chars(repo, 1) : repo; + this.token = token; + this.octokit = github.getOctokit(token); + } + + env_repo() { + const { GITHUB_REPOSITORY } = process.env; + if (GITHUB_REPOSITORY) return `${GITHUB_HOST}${GITHUB_REPOSITORY}`; + } + + env_token() { + const { repo_token, GITHUB_TOKEN } = process.env; + return repo_token || GITHUB_TOKEN; + } + + env_is_pr() { + try { + return typeof github.context.payload.pull_request !== 'undefined'; + } catch (err) { + return false; + } + } + + env_head_sha() { + if (this.env_is_pr()) return github.context.payload.pull_request.head.sha; + + const { GITHUB_SHA } = process.env; + return GITHUB_SHA; + } + + owner_repo(opts = {}) { + const { uri = this.repo } = opts; + return owner_repo({ uri }); + } + + async comment_create(opts = {}) { + const { report: body, commit_sha = this.env_head_sha() } = opts; + + const { url: commit_url } = await this.octokit.repos.createCommitComment({ + ...owner_repo({ uri: this.repo }), + body, + commit_sha + }); + + return commit_url; + } + + async check_create(opts = {}) { + const { + report, + commit_sha: head_sha = this.env_head_sha(), + title = CHECK_TITLE, + name = CHECK_TITLE, + started_at = new Date(), + completed_at = new Date(), + conclusion = 'success', + status = 'completed' + } = opts; + + return await this.octokit.checks.create({ + ...owner_repo({ uri: this.repo }), + head_sha, + started_at, + completed_at, + conclusion, + status, + name, + output: { title, summary: report } + }); + } + + async publish() { + throw new Error('Github does not support publish!'); + } + + async runner_token() { + const { owner, repo } = owner_repo({ uri: this.repo }); + + if (typeof repo !== 'undefined') { + const { + data: { token } + } = await this.octokit.actions.createRegistrationTokenForRepo({ + owner, + repo + }); + + return token; + } + + const { + data: { token } + } = await this.octokit.actions.createRegistrationTokenForOrg({ + org: owner + }); + + return token; + } +} + +module.exports = GithubClient; diff --git a/src/GithubClient.test.js b/src/GithubClient.test.js new file mode 100644 index 000000000..80be281bd --- /dev/null +++ b/src/GithubClient.test.js @@ -0,0 +1,112 @@ +jest.setTimeout(20000); + +const GithubClient = require('./GithubClient'); + +const TOKEN = process.env.GITHUB_TOKEN || process.env.repo_token; +const GITHUB_REPOSITORY = 'DavidGOrtega/3_tensorboard'; +const REPO = `https://github.com/${GITHUB_REPOSITORY}`; +const SHA = 'ee672b3b35c21b440c6fe6890de2fe769fbdbcee'; + +describe('Non Enviromental tests', () => { + const gh_client = new GithubClient({ repo: REPO, token: TOKEN }); + + test('test repo and token', async () => { + expect(gh_client.repo).toBe(REPO); + expect(gh_client.token).toBe(TOKEN); + + const { owner, repo } = gh_client.owner_repo(); + expect(owner).toBe('DavidGOrtega'); + expect(repo).toBe('3_tensorboard'); + }); + + test('Comment', async () => { + const report = '## Test comment'; + const commit_sha = SHA; + + await gh_client.comment_create({ report, commit_sha }); + }); + + test('Check', async () => { + const report = '## Hi this check should be neutral'; + const title = 'CML neutral test'; + const conclusion = `neutral`; + + const output = await gh_client.check_create({ report, title, conclusion }); + expect(output.startsWith('https://')).toBe(true); + }); + + test('Publish', async () => { + await expect(gh_client.publish()).rejects.toThrow( + 'Github does not support publish!' + ); + }); + + test('Runner token', async () => { + const output = await gh_client.runner_token(); + expect(output.length).toBe(29); + }); +}); + +describe('Enviromental tests', () => { + const OLD_ENV = process.env; + + beforeEach(() => { + jest.resetModules(); + + process.env = { ...OLD_ENV }; + + process.env.repo_token = TOKEN; + process.env.GITHUB_REPOSITORY = GITHUB_REPOSITORY; + process.env.GITHUB_SHA = SHA; + }); + + afterAll(() => { + process.env = OLD_ENV; + }); + + test('Env', async () => { + const gh_client = new GithubClient({}); + + expect(gh_client.env_is_pr()).toBe(false); + expect(gh_client.env_head_sha()).toBe(SHA); + expect(gh_client.env_repo()).toBe(REPO); + expect(gh_client.env_token()).toBe(TOKEN); + + expect(gh_client.repo).toBe(REPO); + expect(gh_client.token).toBe(TOKEN); + + const { owner, repo } = gh_client.owner_repo(); + expect(owner).toBe('DavidGOrtega'); + expect(repo).toBe('3_tensorboard'); + }); + + test('Comment', async () => { + const gh_client = new GithubClient({}); + const report = '## Test comment'; + + await gh_client.comment_create({ report }); + }); + + test('Check', async () => { + const gh_client = new GithubClient({}); + const report = '## Hi this check should be neutral'; + const title = 'CML neutral test'; + const conclusion = `neutral`; + + const output = await gh_client.check_create({ report, title, conclusion }); + expect(output.startsWith('https://')).toBe(true); + }); + + test('Publish', async () => { + const gh_client = new GithubClient({}); + await expect(gh_client.publish()).rejects.toThrow( + 'Github does not support publish!' + ); + }); + + test('Runner token', async () => { + const gh_client = new GithubClient({}); + const output = await gh_client.runner_token(); + expect(output.length).toBe(29); + }); +}); diff --git a/src/GitlabClient.js b/src/GitlabClient.js new file mode 100644 index 000000000..462cf1967 --- /dev/null +++ b/src/GitlabClient.js @@ -0,0 +1,111 @@ +const fetch = require('node-fetch'); +const FormData = require('form-data'); +const { URL, URLSearchParams } = require('url'); + +const { fetch_upload_data, strip_last_chars } = require('./utils'); + +class GitlabClient { + constructor(opts = {}) { + const { repo = this.env_repo(), token = this.env_token() } = opts; + + if (!repo) throw new Error('repo not found'); + if (!token) throw new Error('token not found'); + + this.repo = repo.endsWith('/') ? strip_last_chars(repo, 1) : repo; + this.token = token; + + const { protocol, host, pathname } = new URL(repo); + this.repo_origin = `${protocol}//${host}`; + this.api_v4 = `${this.repo_origin}/api/v4`; + this.project_path = encodeURIComponent(pathname.substring(1)); + } + + env_repo() { + const { CI_PROJECT_URL } = process.env; + return CI_PROJECT_URL; + } + + env_token() { + const { repo_token, GITLAB_TOKEN } = process.env; + return repo_token || GITLAB_TOKEN; + } + + env_is_pr() { + const { CI_MERGE_REQUEST_ID } = process.env; + return typeof CI_MERGE_REQUEST_ID !== 'undefined'; + } + + env_head_sha() { + const { CI_COMMIT_SHA } = process.env; + return CI_COMMIT_SHA; + } + + async comment_create(opts = {}) { + const { project_path } = this; + const { commit_sha = this.env_head_sha(), report } = opts; + + const endpoint = `/projects/${project_path}/repository/commits/${commit_sha}/comments`; + const body = new URLSearchParams(); + body.append('note', report); + + const output = await this.request({ endpoint, method: 'POST', body }); + + return output; + } + + async check_create() { + throw new Error('Gitlab does not support check!'); + } + + async publish(opts = {}) { + const { project_path, repo } = this; + const endpoint = `/projects/${project_path}/uploads`; + const { size, mime, data } = await fetch_upload_data(opts); + const body = new FormData(); + body.append('file', data); + + const { url } = await this.request({ endpoint, method: 'POST', body }); + + return { uri: `${repo}${url}`, mime, size }; + } + + async runner_token() { + const { project_path } = this; + + const endpoint = `/projects/${project_path}`; + + const { runners_token } = await this.request({ endpoint }); + + return runners_token; + } + + async register_runner(opts = {}) { + const { token } = this; + const { tags } = opts; + + const endpoint = `/runners`; + const body = new URLSearchParams(); + body.append('token', token); + body.append('tag_list', tags); + body.append('locked', 'true'); + body.append('run_untagged', 'true'); + body.append('access_level', 'not_protected'); + + return await this.request({ endpoint, method: 'POST', body }); + } + + async request(opts = {}) { + const { token, api_v4 } = this; + const { endpoint, method = 'GET', body } = opts; + + if (!endpoint) throw new Error('Gitlab API endpoint not found'); + + const headers = { 'PRIVATE-TOKEN': token, Accept: 'application/json' }; + const url = `${api_v4}${endpoint}`; + const response = await fetch(url, { method, headers, body }); + + return await response.json(); + } +} + +module.exports = GitlabClient; diff --git a/src/GitlabClient.test.js b/src/GitlabClient.test.js new file mode 100644 index 000000000..fe68e6dd9 --- /dev/null +++ b/src/GitlabClient.test.js @@ -0,0 +1,102 @@ +jest.setTimeout(20000); + +const GitlabClient = require('./GitlabClient'); + +const TOKEN = process.env.GITLAB_TOKEN || process.env.repo_token; +const REPO = 'https://gitlab.com/DavidGOrtega/3_tensorboard'; +const SHA = '2dc250a9449728356913e1f0e30758a44da65a12'; + +describe('Non Enviromental tests', () => { + const client = new GitlabClient({ repo: REPO, token: TOKEN }); + + test('test repo and token', async () => { + expect(client.repo).toBe(REPO); + expect(client.token).toBe(TOKEN); + }); + + test('Comment', async () => { + const report = '## Test comment'; + const commit_sha = SHA; + + const { created_at } = await client.comment_create({ report, commit_sha }); + expect(created_at).not.toBeUndefined(); + }); + + test('Check', async () => { + await expect(client.check_create()).rejects.toThrow( + 'Gitlab does not support check!' + ); + }); + + test('Publish', async () => { + const path = `${__dirname}/../assets/logo.png`; + const { uri } = await client.publish({ path }); + + console.log(uri); + expect(uri).not.toBeUndefined(); + }); + + test('Runner token', async () => { + const output = await client.runner_token(); + expect(output.length).toBe(20); + }); +}); + +describe('Enviromental tests', () => { + const OLD_ENV = process.env; + + beforeEach(() => { + jest.resetModules(); + + process.env = { ...OLD_ENV }; + + process.env.repo_token = TOKEN; + process.env.CI_PROJECT_URL = REPO; + process.env.CI_COMMIT_SHA = SHA; + }); + + afterAll(() => { + process.env = OLD_ENV; + }); + + test('Env', async () => { + const client = new GitlabClient(); + + expect(client.env_is_pr()).toBe(false); + expect(client.env_head_sha()).toBe(SHA); + expect(client.env_repo()).toBe(REPO); + expect(client.env_token()).toBe(TOKEN); + + expect(client.repo).toBe(REPO); + expect(client.token).toBe(TOKEN); + }); + + test('Comment', async () => { + const client = new GitlabClient(); + const report = '## Test comment'; + + const { created_at } = await client.comment_create({ report }); + expect(created_at).not.toBeUndefined(); + }); + + test('Check', async () => { + const client = new GitlabClient(); + await expect(client.check_create()).rejects.toThrow( + 'Gitlab does not support check!' + ); + }); + + test('Publish', async () => { + const client = new GitlabClient(); + const path = `${__dirname}/../assets/logo.png`; + const { uri } = await client.publish({ path }); + + expect(uri).not.toBeUndefined(); + }); + + test('Runner token', async () => { + const client = new GitlabClient(); + const output = await client.runner_token(); + expect(output.length).toBe(20); + }); +}); diff --git a/src/cml.js b/src/cml.js new file mode 100644 index 000000000..7eaa90358 --- /dev/null +++ b/src/cml.js @@ -0,0 +1,74 @@ +const GitlabClient = require('./GitlabClient'); +const GithubClient = require('./GithubClient'); +const { upload } = require('./utils'); + +const get_client = (opts) => { + const { driver, repo, token } = opts; + if (!driver) throw new Error('driver not set'); + + if (driver === 'github') return new GithubClient({ repo, token }); + + if (driver === 'gitlab') return new GitlabClient({ repo, token }); + + throw new Error('driver unknown!'); +}; + +class CML { + constructor(opts = {}) { + const env_driver = () => { + const { repo } = opts; + const { GITHUB_REPOSITORY, CI_PROJECT_URL } = process.env; + + if (GITHUB_REPOSITORY || (repo && repo.startsWith('https://github.com'))) + return 'github'; + if (CI_PROJECT_URL || (repo && repo.startsWith('https://gitlab.com'))) + return 'gitlab'; + }; + + const { driver = env_driver(), repo, token } = opts; + this.driver = driver; + this.repo = repo; + this.token = token; + } + + async comment_create(opts = {}) { + const client = get_client(this); + return await client.comment_create(opts); + } + + async check_create(opts = {}) { + const client = get_client(this); + return await client.check_create(opts); + } + + async publish(opts = {}) { + const { title = '', md, gitlab_uploads } = opts; + + let mime, uri; + + if (gitlab_uploads) { + const client = get_client(this); + ({ mime, uri } = await client.publish(opts)); + } else { + ({ mime, uri } = await upload(opts)); + } + + if (md && mime.match('(image|video)/.*')) + return `![](${uri}${title ? ` "${title}"` : ''})`; + + if (md) return `[${title}](${uri})`; + + return uri; + } + + async runner_token() { + const client = get_client(this); + return await client.runner_token(); + } + + log_error(e) { + console.error(e.message); + } +} + +module.exports = CML; diff --git a/src/cml.test.js b/src/cml.test.js new file mode 100644 index 000000000..0287d8ded --- /dev/null +++ b/src/cml.test.js @@ -0,0 +1,171 @@ +const CML = require('./cml'); + +describe('Github tests', () => { + const OLD_ENV = process.env; + + const TOKEN = process.env.GITHUB_TOKEN || process.env.repo_token; + const GITHUB_REPOSITORY = 'DavidGOrtega/3_tensorboard'; + const REPO = `https://github.com/${GITHUB_REPOSITORY}`; + const SHA = 'ee672b3b35c21b440c6fe6890de2fe769fbdbcee'; + + beforeEach(() => { + jest.resetModules(); + + process.env = { ...OLD_ENV }; + process.env.GITHUB_REPOSITORY = GITHUB_REPOSITORY; + process.env.repo_token = TOKEN; + process.env.GITHUB_SHA = SHA; + }); + + afterAll(() => { + process.env = OLD_ENV; + }); + + test('env driver has to be github', async () => { + const cml = new CML(); + expect(cml.driver).toBe('github'); + }); + + test('driver has to be github', async () => { + const cml = new CML({ repo: REPO, token: TOKEN, driver: 'github' }); + expect(cml.driver).toBe('github'); + }); + + test('Publish image without markdown returns an url', async () => { + const path = `${__dirname}/../assets/logo.png`; + + const output = await new CML().publish({ path }); + + expect(output.startsWith('https://')).toBe(true); + }); + + test('Publish image with markdown', async () => { + const path = `${__dirname}/../assets/logo.png`; + const title = 'my title'; + + const output = await new CML().publish({ path, md: true, title }); + + expect(output.startsWith('![](https://')).toBe(true); + expect(output.endsWith(` "${title}")`)).toBe(true); + }); + + test('Publish a non image file in markdown', async () => { + const path = `${__dirname}/../assets/logo.pdf`; + const title = 'my title'; + + const output = await new CML().publish({ path, md: true, title }); + + expect(output.startsWith(`[${title}](https://`)).toBe(true); + expect(output.endsWith(')')).toBe(true); + }); + + test('Comment should succeed with a valid sha', async () => { + const report = '## Test comment'; + const commit_sha = SHA; + + await new CML().comment_create({ report, commit_sha }); + }); + + test('Comment should fail with a unvalid sha', async () => { + let catched_err; + try { + const report = '## Test comment'; + const commit_sha = 'invalid_sha'; + + await new CML().comment_create({ report, commit_sha }); + } catch (err) { + catched_err = err.message; + } + + expect(catched_err).toBe('No commit found for SHA: invalid_sha'); + }); + + test('Check should succeed with a valid sha', async () => { + const report = '## Test comment'; + const commit_sha = SHA; + + await new CML().check_create({ report, commit_sha }); + }); +}); + +describe('Gitlab tests', () => { + const OLD_ENV = process.env; + + const TOKEN = process.env.GITLAB_TOKEN || process.env.repo_token; + const REPO = 'https://gitlab.com/DavidGOrtega/3_tensorboard'; + + beforeEach(() => { + jest.resetModules(); + + process.env = { ...OLD_ENV }; + process.env.CI_PROJECT_URL = REPO; + process.env.repo_token = TOKEN; + }); + + afterAll(() => { + process.env = OLD_ENV; + }); + + test('env driver has to be gitlab', async () => { + const cml = new CML(); + expect(cml.driver).toBe('gitlab'); + }); + + test('driver has to be gitlab', async () => { + const cml = new CML({ repo: REPO, token: TOKEN, driver: 'gitlab' }); + expect(cml.driver).toBe('gitlab'); + }); + + test('Publish image using gl without markdown returns an url', async () => { + const path = `${__dirname}/../assets/logo.png`; + + const output = await new CML().publish({ path, gitlab_uploads: true }); + + expect(output.startsWith('https://')).toBe(true); + }); + + test('Publish image using gl with markdown', async () => { + const path = `${__dirname}/../assets/logo.png`; + const title = 'my title'; + + const output = await new CML().publish({ + path, + md: true, + title, + gitlab_uploads: true + }); + + expect(output.startsWith('![](https://')).toBe(true); + expect(output.endsWith(` "${title}")`)).toBe(true); + }); + + test('Publish a non image file using gl in markdown', async () => { + const path = `${__dirname}/../assets/logo.pdf`; + const title = 'my title'; + + const output = await new CML().publish({ + path, + md: true, + title, + gitlab_uploads: true + }); + + expect(output.startsWith(`[${title}](https://`)).toBe(true); + expect(output.endsWith(')')).toBe(true); + }); + + test('Comment should fail with a unvalid sha', async () => { + let catched_err; + try { + const report = '## Test comment'; + const commit_sha = 'invalid_sha'; + + const response = await new CML().comment_create({ report, commit_sha }); + console.log(response); + } catch (err) { + catched_err = err.message; + } + + expect(catched_err).toBe('HttpError: No commit found for SHA: invalid_sha'); + }); +}); diff --git a/src/github.js b/src/github.js deleted file mode 100644 index 8cadb8dbc..000000000 --- a/src/github.js +++ /dev/null @@ -1,112 +0,0 @@ -const github = require('@actions/github'); - -const { - GITHUB_REPOSITORY = '', - GITHUB_HEAD_REF, - GITHUB_REF, - GITHUB_SHA, - GITHUB_EVENT_NAME, - GITHUB_TOKEN, - repo_token -} = process.env; - -const [owner, repo] = GITHUB_REPOSITORY.split('/'); -const org = owner; -const IS_PR = GITHUB_EVENT_NAME === 'pull_request'; -const REF = IS_PR ? GITHUB_HEAD_REF : GITHUB_REF; -const HEAD_SHA = GITHUB_SHA; -const USER_EMAIL = 'action@github.com'; -const USER_NAME = 'GitHub Action'; - -const TOKEN = repo_token || GITHUB_TOKEN; -const REPO = `https://github.com/${GITHUB_REPOSITORY}`; - -const octokit = github.getOctokit(TOKEN); - -const CHECK_TITLE = 'CML Report'; - -const create_check_report = async (opts) => { - const { - head_sha, - report, - title = CHECK_TITLE, - started_at = new Date(), - completed_at = new Date(), - conclusion = 'success', - status = 'completed' - } = opts; - - const name = title; - const check = await octokit.checks.create({ - owner, - repo, - head_sha, - name, - started_at, - completed_at, - conclusion, - status, - output: { title, summary: report } - }); - - return check; -}; - -const comment = async (opts) => { - const { commit_sha, report } = opts; - - await octokit.repos.createCommitComment({ - owner, - repo, - commit_sha, - body: report - }); -}; - -const get_runner_token = async () => { - if (typeof repo !== 'undefined') { - const { - data: { token } - } = await octokit.actions.createRegistrationTokenForRepo({ - owner, - repo - }); - - return token; - } - - const { - data: { token } - } = await octokit.actions.createRegistrationTokenForOrg({ - org - }); - - return token; -}; - -const register_runner = async (opts) => { - throw new Error('not yet implemented'); -}; - -const handle_error = (e) => { - console.error(e.message); - process.exit(1); -}; - -exports.is_pr = IS_PR; -exports.ref = REF; -exports.head_sha = - GITHUB_EVENT_NAME === 'pull_request' - ? github.context.payload.pull_request.head.sha - : HEAD_SHA; -exports.user_email = USER_EMAIL; -exports.user_name = USER_NAME; -exports.comment = comment; -exports.get_runner_token = get_runner_token; -exports.register_runner = register_runner; -exports.handle_error = handle_error; -exports.token = TOKEN; -exports.repo = REPO; - -exports.CHECK_TITLE = CHECK_TITLE; -exports.create_check_report = create_check_report; diff --git a/src/gitlab.js b/src/gitlab.js deleted file mode 100644 index fa34d1bc2..000000000 --- a/src/gitlab.js +++ /dev/null @@ -1,115 +0,0 @@ -const fetch = require('node-fetch'); -const FormData = require('form-data'); -const { URLSearchParams } = require('url'); - -const { fetch_upload_data } = require('./utils'); - -const { - CI_API_V4_URL, - CI_PROJECT_PATH = '', - CI_PROJECT_ID, - CI_COMMIT_REF_NAME, - CI_COMMIT_SHA, - CI_MERGE_REQUEST_ID, - CI_PROJECT_URL, - GITLAB_USER_EMAIL, - GITLAB_USER_NAME, - GITLAB_TOKEN, - repo_token -} = process.env; - -const IS_PR = CI_MERGE_REQUEST_ID; -const REF = CI_COMMIT_REF_NAME; -const HEAD_SHA = CI_COMMIT_SHA; -const USER_EMAIL = GITLAB_USER_EMAIL; -const USER_NAME = GITLAB_USER_NAME; - -const TOKEN = repo_token || GITLAB_TOKEN; -const REPO = CI_PROJECT_URL; - -const comment = async (opts) => { - const { commit_sha, report } = opts; - - const endpoint = `/projects/${CI_PROJECT_ID}/repository/commits/${commit_sha}/comments`; - - const body = new URLSearchParams(); - body.append('note', report); - - await gitlab_request({ endpoint, method: 'POST', body }); -}; - -const get_runner_token = async () => { - const endpoint = `/projects/${encodeURIComponent(CI_PROJECT_PATH)}`; - const { runners_token } = await gitlab_request({ endpoint }); - - return runners_token; -}; - -const register_runner = async (opts) => { - const endpoint = `/runners`; - - const body = new URLSearchParams(); - body.append('token', opts.token); - body.append('locked', 'true'); - body.append('run_untagged', 'true'); - body.append('access_level', 'not_protected'); - body.append('tag_list', opts.tags); - - const data = await gitlab_request({ endpoint, method: 'POST', body }); - - return data; -}; - -const upload = async (opts) => { - const endpoint = `/projects/${CI_PROJECT_ID}/uploads`; - - const { size, mime, data } = await fetch_upload_data(opts); - const body = new FormData(); - body.append('file', data); - - const { url } = await gitlab_request({ endpoint, method: 'POST', body }); - - return { uri: `${CI_PROJECT_URL}${url}`, mime, size }; -}; - -const gitlab_request = async (opts) => { - const { endpoint, method = 'GET', body } = opts; - - if (!TOKEN) throw new Error('Gitlab API token not found'); - - if (!CI_API_V4_URL) throw new Error('Gitlab API url not found'); - - if (!endpoint) throw new Error('Gitlab API endpoint not found'); - - const headers = { 'PRIVATE-TOKEN': TOKEN, Accept: 'application/json' }; - const response = await fetch(`${CI_API_V4_URL}${endpoint}`, { - method, - headers, - body - }); - const json = await response.json(); - - console.log(json); - - return json; -}; - -const handle_error = (e) => { - console.error(e.message); - process.exit(1); -}; - -exports.is_pr = IS_PR; -exports.ref = REF; -exports.head_sha = HEAD_SHA; -exports.user_email = USER_EMAIL; -exports.user_name = USER_NAME; -exports.comment = comment; -exports.get_runner_token = get_runner_token; -exports.register_runner = register_runner; -exports.upload = upload; -exports.handle_error = handle_error; -exports.token = TOKEN; -exports.repo = REPO; - -exports.CHECK_TITLE = 'CML Report'; diff --git a/src/report.js b/src/report.js deleted file mode 100644 index 5777f9d5b..000000000 --- a/src/report.js +++ /dev/null @@ -1,22 +0,0 @@ -const { upload } = require('./utils'); -const { upload: gl_upload } = require('./gitlab'); - -const publish_file = async (opts) => { - const { md = false, title = '', gitlab_uploads } = opts; - - let mime, uri; - - if (gitlab_uploads) { - ({ mime, uri } = await gl_upload(opts)); - } else { - ({ mime, uri } = await upload(opts)); - } - - if (md && mime.match('(image|video)/.*')) - return `![](${uri}${title ? ` "${title}"` : ''})`; - if (md) return `[${title}](${uri})`; - - return uri; -}; - -exports.publish_file = publish_file; diff --git a/src/report.test.js b/src/report.test.js deleted file mode 100644 index e670d1b6f..000000000 --- a/src/report.test.js +++ /dev/null @@ -1,35 +0,0 @@ -const REPORT = require('../src/report'); - -describe('Report tests', () => { - test('Publish image', async () => { - const path = './assets/logo.png'; - const md = false; - const title = 'my title'; - - const output = await REPORT.publish_file({ path, md, title }); - - expect(output.startsWith('https://')).toBe(true); - }); - - test('Publish image md', async () => { - const path = './assets/logo.png'; - const md = true; - const title = 'my title'; - - const output = await REPORT.publish_file({ path, md, title }); - - expect(output.startsWith('![](https://')).toBe(true); - expect(output.endsWith(` "${title}")`)).toBe(true); - }); - - test('Publish file md', async () => { - const path = './assets/logo.pdf'; - const md = true; - const title = 'my title'; - - const output = await REPORT.publish_file({ path, md, title }); - - expect(output.startsWith(`[${title}](https://`)).toBe(true); - expect(output.endsWith(')')).toBe(true); - }); -}); diff --git a/src/utils.js b/src/utils.js index 0e340a68c..e03b1d3d2 100644 --- a/src/utils.js +++ b/src/utils.js @@ -135,6 +135,11 @@ const parse_param_newline = (param) => { return param.replace(/\\n/g, '\n'); }; +const strip_last_chars = (opts) => { + const { str, size = 0 } = opts; + return str.substr(0, str.length - size); +}; + exports.exec = exec; exports.fetch_upload_data = fetch_upload_data; exports.upload = upload; @@ -143,3 +148,4 @@ exports.sleep = sleep; exports.is_proc_running = is_proc_running; exports.ssh_public_from_private_rsa = ssh_public_from_private_rsa; exports.parse_param_newline = parse_param_newline; +exports.strip_last_chars = strip_last_chars; From e2347808996e5ac8e405e6234435a21d306c3d79 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Fri, 16 Oct 2020 14:19:06 +0200 Subject: [PATCH 02/66] octokit on demand --- src/GithubClient.js | 19 +++++++++++++------ src/GithubClient.test.js | 10 ++++++---- src/cml.js | 1 - 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/GithubClient.js b/src/GithubClient.js index e61e7aada..e43087d60 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -22,16 +22,20 @@ const owner_repo = (opts) => { return { owner, repo }; }; +const octokit = (token) => { + if (!token) throw new Error('token not found'); + + return github.getOctokit(token); +}; + class GithubClient { constructor(opts = {}) { const { repo = this.env_repo(), token = this.env_token() } = opts; if (!repo) throw new Error('repo not found'); - if (!token) throw new Error('token not found'); this.repo = repo.endsWith('/') ? strip_last_chars(repo, 1) : repo; this.token = token; - this.octokit = github.getOctokit(token); } env_repo() { @@ -67,7 +71,9 @@ class GithubClient { async comment_create(opts = {}) { const { report: body, commit_sha = this.env_head_sha() } = opts; - const { url: commit_url } = await this.octokit.repos.createCommitComment({ + const { url: commit_url } = await octokit( + this.token + ).repos.createCommitComment({ ...owner_repo({ uri: this.repo }), body, commit_sha @@ -88,7 +94,7 @@ class GithubClient { status = 'completed' } = opts; - return await this.octokit.checks.create({ + return await octokit(this.token).checks.create({ ...owner_repo({ uri: this.repo }), head_sha, started_at, @@ -106,11 +112,12 @@ class GithubClient { async runner_token() { const { owner, repo } = owner_repo({ uri: this.repo }); + const { actions } = octokit(this.token); if (typeof repo !== 'undefined') { const { data: { token } - } = await this.octokit.actions.createRegistrationTokenForRepo({ + } = await actions.createRegistrationTokenForRepo({ owner, repo }); @@ -120,7 +127,7 @@ class GithubClient { const { data: { token } - } = await this.octokit.actions.createRegistrationTokenForOrg({ + } = await actions.createRegistrationTokenForOrg({ org: owner }); diff --git a/src/GithubClient.test.js b/src/GithubClient.test.js index 80be281bd..06f34e4f8 100644 --- a/src/GithubClient.test.js +++ b/src/GithubClient.test.js @@ -15,8 +15,9 @@ describe('Non Enviromental tests', () => { expect(gh_client.token).toBe(TOKEN); const { owner, repo } = gh_client.owner_repo(); - expect(owner).toBe('DavidGOrtega'); - expect(repo).toBe('3_tensorboard'); + const parts = GITHUB_REPOSITORY.split('/'); + expect(owner).toBe(parts[0]); + expect(repo).toBe(parts[1]); }); test('Comment', async () => { @@ -76,8 +77,9 @@ describe('Enviromental tests', () => { expect(gh_client.token).toBe(TOKEN); const { owner, repo } = gh_client.owner_repo(); - expect(owner).toBe('DavidGOrtega'); - expect(repo).toBe('3_tensorboard'); + const parts = GITHUB_REPOSITORY.split('/'); + expect(owner).toBe(parts[0]); + expect(repo).toBe(parts[1]); }); test('Comment', async () => { diff --git a/src/cml.js b/src/cml.js index 7eaa90358..cc8780d57 100644 --- a/src/cml.js +++ b/src/cml.js @@ -7,7 +7,6 @@ const get_client = (opts) => { if (!driver) throw new Error('driver not set'); if (driver === 'github') return new GithubClient({ repo, token }); - if (driver === 'gitlab') return new GitlabClient({ repo, token }); throw new Error('driver unknown!'); From c67624a02ac9d3c18f66632387cf66989f3f6f4f Mon Sep 17 00:00:00 2001 From: davidgortega Date: Fri, 16 Oct 2020 14:42:59 +0200 Subject: [PATCH 03/66] token --- src/GithubClient.test.js | 2 +- src/cml.test.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/GithubClient.test.js b/src/GithubClient.test.js index 06f34e4f8..f5a161de8 100644 --- a/src/GithubClient.test.js +++ b/src/GithubClient.test.js @@ -2,7 +2,7 @@ jest.setTimeout(20000); const GithubClient = require('./GithubClient'); -const TOKEN = process.env.GITHUB_TOKEN || process.env.repo_token; +const TOKEN = process.env.TEST_GITHUB_TOKEN || process.env.repo_token; const GITHUB_REPOSITORY = 'DavidGOrtega/3_tensorboard'; const REPO = `https://github.com/${GITHUB_REPOSITORY}`; const SHA = 'ee672b3b35c21b440c6fe6890de2fe769fbdbcee'; diff --git a/src/cml.test.js b/src/cml.test.js index 0287d8ded..09c36c5f8 100644 --- a/src/cml.test.js +++ b/src/cml.test.js @@ -3,7 +3,7 @@ const CML = require('./cml'); describe('Github tests', () => { const OLD_ENV = process.env; - const TOKEN = process.env.GITHUB_TOKEN || process.env.repo_token; + const TOKEN = process.env.TEST_GITHUB_TOKEN || process.env.repo_token; const GITHUB_REPOSITORY = 'DavidGOrtega/3_tensorboard'; const REPO = `https://github.com/${GITHUB_REPOSITORY}`; const SHA = 'ee672b3b35c21b440c6fe6890de2fe769fbdbcee'; From b97a4ffad705025e270dbc1c579854c23a0c6367 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Fri, 16 Oct 2020 16:02:44 +0200 Subject: [PATCH 04/66] clean env before tests --- src/GithubClient.test.js | 3 +-- src/GitlabClient.test.js | 3 +-- src/cml.test.js | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/GithubClient.test.js b/src/GithubClient.test.js index f5a161de8..f98fa034a 100644 --- a/src/GithubClient.test.js +++ b/src/GithubClient.test.js @@ -54,8 +54,7 @@ describe('Enviromental tests', () => { beforeEach(() => { jest.resetModules(); - process.env = { ...OLD_ENV }; - + process.env = {}; process.env.repo_token = TOKEN; process.env.GITHUB_REPOSITORY = GITHUB_REPOSITORY; process.env.GITHUB_SHA = SHA; diff --git a/src/GitlabClient.test.js b/src/GitlabClient.test.js index fe68e6dd9..67a65fc3f 100644 --- a/src/GitlabClient.test.js +++ b/src/GitlabClient.test.js @@ -48,8 +48,7 @@ describe('Enviromental tests', () => { beforeEach(() => { jest.resetModules(); - process.env = { ...OLD_ENV }; - + process.env = {}; process.env.repo_token = TOKEN; process.env.CI_PROJECT_URL = REPO; process.env.CI_COMMIT_SHA = SHA; diff --git a/src/cml.test.js b/src/cml.test.js index 09c36c5f8..4c4bc36f4 100644 --- a/src/cml.test.js +++ b/src/cml.test.js @@ -11,7 +11,7 @@ describe('Github tests', () => { beforeEach(() => { jest.resetModules(); - process.env = { ...OLD_ENV }; + process.env = {}; process.env.GITHUB_REPOSITORY = GITHUB_REPOSITORY; process.env.repo_token = TOKEN; process.env.GITHUB_SHA = SHA; @@ -97,7 +97,7 @@ describe('Gitlab tests', () => { beforeEach(() => { jest.resetModules(); - process.env = { ...OLD_ENV }; + process.env = {}; process.env.CI_PROJECT_URL = REPO; process.env.repo_token = TOKEN; }); From decaa7fd258ae211c2c7997e0914ae8a2e6083b4 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Fri, 16 Oct 2020 16:57:57 +0200 Subject: [PATCH 05/66] print env --- src/GitlabClient.test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/GitlabClient.test.js b/src/GitlabClient.test.js index 67a65fc3f..70bfc6e8d 100644 --- a/src/GitlabClient.test.js +++ b/src/GitlabClient.test.js @@ -2,6 +2,7 @@ jest.setTimeout(20000); const GitlabClient = require('./GitlabClient'); +console.log(process.env); const TOKEN = process.env.GITLAB_TOKEN || process.env.repo_token; const REPO = 'https://gitlab.com/DavidGOrtega/3_tensorboard'; const SHA = '2dc250a9449728356913e1f0e30758a44da65a12'; From 0d4246dd9812e72eb6c788073a1db653073d671d Mon Sep 17 00:00:00 2001 From: davidgortega Date: Fri, 16 Oct 2020 17:06:58 +0200 Subject: [PATCH 06/66] yaml --- .github/workflows/publish.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ba99931f5..7c9172f24 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -4,6 +4,8 @@ on: [push, pull_request] env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TEST_GITHUB_TOKEN: ${{ secrets.TEST_GITHUB_TOKEN }} + TEST_GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }} jobs: test_and_deploy: From fe1f7ab6f764f815e4ba6e6bad299facff7ede51 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Fri, 16 Oct 2020 17:10:52 +0200 Subject: [PATCH 07/66] yaml --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 7c9172f24..932f283fb 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -5,7 +5,7 @@ on: [push, pull_request] env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TEST_GITHUB_TOKEN: ${{ secrets.TEST_GITHUB_TOKEN }} - TEST_GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }} + GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }} jobs: test_and_deploy: From 02bb010439e52a57dbeba81009addf3995dc6585 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Fri, 16 Oct 2020 18:23:11 +0200 Subject: [PATCH 08/66] yaml --- src/GithubClient.js | 6 ++++++ src/GitlabClient.test.js | 1 - src/cml.test.js | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/GithubClient.js b/src/GithubClient.js index e43087d60..9a585972d 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -36,6 +36,12 @@ class GithubClient { this.repo = repo.endsWith('/') ? strip_last_chars(repo, 1) : repo; this.token = token; + + console.log('**********'); + console.log(opts); + console.log(this.repo); + console.log(this.token); + console.log('**********'); } env_repo() { diff --git a/src/GitlabClient.test.js b/src/GitlabClient.test.js index 70bfc6e8d..67a65fc3f 100644 --- a/src/GitlabClient.test.js +++ b/src/GitlabClient.test.js @@ -2,7 +2,6 @@ jest.setTimeout(20000); const GitlabClient = require('./GitlabClient'); -console.log(process.env); const TOKEN = process.env.GITLAB_TOKEN || process.env.repo_token; const REPO = 'https://gitlab.com/DavidGOrtega/3_tensorboard'; const SHA = '2dc250a9449728356913e1f0e30758a44da65a12'; diff --git a/src/cml.test.js b/src/cml.test.js index 4c4bc36f4..bf4cf90e1 100644 --- a/src/cml.test.js +++ b/src/cml.test.js @@ -66,7 +66,7 @@ describe('Github tests', () => { await new CML().comment_create({ report, commit_sha }); }); - test('Comment should fail with a unvalid sha', async () => { + test('Comment should fail with a invalid sha', async () => { let catched_err; try { const report = '## Test comment'; From 6931a9b4859ec7c65ad01fa215b91ce5cf80a948 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Fri, 16 Oct 2020 19:03:03 +0200 Subject: [PATCH 09/66] yaml --- bin/cml-send-github-check.test.js | 6 +++++- src/GithubClient.js | 6 ------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/bin/cml-send-github-check.test.js b/bin/cml-send-github-check.test.js index a9ac62ec1..249ca71d8 100644 --- a/bin/cml-send-github-check.test.js +++ b/bin/cml-send-github-check.test.js @@ -14,10 +14,14 @@ describe('CML e2e', () => { test('cml-send-github-check', async () => { const report = `## Test Check Report`; + const title = 'CML success test'; + const conclusion = 'success'; await fs.writeFile(path, report); process.env.GITHUB_ACTIONS && - (await exec(`node ./bin/cml-send-github-check.js ${path}`)); + (await exec( + `node ./bin/cml-send-github-check.js ${path} --title "${title}" --conclusion "${conclusion}"` + )); }); test('cml-send-github-check failure with tile "CML neutral test"', async () => { diff --git a/src/GithubClient.js b/src/GithubClient.js index 9a585972d..e43087d60 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -36,12 +36,6 @@ class GithubClient { this.repo = repo.endsWith('/') ? strip_last_chars(repo, 1) : repo; this.token = token; - - console.log('**********'); - console.log(opts); - console.log(this.repo); - console.log(this.token); - console.log('**********'); } env_repo() { From 8b4c2b27cf77acd3c09229c123d52c947b379d78 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Fri, 16 Oct 2020 19:08:37 +0200 Subject: [PATCH 10/66] check --- bin/cml-send-github-check.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/cml-send-github-check.test.js b/bin/cml-send-github-check.test.js index 249ca71d8..4d94f3afc 100644 --- a/bin/cml-send-github-check.test.js +++ b/bin/cml-send-github-check.test.js @@ -25,7 +25,7 @@ describe('CML e2e', () => { }); test('cml-send-github-check failure with tile "CML neutral test"', async () => { - const report = `## Hi this check should be neutral`; + const report = `## Hi this check should be neutral here`; const title = 'CML neutral test'; const conclusion = 'neutral'; From 40524dbe976a6d0b3faed4e02bf9ff5cbf226ffa Mon Sep 17 00:00:00 2001 From: davidgortega Date: Fri, 16 Oct 2020 19:44:35 +0200 Subject: [PATCH 11/66] fix repo env --- src/GithubClient.js | 11 +++++---- src/GithubClient.test.js | 51 +++++++++++++++++++++------------------- src/cml.test.js | 2 +- 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/src/GithubClient.js b/src/GithubClient.js index e43087d60..1dfc7e195 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -8,14 +8,12 @@ const CHECK_TITLE = 'CML Report'; const owner_repo = (opts) => { let owner, repo; const { uri } = opts; + const { GITHUB_REPOSITORY } = process.env; if (uri) { const { pathname } = new URL(uri); [owner, repo] = pathname.substr(1).split('/'); - } - - const { GITHUB_REPOSITORY } = process.env; - if (GITHUB_REPOSITORY) { + } else if (GITHUB_REPOSITORY) { [owner, repo] = GITHUB_REPOSITORY.split('/'); } @@ -71,6 +69,11 @@ class GithubClient { async comment_create(opts = {}) { const { report: body, commit_sha = this.env_head_sha() } = opts; + console.log({ + ...owner_repo({ uri: this.repo }), + body, + commit_sha + }); const { url: commit_url } = await octokit( this.token ).repos.createCommitComment({ diff --git a/src/GithubClient.test.js b/src/GithubClient.test.js index f98fa034a..f3ca279c1 100644 --- a/src/GithubClient.test.js +++ b/src/GithubClient.test.js @@ -8,13 +8,14 @@ const REPO = `https://github.com/${GITHUB_REPOSITORY}`; const SHA = 'ee672b3b35c21b440c6fe6890de2fe769fbdbcee'; describe('Non Enviromental tests', () => { - const gh_client = new GithubClient({ repo: REPO, token: TOKEN }); + console.log({ repo: REPO, token: TOKEN }); + const client = new GithubClient({ repo: REPO, token: TOKEN }); test('test repo and token', async () => { - expect(gh_client.repo).toBe(REPO); - expect(gh_client.token).toBe(TOKEN); + expect(client.repo).toBe(REPO); + expect(client.token).toBe(TOKEN); - const { owner, repo } = gh_client.owner_repo(); + const { owner, repo } = client.owner_repo(); const parts = GITHUB_REPOSITORY.split('/'); expect(owner).toBe(parts[0]); expect(repo).toBe(parts[1]); @@ -24,7 +25,7 @@ describe('Non Enviromental tests', () => { const report = '## Test comment'; const commit_sha = SHA; - await gh_client.comment_create({ report, commit_sha }); + await client.comment_create({ report, commit_sha }); }); test('Check', async () => { @@ -32,22 +33,23 @@ describe('Non Enviromental tests', () => { const title = 'CML neutral test'; const conclusion = `neutral`; - const output = await gh_client.check_create({ report, title, conclusion }); + const output = await client.check_create({ report, title, conclusion }); expect(output.startsWith('https://')).toBe(true); }); test('Publish', async () => { - await expect(gh_client.publish()).rejects.toThrow( + await expect(client.publish()).rejects.toThrow( 'Github does not support publish!' ); }); test('Runner token', async () => { - const output = await gh_client.runner_token(); + const output = await client.runner_token(); expect(output.length).toBe(29); }); }); +/* describe('Enviromental tests', () => { const OLD_ENV = process.env; @@ -65,49 +67,50 @@ describe('Enviromental tests', () => { }); test('Env', async () => { - const gh_client = new GithubClient({}); + const client = new GithubClient({}); - expect(gh_client.env_is_pr()).toBe(false); - expect(gh_client.env_head_sha()).toBe(SHA); - expect(gh_client.env_repo()).toBe(REPO); - expect(gh_client.env_token()).toBe(TOKEN); + expect(client.env_is_pr()).toBe(false); + expect(client.env_head_sha()).toBe(SHA); + expect(client.env_repo()).toBe(REPO); + expect(client.env_token()).toBe(TOKEN); - expect(gh_client.repo).toBe(REPO); - expect(gh_client.token).toBe(TOKEN); + expect(client.repo).toBe(REPO); + expect(client.token).toBe(TOKEN); - const { owner, repo } = gh_client.owner_repo(); + const { owner, repo } = client.owner_repo(); const parts = GITHUB_REPOSITORY.split('/'); expect(owner).toBe(parts[0]); expect(repo).toBe(parts[1]); }); test('Comment', async () => { - const gh_client = new GithubClient({}); + const client = new GithubClient({}); const report = '## Test comment'; - await gh_client.comment_create({ report }); + await client.comment_create({ report }); }); test('Check', async () => { - const gh_client = new GithubClient({}); + const client = new GithubClient({}); const report = '## Hi this check should be neutral'; const title = 'CML neutral test'; const conclusion = `neutral`; - const output = await gh_client.check_create({ report, title, conclusion }); + const output = await client.check_create({ report, title, conclusion }); expect(output.startsWith('https://')).toBe(true); }); test('Publish', async () => { - const gh_client = new GithubClient({}); - await expect(gh_client.publish()).rejects.toThrow( + const client = new GithubClient({}); + await expect(client.publish()).rejects.toThrow( 'Github does not support publish!' ); }); test('Runner token', async () => { - const gh_client = new GithubClient({}); - const output = await gh_client.runner_token(); + const client = new GithubClient({}); + const output = await client.runner_token(); expect(output.length).toBe(29); }); }); +*/ diff --git a/src/cml.test.js b/src/cml.test.js index bf4cf90e1..910a7e547 100644 --- a/src/cml.test.js +++ b/src/cml.test.js @@ -154,7 +154,7 @@ describe('Gitlab tests', () => { expect(output.endsWith(')')).toBe(true); }); - test('Comment should fail with a unvalid sha', async () => { + test.skip('Comment should fail with a unvalid sha', async () => { let catched_err; try { const report = '## Test comment'; From 7d9021f67df8760b8dc3a49ef3165bedf0a9e2e6 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Fri, 16 Oct 2020 19:53:57 +0200 Subject: [PATCH 12/66] fix repo env --- bin/cml-send-github-check.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/cml-send-github-check.test.js b/bin/cml-send-github-check.test.js index 4d94f3afc..2006e8321 100644 --- a/bin/cml-send-github-check.test.js +++ b/bin/cml-send-github-check.test.js @@ -13,9 +13,9 @@ describe('CML e2e', () => { }); test('cml-send-github-check', async () => { - const report = `## Test Check Report`; - const title = 'CML success test'; - const conclusion = 'success'; + const report = `## Test Check Report failure`; + const title = 'CML failure test'; + const conclusion = 'failure'; await fs.writeFile(path, report); process.env.GITHUB_ACTIONS && From 211c3e48c2bd3de9d68d13bb85e562f164421270 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Fri, 16 Oct 2020 19:54:20 +0200 Subject: [PATCH 13/66] fix repo env --- bin/cml-send-github-check.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/cml-send-github-check.test.js b/bin/cml-send-github-check.test.js index 2006e8321..753671fd6 100644 --- a/bin/cml-send-github-check.test.js +++ b/bin/cml-send-github-check.test.js @@ -26,7 +26,7 @@ describe('CML e2e', () => { test('cml-send-github-check failure with tile "CML neutral test"', async () => { const report = `## Hi this check should be neutral here`; - const title = 'CML neutral test'; + const title = 'CML neutral test neutral'; const conclusion = 'neutral'; await fs.writeFile(path, report); From 501e6f2980d060690ccfd8e9a9919a69ca2f89bd Mon Sep 17 00:00:00 2001 From: davidgortega Date: Fri, 16 Oct 2020 19:57:50 +0200 Subject: [PATCH 14/66] fix repo env --- bin/cml-send-github-check.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/cml-send-github-check.test.js b/bin/cml-send-github-check.test.js index 753671fd6..84aab1c1c 100644 --- a/bin/cml-send-github-check.test.js +++ b/bin/cml-send-github-check.test.js @@ -25,7 +25,7 @@ describe('CML e2e', () => { }); test('cml-send-github-check failure with tile "CML neutral test"', async () => { - const report = `## Hi this check should be neutral here`; + const report = `## Hi this check should be neutral ksjdkjsksdjksdjskdjs`; const title = 'CML neutral test neutral'; const conclusion = 'neutral'; From 37d032d393968c905c7e9011934b5ab515d06be6 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Fri, 16 Oct 2020 20:00:52 +0200 Subject: [PATCH 15/66] check name --- bin/cml-send-github-check.test.js | 12 ++++-------- src/GithubClient.js | 7 +------ 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/bin/cml-send-github-check.test.js b/bin/cml-send-github-check.test.js index 84aab1c1c..a9ac62ec1 100644 --- a/bin/cml-send-github-check.test.js +++ b/bin/cml-send-github-check.test.js @@ -13,20 +13,16 @@ describe('CML e2e', () => { }); test('cml-send-github-check', async () => { - const report = `## Test Check Report failure`; - const title = 'CML failure test'; - const conclusion = 'failure'; + const report = `## Test Check Report`; await fs.writeFile(path, report); process.env.GITHUB_ACTIONS && - (await exec( - `node ./bin/cml-send-github-check.js ${path} --title "${title}" --conclusion "${conclusion}"` - )); + (await exec(`node ./bin/cml-send-github-check.js ${path}`)); }); test('cml-send-github-check failure with tile "CML neutral test"', async () => { - const report = `## Hi this check should be neutral ksjdkjsksdjksdjskdjs`; - const title = 'CML neutral test neutral'; + const report = `## Hi this check should be neutral`; + const title = 'CML neutral test'; const conclusion = 'neutral'; await fs.writeFile(path, report); diff --git a/src/GithubClient.js b/src/GithubClient.js index 1dfc7e195..1316f7982 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -69,11 +69,6 @@ class GithubClient { async comment_create(opts = {}) { const { report: body, commit_sha = this.env_head_sha() } = opts; - console.log({ - ...owner_repo({ uri: this.repo }), - body, - commit_sha - }); const { url: commit_url } = await octokit( this.token ).repos.createCommitComment({ @@ -90,13 +85,13 @@ class GithubClient { report, commit_sha: head_sha = this.env_head_sha(), title = CHECK_TITLE, - name = CHECK_TITLE, started_at = new Date(), completed_at = new Date(), conclusion = 'success', status = 'completed' } = opts; + const name = title; return await octokit(this.token).checks.create({ ...owner_repo({ uri: this.repo }), head_sha, From a6a7b23bc4ca9011529bb3c5c6e13a2f23a5c815 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Fri, 16 Oct 2020 20:10:12 +0200 Subject: [PATCH 16/66] env github tests --- src/GithubClient.test.js | 2 -- src/GitlabClient.test.js | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/GithubClient.test.js b/src/GithubClient.test.js index f3ca279c1..190137725 100644 --- a/src/GithubClient.test.js +++ b/src/GithubClient.test.js @@ -49,7 +49,6 @@ describe('Non Enviromental tests', () => { }); }); -/* describe('Enviromental tests', () => { const OLD_ENV = process.env; @@ -113,4 +112,3 @@ describe('Enviromental tests', () => { expect(output.length).toBe(29); }); }); -*/ diff --git a/src/GitlabClient.test.js b/src/GitlabClient.test.js index 67a65fc3f..f560c5d17 100644 --- a/src/GitlabClient.test.js +++ b/src/GitlabClient.test.js @@ -19,6 +19,7 @@ describe('Non Enviromental tests', () => { const commit_sha = SHA; const { created_at } = await client.comment_create({ report, commit_sha }); + expect(created_at).not.toBeUndefined(); }); @@ -32,12 +33,12 @@ describe('Non Enviromental tests', () => { const path = `${__dirname}/../assets/logo.png`; const { uri } = await client.publish({ path }); - console.log(uri); expect(uri).not.toBeUndefined(); }); test('Runner token', async () => { const output = await client.runner_token(); + expect(output.length).toBe(20); }); }); @@ -96,6 +97,7 @@ describe('Enviromental tests', () => { test('Runner token', async () => { const client = new GitlabClient(); const output = await client.runner_token(); + expect(output.length).toBe(20); }); }); From ee9b1001ab834ec3946b340b2b6c5985d3b50b39 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Fri, 16 Oct 2020 20:11:40 +0200 Subject: [PATCH 17/66] env github tests --- src/GithubClient.test.js | 1 - src/cml.test.js | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/GithubClient.test.js b/src/GithubClient.test.js index 190137725..209736259 100644 --- a/src/GithubClient.test.js +++ b/src/GithubClient.test.js @@ -8,7 +8,6 @@ const REPO = `https://github.com/${GITHUB_REPOSITORY}`; const SHA = 'ee672b3b35c21b440c6fe6890de2fe769fbdbcee'; describe('Non Enviromental tests', () => { - console.log({ repo: REPO, token: TOKEN }); const client = new GithubClient({ repo: REPO, token: TOKEN }); test('test repo and token', async () => { diff --git a/src/cml.test.js b/src/cml.test.js index 910a7e547..63fc912e2 100644 --- a/src/cml.test.js +++ b/src/cml.test.js @@ -160,8 +160,7 @@ describe('Gitlab tests', () => { const report = '## Test comment'; const commit_sha = 'invalid_sha'; - const response = await new CML().comment_create({ report, commit_sha }); - console.log(response); + await new CML().comment_create({ report, commit_sha }); } catch (err) { catched_err = err.message; } From 1474d47f1923f86540b06b19d3cefff550f05955 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Fri, 16 Oct 2020 20:44:55 +0200 Subject: [PATCH 18/66] log check --- src/GithubClient.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/GithubClient.js b/src/GithubClient.js index 1316f7982..f9c1c08d5 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -92,6 +92,17 @@ class GithubClient { } = opts; const name = title; + console.log({ + ...owner_repo({ uri: this.repo }), + head_sha, + started_at, + completed_at, + conclusion, + status, + name, + output: { title, summary: report } + }); + return await octokit(this.token).checks.create({ ...owner_repo({ uri: this.repo }), head_sha, From 4dc836601c9faae556d7354306331403ecb31d8c Mon Sep 17 00:00:00 2001 From: davidgortega Date: Sat, 17 Oct 2020 10:55:23 +0200 Subject: [PATCH 19/66] log check --- src/GithubClient.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/GithubClient.js b/src/GithubClient.js index f9c1c08d5..c46c2038e 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -92,7 +92,7 @@ class GithubClient { } = opts; const name = title; - console.log({ + console.error({ ...owner_repo({ uri: this.repo }), head_sha, started_at, @@ -103,6 +103,8 @@ class GithubClient { output: { title, summary: report } }); + throw new Error('check'); + return await octokit(this.token).checks.create({ ...owner_repo({ uri: this.repo }), head_sha, From e01f3efe13de32d43d6fa3e4e8f4d33fb0b9aba8 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Sat, 17 Oct 2020 11:04:05 +0200 Subject: [PATCH 20/66] no check tessts --- src/GithubClient.js | 13 ------------- src/GithubClient.test.js | 19 ------------------- src/cml.test.js | 7 ------- 3 files changed, 39 deletions(-) diff --git a/src/GithubClient.js b/src/GithubClient.js index c46c2038e..1316f7982 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -92,19 +92,6 @@ class GithubClient { } = opts; const name = title; - console.error({ - ...owner_repo({ uri: this.repo }), - head_sha, - started_at, - completed_at, - conclusion, - status, - name, - output: { title, summary: report } - }); - - throw new Error('check'); - return await octokit(this.token).checks.create({ ...owner_repo({ uri: this.repo }), head_sha, diff --git a/src/GithubClient.test.js b/src/GithubClient.test.js index 209736259..be09d31cf 100644 --- a/src/GithubClient.test.js +++ b/src/GithubClient.test.js @@ -27,15 +27,6 @@ describe('Non Enviromental tests', () => { await client.comment_create({ report, commit_sha }); }); - test('Check', async () => { - const report = '## Hi this check should be neutral'; - const title = 'CML neutral test'; - const conclusion = `neutral`; - - const output = await client.check_create({ report, title, conclusion }); - expect(output.startsWith('https://')).toBe(true); - }); - test('Publish', async () => { await expect(client.publish()).rejects.toThrow( 'Github does not support publish!' @@ -88,16 +79,6 @@ describe('Enviromental tests', () => { await client.comment_create({ report }); }); - test('Check', async () => { - const client = new GithubClient({}); - const report = '## Hi this check should be neutral'; - const title = 'CML neutral test'; - const conclusion = `neutral`; - - const output = await client.check_create({ report, title, conclusion }); - expect(output.startsWith('https://')).toBe(true); - }); - test('Publish', async () => { const client = new GithubClient({}); await expect(client.publish()).rejects.toThrow( diff --git a/src/cml.test.js b/src/cml.test.js index 63fc912e2..e7bb4dd84 100644 --- a/src/cml.test.js +++ b/src/cml.test.js @@ -79,13 +79,6 @@ describe('Github tests', () => { expect(catched_err).toBe('No commit found for SHA: invalid_sha'); }); - - test('Check should succeed with a valid sha', async () => { - const report = '## Test comment'; - const commit_sha = SHA; - - await new CML().check_create({ report, commit_sha }); - }); }); describe('Gitlab tests', () => { From 5ac29a9703babe67f652080053ff77e66eedbdac Mon Sep 17 00:00:00 2001 From: davidgortega Date: Sat, 17 Oct 2020 23:28:24 +0200 Subject: [PATCH 21/66] enviromental tests --- bin/cml-publish.js | 10 ++++++++++ bin/cml-publish.test.js | 14 ++++++++++++++ bin/cml-send-comment.js | 13 ++++++++++++- bin/cml-send-comment.test.js | 20 ++++++++++++++++---- bin/cml-send-github-check.js | 10 ++++++++++ bin/cml-send-github-check.test.js | 4 ++++ src/GithubClient.test.js | 19 ++++++++++--------- src/GitlabClient.js | 2 ++ src/GitlabClient.test.js | 8 +++++--- src/cml.test.js | 28 +++++++++++++++++++--------- 10 files changed, 102 insertions(+), 26 deletions(-) diff --git a/bin/cml-publish.js b/bin/cml-publish.js index 8904f00b5..7e2337472 100644 --- a/bin/cml-publish.js +++ b/bin/cml-publish.js @@ -44,6 +44,16 @@ const argv = yargs 'Append the output to the given file. Create it if does not exist.' ) .alias('file', 'f') + .default('repo') + .describe( + 'repo', + 'Specifies the repo to be used. If not specified is extracted from the CI ENV.' + ) + .default('token') + .describe( + 'token', + 'Personal access token to be used. If not specified in extracted from ENV repo_token or GITLAB_TOKEN.' + ) .help('h') .demand(data ? 0 : 1).argv; diff --git a/bin/cml-publish.test.js b/bin/cml-publish.test.js index 66a60a8e5..3a965fe67 100644 --- a/bin/cml-publish.test.js +++ b/bin/cml-publish.test.js @@ -20,6 +20,10 @@ describe('CML e2e', () => { [boolean] --file, -f Append the output to the given file. Create it if does not exist. + --repo Specifies the repo to be used. If not specified is extracted + from the CI ENV. + --token Personal access token to be used. If not specified in + extracted from ENV repo_token or GITLAB_TOKEN. -h Show help [boolean]" `); }); @@ -86,4 +90,14 @@ describe('CML e2e', () => { expect(fs.existsSync(file)).toBe(true); await fs.promises.unlink(file); }); + + test('cml-publish assets/test.svg in Gitlab storage', async () => { + const { TEST_GITLAB_REPO: repo, TEST_GITLAB_TOKEN: token } = process.env; + + const output = await exec( + `echo none | node ./bin/cml-publish.js --repo=${repo} --token=${token} --gitlab-uploads assets/test.svg` + ); + + expect(output.startsWith('https://')).toBe(true); + }); }); diff --git a/bin/cml-send-comment.js b/bin/cml-send-comment.js index 654c80412..5c78935e4 100644 --- a/bin/cml-send-comment.js +++ b/bin/cml-send-comment.js @@ -8,6 +8,7 @@ const yargs = require('yargs'); const CML = require('../src/cml'); const run = async (opts) => { + console.error(process.env); const { 'commit-sha': sha, 'head-sha': head_sha } = opts; const path = opts._[0]; const report = await fs.readFile(path, 'utf-8'); @@ -24,8 +25,18 @@ const argv = yargs 'Commit SHA linked to this comment. Defaults to HEAD.' ) .default('head-sha') - .describe('head-sha', 'Commit SHA linked to this comment. Defaults to HEAD') + .describe('head-sha', 'Commit SHA linked to this comment. Defaults to HEAD.') .deprecateOption('head-sha', 'Use commit-sha instead') + .default('repo') + .describe( + 'repo', + 'Specifies the repo to be used. If not specified is extracted from the CI ENV.' + ) + .default('token') + .describe( + 'token', + 'Personal access token to be used. If not specified in extracted from ENV repo_token.' + ) .help('h') .demand(1).argv; diff --git a/bin/cml-send-comment.test.js b/bin/cml-send-comment.test.js index 7fee4bfa1..de083d5a2 100644 --- a/bin/cml-send-comment.test.js +++ b/bin/cml-send-comment.test.js @@ -21,16 +21,28 @@ describe('Comment integration tests', () => { Options: --version Show version number [boolean] --commit-sha Commit SHA linked to this comment. Defaults to HEAD. - --head-sha Commit SHA linked to this comment. Defaults to HEAD + --head-sha Commit SHA linked to this comment. Defaults to HEAD. [deprecated: Use commit-sha instead] + --repo Specifies the repo to be used. If not specified is extracted + from the CI ENV. + --token Personal access token to be used. If not specified in extracted + from ENV repo_token. -h Show help [boolean]" `); }); - test('cml-send-comment', async () => { - const report = `## Test Comment Report`; + test('cml-send-comment to specific repo', async () => { + const { + TEST_GITHUB_REPO: repo, + TEST_GITHUB_TOKEN: token, + TEST_GITHUB_SHA: sha + } = process.env; + + const report = `## Test Comment Report specific`; await fs.writeFile(path, report); - await exec(`node ./bin/cml-send-comment.js ${path}`); + await exec( + `node ./bin/cml-send-comment.js --repo=${repo} --token=${token} --commit-sha=${sha} ${path}` + ); }); }); diff --git a/bin/cml-send-github-check.js b/bin/cml-send-github-check.js index df31e4158..aa3a4705c 100644 --- a/bin/cml-send-github-check.js +++ b/bin/cml-send-github-check.js @@ -35,6 +35,16 @@ const argv = yargs ]) .default('title', CHECK_TITLE) .describe('title', 'Sets title of the check.') + .default('repo') + .describe( + 'repo', + 'Specifies the repo to be used. If not specified is extracted from the CI ENV.' + ) + .default('token') + .describe( + 'token', + 'Personal access token to be used. If not specified in extracted from ENV repo_token.' + ) .help('h') .demand(1).argv; diff --git a/bin/cml-send-github-check.test.js b/bin/cml-send-github-check.test.js index a9ac62ec1..bbbcc0ccd 100644 --- a/bin/cml-send-github-check.test.js +++ b/bin/cml-send-github-check.test.js @@ -42,6 +42,10 @@ describe('CML e2e', () => { --version Show version number [boolean] --head-sha Commit sha where the comment will appear. Defaults to HEAD. --title Sets title of the check. [default: \\"CML Report\\"] + --repo Specifies the repo to be used. If not specified is extracted + from the CI ENV. + --token Personal access token to be used. If not specified in extracted + from ENV repo_token. -h Show help [boolean] --conclusion[choices: \\"success\\", \\"failure\\", \\"neutral\\", \\"cancelled\\", \\"skipped\\", \\"timed_out\\"] [default: Sets the conclusion status of the check.]" diff --git a/src/GithubClient.test.js b/src/GithubClient.test.js index be09d31cf..d7fce4966 100644 --- a/src/GithubClient.test.js +++ b/src/GithubClient.test.js @@ -2,10 +2,11 @@ jest.setTimeout(20000); const GithubClient = require('./GithubClient'); -const TOKEN = process.env.TEST_GITHUB_TOKEN || process.env.repo_token; -const GITHUB_REPOSITORY = 'DavidGOrtega/3_tensorboard'; -const REPO = `https://github.com/${GITHUB_REPOSITORY}`; -const SHA = 'ee672b3b35c21b440c6fe6890de2fe769fbdbcee'; +const { + TEST_GITHUB_TOKEN: TOKEN, + TEST_GITHUB_REPO: REPO, + TEST_GITHUB_SHA: SHA +} = process.env; describe('Non Enviromental tests', () => { const client = new GithubClient({ repo: REPO, token: TOKEN }); @@ -15,9 +16,9 @@ describe('Non Enviromental tests', () => { expect(client.token).toBe(TOKEN); const { owner, repo } = client.owner_repo(); - const parts = GITHUB_REPOSITORY.split('/'); - expect(owner).toBe(parts[0]); - expect(repo).toBe(parts[1]); + const parts = REPO.split('/'); + expect(owner).toBe(parts[parts.length - 2]); + expect(repo).toBe(parts[parts.length - 1]); }); test('Comment', async () => { @@ -47,8 +48,8 @@ describe('Enviromental tests', () => { process.env = {}; process.env.repo_token = TOKEN; - process.env.GITHUB_REPOSITORY = GITHUB_REPOSITORY; process.env.GITHUB_SHA = SHA; + process.env.GITHUB_REPOSITORY = new URL(REPO).pathname.substring(1); }); afterAll(() => { @@ -67,7 +68,7 @@ describe('Enviromental tests', () => { expect(client.token).toBe(TOKEN); const { owner, repo } = client.owner_repo(); - const parts = GITHUB_REPOSITORY.split('/'); + const parts = process.env.GITHUB_REPOSITORY.split('/'); expect(owner).toBe(parts[0]); expect(repo).toBe(parts[1]); }); diff --git a/src/GitlabClient.js b/src/GitlabClient.js index 462cf1967..4b887468a 100644 --- a/src/GitlabClient.js +++ b/src/GitlabClient.js @@ -104,6 +104,8 @@ class GitlabClient { const url = `${api_v4}${endpoint}`; const response = await fetch(url, { method, headers, body }); + if (response.status > 300) throw new Error(response.statusText); + return await response.json(); } } diff --git a/src/GitlabClient.test.js b/src/GitlabClient.test.js index f560c5d17..3d25ea8ed 100644 --- a/src/GitlabClient.test.js +++ b/src/GitlabClient.test.js @@ -2,9 +2,11 @@ jest.setTimeout(20000); const GitlabClient = require('./GitlabClient'); -const TOKEN = process.env.GITLAB_TOKEN || process.env.repo_token; -const REPO = 'https://gitlab.com/DavidGOrtega/3_tensorboard'; -const SHA = '2dc250a9449728356913e1f0e30758a44da65a12'; +const { + TEST_GITLAB_TOKEN: TOKEN, + TEST_GITLAB_REPO: REPO, + TEST_GITLAB_SHA: SHA +} = process.env; describe('Non Enviromental tests', () => { const client = new GitlabClient({ repo: REPO, token: TOKEN }); diff --git a/src/cml.test.js b/src/cml.test.js index e7bb4dd84..0b2025800 100644 --- a/src/cml.test.js +++ b/src/cml.test.js @@ -3,18 +3,19 @@ const CML = require('./cml'); describe('Github tests', () => { const OLD_ENV = process.env; - const TOKEN = process.env.TEST_GITHUB_TOKEN || process.env.repo_token; - const GITHUB_REPOSITORY = 'DavidGOrtega/3_tensorboard'; - const REPO = `https://github.com/${GITHUB_REPOSITORY}`; - const SHA = 'ee672b3b35c21b440c6fe6890de2fe769fbdbcee'; + const { + TEST_GITHUB_TOKEN: TOKEN, + TEST_GITHUB_REPO: REPO, + TEST_GITHUB_SHA: SHA + } = process.env; beforeEach(() => { jest.resetModules(); process.env = {}; - process.env.GITHUB_REPOSITORY = GITHUB_REPOSITORY; process.env.repo_token = TOKEN; process.env.GITHUB_SHA = SHA; + process.env.GITHUB_REPOSITORY = new URL(REPO).pathname.substring(1); }); afterAll(() => { @@ -84,8 +85,11 @@ describe('Github tests', () => { describe('Gitlab tests', () => { const OLD_ENV = process.env; - const TOKEN = process.env.GITLAB_TOKEN || process.env.repo_token; - const REPO = 'https://gitlab.com/DavidGOrtega/3_tensorboard'; + const { + TEST_GITLAB_TOKEN: TOKEN, + TEST_GITLAB_REPO: REPO, + TEST_GITLAB_SHA: SHA + } = process.env; beforeEach(() => { jest.resetModules(); @@ -93,6 +97,7 @@ describe('Gitlab tests', () => { process.env = {}; process.env.CI_PROJECT_URL = REPO; process.env.repo_token = TOKEN; + process.env.CI_COMMIT_SHA = SHA; }); afterAll(() => { @@ -147,7 +152,12 @@ describe('Gitlab tests', () => { expect(output.endsWith(')')).toBe(true); }); - test.skip('Comment should fail with a unvalid sha', async () => { + test('Comment should succeed with a valid env sha', async () => { + const report = '## Test comment'; + await new CML().comment_create({ report }); + }); + + test('Comment should fail with a unvalid sha', async () => { let catched_err; try { const report = '## Test comment'; @@ -158,6 +168,6 @@ describe('Gitlab tests', () => { catched_err = err.message; } - expect(catched_err).toBe('HttpError: No commit found for SHA: invalid_sha'); + expect(catched_err).toBe('Not Found'); }); }); From 537ede0adbe5fd6da2fe7ace3451b7d2cad15074 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Sat, 17 Oct 2020 23:39:12 +0200 Subject: [PATCH 22/66] workflow eenv --- .github/workflows/publish.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 932f283fb..59c0f6eff 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -3,9 +3,12 @@ name: "Publish CML dockers" on: [push, pull_request] env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TEST_GITHUB_TOKEN: ${{ secrets.TEST_GITHUB_TOKEN }} - GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }} + TEST_GITHUB_REPO: ${{ secrets.TEST_GITHUB_REPO }} + TEST_GITHUB_SHA: ${{ secrets.TEST_GITHUB_SHA }} + TEST_GITLAB_TOKEN: ${{ secrets.TEST_GITLAB_TOKEN }} + TEST_GITLAB_REPO: ${{ secrets.TEST_GITLAB_REPO }} + TEST_GITLAB_SHA: ${{ secrets.TEST_GITLAB_SHA }} jobs: test_and_deploy: From 07bfccbcf6b8262fd1b53c9d35e43fc538477d5f Mon Sep 17 00:00:00 2001 From: davidgortega Date: Sat, 17 Oct 2020 23:59:54 +0200 Subject: [PATCH 23/66] gitlab uploads and github_token --- .github/workflows/publish.yml | 1 + bin/cml-publish.js | 3 +++ bin/cml-publish.test.js | 20 +------------------- bin/cml-send-comment.js | 3 +++ bin/cml-send-github-check.js | 3 +++ bin/cml-send-github-check.test.js | 16 +--------------- src/cml.js | 11 ++++++----- 7 files changed, 18 insertions(+), 39 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 59c0f6eff..6af0f9f4b 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -3,6 +3,7 @@ name: "Publish CML dockers" on: [push, pull_request] env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TEST_GITHUB_TOKEN: ${{ secrets.TEST_GITHUB_TOKEN }} TEST_GITHUB_REPO: ${{ secrets.TEST_GITHUB_REPO }} TEST_GITHUB_SHA: ${{ secrets.TEST_GITHUB_SHA }} diff --git a/bin/cml-publish.js b/bin/cml-publish.js index 7e2337472..f8e408e29 100644 --- a/bin/cml-publish.js +++ b/bin/cml-publish.js @@ -54,6 +54,9 @@ const argv = yargs 'token', 'Personal access token to be used. If not specified in extracted from ENV repo_token or GITLAB_TOKEN.' ) + .default('driver') + .choices('driver', ['github', 'gitlab']) + .describe('driver', 'If not specify it infers it from the ENV.') .help('h') .demand(data ? 0 : 1).argv; diff --git a/bin/cml-publish.test.js b/bin/cml-publish.test.js index 3a965fe67..a5c704797 100644 --- a/bin/cml-publish.test.js +++ b/bin/cml-publish.test.js @@ -7,25 +7,7 @@ describe('CML e2e', () => { test('cml-publish -h', async () => { const output = await exec(`echo none | node ./bin/cml-publish.js -h`); - expect(output).toMatchInlineSnapshot(` - "Usage: cml-publish.js - - Options: - --version Show version number [boolean] - --md Output in markdown format [title || name](url). [boolean] - --title, -t Markdown title [title](url) or ![](url title). - --gitlab-uploads Uses GitLab uploads instead of CML storage. Use GitLab - uploads to get around CML size limitations for hosting - artifacts persistently. Only available for GitLab CI. - [boolean] - --file, -f Append the output to the given file. Create it if does not - exist. - --repo Specifies the repo to be used. If not specified is extracted - from the CI ENV. - --token Personal access token to be used. If not specified in - extracted from ENV repo_token or GITLAB_TOKEN. - -h Show help [boolean]" - `); + expect(output).toMatchInlineSnapshot(); }); test('cml-publish assets/logo.png --md', async () => { diff --git a/bin/cml-send-comment.js b/bin/cml-send-comment.js index 5c78935e4..66210db41 100644 --- a/bin/cml-send-comment.js +++ b/bin/cml-send-comment.js @@ -37,6 +37,9 @@ const argv = yargs 'token', 'Personal access token to be used. If not specified in extracted from ENV repo_token.' ) + .default('driver') + .choices('driver', ['github', 'gitlab']) + .describe('driver', 'If not specify it infers it from the ENV.') .help('h') .demand(1).argv; diff --git a/bin/cml-send-github-check.js b/bin/cml-send-github-check.js index aa3a4705c..ce064ef34 100644 --- a/bin/cml-send-github-check.js +++ b/bin/cml-send-github-check.js @@ -45,6 +45,9 @@ const argv = yargs 'token', 'Personal access token to be used. If not specified in extracted from ENV repo_token.' ) + .default('driver') + .choices('driver', ['github', 'gitlab']) + .describe('driver', 'If not specify it infers it from the ENV.') .help('h') .demand(1).argv; diff --git a/bin/cml-send-github-check.test.js b/bin/cml-send-github-check.test.js index bbbcc0ccd..3b36cc3bc 100644 --- a/bin/cml-send-github-check.test.js +++ b/bin/cml-send-github-check.test.js @@ -35,20 +35,6 @@ describe('CML e2e', () => { test('cml-send-github-check -h', async () => { const output = await exec(`node ./bin/cml-send-github-check.js -h`); - expect(output).toMatchInlineSnapshot(` - "Usage: cml-send-github-check.js - - Options: - --version Show version number [boolean] - --head-sha Commit sha where the comment will appear. Defaults to HEAD. - --title Sets title of the check. [default: \\"CML Report\\"] - --repo Specifies the repo to be used. If not specified is extracted - from the CI ENV. - --token Personal access token to be used. If not specified in extracted - from ENV repo_token. - -h Show help [boolean] - --conclusion[choices: \\"success\\", \\"failure\\", \\"neutral\\", \\"cancelled\\", \\"skipped\\", - \\"timed_out\\"] [default: Sets the conclusion status of the check.]" - `); + expect(output).toMatchInlineSnapshot(); }); }); diff --git a/src/cml.js b/src/cml.js index cc8780d57..6ca088608 100644 --- a/src/cml.js +++ b/src/cml.js @@ -18,10 +18,11 @@ class CML { const { repo } = opts; const { GITHUB_REPOSITORY, CI_PROJECT_URL } = process.env; - if (GITHUB_REPOSITORY || (repo && repo.startsWith('https://github.com'))) - return 'github'; - if (CI_PROJECT_URL || (repo && repo.startsWith('https://gitlab.com'))) - return 'gitlab'; + if (repo && repo.startsWith('https://github.com')) return 'github'; + if (repo && repo.startsWith('https://gitlab.com')) return 'gitlab'; + + if (GITHUB_REPOSITORY) return 'github'; + if (CI_PROJECT_URL) return 'gitlab'; }; const { driver = env_driver(), repo, token } = opts; @@ -46,7 +47,7 @@ class CML { let mime, uri; if (gitlab_uploads) { - const client = get_client(this); + const client = get_client({ ...this, driver: 'gitlab' }); ({ mime, uri } = await client.publish(opts)); } else { ({ mime, uri } = await upload(opts)); From 8735350083736b45186b30c9b87e7c2192e3263c Mon Sep 17 00:00:00 2001 From: davidgortega Date: Sun, 18 Oct 2020 00:07:48 +0200 Subject: [PATCH 24/66] snapshots --- bin/cml-publish.test.js | 22 +++++++++++++++++++++- bin/cml-send-comment.test.js | 2 ++ bin/cml-send-github-check.test.js | 18 +++++++++++++++++- 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/bin/cml-publish.test.js b/bin/cml-publish.test.js index a5c704797..0537b6bd6 100644 --- a/bin/cml-publish.test.js +++ b/bin/cml-publish.test.js @@ -7,7 +7,27 @@ describe('CML e2e', () => { test('cml-publish -h', async () => { const output = await exec(`echo none | node ./bin/cml-publish.js -h`); - expect(output).toMatchInlineSnapshot(); + expect(output).toMatchInlineSnapshot(` + "Usage: cml-publish.js + + Options: + --version Show version number [boolean] + --md Output in markdown format [title || name](url). [boolean] + --title, -t Markdown title [title](url) or ![](url title). + --gitlab-uploads Uses GitLab uploads instead of CML storage. Use GitLab + uploads to get around CML size limitations for hosting + artifacts persistently. Only available for GitLab CI. + [boolean] + --file, -f Append the output to the given file. Create it if does not + exist. + --repo Specifies the repo to be used. If not specified is extracted + from the CI ENV. + --token Personal access token to be used. If not specified in + extracted from ENV repo_token or GITLAB_TOKEN. + --driver If not specify it infers it from the ENV. + [choices: \\"github\\", \\"gitlab\\"] + -h Show help [boolean]" + `); }); test('cml-publish assets/logo.png --md', async () => { diff --git a/bin/cml-send-comment.test.js b/bin/cml-send-comment.test.js index de083d5a2..89f2fe66d 100644 --- a/bin/cml-send-comment.test.js +++ b/bin/cml-send-comment.test.js @@ -27,6 +27,8 @@ describe('Comment integration tests', () => { from the CI ENV. --token Personal access token to be used. If not specified in extracted from ENV repo_token. + --driver If not specify it infers it from the ENV. + [choices: \\"github\\", \\"gitlab\\"] -h Show help [boolean]" `); }); diff --git a/bin/cml-send-github-check.test.js b/bin/cml-send-github-check.test.js index 3b36cc3bc..91405a6da 100644 --- a/bin/cml-send-github-check.test.js +++ b/bin/cml-send-github-check.test.js @@ -35,6 +35,22 @@ describe('CML e2e', () => { test('cml-send-github-check -h', async () => { const output = await exec(`node ./bin/cml-send-github-check.js -h`); - expect(output).toMatchInlineSnapshot(); + expect(output).toMatchInlineSnapshot(` + "Usage: cml-send-github-check.js + + Options: + --version Show version number [boolean] + --head-sha Commit sha where the comment will appear. Defaults to HEAD. + --title Sets title of the check. [default: \\"CML Report\\"] + --repo Specifies the repo to be used. If not specified is extracted + from the CI ENV. + --token Personal access token to be used. If not specified in extracted + from ENV repo_token. + --driver If not specify it infers it from the ENV. + [choices: \\"github\\", \\"gitlab\\"] + -h Show help [boolean] + --conclusion[choices: \\"success\\", \\"failure\\", \\"neutral\\", \\"cancelled\\", \\"skipped\\", + \\"timed_out\\"] [default: Sets the conclusion status of the check.]" + `); }); }); From 5dd1bcdb381d892d5578458faab4f5255a88d92c Mon Sep 17 00:00:00 2001 From: DavidGOrtega Date: Mon, 19 Oct 2020 14:30:00 +0200 Subject: [PATCH 25/66] Cml contexts (#314) * token * clean env before tests * print env * yaml * yaml * yaml * yaml * check * fix repo env * fix repo env * fix repo env * fix repo env * check name * env github tests * env github tests * log check * log check * no check tessts * enviromental tests * workflow eenv * gitlab uploads and github_token * snapshots --- .github/workflows/publish.yml | 6 +++ bin/cml-publish.js | 13 +++++ bin/cml-publish.test.js | 16 ++++++ bin/cml-send-comment.js | 16 +++++- bin/cml-send-comment.test.js | 22 ++++++-- bin/cml-send-github-check.js | 13 +++++ bin/cml-send-github-check.test.js | 6 +++ src/GithubClient.js | 8 ++- src/GithubClient.test.js | 83 ++++++++++++------------------- src/GitlabClient.js | 2 + src/GitlabClient.test.js | 15 +++--- src/cml.js | 11 ++-- src/cml.test.js | 42 ++++++++-------- 13 files changed, 161 insertions(+), 92 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ba99931f5..6af0f9f4b 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -4,6 +4,12 @@ on: [push, pull_request] env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TEST_GITHUB_TOKEN: ${{ secrets.TEST_GITHUB_TOKEN }} + TEST_GITHUB_REPO: ${{ secrets.TEST_GITHUB_REPO }} + TEST_GITHUB_SHA: ${{ secrets.TEST_GITHUB_SHA }} + TEST_GITLAB_TOKEN: ${{ secrets.TEST_GITLAB_TOKEN }} + TEST_GITLAB_REPO: ${{ secrets.TEST_GITLAB_REPO }} + TEST_GITLAB_SHA: ${{ secrets.TEST_GITLAB_SHA }} jobs: test_and_deploy: diff --git a/bin/cml-publish.js b/bin/cml-publish.js index 8904f00b5..f8e408e29 100644 --- a/bin/cml-publish.js +++ b/bin/cml-publish.js @@ -44,6 +44,19 @@ const argv = yargs 'Append the output to the given file. Create it if does not exist.' ) .alias('file', 'f') + .default('repo') + .describe( + 'repo', + 'Specifies the repo to be used. If not specified is extracted from the CI ENV.' + ) + .default('token') + .describe( + 'token', + 'Personal access token to be used. If not specified in extracted from ENV repo_token or GITLAB_TOKEN.' + ) + .default('driver') + .choices('driver', ['github', 'gitlab']) + .describe('driver', 'If not specify it infers it from the ENV.') .help('h') .demand(data ? 0 : 1).argv; diff --git a/bin/cml-publish.test.js b/bin/cml-publish.test.js index 66a60a8e5..0537b6bd6 100644 --- a/bin/cml-publish.test.js +++ b/bin/cml-publish.test.js @@ -20,6 +20,12 @@ describe('CML e2e', () => { [boolean] --file, -f Append the output to the given file. Create it if does not exist. + --repo Specifies the repo to be used. If not specified is extracted + from the CI ENV. + --token Personal access token to be used. If not specified in + extracted from ENV repo_token or GITLAB_TOKEN. + --driver If not specify it infers it from the ENV. + [choices: \\"github\\", \\"gitlab\\"] -h Show help [boolean]" `); }); @@ -86,4 +92,14 @@ describe('CML e2e', () => { expect(fs.existsSync(file)).toBe(true); await fs.promises.unlink(file); }); + + test('cml-publish assets/test.svg in Gitlab storage', async () => { + const { TEST_GITLAB_REPO: repo, TEST_GITLAB_TOKEN: token } = process.env; + + const output = await exec( + `echo none | node ./bin/cml-publish.js --repo=${repo} --token=${token} --gitlab-uploads assets/test.svg` + ); + + expect(output.startsWith('https://')).toBe(true); + }); }); diff --git a/bin/cml-send-comment.js b/bin/cml-send-comment.js index 654c80412..66210db41 100644 --- a/bin/cml-send-comment.js +++ b/bin/cml-send-comment.js @@ -8,6 +8,7 @@ const yargs = require('yargs'); const CML = require('../src/cml'); const run = async (opts) => { + console.error(process.env); const { 'commit-sha': sha, 'head-sha': head_sha } = opts; const path = opts._[0]; const report = await fs.readFile(path, 'utf-8'); @@ -24,8 +25,21 @@ const argv = yargs 'Commit SHA linked to this comment. Defaults to HEAD.' ) .default('head-sha') - .describe('head-sha', 'Commit SHA linked to this comment. Defaults to HEAD') + .describe('head-sha', 'Commit SHA linked to this comment. Defaults to HEAD.') .deprecateOption('head-sha', 'Use commit-sha instead') + .default('repo') + .describe( + 'repo', + 'Specifies the repo to be used. If not specified is extracted from the CI ENV.' + ) + .default('token') + .describe( + 'token', + 'Personal access token to be used. If not specified in extracted from ENV repo_token.' + ) + .default('driver') + .choices('driver', ['github', 'gitlab']) + .describe('driver', 'If not specify it infers it from the ENV.') .help('h') .demand(1).argv; diff --git a/bin/cml-send-comment.test.js b/bin/cml-send-comment.test.js index 7fee4bfa1..89f2fe66d 100644 --- a/bin/cml-send-comment.test.js +++ b/bin/cml-send-comment.test.js @@ -21,16 +21,30 @@ describe('Comment integration tests', () => { Options: --version Show version number [boolean] --commit-sha Commit SHA linked to this comment. Defaults to HEAD. - --head-sha Commit SHA linked to this comment. Defaults to HEAD + --head-sha Commit SHA linked to this comment. Defaults to HEAD. [deprecated: Use commit-sha instead] + --repo Specifies the repo to be used. If not specified is extracted + from the CI ENV. + --token Personal access token to be used. If not specified in extracted + from ENV repo_token. + --driver If not specify it infers it from the ENV. + [choices: \\"github\\", \\"gitlab\\"] -h Show help [boolean]" `); }); - test('cml-send-comment', async () => { - const report = `## Test Comment Report`; + test('cml-send-comment to specific repo', async () => { + const { + TEST_GITHUB_REPO: repo, + TEST_GITHUB_TOKEN: token, + TEST_GITHUB_SHA: sha + } = process.env; + + const report = `## Test Comment Report specific`; await fs.writeFile(path, report); - await exec(`node ./bin/cml-send-comment.js ${path}`); + await exec( + `node ./bin/cml-send-comment.js --repo=${repo} --token=${token} --commit-sha=${sha} ${path}` + ); }); }); diff --git a/bin/cml-send-github-check.js b/bin/cml-send-github-check.js index df31e4158..ce064ef34 100644 --- a/bin/cml-send-github-check.js +++ b/bin/cml-send-github-check.js @@ -35,6 +35,19 @@ const argv = yargs ]) .default('title', CHECK_TITLE) .describe('title', 'Sets title of the check.') + .default('repo') + .describe( + 'repo', + 'Specifies the repo to be used. If not specified is extracted from the CI ENV.' + ) + .default('token') + .describe( + 'token', + 'Personal access token to be used. If not specified in extracted from ENV repo_token.' + ) + .default('driver') + .choices('driver', ['github', 'gitlab']) + .describe('driver', 'If not specify it infers it from the ENV.') .help('h') .demand(1).argv; diff --git a/bin/cml-send-github-check.test.js b/bin/cml-send-github-check.test.js index a9ac62ec1..91405a6da 100644 --- a/bin/cml-send-github-check.test.js +++ b/bin/cml-send-github-check.test.js @@ -42,6 +42,12 @@ describe('CML e2e', () => { --version Show version number [boolean] --head-sha Commit sha where the comment will appear. Defaults to HEAD. --title Sets title of the check. [default: \\"CML Report\\"] + --repo Specifies the repo to be used. If not specified is extracted + from the CI ENV. + --token Personal access token to be used. If not specified in extracted + from ENV repo_token. + --driver If not specify it infers it from the ENV. + [choices: \\"github\\", \\"gitlab\\"] -h Show help [boolean] --conclusion[choices: \\"success\\", \\"failure\\", \\"neutral\\", \\"cancelled\\", \\"skipped\\", \\"timed_out\\"] [default: Sets the conclusion status of the check.]" diff --git a/src/GithubClient.js b/src/GithubClient.js index e43087d60..1316f7982 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -8,14 +8,12 @@ const CHECK_TITLE = 'CML Report'; const owner_repo = (opts) => { let owner, repo; const { uri } = opts; + const { GITHUB_REPOSITORY } = process.env; if (uri) { const { pathname } = new URL(uri); [owner, repo] = pathname.substr(1).split('/'); - } - - const { GITHUB_REPOSITORY } = process.env; - if (GITHUB_REPOSITORY) { + } else if (GITHUB_REPOSITORY) { [owner, repo] = GITHUB_REPOSITORY.split('/'); } @@ -87,13 +85,13 @@ class GithubClient { report, commit_sha: head_sha = this.env_head_sha(), title = CHECK_TITLE, - name = CHECK_TITLE, started_at = new Date(), completed_at = new Date(), conclusion = 'success', status = 'completed' } = opts; + const name = title; return await octokit(this.token).checks.create({ ...owner_repo({ uri: this.repo }), head_sha, diff --git a/src/GithubClient.test.js b/src/GithubClient.test.js index 06f34e4f8..d7fce4966 100644 --- a/src/GithubClient.test.js +++ b/src/GithubClient.test.js @@ -2,48 +2,40 @@ jest.setTimeout(20000); const GithubClient = require('./GithubClient'); -const TOKEN = process.env.GITHUB_TOKEN || process.env.repo_token; -const GITHUB_REPOSITORY = 'DavidGOrtega/3_tensorboard'; -const REPO = `https://github.com/${GITHUB_REPOSITORY}`; -const SHA = 'ee672b3b35c21b440c6fe6890de2fe769fbdbcee'; +const { + TEST_GITHUB_TOKEN: TOKEN, + TEST_GITHUB_REPO: REPO, + TEST_GITHUB_SHA: SHA +} = process.env; describe('Non Enviromental tests', () => { - const gh_client = new GithubClient({ repo: REPO, token: TOKEN }); + const client = new GithubClient({ repo: REPO, token: TOKEN }); test('test repo and token', async () => { - expect(gh_client.repo).toBe(REPO); - expect(gh_client.token).toBe(TOKEN); + expect(client.repo).toBe(REPO); + expect(client.token).toBe(TOKEN); - const { owner, repo } = gh_client.owner_repo(); - const parts = GITHUB_REPOSITORY.split('/'); - expect(owner).toBe(parts[0]); - expect(repo).toBe(parts[1]); + const { owner, repo } = client.owner_repo(); + const parts = REPO.split('/'); + expect(owner).toBe(parts[parts.length - 2]); + expect(repo).toBe(parts[parts.length - 1]); }); test('Comment', async () => { const report = '## Test comment'; const commit_sha = SHA; - await gh_client.comment_create({ report, commit_sha }); - }); - - test('Check', async () => { - const report = '## Hi this check should be neutral'; - const title = 'CML neutral test'; - const conclusion = `neutral`; - - const output = await gh_client.check_create({ report, title, conclusion }); - expect(output.startsWith('https://')).toBe(true); + await client.comment_create({ report, commit_sha }); }); test('Publish', async () => { - await expect(gh_client.publish()).rejects.toThrow( + await expect(client.publish()).rejects.toThrow( 'Github does not support publish!' ); }); test('Runner token', async () => { - const output = await gh_client.runner_token(); + const output = await client.runner_token(); expect(output.length).toBe(29); }); }); @@ -54,11 +46,10 @@ describe('Enviromental tests', () => { beforeEach(() => { jest.resetModules(); - process.env = { ...OLD_ENV }; - + process.env = {}; process.env.repo_token = TOKEN; - process.env.GITHUB_REPOSITORY = GITHUB_REPOSITORY; process.env.GITHUB_SHA = SHA; + process.env.GITHUB_REPOSITORY = new URL(REPO).pathname.substring(1); }); afterAll(() => { @@ -66,49 +57,39 @@ describe('Enviromental tests', () => { }); test('Env', async () => { - const gh_client = new GithubClient({}); + const client = new GithubClient({}); - expect(gh_client.env_is_pr()).toBe(false); - expect(gh_client.env_head_sha()).toBe(SHA); - expect(gh_client.env_repo()).toBe(REPO); - expect(gh_client.env_token()).toBe(TOKEN); + expect(client.env_is_pr()).toBe(false); + expect(client.env_head_sha()).toBe(SHA); + expect(client.env_repo()).toBe(REPO); + expect(client.env_token()).toBe(TOKEN); - expect(gh_client.repo).toBe(REPO); - expect(gh_client.token).toBe(TOKEN); + expect(client.repo).toBe(REPO); + expect(client.token).toBe(TOKEN); - const { owner, repo } = gh_client.owner_repo(); - const parts = GITHUB_REPOSITORY.split('/'); + const { owner, repo } = client.owner_repo(); + const parts = process.env.GITHUB_REPOSITORY.split('/'); expect(owner).toBe(parts[0]); expect(repo).toBe(parts[1]); }); test('Comment', async () => { - const gh_client = new GithubClient({}); + const client = new GithubClient({}); const report = '## Test comment'; - await gh_client.comment_create({ report }); - }); - - test('Check', async () => { - const gh_client = new GithubClient({}); - const report = '## Hi this check should be neutral'; - const title = 'CML neutral test'; - const conclusion = `neutral`; - - const output = await gh_client.check_create({ report, title, conclusion }); - expect(output.startsWith('https://')).toBe(true); + await client.comment_create({ report }); }); test('Publish', async () => { - const gh_client = new GithubClient({}); - await expect(gh_client.publish()).rejects.toThrow( + const client = new GithubClient({}); + await expect(client.publish()).rejects.toThrow( 'Github does not support publish!' ); }); test('Runner token', async () => { - const gh_client = new GithubClient({}); - const output = await gh_client.runner_token(); + const client = new GithubClient({}); + const output = await client.runner_token(); expect(output.length).toBe(29); }); }); diff --git a/src/GitlabClient.js b/src/GitlabClient.js index 462cf1967..4b887468a 100644 --- a/src/GitlabClient.js +++ b/src/GitlabClient.js @@ -104,6 +104,8 @@ class GitlabClient { const url = `${api_v4}${endpoint}`; const response = await fetch(url, { method, headers, body }); + if (response.status > 300) throw new Error(response.statusText); + return await response.json(); } } diff --git a/src/GitlabClient.test.js b/src/GitlabClient.test.js index fe68e6dd9..3d25ea8ed 100644 --- a/src/GitlabClient.test.js +++ b/src/GitlabClient.test.js @@ -2,9 +2,11 @@ jest.setTimeout(20000); const GitlabClient = require('./GitlabClient'); -const TOKEN = process.env.GITLAB_TOKEN || process.env.repo_token; -const REPO = 'https://gitlab.com/DavidGOrtega/3_tensorboard'; -const SHA = '2dc250a9449728356913e1f0e30758a44da65a12'; +const { + TEST_GITLAB_TOKEN: TOKEN, + TEST_GITLAB_REPO: REPO, + TEST_GITLAB_SHA: SHA +} = process.env; describe('Non Enviromental tests', () => { const client = new GitlabClient({ repo: REPO, token: TOKEN }); @@ -19,6 +21,7 @@ describe('Non Enviromental tests', () => { const commit_sha = SHA; const { created_at } = await client.comment_create({ report, commit_sha }); + expect(created_at).not.toBeUndefined(); }); @@ -32,12 +35,12 @@ describe('Non Enviromental tests', () => { const path = `${__dirname}/../assets/logo.png`; const { uri } = await client.publish({ path }); - console.log(uri); expect(uri).not.toBeUndefined(); }); test('Runner token', async () => { const output = await client.runner_token(); + expect(output.length).toBe(20); }); }); @@ -48,8 +51,7 @@ describe('Enviromental tests', () => { beforeEach(() => { jest.resetModules(); - process.env = { ...OLD_ENV }; - + process.env = {}; process.env.repo_token = TOKEN; process.env.CI_PROJECT_URL = REPO; process.env.CI_COMMIT_SHA = SHA; @@ -97,6 +99,7 @@ describe('Enviromental tests', () => { test('Runner token', async () => { const client = new GitlabClient(); const output = await client.runner_token(); + expect(output.length).toBe(20); }); }); diff --git a/src/cml.js b/src/cml.js index cc8780d57..6ca088608 100644 --- a/src/cml.js +++ b/src/cml.js @@ -18,10 +18,11 @@ class CML { const { repo } = opts; const { GITHUB_REPOSITORY, CI_PROJECT_URL } = process.env; - if (GITHUB_REPOSITORY || (repo && repo.startsWith('https://github.com'))) - return 'github'; - if (CI_PROJECT_URL || (repo && repo.startsWith('https://gitlab.com'))) - return 'gitlab'; + if (repo && repo.startsWith('https://github.com')) return 'github'; + if (repo && repo.startsWith('https://gitlab.com')) return 'gitlab'; + + if (GITHUB_REPOSITORY) return 'github'; + if (CI_PROJECT_URL) return 'gitlab'; }; const { driver = env_driver(), repo, token } = opts; @@ -46,7 +47,7 @@ class CML { let mime, uri; if (gitlab_uploads) { - const client = get_client(this); + const client = get_client({ ...this, driver: 'gitlab' }); ({ mime, uri } = await client.publish(opts)); } else { ({ mime, uri } = await upload(opts)); diff --git a/src/cml.test.js b/src/cml.test.js index 0287d8ded..0b2025800 100644 --- a/src/cml.test.js +++ b/src/cml.test.js @@ -3,18 +3,19 @@ const CML = require('./cml'); describe('Github tests', () => { const OLD_ENV = process.env; - const TOKEN = process.env.GITHUB_TOKEN || process.env.repo_token; - const GITHUB_REPOSITORY = 'DavidGOrtega/3_tensorboard'; - const REPO = `https://github.com/${GITHUB_REPOSITORY}`; - const SHA = 'ee672b3b35c21b440c6fe6890de2fe769fbdbcee'; + const { + TEST_GITHUB_TOKEN: TOKEN, + TEST_GITHUB_REPO: REPO, + TEST_GITHUB_SHA: SHA + } = process.env; beforeEach(() => { jest.resetModules(); - process.env = { ...OLD_ENV }; - process.env.GITHUB_REPOSITORY = GITHUB_REPOSITORY; + process.env = {}; process.env.repo_token = TOKEN; process.env.GITHUB_SHA = SHA; + process.env.GITHUB_REPOSITORY = new URL(REPO).pathname.substring(1); }); afterAll(() => { @@ -66,7 +67,7 @@ describe('Github tests', () => { await new CML().comment_create({ report, commit_sha }); }); - test('Comment should fail with a unvalid sha', async () => { + test('Comment should fail with a invalid sha', async () => { let catched_err; try { const report = '## Test comment'; @@ -79,27 +80,24 @@ describe('Github tests', () => { expect(catched_err).toBe('No commit found for SHA: invalid_sha'); }); - - test('Check should succeed with a valid sha', async () => { - const report = '## Test comment'; - const commit_sha = SHA; - - await new CML().check_create({ report, commit_sha }); - }); }); describe('Gitlab tests', () => { const OLD_ENV = process.env; - const TOKEN = process.env.GITLAB_TOKEN || process.env.repo_token; - const REPO = 'https://gitlab.com/DavidGOrtega/3_tensorboard'; + const { + TEST_GITLAB_TOKEN: TOKEN, + TEST_GITLAB_REPO: REPO, + TEST_GITLAB_SHA: SHA + } = process.env; beforeEach(() => { jest.resetModules(); - process.env = { ...OLD_ENV }; + process.env = {}; process.env.CI_PROJECT_URL = REPO; process.env.repo_token = TOKEN; + process.env.CI_COMMIT_SHA = SHA; }); afterAll(() => { @@ -154,18 +152,22 @@ describe('Gitlab tests', () => { expect(output.endsWith(')')).toBe(true); }); + test('Comment should succeed with a valid env sha', async () => { + const report = '## Test comment'; + await new CML().comment_create({ report }); + }); + test('Comment should fail with a unvalid sha', async () => { let catched_err; try { const report = '## Test comment'; const commit_sha = 'invalid_sha'; - const response = await new CML().comment_create({ report, commit_sha }); - console.log(response); + await new CML().comment_create({ report, commit_sha }); } catch (err) { catched_err = err.message; } - expect(catched_err).toBe('HttpError: No commit found for SHA: invalid_sha'); + expect(catched_err).toBe('Not Found'); }); }); From 164376ab646fc4dc5776a16eb1db690f41680a4b Mon Sep 17 00:00:00 2001 From: davidgortega Date: Mon, 19 Oct 2020 16:22:59 +0200 Subject: [PATCH 26/66] docker entrypooint --- bin/cml-cloud-runner-entrypoint.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/bin/cml-cloud-runner-entrypoint.js b/bin/cml-cloud-runner-entrypoint.js index d0f0ae650..6dccb4607 100755 --- a/bin/cml-cloud-runner-entrypoint.js +++ b/bin/cml-cloud-runner-entrypoint.js @@ -9,7 +9,6 @@ const { DOCKER_MACHINE, // DEPRECATED RUNNER_PATH, - RUNNER_REPO, RUNNER_IDLE_TIMEOUT = 5 * 60, RUNNER_LABELS = 'cml', RUNNER_NAME = randid(), @@ -17,13 +16,19 @@ const { RUNNER_RUNTIME = '', RUNNER_IMAGE = 'dvcorg/cml:latest', + RUNNER_DRIVER, + RUNNER_REPO, repo_token } = process.env; +const cml = new CML({ + driver: RUNNER_DRIVER, + repo: RUNNER_REPO, + token: repo_token +}); +const IS_GITHUB = cml.driver === 'github'; const { protocol, host } = new URL(RUNNER_REPO); const RUNNER_REPO_ORIGIN = `${protocol}//${host}`; -const IS_GITHUB = RUNNER_REPO.startsWith('https://github.com'); -const cml = new CML({ driver: 'github', repo: RUNNER_REPO, token: repo_token }); let TIMEOUT_TIMER = 0; let JOB_RUNNING = false; @@ -49,7 +54,6 @@ const shutdown_host = async () => { ); } catch (err) { console.log(`Failed destroying terraform: ${err.message}`); - // shutdown_host(); } } catch (err) { console.log(err.message); From 9d2cc12aa9a06180b1eda1cdb91b2c9b7a06b10f Mon Sep 17 00:00:00 2001 From: davidgortega Date: Mon, 19 Oct 2020 16:41:34 +0200 Subject: [PATCH 27/66] docker entrypoint register_runner --- bin/cml-cloud-runner-entrypoint.js | 4 ++-- src/GithubClient.js | 4 ++++ src/GitlabClient.js | 5 ++--- src/cml.js | 5 +++++ 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/bin/cml-cloud-runner-entrypoint.js b/bin/cml-cloud-runner-entrypoint.js index 6dccb4607..c50a48f85 100755 --- a/bin/cml-cloud-runner-entrypoint.js +++ b/bin/cml-cloud-runner-entrypoint.js @@ -123,9 +123,9 @@ const run = async () => { command = `${RUNNER_PATH}/run.sh`; } else { console.log('Registering Gitlab runner'); - const runner = await cml.client.register_runner({ + const runner = await cml.register_runner({ tags: RUNNER_LABELS, - token: RUNNER_TOKEN + runner_token: RUNNER_TOKEN }); GITLAB_CI_TOKEN = runner.token; diff --git a/src/GithubClient.js b/src/GithubClient.js index 1316f7982..d1ac1aba1 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -131,6 +131,10 @@ class GithubClient { return token; } + + async register_runner(opts = {}) { + throw new Error('Github does not support register_runner!'); + } } module.exports = GithubClient; diff --git a/src/GitlabClient.js b/src/GitlabClient.js index 4b887468a..e3db283f0 100644 --- a/src/GitlabClient.js +++ b/src/GitlabClient.js @@ -80,12 +80,11 @@ class GitlabClient { } async register_runner(opts = {}) { - const { token } = this; - const { tags } = opts; + const { tags, runner_token } = opts; const endpoint = `/runners`; const body = new URLSearchParams(); - body.append('token', token); + body.append('token', runner_token); body.append('tag_list', tags); body.append('locked', 'true'); body.append('run_untagged', 'true'); diff --git a/src/cml.js b/src/cml.js index 6ca088608..0abbd695b 100644 --- a/src/cml.js +++ b/src/cml.js @@ -66,6 +66,11 @@ class CML { return await client.runner_token(); } + async register_runner(opts = {}) { + const client = get_client(this); + return await client.register_runner(opts); + } + log_error(e) { console.error(e.message); } From c444438e5570e06e6bca480aaa8e50fc85836818 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Mon, 19 Oct 2020 17:24:28 +0200 Subject: [PATCH 28/66] update templates --- bin/cml-cloud-runner.js | 15 ++++++++++++++- bin/cml-cloud-runner.test.js | 8 ++++++-- bin/cml-send-github-check.js | 5 +---- bin/cml-send-github-check.test.js | 2 -- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/bin/cml-cloud-runner.js b/bin/cml-cloud-runner.js index ce6a09f5f..0b3e1dbe8 100644 --- a/bin/cml-cloud-runner.js +++ b/bin/cml-cloud-runner.js @@ -210,7 +210,7 @@ const shutdown = async () => { }; const run = async (opts) => { - const cml = new CML(); + const cml = new CML(opts); REPO = cml.client.env_repo(); TOKEN = cml.client.env_token(); @@ -273,6 +273,19 @@ const argv = yargs .boolean('attached') .describe('attached', 'Runs the runner in the foreground.') .coerce('rsa-private-key', parse_param_newline) + .default('repo') + .describe( + 'repo', + 'Specifies the repo to be used. If not specified is extracted from the CI ENV.' + ) + .default('token') + .describe( + 'token', + 'Personal access token to be used. If not specified in extracted from ENV repo_token or GITLAB_TOKEN.' + ) + .default('driver') + .choices('driver', ['github', 'gitlab']) + .describe('driver', 'If not specify it infers it from the ENV.') .help('h').argv; run(argv).catch((e) => { console.error(e); diff --git a/bin/cml-cloud-runner.test.js b/bin/cml-cloud-runner.test.js index 6d50216f8..a25502493 100644 --- a/bin/cml-cloud-runner.test.js +++ b/bin/cml-cloud-runner.test.js @@ -13,8 +13,8 @@ describe('CML e2e', () => { --version Show version number [boolean] --repo-token Repository token. Defaults to workflow env variable repo_token. - --repo Repository to register with. Tries to guess from workflow - env variables. + --repo Specifies the repo to be used. If not specified is + extracted from the CI ENV. --labels Comma delimited runner labels. Defaults to cml --idle-timeout Time in seconds for the runner to be waiting for jobs before shutting down. Defaults to 5 min @@ -29,6 +29,10 @@ describe('CML e2e', () => { --rsa-private-key Your private RSA SHH key. If not provided will be generated by the tf provider. [default: \\"\\"] --attached Runs the runner in the foreground. [boolean] + --token Personal access token to be used. If not specified in + extracted from ENV repo_token or GITLAB_TOKEN. + --driver If not specify it infers it from the ENV. + [choices: \\"github\\", \\"gitlab\\"] -h Show help [boolean]" `); }); diff --git a/bin/cml-send-github-check.js b/bin/cml-send-github-check.js index ce064ef34..50e187b8c 100644 --- a/bin/cml-send-github-check.js +++ b/bin/cml-send-github-check.js @@ -13,7 +13,7 @@ const run = async (opts) => { const path = opts._[0]; const report = await fs.readFile(path, 'utf-8'); - const cml = new CML(opts); + const cml = new CML({ ...opts, driver: 'github' }); await cml.check_create({ head_sha, report, conclusion, title }); }; @@ -45,9 +45,6 @@ const argv = yargs 'token', 'Personal access token to be used. If not specified in extracted from ENV repo_token.' ) - .default('driver') - .choices('driver', ['github', 'gitlab']) - .describe('driver', 'If not specify it infers it from the ENV.') .help('h') .demand(1).argv; diff --git a/bin/cml-send-github-check.test.js b/bin/cml-send-github-check.test.js index 91405a6da..bbbcc0ccd 100644 --- a/bin/cml-send-github-check.test.js +++ b/bin/cml-send-github-check.test.js @@ -46,8 +46,6 @@ describe('CML e2e', () => { from the CI ENV. --token Personal access token to be used. If not specified in extracted from ENV repo_token. - --driver If not specify it infers it from the ENV. - [choices: \\"github\\", \\"gitlab\\"] -h Show help [boolean] --conclusion[choices: \\"success\\", \\"failure\\", \\"neutral\\", \\"cancelled\\", \\"skipped\\", \\"timed_out\\"] [default: Sets the conclusion status of the check.]" From f4b2ea496ab3a8eadba513fd12328352e19c9802 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Mon, 19 Oct 2020 17:37:09 +0200 Subject: [PATCH 29/66] token repo --- src/cml.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/cml.js b/src/cml.js index 0abbd695b..255e2d2f7 100644 --- a/src/cml.js +++ b/src/cml.js @@ -31,6 +31,22 @@ class CML { this.token = token; } + env_repo() { + return get_client(this).env_repo(); + } + + env_token() { + return get_client(this).env_token(); + } + + env_is_pr() { + return get_client(this).env_is_pr(); + } + + env_head_sha() { + return get_client(this).env_head_sha(); + } + async comment_create(opts = {}) { const client = get_client(this); return await client.comment_create(opts); From c7f901caa5c31ce6d34e61506d2e0eba09067f44 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Mon, 19 Oct 2020 17:47:11 +0200 Subject: [PATCH 30/66] token repo --- bin/cml-cloud-runner.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/cml-cloud-runner.js b/bin/cml-cloud-runner.js index 0b3e1dbe8..35c506954 100644 --- a/bin/cml-cloud-runner.js +++ b/bin/cml-cloud-runner.js @@ -211,8 +211,8 @@ const shutdown = async () => { const run = async (opts) => { const cml = new CML(opts); - REPO = cml.client.env_repo(); - TOKEN = cml.client.env_token(); + REPO = cml.env_repo(); + TOKEN = cml.env_token(); try { const terraform_state = await run_terraform(opts); From a03bd1068e921fdf8d12006357a481f5b426ac34 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Mon, 19 Oct 2020 17:51:38 +0200 Subject: [PATCH 31/66] specify driver --- bin/cml-cloud-runner.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bin/cml-cloud-runner.js b/bin/cml-cloud-runner.js index 35c506954..73a3819b3 100644 --- a/bin/cml-cloud-runner.js +++ b/bin/cml-cloud-runner.js @@ -57,7 +57,8 @@ const setup_runners = async (opts) => { name: runner_name, image = 'dvcorg/cml:latest', 'rsa-private-key': rsa_private_key, - attached + attached, + driver } = opts; const tf_path = path.join(TF_FOLDER, 'main.tf'); @@ -109,6 +110,7 @@ const setup_runners = async (opts) => { -v $(pwd)/main.tf:/main.tf \ -e "repo_token=${repo_token}" \ -e "RUNNER_REPO=${runner_repo}" \ + -e "RUNNER_DRIVER=${driver}" \ ${runner_labels ? `-e "RUNNER_LABELS=${runner_labels}"` : ''} \ ${ runner_idle_timeout @@ -216,7 +218,7 @@ const run = async (opts) => { try { const terraform_state = await run_terraform(opts); - await setup_runners({ terraform_state, ...opts }); + await setup_runners({ terraform_state, ...opts, driver: cml.driver }); await sleep(20); } catch (err) { await destroy_terraform({}); From f23765de0c2a45d3d1cfb2e0420ef5f26e8bb2e0 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Tue, 20 Oct 2020 18:31:18 +0200 Subject: [PATCH 32/66] log env --- src/GithubClient.test.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/GithubClient.test.js b/src/GithubClient.test.js index d7fce4966..ddccfce32 100644 --- a/src/GithubClient.test.js +++ b/src/GithubClient.test.js @@ -50,6 +50,8 @@ describe('Enviromental tests', () => { process.env.repo_token = TOKEN; process.env.GITHUB_SHA = SHA; process.env.GITHUB_REPOSITORY = new URL(REPO).pathname.substring(1); + + console.log(process.env); }); afterAll(() => { @@ -59,7 +61,6 @@ describe('Enviromental tests', () => { test('Env', async () => { const client = new GithubClient({}); - expect(client.env_is_pr()).toBe(false); expect(client.env_head_sha()).toBe(SHA); expect(client.env_repo()).toBe(REPO); expect(client.env_token()).toBe(TOKEN); From 7b2f0a0bccf332255db5fbcff79956a46a305e92 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Tue, 20 Oct 2020 18:33:28 +0200 Subject: [PATCH 33/66] log env --- src/GithubClient.test.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/GithubClient.test.js b/src/GithubClient.test.js index ddccfce32..ac73b026c 100644 --- a/src/GithubClient.test.js +++ b/src/GithubClient.test.js @@ -50,8 +50,6 @@ describe('Enviromental tests', () => { process.env.repo_token = TOKEN; process.env.GITHUB_SHA = SHA; process.env.GITHUB_REPOSITORY = new URL(REPO).pathname.substring(1); - - console.log(process.env); }); afterAll(() => { @@ -75,6 +73,7 @@ describe('Enviromental tests', () => { }); test('Comment', async () => { + console.log(process.env); const client = new GithubClient({}); const report = '## Test comment'; From abdce430d7d50fe01dc5976a0fa9761b4cda23d7 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Tue, 20 Oct 2020 19:56:07 +0200 Subject: [PATCH 34/66] update also github.context --- src/GithubClient.test.js | 6 ++++++ src/GitlabClient.test.js | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/GithubClient.test.js b/src/GithubClient.test.js index ac73b026c..762415e3d 100644 --- a/src/GithubClient.test.js +++ b/src/GithubClient.test.js @@ -1,6 +1,7 @@ jest.setTimeout(20000); const GithubClient = require('./GithubClient'); +const github = require('@actions/github'); const { TEST_GITHUB_TOKEN: TOKEN, @@ -49,6 +50,11 @@ describe('Enviromental tests', () => { process.env = {}; process.env.repo_token = TOKEN; process.env.GITHUB_SHA = SHA; + + try { + github.context.payload.pull_request.head.sha = SHA; + } catch (err) {} + process.env.GITHUB_REPOSITORY = new URL(REPO).pathname.substring(1); }); diff --git a/src/GitlabClient.test.js b/src/GitlabClient.test.js index 3d25ea8ed..2714af9eb 100644 --- a/src/GitlabClient.test.js +++ b/src/GitlabClient.test.js @@ -64,7 +64,6 @@ describe('Enviromental tests', () => { test('Env', async () => { const client = new GitlabClient(); - expect(client.env_is_pr()).toBe(false); expect(client.env_head_sha()).toBe(SHA); expect(client.env_repo()).toBe(REPO); expect(client.env_token()).toBe(TOKEN); From 0958f3c14543dbb512bc3e0ef8f182774cdf5a60 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Tue, 20 Oct 2020 21:45:09 +0200 Subject: [PATCH 35/66] unregister gh runner --- bin/cml-cloud-runner-entrypoint.js | 6 +---- src/GithubClient.js | 42 ++++++++++++++++++++++++++++++ src/GitlabClient.js | 4 +++ src/cml.js | 4 +++ 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/bin/cml-cloud-runner-entrypoint.js b/bin/cml-cloud-runner-entrypoint.js index c50a48f85..4730a7090 100755 --- a/bin/cml-cloud-runner-entrypoint.js +++ b/bin/cml-cloud-runner-entrypoint.js @@ -66,11 +66,7 @@ const shutdown = async (error) => { try { if (IS_GITHUB) { - console.log( - await exec( - `${RUNNER_PATH}/config.sh remove --token "${RUNNER_TOKEN}"` - ) - ); + await cml.unregister_runner({ name: RUNNER_NAME }); } else { console.log(await exec(`gitlab-runner verify --delete`)); console.log( diff --git a/src/GithubClient.js b/src/GithubClient.js index d1ac1aba1..721a316ed 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -135,6 +135,48 @@ class GithubClient { async register_runner(opts = {}) { throw new Error('Github does not support register_runner!'); } + + async unregister_runner(opts) { + const { name } = opts; + const { owner, repo } = owner_repo({ uri: this.repo }); + const { actions } = octokit(this.token); + + if (typeof repo !== 'undefined') { + const runners = actions.listSelfHostedRunnersForRepo({ + owner, + repo + }); + + const { id: runner_id } = runners.filter( + (runner) => runner.name === name + ); + + const { + data: { token } + } = await actions.deleteSelfHostedRunnerFromRepo({ + owner, + repo, + runner_id + }); + + return token; + } + + const runners = actions.listSelfHostedRunnersForOrg({ + org: owner + }); + + const { id: runner_id } = runners.filter((runner) => runner.name === name); + + const { + data: { token } + } = await actions.deleteSelfHostedRunnerFromOrg({ + org: owner, + runner_id + }); + + return token; + } } module.exports = GithubClient; diff --git a/src/GitlabClient.js b/src/GitlabClient.js index e3db283f0..aa9b16e5d 100644 --- a/src/GitlabClient.js +++ b/src/GitlabClient.js @@ -93,6 +93,10 @@ class GitlabClient { return await this.request({ endpoint, method: 'POST', body }); } + async unregister_runner(opts = {}) { + throw new Error('Gitlab does not support unregister_runner!'); + } + async request(opts = {}) { const { token, api_v4 } = this; const { endpoint, method = 'GET', body } = opts; diff --git a/src/cml.js b/src/cml.js index 255e2d2f7..9cb5c116b 100644 --- a/src/cml.js +++ b/src/cml.js @@ -87,6 +87,10 @@ class CML { return await client.register_runner(opts); } + async unregister_runner(opts = {}) { + return await get_client(this).unregister_runner(opts); + } + log_error(e) { console.error(e.message); } From 879999eb05606424b1424e6943c3a9623a91fbb6 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Tue, 20 Oct 2020 22:00:10 +0200 Subject: [PATCH 36/66] log error --- bin/cml-cloud-runner-entrypoint.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bin/cml-cloud-runner-entrypoint.js b/bin/cml-cloud-runner-entrypoint.js index 4730a7090..9640f9540 100755 --- a/bin/cml-cloud-runner-entrypoint.js +++ b/bin/cml-cloud-runner-entrypoint.js @@ -75,7 +75,9 @@ const shutdown = async (error) => { ) ); } - } catch (err) {} + } catch (err) { + console.log(err); + } await shutdown_docker_machine(); await shutdown_host(); From 5b6b7f8305e9cb246026948ce75b33e436013dce Mon Sep 17 00:00:00 2001 From: davidgortega Date: Tue, 20 Oct 2020 22:02:53 +0200 Subject: [PATCH 37/66] log error --- src/GithubClient.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/GithubClient.js b/src/GithubClient.js index 721a316ed..81409b6c4 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -147,6 +147,8 @@ class GithubClient { repo }); + console.log(runners); + const { id: runner_id } = runners.filter( (runner) => runner.name === name ); From 0c6250326e9df51613d957fd2fbb2a2596032976 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Tue, 20 Oct 2020 22:04:26 +0200 Subject: [PATCH 38/66] log error --- src/GithubClient.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/GithubClient.js b/src/GithubClient.js index 81409b6c4..3db15e5ae 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -142,7 +142,7 @@ class GithubClient { const { actions } = octokit(this.token); if (typeof repo !== 'undefined') { - const runners = actions.listSelfHostedRunnersForRepo({ + const runners = await actions.listSelfHostedRunnersForRepo({ owner, repo }); @@ -164,7 +164,7 @@ class GithubClient { return token; } - const runners = actions.listSelfHostedRunnersForOrg({ + const runners = await actions.listSelfHostedRunnersForOrg({ org: owner }); From 0842fc6e388eccae219772be6279bf31461c0c79 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Tue, 20 Oct 2020 22:06:12 +0200 Subject: [PATCH 39/66] await runners --- src/GithubClient.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/GithubClient.js b/src/GithubClient.js index 3db15e5ae..d2d1a1eba 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -142,7 +142,7 @@ class GithubClient { const { actions } = octokit(this.token); if (typeof repo !== 'undefined') { - const runners = await actions.listSelfHostedRunnersForRepo({ + const { runners } = await actions.listSelfHostedRunnersForRepo({ owner, repo }); @@ -164,7 +164,7 @@ class GithubClient { return token; } - const runners = await actions.listSelfHostedRunnersForOrg({ + const { runners } = await actions.listSelfHostedRunnersForOrg({ org: owner }); From aa126196fd8d46d65743c26628a7f5781c1fba13 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Tue, 20 Oct 2020 22:11:23 +0200 Subject: [PATCH 40/66] await runners --- src/GithubClient.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/GithubClient.js b/src/GithubClient.js index d2d1a1eba..55c9e3671 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -142,7 +142,9 @@ class GithubClient { const { actions } = octokit(this.token); if (typeof repo !== 'undefined') { - const { runners } = await actions.listSelfHostedRunnersForRepo({ + const { + data: { runners } + } = await actions.listSelfHostedRunnersForRepo({ owner, repo }); @@ -164,7 +166,9 @@ class GithubClient { return token; } - const { runners } = await actions.listSelfHostedRunnersForOrg({ + const { + data: { runners } + } = await actions.listSelfHostedRunnersForOrg({ org: owner }); From dc5ce24f93bbb4d64844b6ce97edf9831fdd96d8 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Tue, 20 Oct 2020 22:14:17 +0200 Subject: [PATCH 41/66] await runners --- src/GithubClient.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/GithubClient.js b/src/GithubClient.js index 55c9e3671..c52b4ae9e 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -155,6 +155,9 @@ class GithubClient { (runner) => runner.name === name ); + console.log(name); + console.log(runner_id); + const { data: { token } } = await actions.deleteSelfHostedRunnerFromRepo({ From 68495cb33b00f89b035c96678009639d01666a1c Mon Sep 17 00:00:00 2001 From: davidgortega Date: Tue, 20 Oct 2020 23:29:12 +0200 Subject: [PATCH 42/66] await runners --- src/GithubClient.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/GithubClient.js b/src/GithubClient.js index c52b4ae9e..4ff0464ad 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -155,6 +155,7 @@ class GithubClient { (runner) => runner.name === name ); + console.log('ksjdskdjskjdskjdsk'); console.log(name); console.log(runner_id); From de61be2b5e22c44c69a94b1080237409efc7fca2 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Tue, 20 Oct 2020 23:39:37 +0200 Subject: [PATCH 43/66] await runners 100 --- src/GithubClient.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/GithubClient.js b/src/GithubClient.js index 4ff0464ad..684aedc00 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -146,7 +146,8 @@ class GithubClient { data: { runners } } = await actions.listSelfHostedRunnersForRepo({ owner, - repo + repo, + per_page: 100 }); console.log(runners); @@ -155,7 +156,6 @@ class GithubClient { (runner) => runner.name === name ); - console.log('ksjdskdjskjdskjdsk'); console.log(name); console.log(runner_id); @@ -164,7 +164,8 @@ class GithubClient { } = await actions.deleteSelfHostedRunnerFromRepo({ owner, repo, - runner_id + runner_id, + per_page: 100 }); return token; From 0d0e2c0d7a0422b47c95509f46067a5fcf2525e4 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Tue, 20 Oct 2020 23:44:10 +0200 Subject: [PATCH 44/66] await runners 100 --- src/GithubClient.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/GithubClient.js b/src/GithubClient.js index 684aedc00..de0c37f7f 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -154,7 +154,7 @@ class GithubClient { const { id: runner_id } = runners.filter( (runner) => runner.name === name - ); + )[0]; console.log(name); console.log(runner_id); @@ -177,7 +177,9 @@ class GithubClient { org: owner }); - const { id: runner_id } = runners.filter((runner) => runner.name === name); + const { id: runner_id } = runners.filter( + (runner) => runner.name === name + )[0]; const { data: { token } From 4077f6f821560aa093991e8e45d5d01ba6aa0abb Mon Sep 17 00:00:00 2001 From: davidgortega Date: Tue, 20 Oct 2020 23:54:01 +0200 Subject: [PATCH 45/66] proc exit --- bin/cml-cloud-runner-entrypoint.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/bin/cml-cloud-runner-entrypoint.js b/bin/cml-cloud-runner-entrypoint.js index 9640f9540..b35eb1197 100755 --- a/bin/cml-cloud-runner-entrypoint.js +++ b/bin/cml-cloud-runner-entrypoint.js @@ -34,6 +34,7 @@ let TIMEOUT_TIMER = 0; let JOB_RUNNING = false; let RUNNER_TOKEN; let GITLAB_CI_TOKEN; +let PROC; const shutdown_docker_machine = async () => { console.log('Shutting down docker machine'); @@ -65,6 +66,8 @@ const shutdown = async (error) => { console.log('Unregistering runner'); try { + PROC.exit(0); + if (IS_GITHUB) { await cml.unregister_runner({ name: RUNNER_NAME }); } else { @@ -140,9 +143,9 @@ const run = async () => { --limit 1`; } - const proc = spawn(command, { shell: true }); + PROC = spawn(command, { shell: true }); - proc.stderr.on('data', (data) => { + PROC.stderr.on('data', (data) => { data && console.log(data.toString('utf8')); if (data && !IS_GITHUB) { @@ -153,7 +156,7 @@ const run = async () => { } }); - proc.stdout.on('data', async (data) => { + PROC.stdout.on('data', async (data) => { data && console.log(data.toString('utf8')); if (data && IS_GITHUB && data.includes('Running job')) { From c4a451a928a36ad5a3d8a32d67cf1ae32f7f6b39 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Tue, 20 Oct 2020 23:57:44 +0200 Subject: [PATCH 46/66] proc exit --- bin/cml-cloud-runner-entrypoint.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/cml-cloud-runner-entrypoint.js b/bin/cml-cloud-runner-entrypoint.js index b35eb1197..0318110a8 100755 --- a/bin/cml-cloud-runner-entrypoint.js +++ b/bin/cml-cloud-runner-entrypoint.js @@ -66,7 +66,7 @@ const shutdown = async (error) => { console.log('Unregistering runner'); try { - PROC.exit(0); + PROC.kill('SIGHUP'); if (IS_GITHUB) { await cml.unregister_runner({ name: RUNNER_NAME }); From b256b048db325416f53f5e422d6809c0bbd13d22 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Wed, 21 Oct 2020 00:00:26 +0200 Subject: [PATCH 47/66] proc exit --- bin/cml-cloud-runner-entrypoint.js | 2 +- src/GithubClient.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/bin/cml-cloud-runner-entrypoint.js b/bin/cml-cloud-runner-entrypoint.js index 0318110a8..9c5deae58 100755 --- a/bin/cml-cloud-runner-entrypoint.js +++ b/bin/cml-cloud-runner-entrypoint.js @@ -66,7 +66,7 @@ const shutdown = async (error) => { console.log('Unregistering runner'); try { - PROC.kill('SIGHUP'); + // PROC.kill('SIGHUP'); if (IS_GITHUB) { await cml.unregister_runner({ name: RUNNER_NAME }); diff --git a/src/GithubClient.js b/src/GithubClient.js index de0c37f7f..90b36d6bf 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -164,8 +164,7 @@ class GithubClient { } = await actions.deleteSelfHostedRunnerFromRepo({ owner, repo, - runner_id, - per_page: 100 + runner_id }); return token; @@ -174,7 +173,8 @@ class GithubClient { const { data: { runners } } = await actions.listSelfHostedRunnersForOrg({ - org: owner + org: owner, + per_page: 100 }); const { id: runner_id } = runners.filter( From 0fc3991ac847dc9532bcff479df6eb0d61c94f4a Mon Sep 17 00:00:00 2001 From: davidgortega Date: Wed, 21 Oct 2020 00:04:17 +0200 Subject: [PATCH 48/66] proc exit --- src/GithubClient.js | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/GithubClient.js b/src/GithubClient.js index 90b36d6bf..24b4cc2c4 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -159,15 +159,11 @@ class GithubClient { console.log(name); console.log(runner_id); - const { - data: { token } - } = await actions.deleteSelfHostedRunnerFromRepo({ + await actions.deleteSelfHostedRunnerFromRepo({ owner, repo, runner_id }); - - return token; } const { @@ -181,14 +177,10 @@ class GithubClient { (runner) => runner.name === name )[0]; - const { - data: { token } - } = await actions.deleteSelfHostedRunnerFromOrg({ + await actions.deleteSelfHostedRunnerFromOrg({ org: owner, runner_id }); - - return token; } } From d3d1c0358160603863fc0089486f34fa11abecb0 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Wed, 21 Oct 2020 00:06:51 +0200 Subject: [PATCH 49/66] proc exit --- src/GithubClient.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/GithubClient.js b/src/GithubClient.js index 24b4cc2c4..f4626247f 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -164,6 +164,8 @@ class GithubClient { repo, runner_id }); + + return; } const { From 8313ae9279c7c40631874e55838c38029bbd5373 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Wed, 21 Oct 2020 00:11:41 +0200 Subject: [PATCH 50/66] remove log --- bin/cml-cloud-runner-entrypoint.js | 9 +++------ src/GithubClient.js | 5 ----- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/bin/cml-cloud-runner-entrypoint.js b/bin/cml-cloud-runner-entrypoint.js index 9c5deae58..9640f9540 100755 --- a/bin/cml-cloud-runner-entrypoint.js +++ b/bin/cml-cloud-runner-entrypoint.js @@ -34,7 +34,6 @@ let TIMEOUT_TIMER = 0; let JOB_RUNNING = false; let RUNNER_TOKEN; let GITLAB_CI_TOKEN; -let PROC; const shutdown_docker_machine = async () => { console.log('Shutting down docker machine'); @@ -66,8 +65,6 @@ const shutdown = async (error) => { console.log('Unregistering runner'); try { - // PROC.kill('SIGHUP'); - if (IS_GITHUB) { await cml.unregister_runner({ name: RUNNER_NAME }); } else { @@ -143,9 +140,9 @@ const run = async () => { --limit 1`; } - PROC = spawn(command, { shell: true }); + const proc = spawn(command, { shell: true }); - PROC.stderr.on('data', (data) => { + proc.stderr.on('data', (data) => { data && console.log(data.toString('utf8')); if (data && !IS_GITHUB) { @@ -156,7 +153,7 @@ const run = async () => { } }); - PROC.stdout.on('data', async (data) => { + proc.stdout.on('data', async (data) => { data && console.log(data.toString('utf8')); if (data && IS_GITHUB && data.includes('Running job')) { diff --git a/src/GithubClient.js b/src/GithubClient.js index f4626247f..afeaeae05 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -150,15 +150,10 @@ class GithubClient { per_page: 100 }); - console.log(runners); - const { id: runner_id } = runners.filter( (runner) => runner.name === name )[0]; - console.log(name); - console.log(runner_id); - await actions.deleteSelfHostedRunnerFromRepo({ owner, repo, From b3460192d398f4a6f8ec53946903d9b99e4f6abb Mon Sep 17 00:00:00 2001 From: davidgortega Date: Wed, 21 Oct 2020 00:23:05 +0200 Subject: [PATCH 51/66] refactor --- src/GithubClient.js | 56 +++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/src/GithubClient.js b/src/GithubClient.js index afeaeae05..5c60b5fa0 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -140,44 +140,46 @@ class GithubClient { const { name } = opts; const { owner, repo } = owner_repo({ uri: this.repo }); const { actions } = octokit(this.token); + const { id: runner_id } = await this.runner_by_name({ name }); if (typeof repo !== 'undefined') { - const { - data: { runners } - } = await actions.listSelfHostedRunnersForRepo({ - owner, - repo, - per_page: 100 - }); - - const { id: runner_id } = runners.filter( - (runner) => runner.name === name - )[0]; - await actions.deleteSelfHostedRunnerFromRepo({ owner, repo, runner_id }); - - return; + } else { + await actions.deleteSelfHostedRunnerFromOrg({ + org: owner, + runner_id + }); } + } - const { - data: { runners } - } = await actions.listSelfHostedRunnersForOrg({ - org: owner, - per_page: 100 - }); + async runner_by_name(opts = {}) { + const { name } = opts; + const { owner, repo } = owner_repo({ uri: this.repo }); + const { actions } = octokit(this.token); + let runners = []; - const { id: runner_id } = runners.filter( - (runner) => runner.name === name - )[0]; + if (typeof repo !== 'undefined') { + ({ + data: { runners } + } = await actions.listSelfHostedRunnersForRepo({ + owner, + repo, + per_page: 100 + })); + } else { + ({ + data: { runners } + } = await actions.listSelfHostedRunnersForOrg({ + org: owner, + per_page: 100 + })); + } - await actions.deleteSelfHostedRunnerFromOrg({ - org: owner, - runner_id - }); + return runners.filter((runner) => runner.name === name)[0]; } } From fbaac607424412f54466cad38d82b2eeae7d88d2 Mon Sep 17 00:00:00 2001 From: DavidGOrtega Date: Wed, 21 Oct 2020 17:18:54 +0200 Subject: [PATCH 52/66] Cml contexts sha fix (#315) * token * clean env before tests * print env * yaml * yaml * yaml * yaml * check * fix repo env * fix repo env * fix repo env * fix repo env * check name * env github tests * env github tests * log check * log check * no check tessts * enviromental tests * workflow eenv * gitlab uploads and github_token * snapshots * log env * log env * update also github.context * No log --- src/GithubClient.test.js | 7 ++++++- src/GitlabClient.test.js | 1 - 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/GithubClient.test.js b/src/GithubClient.test.js index d7fce4966..eb05fdf1d 100644 --- a/src/GithubClient.test.js +++ b/src/GithubClient.test.js @@ -1,6 +1,7 @@ jest.setTimeout(20000); const GithubClient = require('./GithubClient'); +const github = require('@actions/github'); const { TEST_GITHUB_TOKEN: TOKEN, @@ -49,6 +50,11 @@ describe('Enviromental tests', () => { process.env = {}; process.env.repo_token = TOKEN; process.env.GITHUB_SHA = SHA; + + try { + github.context.payload.pull_request.head.sha = SHA; + } catch (err) {} + process.env.GITHUB_REPOSITORY = new URL(REPO).pathname.substring(1); }); @@ -59,7 +65,6 @@ describe('Enviromental tests', () => { test('Env', async () => { const client = new GithubClient({}); - expect(client.env_is_pr()).toBe(false); expect(client.env_head_sha()).toBe(SHA); expect(client.env_repo()).toBe(REPO); expect(client.env_token()).toBe(TOKEN); diff --git a/src/GitlabClient.test.js b/src/GitlabClient.test.js index 3d25ea8ed..2714af9eb 100644 --- a/src/GitlabClient.test.js +++ b/src/GitlabClient.test.js @@ -64,7 +64,6 @@ describe('Enviromental tests', () => { test('Env', async () => { const client = new GitlabClient(); - expect(client.env_is_pr()).toBe(false); expect(client.env_head_sha()).toBe(SHA); expect(client.env_repo()).toBe(REPO); expect(client.env_token()).toBe(TOKEN); From 20fa7e298eba25d2ad3bbb37aea5cbeb6aa95087 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Wed, 21 Oct 2020 18:00:01 +0200 Subject: [PATCH 53/66] point to iterative repos --- .github/workflows/publish.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 6af0f9f4b..3662b01b1 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -5,11 +5,11 @@ on: [push, pull_request] env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TEST_GITHUB_TOKEN: ${{ secrets.TEST_GITHUB_TOKEN }} - TEST_GITHUB_REPO: ${{ secrets.TEST_GITHUB_REPO }} - TEST_GITHUB_SHA: ${{ secrets.TEST_GITHUB_SHA }} + TEST_GITHUB_REPO: https://github.com/iterative/cml_qa_tests_dummy + TEST_GITHUB_SHA: 62edc8b3f46a60b3fe1e5c08fd3e0046d350ee29 TEST_GITLAB_TOKEN: ${{ secrets.TEST_GITLAB_TOKEN }} - TEST_GITLAB_REPO: ${{ secrets.TEST_GITLAB_REPO }} - TEST_GITLAB_SHA: ${{ secrets.TEST_GITLAB_SHA }} + TEST_GITLAB_REPO: https://gitlab.com/iterative/cml_qa_tests_dummy/ + TEST_GITLAB_SHA: c4c13286e78dc252dd2611f31a755f10d343fbd4 jobs: test_and_deploy: From 1f33b73871c1e027016a80de56c4119a182003b1 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Wed, 21 Oct 2020 18:08:18 +0200 Subject: [PATCH 54/66] point to iterative repos without slash --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 3662b01b1..424cb2e40 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,7 +8,7 @@ env: TEST_GITHUB_REPO: https://github.com/iterative/cml_qa_tests_dummy TEST_GITHUB_SHA: 62edc8b3f46a60b3fe1e5c08fd3e0046d350ee29 TEST_GITLAB_TOKEN: ${{ secrets.TEST_GITLAB_TOKEN }} - TEST_GITLAB_REPO: https://gitlab.com/iterative/cml_qa_tests_dummy/ + TEST_GITLAB_REPO: https://gitlab.com/iterative/cml_qa_tests_dummy TEST_GITLAB_SHA: c4c13286e78dc252dd2611f31a755f10d343fbd4 jobs: From eedd09d95e454227d804eeb2c2a84d716e4a35f5 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Wed, 21 Oct 2020 18:17:07 +0200 Subject: [PATCH 55/66] point to iterative ai --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 424cb2e40..c8dfb2988 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,7 +8,7 @@ env: TEST_GITHUB_REPO: https://github.com/iterative/cml_qa_tests_dummy TEST_GITHUB_SHA: 62edc8b3f46a60b3fe1e5c08fd3e0046d350ee29 TEST_GITLAB_TOKEN: ${{ secrets.TEST_GITLAB_TOKEN }} - TEST_GITLAB_REPO: https://gitlab.com/iterative/cml_qa_tests_dummy + TEST_GITLAB_REPO: https://gitlab.com/iterative.ai/cml_qa_tests_dummy TEST_GITLAB_SHA: c4c13286e78dc252dd2611f31a755f10d343fbd4 jobs: From a0c121adaee905e4d432a8abc54a1c7d4653cf4e Mon Sep 17 00:00:00 2001 From: davidgortega Date: Wed, 21 Oct 2020 23:42:04 +0200 Subject: [PATCH 56/66] test slash --- .github/workflows/publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c8dfb2988..686325db8 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -5,10 +5,10 @@ on: [push, pull_request] env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TEST_GITHUB_TOKEN: ${{ secrets.TEST_GITHUB_TOKEN }} - TEST_GITHUB_REPO: https://github.com/iterative/cml_qa_tests_dummy + TEST_GITHUB_REPO: https://github.com/iterative/cml_qa_tests_dummy/ TEST_GITHUB_SHA: 62edc8b3f46a60b3fe1e5c08fd3e0046d350ee29 TEST_GITLAB_TOKEN: ${{ secrets.TEST_GITLAB_TOKEN }} - TEST_GITLAB_REPO: https://gitlab.com/iterative.ai/cml_qa_tests_dummy + TEST_GITLAB_REPO: https://gitlab.com/iterative.ai/cml_qa_tests_dummy/ TEST_GITLAB_SHA: c4c13286e78dc252dd2611f31a755f10d343fbd4 jobs: From d0e810aac1e018fe913630f00eb24ad7ddd06bba Mon Sep 17 00:00:00 2001 From: davidgortega Date: Wed, 21 Oct 2020 23:47:23 +0200 Subject: [PATCH 57/66] test slash --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 686325db8..0fe7d3469 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,7 +8,7 @@ env: TEST_GITHUB_REPO: https://github.com/iterative/cml_qa_tests_dummy/ TEST_GITHUB_SHA: 62edc8b3f46a60b3fe1e5c08fd3e0046d350ee29 TEST_GITLAB_TOKEN: ${{ secrets.TEST_GITLAB_TOKEN }} - TEST_GITLAB_REPO: https://gitlab.com/iterative.ai/cml_qa_tests_dummy/ + TEST_GITLAB_REPO: https://gitlab.com/iterative.ai/cml_qa_tests_dummy TEST_GITLAB_SHA: c4c13286e78dc252dd2611f31a755f10d343fbd4 jobs: From 4adfb1c9bb24c4bdd632f67d67ca74c3201cfa15 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Thu, 22 Oct 2020 12:25:56 +0200 Subject: [PATCH 58/66] fix strip --- .github/workflows/publish.yml | 2 +- src/GithubClient.js | 4 +++- src/GitlabClient.js | 4 +++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 0fe7d3469..686325db8 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,7 +8,7 @@ env: TEST_GITHUB_REPO: https://github.com/iterative/cml_qa_tests_dummy/ TEST_GITHUB_SHA: 62edc8b3f46a60b3fe1e5c08fd3e0046d350ee29 TEST_GITLAB_TOKEN: ${{ secrets.TEST_GITLAB_TOKEN }} - TEST_GITLAB_REPO: https://gitlab.com/iterative.ai/cml_qa_tests_dummy + TEST_GITLAB_REPO: https://gitlab.com/iterative.ai/cml_qa_tests_dummy/ TEST_GITLAB_SHA: c4c13286e78dc252dd2611f31a755f10d343fbd4 jobs: diff --git a/src/GithubClient.js b/src/GithubClient.js index d1ac1aba1..36c39e0a4 100644 --- a/src/GithubClient.js +++ b/src/GithubClient.js @@ -32,7 +32,9 @@ class GithubClient { if (!repo) throw new Error('repo not found'); - this.repo = repo.endsWith('/') ? strip_last_chars(repo, 1) : repo; + this.repo = repo.endsWith('/') + ? strip_last_chars({ str: repo, size: 1 }) + : repo; this.token = token; } diff --git a/src/GitlabClient.js b/src/GitlabClient.js index e3db283f0..cd40c6267 100644 --- a/src/GitlabClient.js +++ b/src/GitlabClient.js @@ -11,7 +11,9 @@ class GitlabClient { if (!repo) throw new Error('repo not found'); if (!token) throw new Error('token not found'); - this.repo = repo.endsWith('/') ? strip_last_chars(repo, 1) : repo; + this.repo = repo.endsWith('/') + ? strip_last_chars({ str: repo, size: 1 }) + : repo; this.token = token; const { protocol, host, pathname } = new URL(repo); From d21e7103123ab519c492ceb9b96f3615031d1a17 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Thu, 22 Oct 2020 12:39:51 +0200 Subject: [PATCH 59/66] removal of strip --- .github/workflows/publish.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 686325db8..c8dfb2988 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -5,10 +5,10 @@ on: [push, pull_request] env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TEST_GITHUB_TOKEN: ${{ secrets.TEST_GITHUB_TOKEN }} - TEST_GITHUB_REPO: https://github.com/iterative/cml_qa_tests_dummy/ + TEST_GITHUB_REPO: https://github.com/iterative/cml_qa_tests_dummy TEST_GITHUB_SHA: 62edc8b3f46a60b3fe1e5c08fd3e0046d350ee29 TEST_GITLAB_TOKEN: ${{ secrets.TEST_GITLAB_TOKEN }} - TEST_GITLAB_REPO: https://gitlab.com/iterative.ai/cml_qa_tests_dummy/ + TEST_GITLAB_REPO: https://gitlab.com/iterative.ai/cml_qa_tests_dummy TEST_GITLAB_SHA: c4c13286e78dc252dd2611f31a755f10d343fbd4 jobs: From 2cc0ac680f916c96d3273327241a872dfc4edbbc Mon Sep 17 00:00:00 2001 From: davidgortega Date: Thu, 22 Oct 2020 13:25:06 +0200 Subject: [PATCH 60/66] refactor --- .github/workflows/publish.yml | 2 +- src/cml.js | 4 ++-- src/{GithubClient.js => drivers/github.js} | 6 +++--- src/{GithubClient.test.js => drivers/github.test.js} | 2 +- src/{GitlabClient.js => drivers/gitlab.js} | 8 ++++---- src/{GitlabClient.test.js => drivers/gitlab.test.js} | 6 +++--- 6 files changed, 14 insertions(+), 14 deletions(-) rename src/{GithubClient.js => drivers/github.js} (96%) rename src/{GithubClient.test.js => drivers/github.test.js} (98%) rename src/{GitlabClient.js => drivers/gitlab.js} (94%) rename src/{GitlabClient.test.js => drivers/gitlab.test.js} (93%) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c8dfb2988..01ad2b0ae 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,7 +8,7 @@ env: TEST_GITHUB_REPO: https://github.com/iterative/cml_qa_tests_dummy TEST_GITHUB_SHA: 62edc8b3f46a60b3fe1e5c08fd3e0046d350ee29 TEST_GITLAB_TOKEN: ${{ secrets.TEST_GITLAB_TOKEN }} - TEST_GITLAB_REPO: https://gitlab.com/iterative.ai/cml_qa_tests_dummy + TEST_GITLAB_REPO: https://gitlab.com/iterative.ai/cml_qa_tests_dummy/ TEST_GITLAB_SHA: c4c13286e78dc252dd2611f31a755f10d343fbd4 jobs: diff --git a/src/cml.js b/src/cml.js index 255e2d2f7..d50d811b4 100644 --- a/src/cml.js +++ b/src/cml.js @@ -1,5 +1,5 @@ -const GitlabClient = require('./GitlabClient'); -const GithubClient = require('./GithubClient'); +const GitlabClient = require('./drivers/gitlab'); +const GithubClient = require('./drivers/github'); const { upload } = require('./utils'); const get_client = (opts) => { diff --git a/src/GithubClient.js b/src/drivers/github.js similarity index 96% rename from src/GithubClient.js rename to src/drivers/github.js index 36c39e0a4..98836df6d 100644 --- a/src/GithubClient.js +++ b/src/drivers/github.js @@ -1,6 +1,6 @@ const github = require('@actions/github'); -const { strip_last_chars } = require('./utils'); +const { strip_last_chars } = require('../utils'); const GITHUB_HOST = 'https://github.com/'; const CHECK_TITLE = 'CML Report'; @@ -26,7 +26,7 @@ const octokit = (token) => { return github.getOctokit(token); }; -class GithubClient { +class Github { constructor(opts = {}) { const { repo = this.env_repo(), token = this.env_token() } = opts; @@ -139,4 +139,4 @@ class GithubClient { } } -module.exports = GithubClient; +module.exports = Github; diff --git a/src/GithubClient.test.js b/src/drivers/github.test.js similarity index 98% rename from src/GithubClient.test.js rename to src/drivers/github.test.js index eb05fdf1d..25c6ff2d1 100644 --- a/src/GithubClient.test.js +++ b/src/drivers/github.test.js @@ -1,6 +1,6 @@ jest.setTimeout(20000); -const GithubClient = require('./GithubClient'); +const GithubClient = require('./github'); const github = require('@actions/github'); const { diff --git a/src/GitlabClient.js b/src/drivers/gitlab.js similarity index 94% rename from src/GitlabClient.js rename to src/drivers/gitlab.js index cd40c6267..f7763e0ac 100644 --- a/src/GitlabClient.js +++ b/src/drivers/gitlab.js @@ -2,9 +2,9 @@ const fetch = require('node-fetch'); const FormData = require('form-data'); const { URL, URLSearchParams } = require('url'); -const { fetch_upload_data, strip_last_chars } = require('./utils'); +const { fetch_upload_data, strip_last_chars } = require('../utils'); -class GitlabClient { +class Gitlab { constructor(opts = {}) { const { repo = this.env_repo(), token = this.env_token() } = opts; @@ -16,7 +16,7 @@ class GitlabClient { : repo; this.token = token; - const { protocol, host, pathname } = new URL(repo); + const { protocol, host, pathname } = new URL(this.repo); this.repo_origin = `${protocol}//${host}`; this.api_v4 = `${this.repo_origin}/api/v4`; this.project_path = encodeURIComponent(pathname.substring(1)); @@ -111,4 +111,4 @@ class GitlabClient { } } -module.exports = GitlabClient; +module.exports = Gitlab; diff --git a/src/GitlabClient.test.js b/src/drivers/gitlab.test.js similarity index 93% rename from src/GitlabClient.test.js rename to src/drivers/gitlab.test.js index 2714af9eb..9e5472521 100644 --- a/src/GitlabClient.test.js +++ b/src/drivers/gitlab.test.js @@ -1,6 +1,6 @@ jest.setTimeout(20000); -const GitlabClient = require('./GitlabClient'); +const GitlabClient = require('./gitlab'); const { TEST_GITLAB_TOKEN: TOKEN, @@ -32,7 +32,7 @@ describe('Non Enviromental tests', () => { }); test('Publish', async () => { - const path = `${__dirname}/../assets/logo.png`; + const path = `${__dirname}/../../assets/logo.png`; const { uri } = await client.publish({ path }); expect(uri).not.toBeUndefined(); @@ -89,7 +89,7 @@ describe('Enviromental tests', () => { test('Publish', async () => { const client = new GitlabClient(); - const path = `${__dirname}/../assets/logo.png`; + const path = `${__dirname}/../../assets/logo.png`; const { uri } = await client.publish({ path }); expect(uri).not.toBeUndefined(); From f454f1001400f55ea0a34dbd8d06bd9316b4d657 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Thu, 22 Oct 2020 13:33:17 +0200 Subject: [PATCH 61/66] slash --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 01ad2b0ae..c8dfb2988 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -8,7 +8,7 @@ env: TEST_GITHUB_REPO: https://github.com/iterative/cml_qa_tests_dummy TEST_GITHUB_SHA: 62edc8b3f46a60b3fe1e5c08fd3e0046d350ee29 TEST_GITLAB_TOKEN: ${{ secrets.TEST_GITLAB_TOKEN }} - TEST_GITLAB_REPO: https://gitlab.com/iterative.ai/cml_qa_tests_dummy/ + TEST_GITLAB_REPO: https://gitlab.com/iterative.ai/cml_qa_tests_dummy TEST_GITLAB_SHA: c4c13286e78dc252dd2611f31a755f10d343fbd4 jobs: From 9d0f22f243ba81292f1a2154f54cee67ad407ba7 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Mon, 26 Oct 2020 15:30:01 +0100 Subject: [PATCH 62/66] minor refactor --- src/cml.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/cml.js b/src/cml.js index d50d811b4..80a29fe9c 100644 --- a/src/cml.js +++ b/src/cml.js @@ -48,13 +48,11 @@ class CML { } async comment_create(opts = {}) { - const client = get_client(this); - return await client.comment_create(opts); + return await get_client(this).comment_create(opts); } async check_create(opts = {}) { - const client = get_client(this); - return await client.check_create(opts); + return await get_client(this).check_create(opts); } async publish(opts = {}) { @@ -78,13 +76,11 @@ class CML { } async runner_token() { - const client = get_client(this); - return await client.runner_token(); + return await get_client(this).runner_token(); } async register_runner(opts = {}) { - const client = get_client(this); - return await client.register_runner(opts); + return await get_client(this).register_runner(opts); } log_error(e) { From 2738dc9311f7d4ba2e903a5e9feaaea55f92bffa Mon Sep 17 00:00:00 2001 From: davidgortega Date: Mon, 26 Oct 2020 16:01:56 +0100 Subject: [PATCH 63/66] no console --- bin/cml-send-comment.js | 1 - 1 file changed, 1 deletion(-) diff --git a/bin/cml-send-comment.js b/bin/cml-send-comment.js index 66210db41..15e3864ef 100644 --- a/bin/cml-send-comment.js +++ b/bin/cml-send-comment.js @@ -8,7 +8,6 @@ const yargs = require('yargs'); const CML = require('../src/cml'); const run = async (opts) => { - console.error(process.env); const { 'commit-sha': sha, 'head-sha': head_sha } = opts; const path = opts._[0]; const report = await fs.readFile(path, 'utf-8'); From dd042e256aee68206e257a495bf3625fdd0fb584 Mon Sep 17 00:00:00 2001 From: DavidGOrtega Date: Wed, 28 Oct 2020 09:29:49 +0100 Subject: [PATCH 64/66] Cml contexts sha (#326) * git sha * commit_sha * log * log gh sha * log gh sha * show origin * remote as repo * remote as repo * tests * remove one test not working on gitlab * space --- bin/cml-send-comment.test.js | 7 ++++ package-lock.json | 55 ++++++++++++++++++++++++++++ package.json | 1 + src/cml.js | 71 +++++++++++++++++++++--------------- src/cml.test.js | 36 ++++++------------ src/drivers/github.js | 39 +++----------------- src/drivers/github.test.js | 59 ------------------------------ src/drivers/gitlab.js | 32 +++------------- src/drivers/gitlab.test.js | 58 ----------------------------- src/utils.js | 6 --- 10 files changed, 127 insertions(+), 237 deletions(-) diff --git a/bin/cml-send-comment.test.js b/bin/cml-send-comment.test.js index 89f2fe66d..0440242ba 100644 --- a/bin/cml-send-comment.test.js +++ b/bin/cml-send-comment.test.js @@ -47,4 +47,11 @@ describe('Comment integration tests', () => { `node ./bin/cml-send-comment.js --repo=${repo} --token=${token} --commit-sha=${sha} ${path}` ); }); + + test('cml-send-comment to current repo', async () => { + const report = `## Test Comment`; + + await fs.writeFile(path, report); + await exec(`node ./bin/cml-send-comment.js ${path}`); + }); }); diff --git a/package-lock.json b/package-lock.json index 684e9bddb..7ebb6b789 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3280,6 +3280,23 @@ "assert-plus": "^1.0.0" } }, + "git-up": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/git-up/-/git-up-4.0.2.tgz", + "integrity": "sha512-kbuvus1dWQB2sSW4cbfTeGpCMd8ge9jx9RKnhXhuJ7tnvT+NIrTVfYZxjtflZddQYcmdOTlkAcjmx7bor+15AQ==", + "requires": { + "is-ssh": "^1.3.0", + "parse-url": "^5.0.0" + } + }, + "git-url-parse": { + "version": "11.4.0", + "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-11.4.0.tgz", + "integrity": "sha512-KlIa5jvMYLjXMQXkqpFzobsyD/V2K5DRHl5OAf+6oDFPlPLxrGDVQlIdI63c4/Kt6kai4kALENSALlzTGST3GQ==", + "requires": { + "git-up": "^4.0.0" + } + }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -3927,6 +3944,14 @@ "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", "dev": true }, + "is-ssh": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.3.2.tgz", + "integrity": "sha512-elEw0/0c2UscLrNG+OAorbP539E3rhliKPg+hDMWN9VwrDXfYK+4PBEykDPfxlYYtQvl84TascnQyobfQLHEhQ==", + "requires": { + "protocols": "^1.1.0" + } + }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", @@ -5544,6 +5569,11 @@ "remove-trailing-separator": "^1.0.1" } }, + "normalize-url": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==" + }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -5798,6 +5828,26 @@ "error-ex": "^1.2.0" } }, + "parse-path": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-4.0.2.tgz", + "integrity": "sha512-HSqVz6iuXSiL8C1ku5Gl1Z5cwDd9Wo0q8CoffdAghP6bz8pJa1tcMC+m4N+z6VAS8QdksnIGq1TB6EgR4vPR6w==", + "requires": { + "is-ssh": "^1.3.0", + "protocols": "^1.4.0" + } + }, + "parse-url": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-5.0.2.tgz", + "integrity": "sha512-Czj+GIit4cdWtxo3ISZCvLiUjErSo0iI3wJ+q9Oi3QuMYTI6OZu+7cewMWZ+C1YAnKhYTk6/TLuhIgCypLthPA==", + "requires": { + "is-ssh": "^1.3.0", + "normalize-url": "^3.3.0", + "parse-path": "^4.0.0", + "protocols": "^1.4.0" + } + }, "parse5": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", @@ -6007,6 +6057,11 @@ "sisteransi": "^1.0.4" } }, + "protocols": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.8.tgz", + "integrity": "sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg==" + }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", diff --git a/package.json b/package.json index 33700d4bd..e31d528d3 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "@actions/github": "^4.0.0", "file-type": "^14.2.0", "form-data": "^3.0.0", + "git-url-parse": "^11.4.0", "is-svg": "^4.2.1", "node-fetch": "^2.6.0", "node-forge": "^0.10.0", diff --git a/src/cml.js b/src/cml.js index 80a29fe9c..1b524b5a3 100644 --- a/src/cml.js +++ b/src/cml.js @@ -1,6 +1,35 @@ +const { execSync } = require('child_process'); +const git_url_parse = require('git-url-parse'); + const GitlabClient = require('./drivers/gitlab'); const GithubClient = require('./drivers/github'); -const { upload } = require('./utils'); +const { upload, exec } = require('./utils'); + +const uri_no_trailing_slash = (uri) => { + return uri.endsWith('/') ? uri.substr(0, uri.length - 1) : uri; +}; + +const repo_from_origin = () => { + const origin = execSync('git config --get remote.origin.url').toString( + 'utf8' + ); + return git_url_parse(origin).toString('https').replace('.git', ''); +}; + +const infer_driver = (opts = {}) => { + const { repo } = opts; + if (repo && repo.includes('github.com')) return 'github'; + if (repo && repo.includes('gitlab.com')) return 'gitlab'; + + const { GITHUB_REPOSITORY, CI_PROJECT_URL } = process.env; + if (GITHUB_REPOSITORY) return 'github'; + if (CI_PROJECT_URL) return 'gitlab'; +}; + +const env_token = () => { + const { repo_token, GITHUB_TOKEN, GITLAB_TOKEN } = process.env; + return repo_token || GITHUB_TOKEN || GITLAB_TOKEN; +}; const get_client = (opts) => { const { driver, repo, token } = opts; @@ -14,44 +43,28 @@ const get_client = (opts) => { class CML { constructor(opts = {}) { - const env_driver = () => { - const { repo } = opts; - const { GITHUB_REPOSITORY, CI_PROJECT_URL } = process.env; + const { driver, repo, token } = opts; - if (repo && repo.startsWith('https://github.com')) return 'github'; - if (repo && repo.startsWith('https://gitlab.com')) return 'gitlab'; - - if (GITHUB_REPOSITORY) return 'github'; - if (CI_PROJECT_URL) return 'gitlab'; - }; - - const { driver = env_driver(), repo, token } = opts; - this.driver = driver; - this.repo = repo; - this.token = token; - } - - env_repo() { - return get_client(this).env_repo(); - } - - env_token() { - return get_client(this).env_token(); - } - - env_is_pr() { - return get_client(this).env_is_pr(); + this.repo = uri_no_trailing_slash(repo || repo_from_origin()); + this.token = token || env_token(); + this.driver = driver || infer_driver({ repo: this.repo }); } - env_head_sha() { - return get_client(this).env_head_sha(); + async head_sha() { + return (await exec(`git rev-parse HEAD`)).replace(/(\r\n|\n|\r)/gm, ''); } async comment_create(opts = {}) { + const sha = await this.head_sha(); + opts.commit_sha = opts.commit_sha || sha; + return await get_client(this).comment_create(opts); } async check_create(opts = {}) { + const sha = await this.head_sha(); + opts.head_sha = opts.head_sha || sha; + return await get_client(this).check_create(opts); } diff --git a/src/cml.test.js b/src/cml.test.js index 0b2025800..49e1fd17c 100644 --- a/src/cml.test.js +++ b/src/cml.test.js @@ -14,21 +14,14 @@ describe('Github tests', () => { process.env = {}; process.env.repo_token = TOKEN; - process.env.GITHUB_SHA = SHA; - process.env.GITHUB_REPOSITORY = new URL(REPO).pathname.substring(1); }); afterAll(() => { process.env = OLD_ENV; }); - test('env driver has to be github', async () => { - const cml = new CML(); - expect(cml.driver).toBe('github'); - }); - test('driver has to be github', async () => { - const cml = new CML({ repo: REPO, token: TOKEN, driver: 'github' }); + const cml = new CML({ repo: REPO, token: TOKEN }); expect(cml.driver).toBe('github'); }); @@ -62,9 +55,8 @@ describe('Github tests', () => { test('Comment should succeed with a valid sha', async () => { const report = '## Test comment'; - const commit_sha = SHA; - await new CML().comment_create({ report, commit_sha }); + await new CML({ repo: REPO }).comment_create({ report, commit_sha: SHA }); }); test('Comment should fail with a invalid sha', async () => { @@ -73,7 +65,7 @@ describe('Github tests', () => { const report = '## Test comment'; const commit_sha = 'invalid_sha'; - await new CML().comment_create({ report, commit_sha }); + await new CML({ repo: REPO }).comment_create({ report, commit_sha }); } catch (err) { catched_err = err.message; } @@ -95,20 +87,13 @@ describe('Gitlab tests', () => { jest.resetModules(); process.env = {}; - process.env.CI_PROJECT_URL = REPO; process.env.repo_token = TOKEN; - process.env.CI_COMMIT_SHA = SHA; }); afterAll(() => { process.env = OLD_ENV; }); - test('env driver has to be gitlab', async () => { - const cml = new CML(); - expect(cml.driver).toBe('gitlab'); - }); - test('driver has to be gitlab', async () => { const cml = new CML({ repo: REPO, token: TOKEN, driver: 'gitlab' }); expect(cml.driver).toBe('gitlab'); @@ -117,7 +102,10 @@ describe('Gitlab tests', () => { test('Publish image using gl without markdown returns an url', async () => { const path = `${__dirname}/../assets/logo.png`; - const output = await new CML().publish({ path, gitlab_uploads: true }); + const output = await new CML({ repo: REPO }).publish({ + path, + gitlab_uploads: true + }); expect(output.startsWith('https://')).toBe(true); }); @@ -126,7 +114,7 @@ describe('Gitlab tests', () => { const path = `${__dirname}/../assets/logo.png`; const title = 'my title'; - const output = await new CML().publish({ + const output = await new CML({ repo: REPO }).publish({ path, md: true, title, @@ -141,7 +129,7 @@ describe('Gitlab tests', () => { const path = `${__dirname}/../assets/logo.pdf`; const title = 'my title'; - const output = await new CML().publish({ + const output = await new CML({ repo: REPO }).publish({ path, md: true, title, @@ -152,9 +140,9 @@ describe('Gitlab tests', () => { expect(output.endsWith(')')).toBe(true); }); - test('Comment should succeed with a valid env sha', async () => { + test('Comment should succeed with a valid sha', async () => { const report = '## Test comment'; - await new CML().comment_create({ report }); + await new CML({ repo: REPO }).comment_create({ report, commit_sha: SHA }); }); test('Comment should fail with a unvalid sha', async () => { @@ -163,7 +151,7 @@ describe('Gitlab tests', () => { const report = '## Test comment'; const commit_sha = 'invalid_sha'; - await new CML().comment_create({ report, commit_sha }); + await new CML({ repo: REPO }).comment_create({ report, commit_sha }); } catch (err) { catched_err = err.message; } diff --git a/src/drivers/github.js b/src/drivers/github.js index 98836df6d..beb1086cf 100644 --- a/src/drivers/github.js +++ b/src/drivers/github.js @@ -1,8 +1,5 @@ const github = require('@actions/github'); -const { strip_last_chars } = require('../utils'); - -const GITHUB_HOST = 'https://github.com/'; const CHECK_TITLE = 'CML Report'; const owner_repo = (opts) => { @@ -28,48 +25,22 @@ const octokit = (token) => { class Github { constructor(opts = {}) { - const { repo = this.env_repo(), token = this.env_token() } = opts; + const { repo, token } = opts; if (!repo) throw new Error('repo not found'); + if (!token) throw new Error('token not found'); - this.repo = repo.endsWith('/') - ? strip_last_chars({ str: repo, size: 1 }) - : repo; + this.repo = repo; this.token = token; } - env_repo() { - const { GITHUB_REPOSITORY } = process.env; - if (GITHUB_REPOSITORY) return `${GITHUB_HOST}${GITHUB_REPOSITORY}`; - } - - env_token() { - const { repo_token, GITHUB_TOKEN } = process.env; - return repo_token || GITHUB_TOKEN; - } - - env_is_pr() { - try { - return typeof github.context.payload.pull_request !== 'undefined'; - } catch (err) { - return false; - } - } - - env_head_sha() { - if (this.env_is_pr()) return github.context.payload.pull_request.head.sha; - - const { GITHUB_SHA } = process.env; - return GITHUB_SHA; - } - owner_repo(opts = {}) { const { uri = this.repo } = opts; return owner_repo({ uri }); } async comment_create(opts = {}) { - const { report: body, commit_sha = this.env_head_sha() } = opts; + const { report: body, commit_sha } = opts; const { url: commit_url } = await octokit( this.token @@ -85,7 +56,7 @@ class Github { async check_create(opts = {}) { const { report, - commit_sha: head_sha = this.env_head_sha(), + head_sha, title = CHECK_TITLE, started_at = new Date(), completed_at = new Date(), diff --git a/src/drivers/github.test.js b/src/drivers/github.test.js index 25c6ff2d1..5ce0de5ad 100644 --- a/src/drivers/github.test.js +++ b/src/drivers/github.test.js @@ -1,7 +1,6 @@ jest.setTimeout(20000); const GithubClient = require('./github'); -const github = require('@actions/github'); const { TEST_GITHUB_TOKEN: TOKEN, @@ -40,61 +39,3 @@ describe('Non Enviromental tests', () => { expect(output.length).toBe(29); }); }); - -describe('Enviromental tests', () => { - const OLD_ENV = process.env; - - beforeEach(() => { - jest.resetModules(); - - process.env = {}; - process.env.repo_token = TOKEN; - process.env.GITHUB_SHA = SHA; - - try { - github.context.payload.pull_request.head.sha = SHA; - } catch (err) {} - - process.env.GITHUB_REPOSITORY = new URL(REPO).pathname.substring(1); - }); - - afterAll(() => { - process.env = OLD_ENV; - }); - - test('Env', async () => { - const client = new GithubClient({}); - - expect(client.env_head_sha()).toBe(SHA); - expect(client.env_repo()).toBe(REPO); - expect(client.env_token()).toBe(TOKEN); - - expect(client.repo).toBe(REPO); - expect(client.token).toBe(TOKEN); - - const { owner, repo } = client.owner_repo(); - const parts = process.env.GITHUB_REPOSITORY.split('/'); - expect(owner).toBe(parts[0]); - expect(repo).toBe(parts[1]); - }); - - test('Comment', async () => { - const client = new GithubClient({}); - const report = '## Test comment'; - - await client.comment_create({ report }); - }); - - test('Publish', async () => { - const client = new GithubClient({}); - await expect(client.publish()).rejects.toThrow( - 'Github does not support publish!' - ); - }); - - test('Runner token', async () => { - const client = new GithubClient({}); - const output = await client.runner_token(); - expect(output.length).toBe(29); - }); -}); diff --git a/src/drivers/gitlab.js b/src/drivers/gitlab.js index f7763e0ac..90ad1f97c 100644 --- a/src/drivers/gitlab.js +++ b/src/drivers/gitlab.js @@ -2,19 +2,17 @@ const fetch = require('node-fetch'); const FormData = require('form-data'); const { URL, URLSearchParams } = require('url'); -const { fetch_upload_data, strip_last_chars } = require('../utils'); +const { fetch_upload_data } = require('../utils'); class Gitlab { constructor(opts = {}) { - const { repo = this.env_repo(), token = this.env_token() } = opts; + const { repo, token } = opts; - if (!repo) throw new Error('repo not found'); if (!token) throw new Error('token not found'); + if (!repo) throw new Error('repo not found'); - this.repo = repo.endsWith('/') - ? strip_last_chars({ str: repo, size: 1 }) - : repo; this.token = token; + this.repo = repo; const { protocol, host, pathname } = new URL(this.repo); this.repo_origin = `${protocol}//${host}`; @@ -22,29 +20,9 @@ class Gitlab { this.project_path = encodeURIComponent(pathname.substring(1)); } - env_repo() { - const { CI_PROJECT_URL } = process.env; - return CI_PROJECT_URL; - } - - env_token() { - const { repo_token, GITLAB_TOKEN } = process.env; - return repo_token || GITLAB_TOKEN; - } - - env_is_pr() { - const { CI_MERGE_REQUEST_ID } = process.env; - return typeof CI_MERGE_REQUEST_ID !== 'undefined'; - } - - env_head_sha() { - const { CI_COMMIT_SHA } = process.env; - return CI_COMMIT_SHA; - } - async comment_create(opts = {}) { const { project_path } = this; - const { commit_sha = this.env_head_sha(), report } = opts; + const { commit_sha, report } = opts; const endpoint = `/projects/${project_path}/repository/commits/${commit_sha}/comments`; const body = new URLSearchParams(); diff --git a/src/drivers/gitlab.test.js b/src/drivers/gitlab.test.js index 9e5472521..37471af33 100644 --- a/src/drivers/gitlab.test.js +++ b/src/drivers/gitlab.test.js @@ -44,61 +44,3 @@ describe('Non Enviromental tests', () => { expect(output.length).toBe(20); }); }); - -describe('Enviromental tests', () => { - const OLD_ENV = process.env; - - beforeEach(() => { - jest.resetModules(); - - process.env = {}; - process.env.repo_token = TOKEN; - process.env.CI_PROJECT_URL = REPO; - process.env.CI_COMMIT_SHA = SHA; - }); - - afterAll(() => { - process.env = OLD_ENV; - }); - - test('Env', async () => { - const client = new GitlabClient(); - - expect(client.env_head_sha()).toBe(SHA); - expect(client.env_repo()).toBe(REPO); - expect(client.env_token()).toBe(TOKEN); - - expect(client.repo).toBe(REPO); - expect(client.token).toBe(TOKEN); - }); - - test('Comment', async () => { - const client = new GitlabClient(); - const report = '## Test comment'; - - const { created_at } = await client.comment_create({ report }); - expect(created_at).not.toBeUndefined(); - }); - - test('Check', async () => { - const client = new GitlabClient(); - await expect(client.check_create()).rejects.toThrow( - 'Gitlab does not support check!' - ); - }); - - test('Publish', async () => { - const client = new GitlabClient(); - const path = `${__dirname}/../../assets/logo.png`; - const { uri } = await client.publish({ path }); - - expect(uri).not.toBeUndefined(); - }); - - test('Runner token', async () => { - const client = new GitlabClient(); - const output = await client.runner_token(); - - expect(output.length).toBe(20); - }); -}); diff --git a/src/utils.js b/src/utils.js index e03b1d3d2..0e340a68c 100644 --- a/src/utils.js +++ b/src/utils.js @@ -135,11 +135,6 @@ const parse_param_newline = (param) => { return param.replace(/\\n/g, '\n'); }; -const strip_last_chars = (opts) => { - const { str, size = 0 } = opts; - return str.substr(0, str.length - size); -}; - exports.exec = exec; exports.fetch_upload_data = fetch_upload_data; exports.upload = upload; @@ -148,4 +143,3 @@ exports.sleep = sleep; exports.is_proc_running = is_proc_running; exports.ssh_public_from_private_rsa = ssh_public_from_private_rsa; exports.parse_param_newline = parse_param_newline; -exports.strip_last_chars = strip_last_chars; From ccc487e19edbf71ca0b1ea1ab40529cfac01ce23 Mon Sep 17 00:00:00 2001 From: davidgortega Date: Wed, 28 Oct 2020 13:29:01 +0100 Subject: [PATCH 65/66] publish backend --- bin/cml-publish.js | 3 +++ bin/cml-publish.test.js | 7 +++++-- src/cml.js | 6 +++--- src/cml.test.js | 33 ++++++++++++++++++++++++++++++++- src/drivers/github.js | 2 +- src/drivers/github.test.js | 2 +- src/drivers/gitlab.js | 2 +- src/drivers/gitlab.test.js | 2 +- 8 files changed, 47 insertions(+), 10 deletions(-) diff --git a/bin/cml-publish.js b/bin/cml-publish.js index f8e408e29..6d9d42d29 100644 --- a/bin/cml-publish.js +++ b/bin/cml-publish.js @@ -38,6 +38,9 @@ const argv = yargs 'gitlab-uploads', 'Uses GitLab uploads instead of CML storage. Use GitLab uploads to get around CML size limitations for hosting artifacts persistently. Only available for GitLab CI.' ) + .deprecateOption('gitlab-uploads', 'Use backend instead') + .default('backend', 'cml', 'Sets the backend used to publish the assets.') + .choices('backend', ['cml', 'gitlab']) .default('file') .describe( 'file', diff --git a/bin/cml-publish.test.js b/bin/cml-publish.test.js index 0537b6bd6..994a317fb 100644 --- a/bin/cml-publish.test.js +++ b/bin/cml-publish.test.js @@ -17,7 +17,7 @@ describe('CML e2e', () => { --gitlab-uploads Uses GitLab uploads instead of CML storage. Use GitLab uploads to get around CML size limitations for hosting artifacts persistently. Only available for GitLab CI. - [boolean] + [deprecated: Use backend instead] [boolean] --file, -f Append the output to the given file. Create it if does not exist. --repo Specifies the repo to be used. If not specified is extracted @@ -26,7 +26,10 @@ describe('CML e2e', () => { extracted from ENV repo_token or GITLAB_TOKEN. --driver If not specify it infers it from the ENV. [choices: \\"github\\", \\"gitlab\\"] - -h Show help [boolean]" + -h Show help [boolean] + --backend + [choices: \\"cml\\", \\"gitlab\\"] [default: Sets the backend used to publish the + assets.]" `); }); diff --git a/src/cml.js b/src/cml.js index 1b524b5a3..2fd24aadd 100644 --- a/src/cml.js +++ b/src/cml.js @@ -69,13 +69,13 @@ class CML { } async publish(opts = {}) { - const { title = '', md, gitlab_uploads } = opts; + const { title = '', md, gitlab_uploads, backend = 'cml' } = opts; let mime, uri; - if (gitlab_uploads) { + if (gitlab_uploads || backend !== 'cml') { const client = get_client({ ...this, driver: 'gitlab' }); - ({ mime, uri } = await client.publish(opts)); + ({ mime, uri } = await client.upload(opts)); } else { ({ mime, uri } = await upload(opts)); } diff --git a/src/cml.test.js b/src/cml.test.js index 49e1fd17c..8b52a1e1a 100644 --- a/src/cml.test.js +++ b/src/cml.test.js @@ -140,12 +140,43 @@ describe('Gitlab tests', () => { expect(output.endsWith(')')).toBe(true); }); + test('Publish a non image file using gl specifiying backend', async () => { + const path = `${__dirname}/../assets/logo.pdf`; + const title = 'my title'; + + const output = await new CML({ repo: REPO }).publish({ + path, + md: true, + title, + backend: 'gitlab' + }); + + expect(output.startsWith(`[${title}](https://`)).toBe(true); + expect(output.endsWith(')')).toBe(true); + }); + + test('Publish should fail with an invalid backend', async () => { + let catched_err; + try { + const path = `${__dirname}/../assets/logo.pdf`; + await new CML({ repo: REPO }).publish({ + path, + md: true, + backend: 'invalid' + }); + } catch (err) { + catched_err = err.message; + } + + expect(catched_err).not.toBeUndefined(); + }); + test('Comment should succeed with a valid sha', async () => { const report = '## Test comment'; await new CML({ repo: REPO }).comment_create({ report, commit_sha: SHA }); }); - test('Comment should fail with a unvalid sha', async () => { + test('Comment should fail with a invalid sha', async () => { let catched_err; try { const report = '## Test comment'; diff --git a/src/drivers/github.js b/src/drivers/github.js index beb1086cf..49ecba8ff 100644 --- a/src/drivers/github.js +++ b/src/drivers/github.js @@ -77,7 +77,7 @@ class Github { }); } - async publish() { + async upload() { throw new Error('Github does not support publish!'); } diff --git a/src/drivers/github.test.js b/src/drivers/github.test.js index 5ce0de5ad..87e426885 100644 --- a/src/drivers/github.test.js +++ b/src/drivers/github.test.js @@ -29,7 +29,7 @@ describe('Non Enviromental tests', () => { }); test('Publish', async () => { - await expect(client.publish()).rejects.toThrow( + await expect(client.upload()).rejects.toThrow( 'Github does not support publish!' ); }); diff --git a/src/drivers/gitlab.js b/src/drivers/gitlab.js index 90ad1f97c..2906706d4 100644 --- a/src/drivers/gitlab.js +++ b/src/drivers/gitlab.js @@ -37,7 +37,7 @@ class Gitlab { throw new Error('Gitlab does not support check!'); } - async publish(opts = {}) { + async upload(opts = {}) { const { project_path, repo } = this; const endpoint = `/projects/${project_path}/uploads`; const { size, mime, data } = await fetch_upload_data(opts); diff --git a/src/drivers/gitlab.test.js b/src/drivers/gitlab.test.js index 37471af33..82b296885 100644 --- a/src/drivers/gitlab.test.js +++ b/src/drivers/gitlab.test.js @@ -33,7 +33,7 @@ describe('Non Enviromental tests', () => { test('Publish', async () => { const path = `${__dirname}/../../assets/logo.png`; - const { uri } = await client.publish({ path }); + const { uri } = await client.upload({ path }); expect(uri).not.toBeUndefined(); }); From f2ec83bb20bb38aeaf1b00f9e55a15351d3a78eb Mon Sep 17 00:00:00 2001 From: davidgortega Date: Wed, 28 Oct 2020 15:34:46 +0100 Subject: [PATCH 66/66] no banckend in publish --- bin/cml-publish.js | 9 ++++++--- bin/cml-publish.test.js | 9 ++++----- src/cml.js | 37 ++++++++++++++++++------------------- src/cml.test.js | 10 +++++----- 4 files changed, 33 insertions(+), 32 deletions(-) diff --git a/bin/cml-publish.js b/bin/cml-publish.js index 6d9d42d29..c89a6faa2 100644 --- a/bin/cml-publish.js +++ b/bin/cml-publish.js @@ -38,9 +38,12 @@ const argv = yargs 'gitlab-uploads', 'Uses GitLab uploads instead of CML storage. Use GitLab uploads to get around CML size limitations for hosting artifacts persistently. Only available for GitLab CI.' ) - .deprecateOption('gitlab-uploads', 'Use backend instead') - .default('backend', 'cml', 'Sets the backend used to publish the assets.') - .choices('backend', ['cml', 'gitlab']) + .deprecateOption('gitlab-uploads', 'Use native instead') + .boolean('native') + .describe( + 'native', + "Uses driver's native capabilities to upload assets instead of CML's backend." + ) .default('file') .describe( 'file', diff --git a/bin/cml-publish.test.js b/bin/cml-publish.test.js index 994a317fb..c48522f42 100644 --- a/bin/cml-publish.test.js +++ b/bin/cml-publish.test.js @@ -17,7 +17,9 @@ describe('CML e2e', () => { --gitlab-uploads Uses GitLab uploads instead of CML storage. Use GitLab uploads to get around CML size limitations for hosting artifacts persistently. Only available for GitLab CI. - [deprecated: Use backend instead] [boolean] + [deprecated: Use native instead] [boolean] + --native Uses driver's native capabilities to upload assets instead + of CML's backend. [boolean] --file, -f Append the output to the given file. Create it if does not exist. --repo Specifies the repo to be used. If not specified is extracted @@ -26,10 +28,7 @@ describe('CML e2e', () => { extracted from ENV repo_token or GITLAB_TOKEN. --driver If not specify it infers it from the ENV. [choices: \\"github\\", \\"gitlab\\"] - -h Show help [boolean] - --backend - [choices: \\"cml\\", \\"gitlab\\"] [default: Sets the backend used to publish the - assets.]" + -h Show help [boolean]" `); }); diff --git a/src/cml.js b/src/cml.js index 2fd24aadd..04f53ce44 100644 --- a/src/cml.js +++ b/src/cml.js @@ -1,8 +1,8 @@ const { execSync } = require('child_process'); const git_url_parse = require('git-url-parse'); -const GitlabClient = require('./drivers/gitlab'); -const GithubClient = require('./drivers/github'); +const Gitlab = require('./drivers/gitlab'); +const Github = require('./drivers/github'); const { upload, exec } = require('./utils'); const uri_no_trailing_slash = (uri) => { @@ -26,27 +26,27 @@ const infer_driver = (opts = {}) => { if (CI_PROJECT_URL) return 'gitlab'; }; -const env_token = () => { - const { repo_token, GITHUB_TOKEN, GITLAB_TOKEN } = process.env; - return repo_token || GITHUB_TOKEN || GITLAB_TOKEN; -}; - -const get_client = (opts) => { +const get_driver = (opts) => { const { driver, repo, token } = opts; if (!driver) throw new Error('driver not set'); - if (driver === 'github') return new GithubClient({ repo, token }); - if (driver === 'gitlab') return new GitlabClient({ repo, token }); + if (driver === 'github') return new Github({ repo, token }); + if (driver === 'gitlab') return new Gitlab({ repo, token }); throw new Error('driver unknown!'); }; +const infer_token = () => { + const { repo_token, GITHUB_TOKEN, GITLAB_TOKEN } = process.env; + return repo_token || GITHUB_TOKEN || GITLAB_TOKEN; +}; + class CML { constructor(opts = {}) { const { driver, repo, token } = opts; this.repo = uri_no_trailing_slash(repo || repo_from_origin()); - this.token = token || env_token(); + this.token = token || infer_token(); this.driver = driver || infer_driver({ repo: this.repo }); } @@ -58,23 +58,22 @@ class CML { const sha = await this.head_sha(); opts.commit_sha = opts.commit_sha || sha; - return await get_client(this).comment_create(opts); + return await get_driver(this).comment_create(opts); } async check_create(opts = {}) { const sha = await this.head_sha(); opts.head_sha = opts.head_sha || sha; - return await get_client(this).check_create(opts); + return await get_driver(this).check_create(opts); } async publish(opts = {}) { - const { title = '', md, gitlab_uploads, backend = 'cml' } = opts; + const { title = '', md, native, gitlab_uploads } = opts; let mime, uri; - - if (gitlab_uploads || backend !== 'cml') { - const client = get_client({ ...this, driver: 'gitlab' }); + if (native || gitlab_uploads) { + const client = get_driver(this); ({ mime, uri } = await client.upload(opts)); } else { ({ mime, uri } = await upload(opts)); @@ -89,11 +88,11 @@ class CML { } async runner_token() { - return await get_client(this).runner_token(); + return await get_driver(this).runner_token(); } async register_runner(opts = {}) { - return await get_client(this).register_runner(opts); + return await get_driver(this).register_runner(opts); } log_error(e) { diff --git a/src/cml.test.js b/src/cml.test.js index 8b52a1e1a..06696bf7d 100644 --- a/src/cml.test.js +++ b/src/cml.test.js @@ -140,7 +140,7 @@ describe('Gitlab tests', () => { expect(output.endsWith(')')).toBe(true); }); - test('Publish a non image file using gl specifiying backend', async () => { + test('Publish a non image file using native', async () => { const path = `${__dirname}/../assets/logo.pdf`; const title = 'my title'; @@ -148,21 +148,21 @@ describe('Gitlab tests', () => { path, md: true, title, - backend: 'gitlab' + native: true }); expect(output.startsWith(`[${title}](https://`)).toBe(true); expect(output.endsWith(')')).toBe(true); }); - test('Publish should fail with an invalid backend', async () => { + test('Publish should fail with an invalid driver', async () => { let catched_err; try { const path = `${__dirname}/../assets/logo.pdf`; - await new CML({ repo: REPO }).publish({ + await new CML({ repo: REPO, driver: 'invalid' }).publish({ path, md: true, - backend: 'invalid' + native: true }); } catch (err) { catched_err = err.message;