or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cli-commands.mdconfiguration.mdcore-version-management.mdfile-operations.mdhooks.mdindex.mdscm-integration.md

hooks.mddocs/

0

# Hook System

1

2

Pre-commit, post-commit, and setup hook system for extending bump-my-version functionality with custom automation workflows. Provides shell command execution at key points in the version bump process with full context access and error handling.

3

4

## Capabilities

5

6

### Hook Execution Functions

7

8

Functions for executing hooks at different stages of the version bump workflow.

9

10

```python { .api }

11

def run_setup_hooks(

12

config: Config,

13

current_version: Version,

14

dry_run: bool = False

15

) -> None:

16

"""

17

Execute setup hooks before version processing begins.

18

19

Runs configured setup hooks in sequence before any version analysis

20

or file modifications. Useful for environment preparation or validation.

21

22

Args:

23

config: Configuration containing setup_hooks list

24

current_version: Current Version object for context

25

dry_run: Preview operations without executing

26

27

Raises:

28

HookError: Hook execution failed

29

"""

30

31

def run_pre_commit_hooks(

32

config: Config,

33

current_version: Version,

34

new_version: Version,

35

dry_run: bool = False

36

) -> None:

37

"""

38

Execute pre-commit hooks before SCM operations.

39

40

Runs configured pre-commit hooks after file modifications but before

41

creating commits or tags. Ideal for formatting, linting, or testing.

42

43

Args:

44

config: Configuration containing pre_commit_hooks list

45

current_version: Current Version object

46

new_version: New Version object

47

dry_run: Preview operations without executing

48

49

Raises:

50

HookError: Hook execution failed

51

"""

52

53

def run_post_commit_hooks(

54

config: Config,

55

current_version: Version,

56

new_version: Version,

57

dry_run: bool = False

58

) -> None:

59

"""

60

Execute post-commit hooks after SCM operations complete.

61

62

Runs configured post-commit hooks after all version bump operations

63

including commits and tags. Perfect for deployment, notifications, or cleanup.

64

65

Args:

66

config: Configuration containing post_commit_hooks list

67

current_version: Current Version object

68

new_version: New Version object

69

dry_run: Preview operations without executing

70

71

Raises:

72

HookError: Hook execution failed

73

"""

74

```

75

76

### Hook Configuration

77

78

Hook settings are configured in the main bump-my-version configuration:

79

80

```python { .api }

81

class Config(BaseSettings):

82

# Hook configuration lists

83

setup_hooks: List[str] = []

84

pre_commit_hooks: List[str] = []

85

post_commit_hooks: List[str] = []

86

```

87

88

## Hook Types and Timing

89

90

### Setup Hooks

91

92

Execute before any version processing begins:

93

94

```toml

95

[tool.bumpversion]

96

setup_hooks = [

97

"echo 'Starting version bump process'",

98

"uv sync --upgrade",

99

"python -m pytest --no-cov -x",

100

"pre-commit run --all-files"

101

]

102

```

103

104

**Use Cases:**

105

- Environment validation and setup

106

- Dependency updates

107

- Pre-flight testing

108

- Code formatting and linting

109

- Documentation generation

110

111

### Pre-commit Hooks

112

113

Execute after file modifications but before SCM operations:

114

115

```toml

116

[tool.bumpversion]

117

pre_commit_hooks = [

118

"python setup.py check",

119

"uv build",

120

"twine check dist/*",

121

"git add dist/",

122

"git add CHANGELOG.md"

123

]

124

```

125

126

**Use Cases:**

127

- Package building and validation

128

- Additional file modifications

129

- Staging extra files for commit

130

- Running final tests

131

- Documentation updates

132

133

### Post-commit Hooks

134

135

Execute after all SCM operations complete:

136

137

```toml

138

[tool.bumpversion]

139

post_commit_hooks = [

140

"git push origin main",

141

"git push --tags",

142

"gh release create {new_version} --generate-notes",

143

"uv publish",

144

"slack-notify 'Released {new_version}'"

145

]

146

```

147

148

**Use Cases:**

149

- Pushing changes to remote repositories

150

- Creating GitHub/GitLab releases

151

- Publishing packages to registries

152

- Sending notifications

153

- Triggering CI/CD pipelines

154

- Deployment automation

155

156

## Hook Context and Templating

157

158

Hooks have access to the full template context including version information, timestamps, and SCM details:

159

160

### Available Context Variables

161

162

