# Olakunlevpn Deployment Skills

> Use when setting up deployment scripts, configuring auto-deploy, creating cron jobs, or deploying Laravel and Inertia applications to production servers. Generates deploy-pull.sh and auto-deploy.sh scripts with proper deployment sequence, logging, error handling, and cron configuration.

- **Type:** Skill
- **Install:** `agentstack add skill-olakunlevpn-olakunlevpn-deployment-skills-olakunlevpn-deployment-skills`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [olakunlevpn](https://agentstack.voostack.com/s/olakunlevpn)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [olakunlevpn](https://github.com/olakunlevpn)
- **Source:** https://github.com/olakunlevpn/olakunlevpn-deployment-skills

## Install

```sh
agentstack add skill-olakunlevpn-olakunlevpn-deployment-skills-olakunlevpn-deployment-skills
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Laravel Deployment Scripts

Generate production-ready deployment scripts for Laravel + Inertia applications. Two scripts: manual deploy and auto-deploy with GitHub polling. Always ask for the project path and log path before generating.

## Rules

1. **ALWAYS ask for the server project directory path and log directory path before generating scripts.** These are SERVER paths, not local machine paths. Every server is different.
2. **NEVER hardcode paths, usernames, domains, or server-specific values.** The scripts use configurable variables at the top that the user sets once for their server.
3. **NEVER skip migration.** Always include `php artisan migrate --force --no-interaction`.
4. **ALWAYS clear and rebuild cache.** `optimize:clear` then `optimize` in that order.
5. **ALWAYS stash local changes before pulling.** Prevents merge conflicts on server.
6. **ALWAYS include error handling.** Scripts should exit on failure with clear error messages.
7. **NEVER run `npm run dev` in production.** Always `npm run build`.
8. **ALWAYS log deployments with timestamps.**
9. **Auto-deploy checks every 2 minutes by default.** Configurable.
10. **Both scripts must be in the project root** and added to `.gitignore`.

---

## Phase 1: Gather Information

Before generating anything, you MUST ask the user these questions. Do NOT assume any answers. Do NOT generate scripts until all required answers are collected.

```
ASK THESE QUESTIONS (one message, wait for all answers):

1. "What is the full server path to your project?"
   Example: /home/ubuntu/htdocs/example.com
   This is the path ON THE SERVER, not your local machine.

2. "Do you need npm install and npm run build in the deploy?"
   - YES = project has frontend assets (React, Vue, Vite, etc.)
   - NO = backend-only project, no frontend build step

3. "Do you need composer install in the deploy?"
   - YES = always run composer install on deploy
   - AUTO = only run when composer.lock changes (recommended)
   - NO = skip composer entirely

4. "What git branch do you deploy from?" (default: main)

5. "Does your project use any of these? (list all that apply)"
   - Filament (adds filament:optimize + icons:cache)
   - Queue workers (adds queue:restart)
   - Horizon (adds horizon:terminate)
   - Reverb/WebSockets (adds reverb:restart)
   - None of the above
```

**Do NOT proceed until the user answers questions 1, 2, and 3. These are mandatory.**

Questions 4 and 5 have sensible defaults (main, none) but still ask.

After collecting answers, generate scripts tailored to their exact setup. If they said no npm, the script has no npm steps. If they said no composer, no composer steps. Only include what they need.

---

## Phase 2: Generate Scripts

### Script 1: deploy-pull.sh (Manual Deploy)

Generate this script based on the user's answers. Only include the steps they need.

**Template (adapt based on answers):**

```bash
#!/bin/bash
set -e

# ============================================
# Manual Deploy Script
# Usage: bash deploy-pull.sh
# ============================================
BRANCH="main"

PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
LOG_DIR="${LOG_DIR:-$PROJECT_DIR/storage/logs}"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')

mkdir -p "$LOG_DIR"
LOG_FILE="$LOG_DIR/deploy.log"
exec > >(tee -a "$LOG_FILE") 2>&1

echo ""
echo "=== Deploy started at $TIMESTAMP ==="
cd "$PROJECT_DIR"

echo "[1/N] Stashing local changes..."
git stash 2>/dev/null || true

echo "[2/N] Pulling from $BRANCH..."
git pull origin "$BRANCH"

# INCLUDE IF user answered YES or AUTO to composer:
# If AUTO: conditional check
if git diff HEAD@{1} --name-only 2>/dev/null | grep -q "composer.lock"; then
    echo "[3/N] Installing PHP dependencies..."
    composer install --no-dev --no-interaction --optimize-autoloader
else
    echo "[3/N] No composer changes, skipping..."
fi
# If YES: always run (remove the if/else, just run composer install)
# If NO: remove this entire block

# INCLUDE IF user answered YES to npm:
echo "[4/N] Installing npm packages..."
npm install --legacy-peer-deps 2>/dev/null

echo "[5/N] Building frontend assets..."
npm run build
# If NO: remove both npm steps entirely

echo "[6/N] Running migrations..."
php artisan migrate --force --no-interaction

echo "[7/N] Optimizing..."
php artisan optimize:clear
php artisan optimize

# INCLUDE based on question 5 answers:
# php artisan filament:optimize && php artisan icons:cache   # Filament
# php artisan queue:restart                                  # Queues
# php artisan horizon:terminate                              # Horizon
# php artisan reverb:restart                                 # Reverb

echo "=== Deploy completed at $(date '+%Y-%m-%d %H:%M:%S') ==="
echo ""
```

**Adjust step numbers [1/N] based on how many steps are included.**
- No npm + no composer = fewer steps
- All features = more steps
- Always count accurately. Never show [4/7] when there are only 5 steps.

### Script 2: auto-deploy.sh (Auto Deploy via Cron)

Same rules apply -- only include steps the user asked for.

```bash
#!/bin/bash
set -e

# ============================================
# Auto Deploy Script (runs via cron)
# Checks GitHub for new commits every 2 minutes
# Only deploys if new changes detected
# ============================================
BRANCH="main"

PROJECT_DIR="$(cd "$(dirname "$0")" && pwd)"
LOG_DIR="${LOG_DIR:-$PROJECT_DIR/storage/logs}"

mkdir -p "$LOG_DIR"
LOG_FILE="$LOG_DIR/auto-deploy.log"

cd "$PROJECT_DIR"

git fetch origin "$BRANCH" --quiet

LOCAL=$(git rev-parse HEAD)
REMOTE=$(git rev-parse "origin/$BRANCH")

if [ "$LOCAL" = "$REMOTE" ]; then
    exit 0
fi

echo "" >> "$LOG_FILE"
echo "=== Auto-deploy started at $(date '+%Y-%m-%d %H:%M:%S') ===" >> "$LOG_FILE"
echo "Local:  $LOCAL" >> "$LOG_FILE"
echo "Remote: $REMOTE" >> "$LOG_FILE"

exec >> "$LOG_FILE" 2>&1

git stash 2>/dev/null || true
git pull origin "$BRANCH"

# SAME CONDITIONAL BLOCKS AS deploy-pull.sh:
# Include composer if user said YES or AUTO
# Include npm install + npm run build if user said YES
# Include service restarts based on question 5

php artisan migrate --force --no-interaction
php artisan optimize:clear
php artisan optimize

echo "=== Auto-deploy completed at $(date '+%Y-%m-%d %H:%M:%S') ===" >> "$LOG_FILE"
```

---

## Phase 3: Setup Instructions

After generating scripts, provide setup steps using the ACTUAL paths the user gave you. Never use placeholders in the final output.

```
Step 1 — Make executable:
chmod +x /path/user/gave/deploy-pull.sh
chmod +x /path/user/gave/auto-deploy.sh

Step 2 — Add to .gitignore:
echo "deploy-pull.sh" >> .gitignore
echo "auto-deploy.sh" >> .gitignore

Step 3 — Add cron jobs:
crontab -e

Add these lines (use the ACTUAL server path the user provided):
*/2 * * * * /bin/bash /path/user/gave/auto-deploy.sh 2>&1
* * * * * cd /path/user/gave && php artisan schedule:run >> /dev/null 2>&1

Step 4 — Verify:
crontab -l
bash /path/user/gave/deploy-pull.sh
tail -f /path/user/gave/storage/logs/auto-deploy.log
```

**By default, logs go to `storage/logs/` inside the project.** If the user wants logs elsewhere, they set `LOG_DIR` env variable:
```
LOG_DIR=/var/log/myapp bash deploy-pull.sh
```

---

## Phase 4: Variations

### For projects with queue workers

Add after the optimize step:
```bash
php artisan queue:restart
```

### For projects with Horizon

Add after the optimize step:
```bash
php artisan horizon:terminate
```
Supervisor will auto-restart Horizon.

### For projects with Filament

Add after the optimize step:
```bash
php artisan filament:optimize
php artisan icons:cache
```

### For projects with scheduled tasks

Ensure this cron exists:
```
* * * * * cd [PROJECT_DIR] && php artisan schedule:run >> /dev/null 2>&1
```

### For projects with Reverb (WebSockets)

Add after the optimize step:
```bash
php artisan reverb:restart
```

### For projects needing Composer install

Only run when `composer.lock` changed:
```bash
if git diff HEAD@{1} --name-only | grep -q "composer.lock"; then
    composer install --no-dev --no-interaction --optimize-autoloader
fi
```

### For projects with specific PHP version

Replace `php` with the full path:
```bash
/usr/bin/php8.3 artisan migrate --force --no-interaction
```

### For multiple environments (staging + production)

Create separate scripts:
```
deploy-staging.sh   → pulls from develop branch
deploy-production.sh → pulls from main branch
```

### For Webhook-based deploy (instead of polling)

Instead of cron polling, use a GitHub webhook that hits a deploy URL:
```
Route: POST /deploy-webhook
Secret: validated via X-Hub-Signature-256 header
Action: Runs deploy-pull.sh
```

---

## Deployment Sequence (Strict Order)

This order matters. Never rearrange.

```
1. git stash              → Protect local changes
2. git pull               → Get latest code
3. composer install        → PHP dependencies (if changed)
4. npm install             → JS dependencies
5. npm run build           → Build frontend assets
6. php artisan migrate     → Database changes
7. php artisan optimize:clear → Clear ALL caches
8. php artisan optimize    → Rebuild caches
9. [Service restarts]      → Queue, Horizon, Reverb, etc.
```

**Why this order:**
- Stash before pull prevents merge conflicts
- Composer before npm because PHP may generate assets npm needs
- npm install before build because build needs all packages
- Build before migrate because sometimes migrations reference frontend
- Clear before optimize to ensure fresh cache state
- Service restarts LAST because they need the new code + cache

---

## Monitoring Commands

```bash
# Watch deploy log live
tail -f storage/logs/auto-deploy.log

# Check last 50 lines
tail -50 storage/logs/deploy.log

# Check if cron is running
crontab -l

# Check last deploy time
grep "Deploy completed" storage/logs/auto-deploy.log | tail -1

# Check current commit on server
cd [PROJECT_DIR] && git log --oneline -1

# Compare with remote
cd [PROJECT_DIR] && git fetch && git log HEAD..origin/main --oneline

# Stop auto-deploy
crontab -e   # Remove the auto-deploy line

# Force manual deploy
bash [PROJECT_DIR]/deploy-pull.sh
```

---

## How to Use

**Set up deployment for a new project:**
```
Set up deployment scripts for my project at /home/user/htdocs/myapp.com
Logs should go to /home/user/logs
```

**Set up with extras:**
```
Set up deployment for /var/www/myapp with Filament, queues, and Horizon.
Log to /var/log/myapp
```

**Fix a failed deploy:**
```
My auto-deploy failed. Check the log and fix the issue.
```

**Add deploy to existing project:**
```
Add deploy-pull.sh and auto-deploy.sh to this project.
My server path is /home/user/htdocs/example.com
```

**Switch from polling to webhook:**
```
Replace the cron-based auto-deploy with a GitHub webhook.
```

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [olakunlevpn](https://github.com/olakunlevpn)
- **Source:** [olakunlevpn/olakunlevpn-deployment-skills](https://github.com/olakunlevpn/olakunlevpn-deployment-skills)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-olakunlevpn-olakunlevpn-deployment-skills-olakunlevpn-deployment-skills
- Seller: https://agentstack.voostack.com/s/olakunlevpn
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
