Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: Documentation
on:
push:
branches:
- master
- main
permissions:
contents: read
pages: write
id-token: write
jobs:
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- uses: actions/configure-pages@v6
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: 3.x
- run: pip install zensical
- run: zensical build --clean
- uses: actions/upload-pages-artifact@v5
with:
path: site
- uses: actions/deploy-pages@v5
id: deployment
6 changes: 1 addition & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,10 @@ It supports multiple deployment types:

## Installation

```bash
pip install deploy
```

With [`uv`](https://docs.astral.sh/uv/):

```bash
uv tool install deploy
uv tool install https://github.com/trobz/deploy.py.git
```

On remote server where applications will be deployed:
Expand Down
91 changes: 91 additions & 0 deletions docs/commands/configure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# deploy configure

Clone a repository, set up the application environment, and install a
systemd user unit on the target host.

## Signature

```bash
deploy [--config FILE] configure <instance_name> [<ssh_host>] [<repo_url>] \
[--type odoo|python|service] [-p PORT] [--force]
```

## Arguments

| Argument | Required without config | Description |
|----------|------------------------|-------------|
| `instance_name` | Always | Logical name for the instance |
| `ssh_host` | If not in config | SSH target, or `localhost` / omit for local execution |
| `repo_url` | If not in config | Git repository URL |

## Options

| Option | Default | Description |
|--------|---------|-------------|
| `--type` | auto | Deployment type: `odoo`, `python`, or `service` |
| `-p`, `--port` | — | SSH port on the remote host |
| `--force` | `False` | Re-run steps 3–4 even if the instance directory already exists |

## Steps

1. **Connect** — open SSH connection if `ssh_host` is set and is not `localhost`.
2. **Clone repository** — clone `repo_url` into `~/<instance_name>`.
- If the directory already exists without `--force`: abort with exit 1.
- With `--force`: skip clone, proceed to step 3.
3. **Set up environment**

=== "odoo"

```bash
odoo-venv create --project-dir ~/<instance_name> --preset project
odoo-addons-path ~/<instance_name>
```

=== "python"

```bash
uv venv .venv
uv pip install -r requirements.txt # if requirements.txt exists
uv sync # if pyproject.toml exists
```

=== "service"

Runs the `build` command defined in `deploy.yml`.

4. **Install systemd unit** — render the bundled template and register it:

```bash
mkdir -p ~/.config/systemd/user/
# write ~/<instance_name>.service
loginctl enable-linger
systemctl --user daemon-reload
systemctl --user enable --now <instance_name>
```

## Exit codes

| Condition | Exit code |
|-----------|-----------|
| All steps succeeded | 0 |
| SSH connection failed | 1 |
| Repository already exists (without `--force`) | 1 |
| Git clone failed | 1 |
| Virtual environment step failed | 1 |
| Template rendering / write failed | 1 |

## Examples

```bash
# Auto-detect type from prefix, read config from deploy.yml
deploy configure odoo-myproject-production

# Explicit SSH host and repo
deploy configure service-api-staging deploy@host.example.com git@github.com:org/api.git

# Custom SSH port
deploy configure odoo-myproject-staging -p 2222

# Re-run environment setup without re-cloning
deploy configure odoo-myproject-production --force
```
28 changes: 28 additions & 0 deletions docs/commands/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Commands

`deploy` provides three commands. All commands accept global options:

| Option | Default | Description |
|--------|---------|-------------|
| `--config FILE` | `deploy.yml` | Path to the configuration file (resolved locally) |
| `--verbose` | `False` | Print each remote command and its output as it runs |

## Overview

| Command | Purpose |
|---------|---------|
| [`configure`](configure.md) | Clone repo, set up environment, install systemd unit |
| [`update`](update.md) | Pull latest code, sync deps, restart service |
| [`status`](status.md) | Show git info and systemd unit state |

## Global usage

```bash
deploy [--config FILE] [--verbose] <command> [args...]
```

Example using a custom config path:

```bash
deploy --config /etc/deploy/myserver.yml update odoo-myproject-production
```
61 changes: 61 additions & 0 deletions docs/commands/status.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# deploy status

Show the current state of a deployment instance: git info and systemd unit status.

## Signature

```bash
deploy [--config FILE] status <instance_name> [<ssh_host>] [-p PORT]
```

## Arguments

| Argument | Required without config | Description |
|----------|------------------------|-------------|
| `instance_name` | Always | Name of the previously configured instance |
| `ssh_host` | If not in config | SSH target, or `localhost` / omit for local execution |

## Options

| Option | Default | Description |
|--------|---------|-------------|
| `-p`, `--port` | — | SSH port on the remote host |

## Output

```
Instance: odoo-myproject-production
Remote: git@github.com:org/repo.git
Branch: main (abc1234)
Unit: active (running) since 2026-03-09 08:12:03
```

## Steps

1. **Connect** — open SSH connection if `ssh_host` is not `localhost`.
2. **Git info** — inside `~/<instance_name>`:
- `git remote get-url origin` → remote URL
- `git rev-parse --abbrev-ref HEAD` → branch
- `git rev-parse --short HEAD` → commit hash
3. **Unit status** — via `systemctl --user show`.

## Exit codes

| Condition | Exit code |
|-----------|-----------|
| All steps succeeded | 0 |
| SSH connection failed | 1 |
| Instance directory not found | 1 |

## Examples

```bash
# Read ssh_host from deploy.yml
deploy status odoo-myproject-production

# Explicit host
deploy status odoo-myproject-production deploy@myserver.example.com

# Custom SSH port
deploy status odoo-myproject-production -p 2222
```
96 changes: 96 additions & 0 deletions docs/commands/update.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
# deploy update

Pull the latest code, update dependencies, and restart the service on the
target host.

## Signature

```bash
deploy [--config FILE] update <instance_name> [<ssh_host>] \
[--type odoo|python|service] [-p PORT] [--db DATABASE] [--ignore-hooks]
```

## Arguments

| Argument | Required without config | Description |
|----------|------------------------|-------------|
| `instance_name` | Always | Name of the previously configured instance |
| `ssh_host` | If not in config | SSH target, or `localhost` / omit for local execution |

## Options

| Option | Default | Description |
|--------|---------|-------------|
| `--type` | auto | Deployment type: `odoo`, `python`, or `service` |
| `-p`, `--port` | — | SSH port on the remote host |
| `--db` | `<instance_name>` | Override target database name (Odoo only) |
| `--ignore-hooks` | `False` | Skip all hook execution |

## Steps

1. **Connect** — open SSH connection if `ssh_host` is not `localhost`.
2. **`pre-update` hooks** — non-blocking.
3. **`pre-update-required` hooks** — abort with exit 1 on failure; runs `pre-update-fail` first.
4. **`pre-update-success` or `pre-update-fail`** — based on steps 2–3 outcome.
5. **Pull latest code** — `git pull` inside `~/<instance_name>`.
6. **Update dependencies / rebuild**

=== "odoo"
```bash
odoo-venv update .venv --backup --yes
```

=== "python"
```bash
uv pip install -r requirements.txt # if requirements.txt exists
uv sync # if pyproject.toml exists
```

=== "service"
Runs the `build` command from `deploy.yml`.

7. **Apply changes**

=== "odoo"
```bash
~/<instance_name>/.venv/bin/click-odoo-upgrade -d <database_name>
systemctl --user restart <instance_name>
```

=== "python / service"
```bash
systemctl --user restart <instance_name>
```

8. **`post-update` hooks**, then `post-update-success` or `post-update-fail`.

## Exit codes

| Condition | Exit code |
|-----------|-----------|
| All steps succeeded | 0 |
| SSH connection failed | 1 |
| Instance directory not found | 1 |
| `pre-update-required` hook failed | 1 |
| `git pull` failed | 1 |
| Dependency update failed | 1 |
| Upgrade / restart command failed | 1 |

## Examples

```bash
# Standard update — reads all values from deploy.yml
deploy update odoo-myproject-production

# Override database name
deploy update odoo-myproject-production --db myproject_alt

# Custom SSH port
deploy update odoo-myproject-staging -p 2222

# Skip hooks for emergency deploys
deploy update odoo-myproject-production --ignore-hooks

# Verbose output to see every remote command
deploy --verbose update odoo-myproject-production
```
Loading
Loading