```python

163

context = {

164

# Version information

165

"current_version": "1.0.0",

166

"new_version": "1.0.1",

167

"major": "1",

168

"minor": "0",

169

"patch": "1",

170

171

# SCM information

172

"commit_sha": "abc123...",

173

"branch_name": "main",

174

"tag_name": "v1.0.1",

175

176

# Timestamps

177

"now": datetime.now(),

178

"utcnow": datetime.utcnow(),

179

180

# Environment variables (BMP_* prefixed)

181

"BMP_CUSTOM_VAR": "value"

182

}

183

```

184

185

### Template Usage in Hooks

186

187

```toml

188

[tool.bumpversion]

189

post_commit_hooks = [

190

"echo 'Released version {new_version} on {now:%Y-%m-%d}'",

191

"git tag -a archive-{current_version} -m 'Archive old version {current_version}'",

192

"curl -X POST https://api.example.com/releases -d version={new_version}",

193

"docker build -t myapp:{new_version} .",

194

"docker push myapp:{new_version}"

195

]

196

```

197

198

## Configuration Examples

199

200

### Basic Hook Configuration

201

202

```toml

203

[tool.bumpversion]

204

current_version = "1.0.0"

205

commit = true

206

tag = true

207

208

# Simple hooks

209

setup_hooks = ["python -m pytest"]

210

pre_commit_hooks = ["python setup.py check"]

211

post_commit_hooks = ["git push --follow-tags"]

212

```

213

214

### Advanced Hook Workflows

215

216

```toml

217

[tool.bumpversion]

218

current_version = "1.0.0"

219

commit = true

220

tag = true

221

222

# Comprehensive development workflow

223

setup_hooks = [

224

"echo 'Starting release process for {current_version} → {new_version}'",

225

"uv sync --upgrade",

226

"python -m pytest --cov=src --cov-report=html",

227

"pre-commit run --all-files",

228

"python -c 'import sys; sys.exit(0 if \"{new_version}\" > \"{current_version}\" else 1)'"

229

]

230

231

pre_commit_hooks = [

232

"uv build",

233

"twine check dist/*",

234

"python scripts/update_changelog.py {current_version} {new_version}",

235

"git add CHANGELOG.md",

236

"python scripts/update_docs.py {new_version}",

237

"git add docs/"

238

]

239

240

post_commit_hooks = [

241

"git push origin {branch_name}",

242

"git push --tags",

243

"gh release create {new_version} dist/* --generate-notes",

244

"uv publish --token $PYPI_TOKEN",

245

"python scripts/notify_slack.py 'Released {new_version}'",

246

"python scripts/update_dependencies.py {new_version}"

247

]

248

```

249

250

### CI/CD Integration Hooks

251

252

```toml

253

[tool.bumpversion]

254

# Hooks for CI/CD pipeline integration

255

setup_hooks = [

256

"echo 'CI Release Process Started'",

257

"echo 'RELEASE_VERSION={new_version}' >> $GITHUB_ENV"

258

]

259

260

pre_commit_hooks = [

261

"docker build -t myapp:{new_version} .",

262

"docker run --rm myapp:{new_version} python -m pytest",

263

"echo 'DOCKER_IMAGE=myapp:{new_version}' >> $GITHUB_ENV"

264

]

265

266

post_commit_hooks = [

267

"docker push myapp:{new_version}",

268

"docker tag myapp:{new_version} myapp:latest",

269

"docker push myapp:latest",

270

"kubectl set image deployment/myapp myapp=myapp:{new_version}"

271

]

272

```

273

274

## Usage Examples

275

276

### Programmatic Hook Execution

277

278

```python

279

from bumpversion.hooks import run_setup_hooks, run_pre_commit_hooks, run_post_commit_hooks

280

from bumpversion.config import get_configuration

281

from bumpversion.context import get_context

282

283

# Load configuration

284

config = get_configuration()

285

286

# Create context

287

context = get_context(config)

288

context.update({

289

"current_version": "1.0.0",

290

"new_version": "1.0.1"

291

})

292

293

# Create version objects

294

from bumpversion.versioning.models import Version

295

current_version = Version({"major": "1", "minor": "0", "patch": "0"}, None)

296

new_version = Version({"major": "1", "minor": "0", "patch": "1"}, None)

297

298

try:

299

# Execute hooks in sequence

300

run_setup_hooks(config, current_version, dry_run=False)

301

print("Setup hooks completed successfully")

302

303

# ... perform version bump operations ...

304

305

run_pre_commit_hooks(config, current_version, new_version, dry_run=False)

306

print("Pre-commit hooks completed successfully")

307

308

# ... perform SCM operations ...

309

310

run_post_commit_hooks(config, current_version, new_version, dry_run=False)

311

print("Post-commit hooks completed successfully")

312

313

except HookError as e:

314

print(f"Hook execution failed: {e}")

315

print(f"Failed command: {e.command}")

316

print(f"Exit code: {e.exit_code}")

317

print(f"Output: {e.output}")

318

```

