mirror of https://github.com/grafana/grafana
Packages: Use lerna for release orchestration (#17985)
parent
6599bdc7f1
commit
c32365f424
@ -0,0 +1,6 @@ |
|||||||
|
{ |
||||||
|
"npmClient": "yarn", |
||||||
|
"useWorkspaces": true, |
||||||
|
"packages": ["packages/*"], |
||||||
|
"version": "6.3.0-alpha.36" |
||||||
|
} |
@ -0,0 +1,15 @@ |
|||||||
|
## Grafana frontend packages |
||||||
|
|
||||||
|
## Releasing new version |
||||||
|
We use [Lerna](https://github.com/lerna/lerna) for packages versioning and releases |
||||||
|
|
||||||
|
### Manual release |
||||||
|
1. Run `packages:prepare` script from root directory. This will perform cleanup, run all tests and bump version for all packages. Also, it will create `@packages@[version]` tag and version bump commit with `Packages: publish [version]` message. |
||||||
|
2. Run `packages:build` script that will prepare distribution packages. |
||||||
|
3. Run `packages:publish` to publish new versions |
||||||
|
- add `--dist-tag next` to publish under `next` tag |
||||||
|
4. Push version commit |
||||||
|
|
||||||
|
### Building individual packages |
||||||
|
To build induvidual packages run `grafana-toolkit package:build --scope=<ui|toolkit|runtime|data>` |
||||||
|
|
@ -0,0 +1,3 @@ |
|||||||
|
# (2019-07-08) |
||||||
|
First public release |
||||||
|
|
@ -0,0 +1,3 @@ |
|||||||
|
# (2019-07-08) |
||||||
|
First public release |
||||||
|
|
@ -1,190 +0,0 @@ |
|||||||
import execa = require('execa'); |
|
||||||
import { execTask } from '../utils/execTask'; |
|
||||||
import { changeCwdToGrafanaUiDist, changeCwdToGrafanaUi, restoreCwd } from '../utils/cwd'; |
|
||||||
import { ReleaseType, inc } from 'semver'; |
|
||||||
import { prompt } from 'inquirer'; |
|
||||||
import chalk from 'chalk'; |
|
||||||
import { useSpinner } from '../utils/useSpinner'; |
|
||||||
import { savePackage, buildTask, clean } from './grafanaui.build'; |
|
||||||
import { TaskRunner, Task } from './task'; |
|
||||||
|
|
||||||
type VersionBumpType = 'prerelease' | 'patch' | 'minor' | 'major'; |
|
||||||
|
|
||||||
interface ReleaseTaskOptions { |
|
||||||
publishToNpm: boolean; |
|
||||||
usePackageJsonVersion: boolean; |
|
||||||
createVersionCommit: boolean; |
|
||||||
} |
|
||||||
|
|
||||||
const promptBumpType = async () => { |
|
||||||
return prompt<{ type: VersionBumpType }>([ |
|
||||||
{ |
|
||||||
type: 'list', |
|
||||||
message: 'Select version bump', |
|
||||||
name: 'type', |
|
||||||
choices: ['prerelease', 'patch', 'minor', 'major'], |
|
||||||
}, |
|
||||||
]); |
|
||||||
}; |
|
||||||
|
|
||||||
const promptPrereleaseId = async (message = 'Is this a prerelease?', allowNo = true) => { |
|
||||||
return prompt<{ id: string }>([ |
|
||||||
{ |
|
||||||
type: 'list', |
|
||||||
message: message, |
|
||||||
name: 'id', |
|
||||||
choices: allowNo ? ['no', 'alpha', 'beta'] : ['alpha', 'beta'], |
|
||||||
}, |
|
||||||
]); |
|
||||||
}; |
|
||||||
|
|
||||||
const promptConfirm = async (message?: string) => { |
|
||||||
return prompt<{ confirmed: boolean }>([ |
|
||||||
{ |
|
||||||
type: 'confirm', |
|
||||||
message: message || 'Is that correct?', |
|
||||||
name: 'confirmed', |
|
||||||
default: false, |
|
||||||
}, |
|
||||||
]); |
|
||||||
}; |
|
||||||
|
|
||||||
// Since Grafana core depends on @grafana/ui highly, we run full check before release
|
|
||||||
const runChecksAndTests = async () => |
|
||||||
// @ts-ignore
|
|
||||||
useSpinner<void>(`Running checks and tests`, async () => { |
|
||||||
try { |
|
||||||
await execa('npm', ['run', 'test']); |
|
||||||
} catch (e) { |
|
||||||
console.log(e); |
|
||||||
throw e; |
|
||||||
} |
|
||||||
})(); |
|
||||||
|
|
||||||
const bumpVersion = (version: string) => |
|
||||||
// @ts-ignore
|
|
||||||
useSpinner<void>(`Saving version ${version} to package.json`, async () => { |
|
||||||
changeCwdToGrafanaUi(); |
|
||||||
await execa('npm', ['version', version]); |
|
||||||
changeCwdToGrafanaUiDist(); |
|
||||||
const pkg = require(`${process.cwd()}/package.json`); |
|
||||||
pkg.version = version; |
|
||||||
await savePackage({ path: `${process.cwd()}/package.json`, pkg }); |
|
||||||
})(); |
|
||||||
|
|
||||||
const publishPackage = (name: string, version: string) => |
|
||||||
// @ts-ignore
|
|
||||||
useSpinner<void>(`Publishing ${name} @ ${version} to npm registry...`, async () => { |
|
||||||
changeCwdToGrafanaUiDist(); |
|
||||||
await execa('npm', ['publish', '--access', 'public']); |
|
||||||
})(); |
|
||||||
|
|
||||||
const ensureMasterBranch = async () => { |
|
||||||
const currentBranch = await execa.stdout('git', ['symbolic-ref', '--short', 'HEAD']); |
|
||||||
const status = await execa.stdout('git', ['status', '--porcelain']); |
|
||||||
|
|
||||||
if (currentBranch !== 'master' && status !== '') { |
|
||||||
console.error(chalk.red.bold('You need to be on clean master branch to release @grafana/ui')); |
|
||||||
process.exit(1); |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
const prepareVersionCommitAndPush = async (version: string) => |
|
||||||
// @ts-ignore
|
|
||||||
useSpinner<void>('Commiting and pushing @grafana/ui version update', async () => { |
|
||||||
await execa.stdout('git', ['commit', '-a', '-m', `Upgrade @grafana/ui version to v${version}`]); |
|
||||||
await execa.stdout('git', ['push']); |
|
||||||
})(); |
|
||||||
|
|
||||||
const releaseTaskRunner: TaskRunner<ReleaseTaskOptions> = async ({ |
|
||||||
publishToNpm, |
|
||||||
usePackageJsonVersion, |
|
||||||
createVersionCommit, |
|
||||||
}) => { |
|
||||||
changeCwdToGrafanaUi(); |
|
||||||
// @ts-ignore
|
|
||||||
await clean(); // Clean previous build if exists
|
|
||||||
restoreCwd(); |
|
||||||
|
|
||||||
if (publishToNpm) { |
|
||||||
// TODO: Ensure release branch
|
|
||||||
// When need to update this when we star keeping @grafana/ui releases in sync with core
|
|
||||||
await ensureMasterBranch(); |
|
||||||
} |
|
||||||
|
|
||||||
await runChecksAndTests(); |
|
||||||
|
|
||||||
await execTask(buildTask)({} as any); |
|
||||||
|
|
||||||
let releaseConfirmed = false; |
|
||||||
let nextVersion; |
|
||||||
changeCwdToGrafanaUiDist(); |
|
||||||
|
|
||||||
const pkg = require(`${process.cwd()}/package.json`); |
|
||||||
|
|
||||||
console.log(`Current version: ${pkg.version}`); |
|
||||||
|
|
||||||
do { |
|
||||||
if (!usePackageJsonVersion) { |
|
||||||
const { type } = await promptBumpType(); |
|
||||||
console.log(type); |
|
||||||
if (type === 'prerelease') { |
|
||||||
const { id } = await promptPrereleaseId('What kind of prerelease?', false); |
|
||||||
nextVersion = inc(pkg.version, type, id as any); |
|
||||||
} else { |
|
||||||
const { id } = await promptPrereleaseId(); |
|
||||||
if (id !== 'no') { |
|
||||||
nextVersion = inc(pkg.version, `pre${type}` as ReleaseType, id as any); |
|
||||||
} else { |
|
||||||
nextVersion = inc(pkg.version, type as ReleaseType); |
|
||||||
} |
|
||||||
} |
|
||||||
} else { |
|
||||||
nextVersion = pkg.version; |
|
||||||
} |
|
||||||
|
|
||||||
console.log(chalk.yellowBright.bold(`You are going to release a new version of ${pkg.name}`)); |
|
||||||
|
|
||||||
if (usePackageJsonVersion) { |
|
||||||
console.log(chalk.green(`Version based on package.json: `), chalk.bold.yellowBright(`${nextVersion}`)); |
|
||||||
} else { |
|
||||||
console.log(chalk.green(`Version bump: ${pkg.version} ->`), chalk.bold.yellowBright(`${nextVersion}`)); |
|
||||||
} |
|
||||||
|
|
||||||
const { confirmed } = await promptConfirm(); |
|
||||||
|
|
||||||
releaseConfirmed = confirmed; |
|
||||||
} while (!releaseConfirmed); |
|
||||||
|
|
||||||
if (!usePackageJsonVersion) { |
|
||||||
await bumpVersion(nextVersion); |
|
||||||
} |
|
||||||
|
|
||||||
if (createVersionCommit) { |
|
||||||
await prepareVersionCommitAndPush(nextVersion); |
|
||||||
} |
|
||||||
|
|
||||||
if (publishToNpm) { |
|
||||||
console.log(chalk.yellowBright.bold(`\nReview dist package.json before proceeding!\n`)); |
|
||||||
const { confirmed } = await promptConfirm('Are you ready to publish to npm?'); |
|
||||||
|
|
||||||
if (!confirmed) { |
|
||||||
process.exit(); |
|
||||||
} |
|
||||||
|
|
||||||
await publishPackage(pkg.name, nextVersion); |
|
||||||
console.log(chalk.green(`\nVersion ${nextVersion} of ${pkg.name} succesfully released!`)); |
|
||||||
console.log(chalk.yellow(`\nUpdated @grafana/ui/package.json with version bump created.`)); |
|
||||||
|
|
||||||
process.exit(); |
|
||||||
} else { |
|
||||||
console.log( |
|
||||||
chalk.green( |
|
||||||
`\nVersion ${nextVersion} of ${pkg.name} succesfully prepared for release. See packages/grafana-ui/dist` |
|
||||||
) |
|
||||||
); |
|
||||||
console.log(chalk.green(`\nTo publish to npm registry run`), chalk.bold.blue(`npm run gui:publish`)); |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
export const releaseTask = new Task<ReleaseTaskOptions>('@grafana/ui release', releaseTaskRunner); |
|
Loading…
Reference in new issue