diff --git a/packages/grafana-toolkit/bin/grafana-toolkit.dist.js b/packages/grafana-toolkit/bin/grafana-toolkit.dist.js index a1cff04187d..a48b032c8f1 100755 --- a/packages/grafana-toolkit/bin/grafana-toolkit.dist.js +++ b/packages/grafana-toolkit/bin/grafana-toolkit.dist.js @@ -4,10 +4,16 @@ const fs = require('fs'); entrypoint = () => { const defaultEntryPoint = '../src/cli/index.js'; - // We are running in dev mode. Don't use compiled binaries, rather use the dev entrypoint. - if (fs.existsSync(`${process.env['HOME']}/.config/yarn/link/@grafana/toolkit`)) { - console.log('Running in linked mode'); - return `${__dirname}/grafana-toolkit.js`; + const toolkitDirectory = `${process.env['PWD']}/node_modules/@grafana/toolkit`; + + // IF we have a toolkit directory AND linked grafana toolkit AND the toolkit dir is a symbolic lik + // THEN run everything in linked mode + if (fs.existsSync(toolkitDirectory)) { + const tkStat = fs.lstatSync(toolkitDirectory); + if (fs.existsSync(`${process.env['HOME']}/.config/yarn/link/@grafana/toolkit`) && tkStat.isSymbolicLink()) { + console.log('Running in linked mode'); + return `${__dirname}/grafana-toolkit.js`; + } } // We are using npx, and a relative path does not find index.js diff --git a/packages/grafana-toolkit/src/cli/tasks/plugin.utils.ts b/packages/grafana-toolkit/src/cli/tasks/plugin.utils.ts index 63076ffb498..8d6acc7188e 100755 --- a/packages/grafana-toolkit/src/cli/tasks/plugin.utils.ts +++ b/packages/grafana-toolkit/src/cli/tasks/plugin.utils.ts @@ -10,6 +10,8 @@ import path = require('path'); import execa = require('execa'); interface Command extends Array {} +const DEFAULT_EMAIL_ADDRESS = 'eng@graafna.com'; +const DEFAULT_USERNAME = 'CircleCI Automation'; const releaseNotes = async (): Promise => { const { stdout } = await execa.shell(`awk \'BEGIN {FS="##"; RS=""} FNR==3 {print; exit}\' CHANGELOG.md`); @@ -62,12 +64,10 @@ const prepareRelease = useSpinner('Preparing release', async ({ dryrun, ver const distContentDir = path.resolve(distDir, getPluginId()); const pluginJsonFile = path.resolve(distContentDir, 'plugin.json'); const pluginJson = getPluginJson(pluginJsonFile); - const GIT_EMAIL = 'eng@grafana.com'; - const GIT_USERNAME = 'CircleCI Automation'; const githubPublishScript: Command = [ - ['git', ['config', 'user.email', GIT_EMAIL]], - ['git', ['config', 'user.name', GIT_USERNAME]], + ['git', ['config', 'user.email', DEFAULT_EMAIL_ADDRESS]], + ['git', ['config', 'user.name', DEFAULT_USERNAME]], await checkoutBranch(`release-${pluginJson.info.version}`), ['cp', ['-rf', distContentDir, 'dist']], ['git', ['add', '--force', distDir], { dryrun }], @@ -138,14 +138,14 @@ const prepareRelease = useSpinner('Preparing release', async ({ dryrun, ver interface GithubPublishReleaseOptions { commitHash?: string; githubToken: string; - gitRepoOwner: string; + githubEmail: string; gitRepoName: string; } const createRelease = useSpinner( 'Creating release', - async ({ commitHash, githubToken, gitRepoName, gitRepoOwner }) => { - const gitRelease = new GitHubRelease(githubToken, gitRepoOwner, gitRepoName, await releaseNotes(), commitHash); + async ({ commitHash, githubEmail, githubToken, gitRepoName }) => { + const gitRelease = new GitHubRelease(githubToken, githubEmail, gitRepoName, await releaseNotes(), commitHash); return gitRelease.release(); } ); @@ -159,16 +159,31 @@ export interface GithubPublishOptions { const githubPublishRunner: TaskRunner = async ({ dryrun, verbose, commitHash }) => { if (!process.env['CIRCLE_REPOSITORY_URL']) { - throw `The release plugin requires you specify the repository url as environment variable CIRCLE_REPOSITORY_URL`; + throw new Error( + 'The release plugin requires you specify the repository url as environment variable CIRCLE_REPOSITORY_URL' + ); } - if (!process.env['GITHUB_TOKEN']) { - throw `Github publish requires that you set the environment variable GITHUB_TOKEN to a valid github api token. - See: https://github.com/settings/tokens for more details.`; + if (!process.env['GITHUB_ACCESS_TOKEN']) { + // Try to use GITHUB_TOKEN, which may be set. + if (process.env['GITHUB_TOKEN']) { + process.env['GITHUB_ACCESS_TOKEN'] = process.env['GITHUB_TOKEN']; + } else { + throw new Error( + `Github publish requires that you set the environment variable GITHUB_ACCESS_TOKEN to a valid github api token. + See: https://github.com/settings/tokens for more details.` + ); + } + } + + if (!process.env['GITHUB_USERNAME']) { + // We can default this one + process.env['GITHUB_USERNAME'] = DEFAULT_EMAIL_ADDRESS; } const parsedUrl = gitUrlParse(process.env['CIRCLE_REPOSITORY_URL']); - const githubToken = process.env['GITHUB_TOKEN']; + const githubToken = process.env['GITHUB_ACCESS_TOKEN']; + const githubEmail = process.env['GITHUB_USERNAME']; await prepareRelease({ dryrun, @@ -177,8 +192,8 @@ const githubPublishRunner: TaskRunner = async ({ dryrun, v await createRelease({ commitHash, + githubEmail, githubToken, - gitRepoOwner: parsedUrl.owner, gitRepoName: parsedUrl.name, }); }; diff --git a/packages/grafana-toolkit/src/cli/utils/githubRelease.test.ts b/packages/grafana-toolkit/src/cli/utils/githubRelease.test.ts new file mode 100644 index 00000000000..74fedc2a759 --- /dev/null +++ b/packages/grafana-toolkit/src/cli/utils/githubRelease.test.ts @@ -0,0 +1,10 @@ +import { GitHubRelease } from './githubRelease'; + +describe('GithubRelease', () => { + it('should initialise a GithubRelease', () => { + process.env.GITHUB_ACCESS_TOKEN = '12345'; + process.env.GITHUB_USERNAME = 'test@grafana.com'; + const github = new GitHubRelease('A token', 'A username', 'A repo', 'Some release notes'); + expect(github).toBeInstanceOf(GitHubRelease); + }); +}); diff --git a/packages/grafana-toolkit/src/cli/utils/githubRelease.ts b/packages/grafana-toolkit/src/cli/utils/githubRelease.ts index 976060e2469..2d30b2e1a53 100644 --- a/packages/grafana-toolkit/src/cli/utils/githubRelease.ts +++ b/packages/grafana-toolkit/src/cli/utils/githubRelease.ts @@ -37,6 +37,7 @@ class GitHubRelease { this.commitHash = commitHash; this.git = new GithubClient({ + required: true, repo: repository, }); } @@ -97,7 +98,9 @@ class GitHubRelease { `https://uploads.github.com/repos/${this.username}/${this.repository}/releases/${newReleaseResponse.data.id}/assets` ); } catch (reason) { - console.error('error', reason); + console.error(reason.data?.message ?? reason); + // Rethrow the error so that we can trigger a non-zero exit code to circle-ci + throw reason; } } }