From 3a35a379243d3cbcad287075329f2efdf377c718 Mon Sep 17 00:00:00 2001 From: Andrew Lisowski Date: Sun, 17 May 2020 15:46:36 -0700 Subject: [PATCH] clean up writing plugin docs --- docs/pages/plugins/configuration-hooks.md | 4 +- docs/pages/plugins/hook-api-docs.md | 3 +- docs/pages/plugins/writing-plugins.md | 99 +++++++++++++------ .../plugins/writing-publishing-plugins.md | 83 +--------------- 4 files changed, 75 insertions(+), 114 deletions(-) diff --git a/docs/pages/plugins/configuration-hooks.md b/docs/pages/plugins/configuration-hooks.md index 4a0f77776..90463eb66 100644 --- a/docs/pages/plugins/configuration-hooks.md +++ b/docs/pages/plugins/configuration-hooks.md @@ -103,7 +103,7 @@ Make sure to account for the [different ways you plugin can be included](./plugi ```ts auto.hooks.validateConfig.tapPromise("test", (name, options) => { - if (name === this.name || name === `@auto-it/${this.name}`) { + if (name === this.name || name === `auto-plugin-${this.name}`) { return; // your validation error. Can either be strings for { path, expectedType, value } } }); @@ -137,7 +137,7 @@ To do this `auto` exposes a helper function to validate you plugins with the `io import { validatePluginConfiguration } from "@auto-it/core"; auto.hooks.validateConfig.tapPromise("test", (name, options) => { - if (name === this.name || name === `@auto-it/${this.name}`) { + if (name === this.name || name === `auto-plugin-${this.name}`) { return validatePluginConfiguration(this.name, pluginOptions, options); } }); diff --git a/docs/pages/plugins/hook-api-docs.md b/docs/pages/plugins/hook-api-docs.md index 0e513d06f..40d461b37 100644 --- a/docs/pages/plugins/hook-api-docs.md +++ b/docs/pages/plugins/hook-api-docs.md @@ -16,10 +16,9 @@ Some hooks are specific to a single command, such as the "Init" hooks, and other This is the general flow when any `auto` command is ran: - Call configuration hooks -- Run `before` release lifecycle hooks - Get `git log` => Pass through `LogParse` hooks - If necessary: Create a changelog and => Call `Changelog` hooks -- Run necessary remaining release lifecycle hooks +- Run release lifecycle hooks ## Plugin Ideas diff --git a/docs/pages/plugins/writing-plugins.md b/docs/pages/plugins/writing-plugins.md index d6dc80ee2..ccecc38a6 100644 --- a/docs/pages/plugins/writing-plugins.md +++ b/docs/pages/plugins/writing-plugins.md @@ -4,9 +4,8 @@ If you've ever written a `webpack` plugin it's a lot like that. A plugin definition is: -- a class the has an `apply` function where a plugin hooks into various functions in auto (REQUIRED) - a name for the plugin, should match the [name of the package](../plugins.md#plugin-declaration) (REQUIRED) -- a constructor where you can load plugin specific config +- a class the has an `apply` function where a plugin hooks into various functions in auto (REQUIRED) ```ts import { Auto, IPlugin } from "auto"; @@ -14,15 +13,8 @@ import { Auto, IPlugin } from "auto"; export default class TestPlugin implements IPlugin { name = "test"; - private readonly config: any; - - constructor(config: any) { - this.config = config; - } - - apply(auto: Auto) { - // hook into auto - } + /** Tap into auto plugin points. */ + apply(auto: Auto) {} } ``` @@ -30,50 +22,95 @@ Or in JavaScript: ```js module.exports = class TestPlugin { - constructor(config) { - this.config = config; + constructor() { this.name = "test"; } /** - * Setup the plugin + * Tap into auto plugin points. * @param {import('@auto-it/core').default} auto */ - apply(auto) { - // hook into auto - } + apply(auto) {} }; ``` -## Constructor +## Hooks -In the constructor you have access to any plugin specific config provided in the `.autorc`. -It might be useful to write a more type-safe interface for your config. +Plugins work by hooking into various actions that `auto` has to do in order to facilitate a release or interact with your GitHub repo. + +[Read more about using hooks](./hook-api-docs.md) + +## Adding Options + +Most plugins will find the need to some some options from the user. +The constructor of the plugin gets access to the options passed in the `.autorc`. ```ts -import { Auto, IPlugin } from "auto"; +import { Auto, IPlugin } from "@auto-it/core"; -interface ITestPluginConfig { - foo?: string; - bar?: boolean; +interface TestPluginOptions { + someOption?: boolean; } export default class TestPlugin implements IPlugin { + /** The name of the plugin */ name = "test"; - private readonly config: ITestPluginConfig; + /** The options of the plugin */ + readonly options: TestPluginOptions; - constructor(config: ITestPluginConfig) { - this.config = config; + /** Initialize the plugin with it's options */ + constructor(options: TestPluginOptions) { + this.options = options; } } ``` -## Hooks +### Validation -Plugins work by hooking into various actions that `auto` has to do in order to facilitate a release or interact with your GitHub repo. +To get validate of the options passed to plugins, `auto` uses [io-ts](https://github.com/gcanti/io-ts) and exports a utility function to validate the structured produced by `io-ts`. +It lets you defined your interfaces in JavaScript and easily convert them to TypeScript. +This means it's super simple to have type-safe code and runtime validation checking! -[Read more about using hooks](./hook-api-docs.md) +First install the following: + +```sh +npm i --save io-ts fp-ts +# or +yarn add io-ts fp-ts +``` + +Then convert your options interface to the equivalent `io-ts` structure. + +```ts +import * as t from "io-ts"; + +const pluginOptions = t.partial({ + someOption: t.boolean, +}); + +export type TestPluginOptions = t.TypeOf; +``` + +Then tap into the `validateConfig` hook and use the `validatePluginConfiguration` utility. + +```ts +import { validatePluginConfiguration } from "@auto-it/core"; + +export default class MyPlugin implements IPlugin { + // ... + apply(auto: Auto) { + auto.hooks.validateConfig.tapPromise(this.name, async (name, options) => { + if (name === this.name || name === `auto-plugin-${this.name}`) { + return validatePluginConfiguration(this.name, pluginOptions, options); + } + }); + } +} +``` + +And that's it! +Now `auto` will validate your plugins configuration before running. ## Example Plugin - NPM (simple) @@ -138,3 +175,5 @@ export default class NPMPlugin { } } ``` + +[Read more about creating publishing plugins.](./writing-publishing-plugins.md) diff --git a/docs/pages/plugins/writing-publishing-plugins.md b/docs/pages/plugins/writing-publishing-plugins.md index 18a7e7a32..ce5d0b1c1 100644 --- a/docs/pages/plugins/writing-publishing-plugins.md +++ b/docs/pages/plugins/writing-publishing-plugins.md @@ -120,83 +120,6 @@ Once you have the above hooks implemented you should be able to successfully use The above plugins is pretty simple and there are a bunch of features you can add to your plugin through hooks or functions that `auto` exports. -## Adding Options - -Most plugins will find the need to some some options from the user. -The constructor of the plugin gets access to the options passed in the `.autorc`. - -```ts -import { Auto, IPlugin } from "@auto-it/core"; - -interface IGitTagPluginOptions { - someOption?: boolean; -} - -export default class GitTagPlugin implements IPlugin { - /** The name of the plugin */ - name = "my-git-tag"; - - /** The options of the plugin */ - readonly options: IGitTagPluginOptions; - - /** Initialize the plugin with it's options */ - constructor(options: IGitTagPluginOptions) { - this.options = options; - } - - /** Tap into auto plugin points. */ - apply(auto: Auto) { - console.log(this.options.someOption); - } -} -``` - -### Validation - -To get validate of the options passed to plugins, `auto` uses [io-ts](https://github.com/gcanti/io-ts) and exports a utility function to validate the structured produced by `io-ts`. -It lets you defined your interfaces in JavaScript and easily convert them to TypeScript. -This means it's super simple to have type-safe code and runtime validation checking! - -First install the following: - -```sh -npm i --save io-ts fp-ts -# or -yarn add io-ts fp-ts -``` - -Then convert your options interface to the equivalent `io-ts` structure. - -```ts -import * as t from "io-ts"; - -const pluginOptions = t.partial({ - someOption: t.boolean, -}); - -export type IGitTagPluginOptions = t.TypeOf; -``` - -Then tap into the `validateConfig` hook and use the `validatePluginConfiguration` utility. - -```ts -import { validatePluginConfiguration } from "@auto-it/core"; - -export default class GitTagPlugin implements IPlugin { - // ... - apply(auto: Auto) { - auto.hooks.validateConfig.tapPromise(this.name, async (name, options) => { - if (name === this.name || name === `@auto-it/${this.name}`) { - return validatePluginConfiguration(this.name, pluginOptions, options); - } - }); - } -} -``` - -And that's it! -Now `auto` will validate your plugins configuration before running. - ## Advanced Release Hooks ### `canary` @@ -225,7 +148,7 @@ Like the `canary` hook your package management platform must support separate re These hooks are not required for publishing plugins, but can really improve the developer experience of it. -### beforeRun +### `beforeRun` Happens before anything is done. This is a great place to check for platform specific secrets such as a npm token. @@ -242,7 +165,7 @@ export default class GitTagPlugin implements IPlugin { } ``` -### getAuthor +### `getAuthor` Get git author to commit with. Typically from a package distribution description file. @@ -257,7 +180,7 @@ auto.hooks.getAuthor.tapPromise("NPM", async () => { }); ``` -### getRepository +### `getRepository` Get owner and repository for the project to automate releases for. Typically from a package distribution description file.