Commit 20d3a9a0 by Stephanie Closson Committed by GitHub

Circle ci fixes automated build (#23373)

* Lessons learned from using circle-ci
1. Make it clearer that GITHUB_TOKEN or GITHUB_ACCESS_TOKEN
are required for a release. Don't build without them.
2. Default gracefully to an reasonable email address.

(It does not have to actually exist, but the api needs it to publish)

* template for testing

* Wrote a basic test.

* Simple test

* Slight fix to brackets

* Code review changes

* Fix for test. Setup environment properly
parent 2ecc7f22
......@@ -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
......
......@@ -10,6 +10,8 @@ import path = require('path');
import execa = require('execa');
interface Command extends Array<any> {}
const DEFAULT_EMAIL_ADDRESS = 'eng@graafna.com';
const DEFAULT_USERNAME = 'CircleCI Automation';
const releaseNotes = async (): Promise<string> => {
const { stdout } = await execa.shell(`awk \'BEGIN {FS="##"; RS=""} FNR==3 {print; exit}\' CHANGELOG.md`);
......@@ -62,12 +64,10 @@ const prepareRelease = useSpinner<any>('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<any>('Preparing release', async ({ dryrun, ver
interface GithubPublishReleaseOptions {
commitHash?: string;
githubToken: string;
gitRepoOwner: string;
githubEmail: string;
gitRepoName: string;
}
const createRelease = useSpinner<GithubPublishReleaseOptions>(
'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<GithubPublishOptions> = 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<GithubPublishOptions> = async ({ dryrun, v
await createRelease({
commitHash,
githubEmail,
githubToken,
gitRepoOwner: parsedUrl.owner,
gitRepoName: parsedUrl.name,
});
};
......
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);
});
});
......@@ -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;
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment