or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

api.mdcli.mdconfiguration.mdindex.mdlifecycle.mdupdaters.md

lifecycle.mddocs/

0

# Lifecycle Hooks

1

2

Standard Version provides comprehensive lifecycle hook support, allowing custom scripts to run at specific stages of the release process. This enables integration with build systems, testing frameworks, deployment pipelines, and custom validation workflows.

3

4

## Capabilities

5

6

### Lifecycle Script Execution

7

8

Core function for executing lifecycle hook scripts.

9

10

```javascript { .api }

11

/**

12

* Execute lifecycle script for specified hook name

13

* @param {Object} args - Configuration object containing scripts definition

14

* @param {string} hookName - Name of the lifecycle hook to execute

15

* @returns {Promise<string>} Promise resolving to script output (stdout)

16

* @throws {Error} If script execution fails or returns non-zero exit code

17

*/

18

async function runLifecycleScript(args, hookName);

19

```

20

21

**Usage Examples:**

22

23

```javascript

24

const runLifecycleScript = require('standard-version/lib/run-lifecycle-script');

25

26

const config = {

27

scripts: {

28

prebump: 'npm run test',

29

postbump: 'npm run build',

30

posttag: 'npm publish'

31

},

32

silent: false

33

};

34

35

try {

36

// Execute prebump hook

37

const output = await runLifecycleScript(config, 'prebump');

38

console.log('Prebump output:', output);

39

40

// Execute hook that doesn't exist (returns resolved promise)

41

await runLifecycleScript(config, 'nonexistent'); // No-op

42

43

} catch (error) {

44

console.error('Script failed:', error.message);

45

}

46

```

47

48

### Available Lifecycle Hooks

49

50

Standard Version supports hooks at eight key stages of the release process.

51

52

```javascript { .api }

53

/**

54

* Lifecycle hook execution order and timing:

55

*

56

* 1. prerelease - Before any release processing begins

57

* 2. prebump - Before version calculation and file updates

58

* 3. postbump - After version bump, before changelog generation

59

* 4. prechangelog- Before changelog generation

60

* 5. postchangelog - After changelog generation, before commit

61

* 6. precommit - Before git commit creation

62

* 7. postcommit - After git commit, before tag creation

63

* 8. pretag - Before git tag creation

64

* 9. posttag - After git tag creation (final step)

65

*/

66

```

67

68

**Hook Execution Flow:**

69

70

```javascript

71

// Standard Version execution flow with hooks:

72

73

await runLifecycleScript(args, 'prerelease');

74

// → Validate environment, prepare workspace

75

76

await runLifecycleScript(args, 'prebump');

77

// → Run tests, lint code, validate dependencies

78

79

const newVersion = await bump(args, currentVersion);

80

81

await runLifecycleScript(args, 'postbump');

82

// → Build artifacts, update documentation

83

84

await runLifecycleScript(args, 'prechangelog');

85

// → Generate additional release notes, validate commits

86

87

await changelog(args, newVersion);

88

89

await runLifecycleScript(args, 'postchangelog');

90

// → Format changelog, add custom sections

91

92

await runLifecycleScript(args, 'precommit');

93

// → Final validation, security checks

94

95

await commit(args, newVersion);

96

97

await runLifecycleScript(args, 'postcommit');

98

// → Notify systems, prepare for tagging

99

100

await runLifecycleScript(args, 'pretag');

101

// → Final pre-tag validation

102

103

await tag(newVersion, isPrivate, args);

104

105

await runLifecycleScript(args, 'posttag');

106

// → Publish packages, deploy, notify stakeholders

107

```

108

109

### Hook Configuration

110

111

Configure lifecycle hooks through the scripts configuration object.

112

113

