Files
moko-platform/docs/workflows/dev-deployment.md
T
2026-04-26 23:11:26 -05:00

281 lines
9.2 KiB
Markdown

<!--
Copyright (C) 2026 Moko Consulting <hello@mokoconsulting.tech>
This file is part of a Moko Consulting project.
SPDX-License-Identifier: GPL-3.0-or-later
# FILE INFORMATION
DEFGROUP: MokoStandards.Documentation
INGROUP: MokoStandards
REPO: https://git.mokoconsulting.tech/MokoConsulting/MokoStandards-API
PATH: /docs/workflows/dev-deployment.md
VERSION: 04.06.00
BRIEF: Guide for the SFTP development server deployment workflow
-->
[![MokoStandards](https://img.shields.io/badge/MokoStandards-04.06.00-orange)](https://git.mokoconsulting.tech/MokoConsulting/MokoStandards)
# Development Server Deployment
Automated SFTP deployment of the `src/` directory to the development server.
## Overview
The `deploy-dev.yml` workflow pushes the contents of `src/` to a development server over **SFTP only** when:
- A commit is pushed to `dev/**`, `alpha/**`, `beta/**`, `rc/**`, `develop`, or `development` branches (and `src/**` changed)
- A pull request targeting those branches is **merged** (skips `chore/` branches)
- Triggered manually via workflow dispatch
**Access control:** `jmiller` and `gitea-actions[bot]` are always authorized. Other actors need **admin** or **maintain** role.
**Skips when:** `DEV_FTP_SUFFIX` variable is not set, or the branch starts with `chore/`.
---
## Configuration
### Organization Variables (required)
Configure at the **organization** level in **Settings → Secrets and variables → Actions → Variables**:
| Variable | Example | Description |
|----------|---------|-------------|
| `DEV_FTP_HOST` | `dev.example.com` | Dev server hostname. May include an explicit port suffix — `dev.example.com:2222`. |
| `DEV_FTP_PATH` | `/var/www/html` | Base remote path where files are deployed. |
| `DEV_FTP_USERNAME` | `deployuser` | SFTP username for authentication. |
### Organization Variable (optional)
| Variable | Example | Description |
|----------|---------|-------------|
| `DEV_FTP_PORT` | `2222` | Explicit port override. See **Port resolution** below. |
### Repository Variable (optional)
| Variable | Example | Description |
|----------|---------|-------------|
| `DEV_FTP_SUFFIX` | `my-module` | Appended to `DEV_FTP_PATH` to form the final deploy path: `DEV_FTP_PATH/DEV_FTP_SUFFIX`. Useful for deploying multiple repos to the same server. |
### Organization Secrets (credentials)
At least one of the following must be set:
| Secret | Description |
|--------|-------------|
| `DEV_FTP_KEY` | **Preferred.** SSH private key (any format supported by OpenSSH). |
| `DEV_FTP_PASSWORD` | SFTP password. Also used as the key passphrase when set alongside `DEV_FTP_KEY`. |
---
## Authentication logic
The workflow determines the connection method at runtime:
| Secrets present | Behaviour |
|-----------------|-----------|
| `DEV_FTP_KEY` + `DEV_FTP_PASSWORD` | Key auth with `DEV_FTP_PASSWORD` as the key passphrase. If key auth fails, retries with `DEV_FTP_PASSWORD` alone as an SFTP password. |
| `DEV_FTP_KEY` only | Key auth (no passphrase). Fails hard on auth error — no password fallback. |
| `DEV_FTP_PASSWORD` only | Password auth directly. |
| Neither | Workflow fails with an error message. |
---
## Port resolution
The SFTP port is determined in the following order — the first match wins:
1. **`DEV_FTP_PORT` variable** — explicit override, highest priority.
2. **Port suffix in `DEV_FTP_HOST`** — if the host value contains `:`, the suffix is extracted and the bare hostname is used (e.g. `dev.example.com:2222` → host `dev.example.com`, port `2222`).
3. **Default** — port **22** is assumed when neither of the above is present.
---
## Remote path
The final remote path is constructed as:
```
DEV_FTP_PATH/DEV_FTP_SUFFIX
```
`DEV_FTP_SUFFIX` is optional. When set, exactly one `/` is inserted between the base path and the value regardless of trailing/leading slashes in the values.
---
## Manual dispatch
1. Go to **Actions → Deploy to Dev Server (SFTP)**.
2. Click **Run workflow**.
3. Optionally override the source directory (default: `src`) or enable **Dry run** to list files without uploading.
---
## Repository health checks
The `check_repo_health.php` script scores deployment readiness as part of the overall health report. When `--repo owner/repo` is supplied, it also calls the GitHub API to verify secrets and variables are configured.
### Deployment category checks
| Check | Points | Requires `--repo` |
|-------|--------|------------------|
| `deploy-dev.yml` workflow exists | 5 | No |
| `DEV_FTP_HOST` variable configured | 3 | Yes |
| `DEV_FTP_PATH` variable configured | 3 | Yes |
| `DEV_FTP_USERNAME` variable configured | 2 | Yes |
| SFTP credentials configured (`DEV_FTP_KEY` or `DEV_FTP_PASSWORD`) | 2 | Yes |
Variables and secrets are checked at both the **org level** and **repo level** — a check passes if the item exists at either scope.
---
## Examples
### Example 1 — SSH key with passphrase, custom port
**Org variables:**
```
DEV_FTP_HOST = dev.example.com
DEV_FTP_PORT = 2222
DEV_FTP_PATH = /var/www/html
DEV_FTP_USERNAME = deployuser
```
**Org secrets:**
```
DEV_FTP_KEY = <passphrase-protected SSH private key>
DEV_FTP_PASSWORD = mysecretphrase
```
**Behaviour:** Key loaded with `mysecretphrase` as passphrase. If key auth fails, retries with `mysecretphrase` as the SFTP password.
---
### Example 2 — SSH key, port embedded in host
**Org variables:**
```
DEV_FTP_HOST = dev.example.com:2222
DEV_FTP_PATH = /var/www/html
DEV_FTP_USERNAME = deployuser
```
**Org secret:**
```
DEV_FTP_KEY = <unprotected SSH private key>
```
**Behaviour:** Port `2222` extracted from host. Key used without passphrase; no password fallback.
---
### Example 3 — Password only, default port
**Org variables:**
```
DEV_FTP_HOST = dev.example.com
DEV_FTP_PATH = /var/www/html
DEV_FTP_USERNAME = deployuser
```
**Org secret:**
```
DEV_FTP_PASSWORD = secretpass
```
**Behaviour:** Port defaults to 22. Connects with password directly.
---
### Example 4 — Multiple repos, same server
Each repo sets its own `DEV_FTP_SUFFIX`:
| Repo | Suffix | Deploys to |
|------|--------|------------|
| `project-a` | `/project-a` | `/var/www/html/project-a` |
| `project-b` | `/project-b` | `/var/www/html/project-b` |
---
## Troubleshooting
### Permission denied
```
❌ Deployment requires admin or maintain role.
```
Only org/repo administrators and maintainers may deploy. Contact your org administrator.
### No credentials configured
```
❌ No SFTP credentials configured.
Set DEV_FTP_KEY (preferred) or DEV_FTP_PASSWORD as an org-level secret.
```
Set at least one of `DEV_FTP_KEY` or `DEV_FTP_PASSWORD` in **Org Settings → Secrets**.
### Key authentication failed, no fallback
```
RuntimeError: Key authentication failed and no password fallback is available: ...
```
The SSH private key was rejected and `DEV_FTP_PASSWORD` is not set. Check the key is correct and authorized on the server, or add `DEV_FTP_PASSWORD` as a fallback.
### Missing source directory
```
⚠️ Source directory 'src' not found — skipping deployment
```
Expected behaviour for repos without a `src/` directory. No files are uploaded; the workflow exits successfully.
### Connection refused
```
[Errno 111] Connection refused
```
- Verify `DEV_FTP_HOST` is correct.
- Check the resolved port (shown in the **Resolve SFTP host and port** step log).
- Confirm the server firewall allows inbound SFTP on that port.
---
## Related documentation
- [Workflow inventory](./workflow-inventory.md)
- [Bulk repository sync](./bulk-repo-sync.md)
- [MokoStandards repo-sync guide](../guide/repo-sync.md)
- [Workflow template source](../../templates/workflows/shared/deploy-dev.yml.template)
---
## Metadata
| Field | Value |
|---------------|-------------------------------------------------------------|
| Document Type | Guide |
| Domain | Operations |
| Applies To | All Repositories |
| Jurisdiction | Tennessee, USA |
| Owner | Moko Consulting |
| Repo | https://git.mokoconsulting.tech/MokoConsulting/MokoStandards |
| Path | /docs/workflows/dev-deployment.md |
| Version | 04.06.00 |
| Status | Active |
| Last Reviewed | 2026-04-07 |
| Reviewed By | Documentation Team |
## Revision History
| Date | Author | Change |
|------------|-----------------|----------------------------------------------------------------------|
| 2026-03-12 | Moko Consulting | Rewrote for SFTP-only workflow; added auth fallback, port resolution, health check docs |
| 2026-01-28 | Moko Consulting | Standardized metadata and revision history |
| 2026-01-17 | Moko Consulting | Initial dev deployment workflow documentation |