Hooks: adding support for prepublish steps (#319)

* adding a hooks option for prepublish foolery

* Change files

* functional hook

* putting hooks at the right place

* adding a test for the new publish hooks

* adding tests to ensure git push are from original code

* get rid of fit
This commit is contained in:
Kenneth Chau 2020-04-15 16:39:07 -07:00 коммит произвёл GitHub
Родитель e344d8fddb
Коммит bddea23335
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 104 добавлений и 1 удалений

Просмотреть файл

@ -0,0 +1,8 @@
{
"type": "minor",
"comment": "adding a hooks option for prepublish foolery",
"packageName": "beachball",
"email": "kchau@microsoft.com",
"dependentChangeType": "patch",
"date": "2020-04-15T21:48:23.323Z"
}

Просмотреть файл

@ -5,6 +5,9 @@ import { git } from '../git';
import { publish } from '../commands/publish';
import { RepositoryFactory } from '../fixtures/repository';
import { MonoRepoFactory } from '../fixtures/monorepo';
import fs from 'fs';
import path from 'path';
import { BumpInfo } from '../types/BumpInfo';
describe('publish command (e2e)', () => {
let registry: Registry;
@ -172,4 +175,73 @@ describe('publish command (e2e)', () => {
expect(barGitResults.success).toBeTruthy();
expect(barGitResults.stdout).toBe('bar_v1.4.0');
});
it('should respect prepublish hooks', async () => {
repositoryFactory = new MonoRepoFactory();
await repositoryFactory.create();
const repo = await repositoryFactory.cloneRepository();
writeChangeFiles(
{
foo: {
type: 'minor',
comment: 'test',
date: new Date('2019-01-01'),
email: 'test@test.com',
packageName: 'foo',
dependentChangeType: 'patch',
},
},
repo.rootPath
);
git(['push', 'origin', 'master'], { cwd: repo.rootPath });
await publish({
branch: 'origin/master',
command: 'publish',
message: 'apply package updates',
path: repo.rootPath,
publish: true,
bumpDeps: true,
push: true,
registry: registry.getUrl(),
tag: 'latest',
token: '',
yes: true,
new: false,
access: 'public',
package: '',
changehint: 'Run "beachball change" to create a change file',
type: null,
fetch: true,
disallowedChangeTypes: null,
defaultNpmTag: 'latest',
retries: 3,
hooks: {
prepublish: (bumpInfo: BumpInfo) => {
bumpInfo.packageInfos.foo.version = bumpInfo.packageInfos.foo.version + '-beta';
}
}
});
// All npm results should refer to 1.1.0-beta (the mod in the publish step above)
const fooNpmResult = npm(['--registry', registry.getUrl(), 'show', 'foo', '--json']);
expect(fooNpmResult.success).toBeTruthy();
const show = JSON.parse(fooNpmResult.stdout);
expect(show.name).toEqual('foo');
expect(show.versions.length).toEqual(1);
expect(show['dist-tags'].latest).toEqual('1.1.0-beta');
git(['checkout', 'master'], { cwd: repo.rootPath });
git(['pull'], { cwd: repo.rootPath });
// All git results should refer to 1.1.0
const fooGitResults = git(['describe', '--abbrev=0'], { cwd: repo.rootPath });
expect(fooGitResults.success).toBeTruthy();
expect(fooGitResults.stdout).toBe('foo_v1.1.0');
const fooPackageJson = JSON.parse(fs.readFileSync(path.join(repo.rootPath, 'packages/foo/package.json'), 'utf-8'));
expect(fooPackageJson.version).toBe('1.1.0');
});
});

Просмотреть файл

@ -4,11 +4,22 @@ import { BeachballOptions } from '../types/BeachballOptions';
import { packagePublish } from '../packageManager/packagePublish';
import { validatePackageVersions } from './validatePackageVersions';
import { displayManualRecovery } from './displayManualRecovery';
import _ from 'lodash';
export async function publishToRegistry(bumpInfo: BumpInfo, options: BeachballOptions) {
export async function publishToRegistry(originalBumpInfo: BumpInfo, options: BeachballOptions) {
const { registry, tag, token, access, timeout } = options;
const bumpInfo = _.cloneDeep(originalBumpInfo);
const { modifiedPackages, newPackages } = bumpInfo;
// Execute prepublish hook if available
if (options.hooks?.prepublish) {
const maybePromise = options.hooks.prepublish(bumpInfo);
if (maybePromise instanceof Promise) {
await maybePromise;
}
}
await performBump(bumpInfo, options);
const succeededPackages = new Set<string>();
@ -61,5 +72,6 @@ export async function publishToRegistry(bumpInfo: BumpInfo, options: BeachballOp
);
}
});
return;
}

Просмотреть файл

@ -1,6 +1,7 @@
import { ChangeType } from './ChangeInfo';
import { ChangeFilePromptOptions } from './ChangeFilePrompt';
import { ChangelogOptions } from './ChangelogOptions';
import { BumpInfo } from './BumpInfo';
export type BeachballOptions = CliOptions & RepoOptions & PackageOptions;
@ -49,6 +50,16 @@ export interface RepoOptions {
groups?: VersionGroupOptions[];
changelog?: ChangelogOptions;
changeFilePrompt?: ChangeFilePromptOptions;
hooks?: {
/**
* Prepublish hook gets run right before npm publish (during performBump)
* the changes will be reverted before pushing
*
* This hook expects manipulation to the bumpInfo object (side effects)
*/
prepublish?: (bumpInfo: BumpInfo) => void | Promise<void>;
};
}
export interface PackageOptions {