```javascript { .api }

114

interface LifecycleScripts {

115

prerelease?: string; // Before any release processing

116

prebump?: string; // Before version calculation

117

postbump?: string; // After version bump

118

prechangelog?: string; // Before changelog generation

119

postchangelog?: string; // After changelog generation

120

precommit?: string; // Before git commit

121

postcommit?: string; // After git commit

122

pretag?: string; // Before git tag

123

posttag?: string; // After git tag (final)

124

}

125

```

126

127

**Usage Examples:**

128

129

```json

130

{

131

"scripts": {

132

"prerelease": "echo 'Starting release process'",

133

"prebump": "npm run lint && npm run test",

134

"postbump": "npm run build:prod",

135

"prechangelog": "node scripts/gather-contributors.js",

136

"postchangelog": "node scripts/format-changelog.js",

137

"precommit": "npm run security-audit",

138

"postcommit": "echo 'Changes committed successfully'",

139

"pretag": "npm run validate-build",

140

"posttag": "npm publish && npm run deploy"

141

}

142

}

143

```

144

145

### Common Hook Patterns

146

147

Typical use cases and patterns for each lifecycle hook.

148

149

**Development and Testing Hooks:**

150

151

```json { .api }

152

{

153

"scripts": {

154

"prerelease": "git status --porcelain | grep -q . && exit 1 || echo 'Working directory clean'",

155

"prebump": "npm run lint && npm run test && npm run test:integration",

156

"postbump": "npm run build && npm run test:build"

157

}

158

}

159

```

160

161

**Build and Deployment Hooks:**

162

163

```json { .api }

164

{

165

"scripts": {

166

"postbump": "npm run build:prod && npm run compress-assets",

167

"postchangelog": "node scripts/update-docs.js",

168

"precommit": "npm run validate-bundle-size",

169

"posttag": "npm publish && docker build -t myapp:$npm_package_version ."

170

}

171

}

172

```

173

174

**Notification and Integration Hooks:**

175

176

```json { .api }

177

{

178

"scripts": {

179

"prerelease": "slack-notify 'Starting release for $npm_package_name'",

180

"postcommit": "git push origin main",

181

"posttag": "github-release create --tag $npm_package_version && slack-notify 'Released $npm_package_version'"

182

}

183

}

184

```

185

186

### Environment Variables in Hooks

187

188

Hooks have access to npm environment variables and can use them for dynamic behavior.

189

190

```javascript { .api }

191

/**

192

* Available environment variables in hook scripts:

193

* - npm_package_name - Package name from package.json

194

* - npm_package_version - Current version from package.json

195

* - npm_config_* - npm configuration values

196

* - Standard shell environment variables

197

*/

198

```

199

200

**Usage Examples:**

201

202

```json

203

{

204

"scripts": {

205

"postbump": "echo 'Building $npm_package_name version $npm_package_version'",

206

"posttag": "docker tag myapp:latest myapp:$npm_package_version",

207

"precommit": "echo 'Committing version $npm_package_version' >> release.log"

208

}

209

}

210

```

211

212

### Complex Hook Examples

213

214

Advanced hook configurations for sophisticated workflows.

215

216

**Multi-step Hook with Error Handling:**

217

218

```json { .api }

219

{

220

"scripts": {

221

"prebump": "npm run lint && npm run test && npm run security-check || (echo 'Pre-bump validation failed' && exit 1)",

222

"postbump": "npm run build && npm run package && npm run verify-package",

223

"posttag": "npm publish && npm run deploy-docs && npm run notify-slack"

224

}

225

}

226

```

227

228

**Conditional Hook Execution:**

229

230

```json { .api }

231

{

232

"scripts": {

233

"prebump": "[ \"$CI\" = \"true\" ] && npm run test:ci || npm run test",

234

"posttag": "[ \"$NODE_ENV\" = \"production\" ] && npm publish || echo 'Skipping publish in non-production'",

235

"postcommit": "[ -f \"deploy.sh\" ] && ./deploy.sh || echo 'No deploy script found'"

236

}

237

}

238

```

239

240

**Hook with Custom Script Files:**

241

242

