Great ! Developing sentenza providers is not that complicated.
In this guide, we will assume that you want to create a plugin for the fictional provider Awesome CI
.
You just have to extend main sentenza
package's abstract classes in a new NPM package called sentenza-awesome-ci
Feel free to check the sentenza-bitbucket
source code and use mimicry.
First create your package using npm init
. Name it sentenza-awesome-ci
.
Create a class SentenzaAwesomeCI
extending SentenzaProvider
.
// src/provider.ts
import { SentenzaProvider, TargetOptions, TriggerOptions } from 'sentenza';
export class SentenzaAwesomeCI extends SentenzaProvider {
// Store infos to authenticate end user
private _auth: ICredentials;
on(target: TargetOptions): SentenzaBitbucket {
// Logic handling method overload to define target is available in parent class
super.on(target);
// If you have somethinfg else to do, do it here :)
// sentenza uses fluid syntax, return this so methods can be chained
return this;
}
// Provide a method to give credentials
auth(credentials: ICredentials): SentenzaBitbucket {
this._auth = credentials;
return this;
}
// Provide a method to repository credentials
repository(url: string): SentenzaBitbucket {
// Here you can parse argument and store validated form
return this;
}
async trigger(pipeline: string | TriggerOptions): Promise<SentenzaBitbucketPipeline> {
// Logic handling method overload to define pipeline to apply is available in parent class
// You can reuse it 👍
await super.trigger(pipeline);
// Here you typically check that every information required to make API call to trigger pipeline has been given
// ...
// Then perform API call trigerring the pipeline to the CI provider
// ...
// Return an object representing the pipeline execution. See next section for more infos.
return new SentenzaAwesomeCI();
}
}
Your provider class SentenzaProvider
must have a method trigger which returns a SentenzaPipeline
sub-class.
Let's see this in details.
The base class is very concise and let you to proceed anyway you want.
export abstract class SentenzaPipeline {
abstract finished(): Promise<unknown>;
abstract succeeded(): Promise<unknown>;
}
You just have to implement two methods:
finished
which wait for your pipeline to finishsucceeded
which wait for your pipeline to finish and throw if it did not succeed.
You can return anything you want. Typically, pipeline execution summary.
To wait for your pipeline to finish you can use long polling as it is done in sentenza-bitbucket
.
Your NPM package must a SentenzaProvider
provider instance as default export.
To do so, in the module entrypoint (generally src/index.ts
), create an instance and export it:
import { SentenzaAwesomeCI } from './provider';
const provider = new SentenzaAwesomeCI();
// also export type definition
export * from './provider';
export default provider;
Do not forget to declare your entry point and type definition root in package.json
.
{
"name": "sentenza-awesome-ci",
"version": "0.0.1",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"peerDependencies": {
"sentenza": "^1.0.0" // you should declare sentenza as peer dependency
}
}
Once your package published people will be able to use it by installing npm i sentenza sentenza-awesome-ci
In their project, they can use you provider this way:
import { Sentenza } from 'sentenza';
import { SentenzaAwesomeCi } from 'sentenza-awesome-ci';
// create an instance of your provider
const runner = Sentenza.provider<SentenzaAwesomeCi>('awesome-ci');
// use it
await runner.auth(/* credentials */).repository('foo/bar').trigger('master')
You can also expose a provider for sentenza CLI.
To do so create your have to create own CLI program.
We strongly recommend to use commander or yargs to parse arguments process.argv
.
Once your program implemented you must declare it package.json
in the binary map.
{
"name": "sentenza-awesome-ci",
"version": "0.0.1",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"bin": {
"sentenza-awesome-cli": "lib/cli/index.js" // wherever your compiled CLI program is located
},
"peerDependencies": {
"sentenza": "^1.0.0"
}
}
Note: your main CLI file must have the shebang #!/usr/bin/env node
Once published, sentenza CLI will use npx
to call the matching provider CLI.
Invoking sentenza -p awesome-cli
will call npx sentenza-awesome-cli@latest
.
Main CLI will forward all subsequent arguments and options (sentenza -p awesome-cli command <argument> --option value
=> npx sentenza-awesome-cli@latest command <argument> --option value
).
All environment variables are also forwarded.