# DEPLOYMENT_PIPELINE.md

# Pipeline de Deploy

## Resumen

Este proyecto utiliza un sistema de deploy automatizado basado en:

- GitHub Actions
- Deployer
- Releases atómicos de Laravel
- Versionado de releases
- Rollback manual

Actualmente solo existe el entorno **Stage**.

---

# Flujo del Deploy

```text
Push a staging
↓
GitHub Actions
↓
composer install
↓
Construcción de .build
↓
Upload vía SSH
↓
Nuevo release
↓
Links shared/
↓
Limpieza de caché
↓
Scripts release
↓
Actualización de current
```

---

# Trigger del Deploy

El deploy se ejecuta automáticamente al hacer push a:

```text
staging
```

Workflow:

```yaml
on:
push:
branches:
    - staging
```

---

# Estructura del Servidor

```text
/home/salkanta/stage/stage.api.salkantay-trekking.com
├── current -> releases/12
├── releases/
├── shared/
```

---

# Cómo Funcionan los Releases

Cada deploy crea un nuevo release dentro de:

```text
releases/
```

La aplicación activa siempre es:

```text
current
```

Ejemplo:

```text
current -> releases/12
```

Esto permite:

- Deploys atómicos
- Rollback rápido
- Evitar downtime parcial

---

# Retención de Releases

```php
set('keep_releases', 5);
```

Solo se mantienen los últimos 5 releases.

---

# Shared Files y Shared Directories

## Shared Files

```php
add('shared_files', [
'.env',
]);
```

## Shared Directories

```php
add('shared_dirs', [
'storage',
'config',
]);
```

Persisten entre releases.

---

# Directorios Writable

```php
add('writable_dirs', [
'storage',
'bootstrap/cache',
]);
```

---

# Build del Proyecto

El build se realiza en GitHub Actions.

El servidor no compila código.

---

# Instalación de Dependencias

```bash
composer install --no-dev --prefer-dist --optimize-autoloader
```

---

# Construcción del Package

```bash
rm -rf .build
mkdir .build

rsync -az --exclude-from=".buildignore" ./ .build/

mkdir -p .build/vendor
cp -R vendor .build/
```

---

# Secrets Requeridos

| Secret                | Descripción       |
| --------------------- | ----------------- |
| STAGE_HOST            | Host SSH          |
| STAGE_USERNAME        | Usuario SSH       |
| STAGE_SSH_PRIVATE_KEY | Clave privada SSH |

---

# Configuración del Host

```php
host('stage')
->set('hostname', '167.114.34.144')
->set('remote_user', 'salkanta')
->set('identity_file', '~/.ssh/id_ed25519')
->set('deploy_path', '/home/salkanta/stage/stage.api.salkantay-trekking.com');
```

---

# Tasks Principales

## Upload

```php
task('upload', function () {
upload('.build/', '{{release_path}}');
});
```

## Limpieza de Caché

```php
task('artisan:clear-cache', function () {
run('{{bin/php}} {{release_path}}/artisan optimize:clear');
});
```

## Scripts Release

```php
task('db:migrate', function () {
run('{{bin/php}} {{release_path}}/artisan execute:releases');
});
```

---

# Orden del Deploy

```php
task('deploy', [
'deploy:info',
'deploy:setup',
'deploy:lock',
'deploy:release',

'upload',

'deploy:shared',
'deploy:writable',

'artisan:clear-cache',

'db:migrate',
'deploy:publish',
]);
```

---

# Rollback Manual

## Ver Releases

```bash
ls releases
```

## Cambiar Release Activo

```bash
ln -sfn releases/11 current
```

---

# Verificación del Deploy

## Ver Release Actual

```bash
readlink current
```

## Revisar Laravel

```bash
php artisan about
```

---

# Troubleshooting

## Error SSH

```text
Permission denied (publickey)
```

Verificar:

- SSH key
- GitHub Secrets
- authorized_keys

---

## Release No Actualizado

```bash
readlink current
```

---

## Error de Dependencias

```text
Class not found
```

Verificar copia correcta de `vendor/`.

---

## Error de Permisos

Verificar:

```text
storage/
bootstrap/cache
```

---

# Consideraciones de Seguridad

- Nunca commitear `.env`
- Nunca commitear claves SSH
- Usar únicamente GitHub Secrets
- No modificar releases manualmente
- Solo `current/` debe ser público

---

# Notas Importantes

## Composer NO se ejecuta en servidor

Las dependencias llegan construidas desde GitHub Actions.

---

## Los Releases Son Inmutables

No editar manualmente:

```text
current/
```

Todo cambio debe venir desde Git.