```json { .api }

243

{

244

"scripts": {

245

"prebump": "./scripts/pre-release-check.sh",

246

"postbump": "node scripts/build-and-test.js",

247

"postchangelog": "python scripts/update-changelog.py",

248

"posttag": "./scripts/deploy-release.sh $npm_package_version"

249

}

250

}

251

```

252

253

### Hook Script Output Handling

254

255

Hook scripts can influence standard-version behavior through their output.

256

257

```javascript { .api }

258

/**

259

* Special hook output behaviors:

260

*

261

* prebump hook output:

262

* - If prebump script outputs text, it overrides --release-as option

263

* - Output should be: major, minor, patch, or specific version number

264

*

265

* All hooks:

266

* - stdout is captured and can be logged

267

* - stderr is displayed immediately

268

* - Non-zero exit code stops release process

269

*/

270

```

271

272

**Usage Examples:**

273

274

```bash

275

#!/bin/bash

276

# prebump hook that determines release type based on commit analysis

277

if git log --oneline -1 | grep -q "BREAKING CHANGE"; then

278

echo "major"

279

elif git log --oneline -1 | grep -q "feat:"; then

280

echo "minor"

281

else

282

echo "patch"

283

fi

284

```

285

286

```javascript

287

// Node.js prebump script

288

const { execSync } = require('child_process');

289

290

// Analyze commits to determine version bump

291

const commits = execSync('git log --oneline --since="1 week ago"', { encoding: 'utf8' });

292

293

if (commits.includes('BREAKING CHANGE') || commits.includes('!:')) {

294

console.log('major');

295

} else if (commits.includes('feat:')) {

296

console.log('minor');

297

} else {

298

console.log('patch');

299

}

300

```

301

302

### Error Handling in Hooks

303

304

Proper error handling patterns for lifecycle hooks.

305

306

```javascript { .api }

307

/**

308

* Hook error handling:

309

* - Script exit code 0: Success, continue release process

310

* - Script exit code non-zero: Failure, abort release process

311

* - Uncaught exceptions in Node.js hooks: Abort release process

312

* - Empty or missing script: No-op, continue release process

313

*/

314

```

315

316

**Usage Examples:**

317

318

```bash

319

#!/bin/bash

320

# Robust prebump hook with error handling

321

set -e # Exit on any error

322

323

echo "Running pre-bump validations..."

324

325

# Run tests with proper error handling

326

if ! npm run test; then

327

echo "Tests failed, aborting release"

328

exit 1

329

fi

330

331

# Check for uncommitted changes

332

if [ -n "$(git status --porcelain)" ]; then

333

echo "Working directory not clean, aborting release"

334

exit 1

335

fi

336

337

echo "All validations passed"

338

exit 0

339

```

340

341

```javascript

342

// Node.js hook with error handling

343

const { execSync } = require('child_process');

344

345

try {

346

console.log('Running build and validation...');

347

348

execSync('npm run build', { stdio: 'inherit' });

349

execSync('npm run test:build', { stdio: 'inherit' });

350

351

console.log('Build and validation successful');

352

process.exit(0);

353

354

} catch (error) {

355

console.error('Build or validation failed:', error.message);

356

process.exit(1);

357

}

358

```

359

360

### Hook Integration with CI/CD

361

362

Patterns for using hooks effectively in continuous integration environments.

363

364

```json { .api }

365

{

366

"scripts": {

367

"prerelease": "[ \"$CI\" != \"true\" ] && echo 'Running in development mode' || echo 'Running in CI mode'",

368

"prebump": "[ \"$CI\" = \"true\" ] && npm ci || npm install",

369

"postbump": "[ \"$CI\" = \"true\" ] && npm run build:ci || npm run build:dev",

370

"posttag": "[ \"$CI\" = \"true\" ] && [ \"$BRANCH\" = \"main\" ] && npm publish || echo 'Skipping publish'"

371

}

372

}

373

```