or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-interface.mdconfiguration.mdcore-orchestration.mdgit-operations.mdgithub-integration.mdgitlab-integration.mdindex.mdnpm-publishing.mdplugin-system.md

plugin-system.mddocs/

0

# Plugin System

1

2

Release It!'s plugin system provides an extensible architecture for implementing release functionality. Plugins participate in a well-defined lifecycle and can communicate through shared context.

3

4

## Capabilities

5

6

### Base Plugin Class

7

8

Foundation class for all Release It! plugins with lifecycle hooks and utilities.

9

10

```javascript { .api }

11

/**

12

* Base plugin class providing lifecycle hooks and utilities

13

* All Release It! plugins extend this class

14

*/

15

class Plugin {

16

/**

17

* Create plugin instance

18

* @param options - Plugin configuration options

19

*/

20

constructor(options: PluginOptions);

21

22

/**

23

* Check if plugin should be enabled

24

* @param options - Plugin configuration options

25

* @returns Boolean indicating if plugin is enabled

26

*/

27

static isEnabled(options: any): boolean | Promise<boolean>;

28

29

/**

30

* Disable plugin and return null

31

* @returns null to indicate plugin is disabled

32

*/

33

static disablePlugin(): null;

34

35

/** Initialize plugin - called once during startup */

36

init(): void | Promise<void>;

37

38

/** Get package/project name */

39

getName(): string | Promise<string>;

40

41

/** Get current/latest version */

42

getLatestVersion(): string | Promise<string>;

43

44

/** Get changelog content for the release */

45

getChangelog(latestVersion?: string): string | Promise<string>;

46

47

/**

48

* Get version increment suggestion

49

* @param incrementBase - Base increment information

50

* @returns Suggested increment (major/minor/patch/etc)

51

*/

52

getIncrement(incrementBase: IncrementBase): string | Promise<string>;

53

54

/**

55

* Get incremented version for CI mode

56

* @param incrementBase - Base increment information

57

* @returns New version string

58

*/

59

getIncrementedVersionCI(incrementBase: IncrementBase): string | Promise<string>;

60

61

/**

62

* Get incremented version with user interaction

63

* @param incrementBase - Base increment information

64

* @returns New version string

65

*/

66

getIncrementedVersion(incrementBase: IncrementBase): string | Promise<string>;

67

68

/** Hook called before version bump */

69

beforeBump(): void | Promise<void>;

70

71

/**

72

* Hook called to perform version bump

73

* @param version - New version to bump to

74

* @returns True if bump was performed, false to skip

75

*/

76

bump(version: string): boolean | Promise<boolean>;

77

78

/** Hook called before release operations */

79

beforeRelease(): void | Promise<void>;

80

81

/**

82

* Hook called to perform release operations

83

* @returns True if release was performed, false to skip

84

*/

85

release(): boolean | Promise<boolean>;

86

87

/** Hook called after release operations */

88

afterRelease(): void | Promise<void>;

89

90

/**

91

* Get plugin context with optional path

92

* @param path - Optional dot-notation path to nested value

93

* @returns Context value or entire context

94

*/

95

getContext(path?: string): any;

96

97

/**

98

* Set plugin context by merging with existing

99

* @param context - Context to merge

100

*/

101

setContext(context: any): void;

102

103

/**

104

* Execute shell command with context interpolation

105

* @param command - Command to execute

106

* @param options - Execution options

107

* @returns Promise resolving to command output

108

*/

109

exec(command: string, options?: ExecOptions): Promise<string>;

110

111

/**

112

* Register interactive prompts for this plugin

113

* @param prompts - Prompt definitions

114

*/

115

registerPrompts(prompts: any): void;

116

117

/**

118

* Show interactive prompt

119

* @param options - Prompt options

120

* @returns Promise resolving to user input

121

*/

122

showPrompt(options: PromptOptions): Promise<any>;

123

124

/**

125

* Execute step with spinner or prompt based on mode

126

* @param options - Step execution options

127

* @returns Promise resolving to step result

128

*/

129

step(options: StepOptions): Promise<any>;

130

131

/**

132

* Get initial plugin options from configuration

133

* @param options - Full configuration options

134

* @param namespace - Plugin namespace

135

* @returns Plugin-specific options

136

*/

137

getInitialOptions(options: any, namespace: string): any;

138

}

139

140

interface PluginOptions {

141

/** Plugin namespace for configuration */

142

namespace: string;

143

/** Plugin-specific options */

144

options?: any;

145

/** Dependency injection container */

146

container?: DependencyContainer;

147

}

148

149

interface IncrementBase {

150

/** Current latest version */

151

latestVersion: string;

152

/** Requested increment type */

153

increment: string;

154

/** Whether this is a pre-release */

155

isPreRelease: boolean;

156

/** Pre-release identifier */

157

preReleaseId?: string;

158

/** Pre-release base version */

159

preReleaseBase?: string;

160

}

161

162

interface ExecOptions {

163

/** Additional execution options */

164

options?: any;

165

/** Context for template interpolation */

166

context?: any;

167

}

168

169

interface StepOptions {

170

/** Whether step is enabled */

171

enabled?: boolean;

172

/** Task function to execute */

173

task?: () => Promise<any>;

174

/** Step label for display */

175

label?: string;

176

/** Prompt type for interactive mode */

177

prompt?: string;

178

/** Context for template interpolation */

179

context?: any;

180

/** Whether this is an external command */

181

external?: boolean;

182

}

183

184

interface PromptOptions {

185

/** Prompt type */

186

type?: string;

187

/** Prompt name/key */

188

name?: string;

189

/** Prompt message */

190

message?: string;

191

/** Available choices for select prompts */

192

choices?: any[];

193

/** Default value */

194

default?: any;

195

/** Plugin namespace */

196

namespace?: string;

197

/** Value transformer function */

198

transformer?: (value: any) => any;

199

}

200

201

interface DependencyContainer {

202

/** Configuration instance */

203

config?: any;

204

/** Logger instance */

205

log?: any;

206

/** Shell executor instance */

207

shell?: any;

208

/** Spinner instance */

209

spinner?: any;

210

/** Prompt handler instance */

211

prompt?: any;

212

}

213

```