319

320

### Custom Hook Runner

321

322

```python

323

import subprocess

324

from typing import List, Dict, Any

325

from bumpversion.exceptions import HookError

326

327

def run_custom_hooks(

328

hooks: List[str],

329

context: Dict[str, Any],

330

cwd: Optional[Path] = None

331

) -> None:

332

"""

333

Run custom hooks with enhanced error handling.

334

335

Args:

336

hooks: List of shell commands to execute

337

context: Template context for command formatting

338

cwd: Working directory for command execution

339

"""

340

for hook in hooks:

341

try:

342

# Format command with context

343

formatted_command = hook.format(**context)

344

print(f"Executing hook: {formatted_command}")

345

346

# Execute command

347

result = subprocess.run(

348

formatted_command,

349

shell=True,

350

cwd=cwd,

351

capture_output=True,

352

text=True,

353

check=True

354

)

355

356

print(f"Hook output: {result.stdout}")

357

358

except subprocess.CalledProcessError as e:

359

raise HookError(

360

f"Hook failed: {formatted_command}",

361

command=formatted_command,

362

exit_code=e.returncode,

363

output=e.stderr

364

)

365

```

366

367

### Conditional Hook Execution

368

369

```python

370

import os

371

from bumpversion.hooks import run_post_commit_hooks

372

373

# Only run deployment hooks in production environment

374

if os.getenv("ENVIRONMENT") == "production":

375

config.post_commit_hooks.extend([

376

"python scripts/deploy_production.py {new_version}",

377

"python scripts/notify_team.py 'Production deployment of {new_version} complete'"

378

])

379

380

# Run different hooks based on version type

381

if context.get("patch") != "0":

382

# Patch release

383

config.post_commit_hooks.append("python scripts/hotfix_notification.py")

384

elif context.get("minor") != "0":

385

# Minor release

386

config.post_commit_hooks.append("python scripts/feature_announcement.py")

387

else:

388

# Major release

389

config.post_commit_hooks.extend([

390

"python scripts/major_release_blog.py {new_version}",

391

"python scripts/social_media_announcement.py {new_version}"

392

])

393

```

394

395

### Hook Error Handling

396

397

```python

398

from bumpversion.hooks import run_pre_commit_hooks

399

from bumpversion.exceptions import HookError

400

401

try:

402

run_pre_commit_hooks(config, current_version, new_version)

403

except HookError as e:

404

print(f"Pre-commit hook failed: {e}")

405

406

# Check if it's a specific type of failure

407

if "pytest" in e.command:

408

print("Tests failed - aborting release")

409

sys.exit(1)

410

elif "build" in e.command:

411

print("Build failed - checking for dependency issues")

412

# Could implement recovery logic here

413

else:

414

print(f"Unknown hook failure: {e.command}")

415

print(f"Exit code: {e.exit_code}")

416

print(f"Error output: {e.output}")

417

```

418

419

### Environment-Specific Hooks

420

421

```toml

422

[tool.bumpversion]

423

# Base configuration

424

current_version = "1.0.0"

425

426

# Development environment hooks

427

setup_hooks = [

428

"python -c 'import os; print(f\"Environment: {os.getenv(\"ENVIRONMENT\", \"development\")}\")'",

429

"if [ \"$ENVIRONMENT\" = \"development\" ]; then echo 'Dev mode - skipping some checks'; fi"

430

]

431

432

post_commit_hooks = [

433

# Always push to origin

434

"git push origin {branch_name}",

435

"git push --tags",

436

437

# Conditional publishing

438

"if [ \"$ENVIRONMENT\" = \"production\" ]; then uv publish; fi",

439

"if [ \"$ENVIRONMENT\" = \"staging\" ]; then uv publish --repository testpypi; fi"

440

]

441

```

442

443

## Hook Best Practices

444

445

### Error Handling

446

447

- Always use proper exit codes in hook scripts

448

- Provide meaningful error messages

449

- Consider implementing rollback mechanisms

450

- Log hook execution for debugging

451

452

### Performance

453

454

- Keep hooks lightweight and fast

455

- Use parallel execution where possible

456

- Cache dependencies and build artifacts

457

- Avoid redundant operations

458

459

### Security

460

461

- Validate all inputs and context variables

462

- Use secure credential management

463

- Audit hook commands for security issues

464

- Limit hook permissions appropriately

465

466

### Testing

467

468

- Test hooks in isolation

469

- Use dry-run modes where available

470

- Implement hook validation scripts

471

- Test error conditions and recovery