Skip to content

Release Hooks

Tag-specific deployment scripts that run during tenant upgrades.

Overview

The cbapp team can include release hooks in the release/ directory of cbapp. These scripts are automatically discovered and executed at specific points during the upgrade process, allowing for custom deployment logic per release.

Hook Naming Convention

release/<tag>.sh               # Default (runs as post-pull)
release/<tag>.pre-pull.sh      # Before git checkout
release/<tag>.post-pull.sh     # After git checkout
release/<tag>.pre-migrate.sh   # Before database migration
release/<tag>.post-migrate.sh  # After database migration

Examples

File When it runs
v0.3.28.sh After git checkout (default = post-pull)
v0.4.0.pre-pull.sh Before git checkout
v0.4.0.post-migrate.sh After all migrations complete

Upgrade Workflow

The tenant upgrade process executes hooks at these points:

1.  Stop services
2.  Backup database
3.  Git fetch
4.  Determine target version
5.  ▶ PRE-PULL HOOKS
6.  Git checkout target version
7.  ▶ POST-PULL HOOKS (includes default <tag>.sh)
8.  pip install requirements
9.  ▶ PRE-MIGRATE HOOKS
10. Run database migrations
11. ▶ POST-MIGRATE HOOKS
12. Update version tracking
13. Start services
14. Health check

Environment Variables

Scripts receive these environment variables:

Variable Description Example
DEPLOY_TAG Version tag being deployed v0.3.28
DEPLOY_ENV Tenant slug/environment name testsite
APP_DIR Application root directory /home/.../testsite
DATA_DIR Database directory /home/.../testsite/db

Script Requirements

  1. Idempotent - Safe to run multiple times
  2. Exit codes - Return 0 on success, non-zero on failure
  3. Logging - Echo status messages for audit trail
  4. Backups - Create backups before destructive operations

Example Script

#!/bin/bash
# Release hook for v0.4.0
set -e  # Exit on error

echo "=== Release hook: $DEPLOY_TAG ==="

# Idempotency check - skip if already done
MARKER="$APP_DIR/.release-${DEPLOY_TAG}-done"
if [ -f "$MARKER" ]; then
    echo "Already applied, skipping"
    exit 0
fi

# Your release tasks here
echo "Running release tasks for $DEPLOY_ENV..."

# Example: Sync static files
cp "$APP_DIR/src/app/static/data/new-file.json" \
   "/other/deployment/static/data/" 2>/dev/null || true

# Example: Clear cache
rm -rf "$APP_DIR/cache/*" 2>/dev/null || true

# Mark as complete
touch "$MARKER"
echo "=== Release hook complete ==="

API Response

The upgrade endpoint includes hook execution results:

{
  "status": "success",
  "previous_version": "v0.3.27",
  "new_version": "v0.3.28",
  "commit": "abc123",
  "migrations_run": ["scripts/add_segment_tables.py"],
  "hooks_executed": [
    "post-pull: v0.3.28.sh - OK"
  ],
  "backup_path": "/path/to/pocket.db.backup_20251216",
  "details": [
    "Stopping services...",
    "Services stopped",
    "Backing up database...",
    "Post-pull hook OK: v0.3.28.sh",
    "Running migrations...",
    "Ran 1 migrations",
    "Starting services...",
    "Health check passed"
  ]
}

Common Use Cases

Use Case Hook Phase Example
Regenerate static files post-pull Rebuild JSON data from cache
Sync to other deployments post-pull Copy files to testsite
Pre-migration data prep pre-migrate Backup specific tables
Cache warmup post-migrate Pre-populate caches
Config updates pre-pull Set new environment variables

Error Handling

  • If a hook fails (non-zero exit), the upgrade aborts
  • Failed hooks are logged with error details
  • Services are restarted even on failure (best effort)
  • Check tenant logs for hook output

Files

File Purpose
cbapp/release/README.md Hook documentation (cbapp team)
cbapp/release/*.sh Hook scripts (cbapp team)
cbtenant/api/utils/release_hooks.py Hook execution logic
cbtenant/api/routes/upgrade.py Upgrade workflow integration

See also: Upgrading Tenants | Tenant Deployment