214

215

### Plugin Factory

216

217

Factory function for loading and instantiating plugins.

218

219

```javascript { .api }

220

/**

221

* Get plugin instances for the current configuration

222

* @param config - Configuration instance

223

* @param container - Dependency injection container

224

* @returns Tuple of [internal plugins, external plugins]

225

*/

226

function getPlugins(

227

config: Config,

228

container: DependencyContainer

229

): Promise<[Plugin[], Plugin[]]>;

230

```

231

232

### Built-in Plugins

233

234

Release It! includes several built-in plugins:

235

236

#### Version Plugin

237

Manages version updates in files (package.json, etc.)

238

239

#### Git Plugin

240

Handles Git operations (commit, tag, push)

241

242

#### npm Plugin

243

Manages npm publishing and registry operations

244

245

#### GitHub Plugin

246

Creates GitHub releases and uploads assets

247

248

#### GitLab Plugin

249

Creates GitLab releases

250

251

### Custom Plugin Development

252

253

```javascript { .api }

254

/**

255

* Example custom plugin implementation

256

* Custom plugins extend the base Plugin class

257

*/

258

class CustomPlugin extends Plugin {

259

constructor(options) {

260

super(options);

261

this.namespace = 'custom';

262

}

263

264

static isEnabled(options) {

265

return options !== false;

266

}

267

268

async init() {

269

// Plugin initialization logic

270

this.log.info('Custom plugin initialized');

271

}

272

273

async beforeRelease() {

274

// Custom pre-release logic

275

await this.exec('custom-pre-release-command');

276

}

277

278

async release() {

279

// Custom release logic

280

const result = await this.step({

281

enabled: this.options.deploy,

282

task: () => this.deploy(),

283

label: 'Custom deployment',

284

prompt: 'deploy'

285

});

286

287

return result;

288

}

289

290

async deploy() {

291

// Custom deployment logic

292

const version = this.config.getContext('version');

293

await this.exec(`deploy --version ${version}`);

294

}

295

}

296

297

export default CustomPlugin;

298

```

299

300

**Usage Examples:**

301

302

```javascript

303

// Using built-in plugins through configuration

304

const result = await runTasks({

305

git: {

306

commit: true,

307

tag: true,

308

push: true

309

},

310

npm: {

311

publish: true

312

},

313

github: {

314

release: true,

315

assets: ['dist/*.zip']

316

}

317

});

318

319

// Loading custom plugins

320

const result = await runTasks({

321

plugins: {

322

'./custom-plugin.js': {

323

deploy: true,

324

environment: 'production'

325

}

326

}

327

});

328

```

329

330

### Plugin Configuration

331

332

Each plugin accepts configuration through the main configuration object:

333

334

```json

335

{

336

"git": {

337

"commit": true,

338

"commitMessage": "Release ${version}",

339

"tag": true,

340

"push": true

341

},

342

"npm": {

343

"publish": true,

344

"tag": "latest"

345

},

346

"github": {

347

"release": true,

348

"releaseName": "Release ${version}",

349

"assets": ["dist/*.zip", "docs/*.pdf"]

350

},

351

"plugins": {

352

"@release-it/conventional-changelog": {

353

"preset": "angular"

354

},

355

"./plugins/custom-notifier.js": {

356

"webhook": "https://hooks.slack.com/..."

357

}

358

}

359

}

360

```

361

362

### Plugin Lifecycle

363

364

The plugin lifecycle ensures coordinated execution:

365

366

1. **Plugin Discovery**: Load internal and external plugins

367

2. **Initialization**: Call `init()` on all plugins

368

3. **Version Resolution**: Get current version and determine increment

369

4. **Pre-Bump Phase**: Call `beforeBump()` hooks

370

5. **Bump Phase**: Call `bump(version)` hooks

371

6. **Pre-Release Phase**: Call `beforeRelease()` hooks

372

7. **Release Phase**: Call `release()` hooks

373

8. **Post-Release Phase**: Call `afterRelease()` hooks

374

375

### Context Sharing

376

377

Plugins communicate through shared context:

378

379

```javascript

380

// Plugin A sets context

381

this.setContext({ buildId: '12345' });

382

383

// Plugin B reads context

384

const buildId = this.getContext('buildId');

385

386

// Global context access

387

const version = this.config.getContext('version');

388

```