@@ -0,0 +1,217 @@
|
||||
# RPA Dashboard — Autodeploy con Woodpecker CI
|
||||
|
||||
## Panoramica
|
||||
|
||||
Il deploy avviene automaticamente tramite **Woodpecker CI** collegato a **Gitea**.
|
||||
Non serve nessun intervento manuale: basta taggare un commit con `test` o `prod`.
|
||||
|
||||
La pipeline è suddivisa in tre file indipendenti in `.woodpecker/`:
|
||||
|
||||
| File | Trigger | Cosa fa |
|
||||
|---|---|---|
|
||||
| `ci.yml` | ogni push / PR / tag | lint + syntax check |
|
||||
| `deploy-test.yml` | tag `test` | build + deploy su VM Linux (Docker + Traefik) |
|
||||
| `deploy-prod.yml` | tag `prod` | build + deploy su VM Windows (SSH, senza Docker) |
|
||||
|
||||
---
|
||||
|
||||
## Flusso
|
||||
|
||||
```
|
||||
push / PR → ci.yml: lint + syntax
|
||||
|
||||
tag test → ci.yml: lint + syntax
|
||||
deploy-test.yml: build → deploy Docker Linux
|
||||
└─ estrae i file su /ATG_RUN_TEST/Dashboard
|
||||
└─ riavvia il container Docker
|
||||
└─ dashboard live su https://dashboard.57.131.52.95.nip.io
|
||||
|
||||
tag prod → ci.yml: lint + syntax
|
||||
deploy-prod.yml: build → deploy Windows SSH
|
||||
└─ copia zip su C:/ATG_RUN/Dashboard (SCP)
|
||||
└─ riavvia il Windows Service "rpa-dashboard"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Pubblicare una nuova versione
|
||||
|
||||
### Deploy su Linux — tag `test`
|
||||
|
||||
```bash
|
||||
# 1. Commit delle modifiche
|
||||
git add .
|
||||
git commit -m "descrizione modifica"
|
||||
|
||||
# 2. Spostare il tag test sul commit corrente e pubblicare
|
||||
git tag -f test
|
||||
git push --force --tags
|
||||
```
|
||||
|
||||
### Deploy su Windows — tag `prod`
|
||||
|
||||
```bash
|
||||
# 1. Commit delle modifiche
|
||||
git add .
|
||||
git commit -m "descrizione modifica"
|
||||
|
||||
# 2. Spostare il tag prod sul commit corrente e pubblicare
|
||||
git tag -f prod
|
||||
git push --force --tags
|
||||
```
|
||||
|
||||
Woodpecker riceve il webhook da Gitea e avvia la pipeline in automatico.
|
||||
|
||||
### Manuale — dal pannello Woodpecker
|
||||
|
||||
Apri la pipeline su Woodpecker UI → pulsante **"trigger manually"**.
|
||||
Esegue build + deploy senza bisogno di taggare (utile per fix rapidi).
|
||||
|
||||
---
|
||||
|
||||
## Step della pipeline
|
||||
|
||||
### `ci.yml` — Lint + Syntax (ogni push/PR/tag)
|
||||
|
||||
| Step | Cosa fa |
|
||||
|---|---|
|
||||
| `lint` | flake8 — controlla stile e errori Python |
|
||||
| `syntax` | `py_compile` su tutti i `.py` |
|
||||
|
||||
### `deploy-test.yml` — Linux Docker (tag `test`)
|
||||
|
||||
| Step | Cosa fa |
|
||||
|---|---|
|
||||
| `build` | crea `rpa-tdi-dashboard-prod.zip` (esclude `.env`, `__pycache__`, `*.md`, ecc.) |
|
||||
| `deploy` | estrae lo zip in `/ATG_RUN_TEST/Dashboard`, riavvia il container Docker |
|
||||
|
||||
### `deploy-prod.yml` — Windows SSH (tag `prod`)
|
||||
|
||||
| Step | Cosa fa |
|
||||
|---|---|
|
||||
| `build` | crea `rpa-tdi-dashboard-prod.zip` (stesso del test) |
|
||||
| `deploy` | copia zip via SCP, estrae con PowerShell, riavvia il Service `rpa-dashboard` |
|
||||
|
||||
---
|
||||
|
||||
## Infrastruttura
|
||||
|
||||
### Linux (test)
|
||||
|
||||
| Componente | Dettaglio |
|
||||
|---|---|
|
||||
| VM | `57.131.52.95` |
|
||||
| URL dashboard | `https://dashboard.57.131.52.95.nip.io` |
|
||||
| Cartella deploy | `/ATG_RUN_TEST/Dashboard` |
|
||||
| Cartella DB | `/ATG_RUN_TEST/db` |
|
||||
| Container | `rpa-dashboard-test` |
|
||||
| Rete | `traefik_public` |
|
||||
|
||||
### Windows (prod)
|
||||
|
||||
| Componente | Dettaglio |
|
||||
|---|---|
|
||||
| VM | configurata via secret `win_host` |
|
||||
| Utente SSH | configurato via secret `win_user` |
|
||||
| Cartella deploy | `C:/ATG_RUN/Dashboard` |
|
||||
| Windows Service | `rpa-dashboard` (gestito con NSSM) |
|
||||
|
||||
### CI
|
||||
|
||||
| Componente | Dettaglio |
|
||||
|---|---|
|
||||
| Forge | Gitea (self-hosted) |
|
||||
| CI | Woodpecker CI — Ubuntu cloud + Docker |
|
||||
| Immagine Python | `python:3.14` |
|
||||
|
||||
---
|
||||
|
||||
## Secrets richiesti in Woodpecker
|
||||
|
||||
Configurare in **Woodpecker UI → Settings → Secrets**:
|
||||
|
||||
| Secret | Valore |
|
||||
|---|---|
|
||||
| `win_host` | IP o hostname della VM Windows |
|
||||
| `win_user` | utente SSH (es. `Administrator`) |
|
||||
| `win_ssh_key` | chiave privata SSH (contenuto del file `id_rsa`) |
|
||||
|
||||
---
|
||||
|
||||
## Prerequisiti — VM Linux (setup iniziale, una tantum)
|
||||
|
||||
```bash
|
||||
# Creare le cartelle
|
||||
mkdir -p /ATG_RUN_TEST/Dashboard
|
||||
mkdir -p /ATG_RUN_TEST/db
|
||||
|
||||
# Creare il .env
|
||||
cat > /ATG_RUN_TEST/Dashboard/.env <<EOF
|
||||
LOGIN=true
|
||||
DASHBOARD_USER=TDI_admin
|
||||
DASHBOARD_PASSWORD=Dashboard_TDI_26!
|
||||
RPA_REPORT_PORT=8473
|
||||
EOF
|
||||
|
||||
# Copiare i file .db nella cartella db
|
||||
# es. cp rpa_FORMAZIONE.db /ATG_RUN_TEST/db/
|
||||
```
|
||||
|
||||
Abilitare i volume mounts nel Woodpecker runner:
|
||||
|
||||
```env
|
||||
WOODPECKER_BACKEND_DOCKER_VOLUMES=true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Prerequisiti — VM Windows (setup iniziale, una tantum)
|
||||
|
||||
```powershell
|
||||
# 1. Abilitare OpenSSH Server
|
||||
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
|
||||
Start-Service sshd
|
||||
Set-Service -Name sshd -StartupType Automatic
|
||||
|
||||
# 2. Creare le cartelle
|
||||
New-Item -ItemType Directory -Force -Path C:/ATG_RUN/Dashboard
|
||||
New-Item -ItemType Directory -Force -Path C:/ATG_RUN/db
|
||||
|
||||
# 3. Creare il .env
|
||||
Set-Content C:/ATG_RUN/Dashboard/.env "LOGIN=true`nDASHBOARD_USER=TDI_admin`nDASHBOARD_PASSWORD=Dashboard_TDI_26!`nRPA_REPORT_PORT=8473"
|
||||
|
||||
# 4. Installare NSSM e creare il Windows Service
|
||||
# Scaricare NSSM da https://nssm.cc
|
||||
nssm install rpa-dashboard python C:/ATG_RUN/Dashboard/Dashboard.py
|
||||
nssm set rpa-dashboard AppDirectory C:/ATG_RUN/Dashboard
|
||||
nssm start rpa-dashboard
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Verifica deploy
|
||||
|
||||
### Linux
|
||||
|
||||
```bash
|
||||
# Stato del container
|
||||
docker ps | grep rpa-dashboard-test
|
||||
|
||||
# Log in tempo reale
|
||||
docker logs -f rpa-dashboard-test
|
||||
|
||||
# Riavvio manuale
|
||||
docker restart rpa-dashboard-test
|
||||
```
|
||||
|
||||
Dashboard: `https://dashboard.57.131.52.95.nip.io`
|
||||
|
||||
### Windows
|
||||
|
||||
```powershell
|
||||
# Stato del service
|
||||
Get-Service rpa-dashboard
|
||||
|
||||
# Riavvio manuale
|
||||
Restart-Service rpa-dashboard
|
||||
```
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
# ci.yml — Lint + Syntax check
|
||||
# Eseguito su ogni push, PR, tag e manual
|
||||
|
||||
when:
|
||||
event: [push, pull_request, tag, manual]
|
||||
|
||||
steps:
|
||||
- name: lint
|
||||
image: python:3.14
|
||||
commands:
|
||||
- pip install --upgrade pip --quiet
|
||||
- pip install flake8 --quiet
|
||||
- flake8 . --max-line-length=120 --exclude=__pycache__
|
||||
|
||||
- name: syntax
|
||||
image: python:3.14
|
||||
depends_on: [lint]
|
||||
commands:
|
||||
- pip install --upgrade pip --quiet
|
||||
- pip install python-dotenv --quiet
|
||||
- python -m compileall -q .
|
||||
@@ -0,0 +1,83 @@
|
||||
---
|
||||
# deploy-prod.yml — Build + Deploy su VM Windows remota (SSH, senza Docker)
|
||||
#
|
||||
# Trigger: git tag prod && git push --force --tags
|
||||
#
|
||||
# Prerequisiti sulla VM Windows:
|
||||
# - OpenSSH Server abilitato
|
||||
# - Windows Service "rpa-dashboard" creato con NSSM
|
||||
# - C:/ATG_RUN/Dashboard/.env → già presente
|
||||
#
|
||||
# Secrets richiesti in Woodpecker:
|
||||
# win_host → IP o hostname della VM Windows
|
||||
# win_user → utente SSH (es. Administrator)
|
||||
# win_ssh_key → chiave privata SSH (contenuto id_rsa)
|
||||
|
||||
when:
|
||||
event: [tag, manual]
|
||||
tag: prod
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: python:3.14
|
||||
commands:
|
||||
- apt-get update -qq && apt-get install -y zip --quiet
|
||||
- pip install --upgrade pip --quiet
|
||||
- pip install python-dotenv rcssmin rjsmin --quiet
|
||||
- |
|
||||
python - <<'EOF'
|
||||
import os, zipfile, fnmatch
|
||||
|
||||
EXCLUDE_FILES = ["tmp_*", "*.md"]
|
||||
EXCLUDE_DIRS = {".git", "__pycache__", "data", "tests", "docs", "secrets"}
|
||||
EXCLUDE_EXACTLY = {".env"}
|
||||
OUT = "rpa-tdi-dashboard-prod.zip"
|
||||
|
||||
def is_excluded(rel):
|
||||
parts = rel.replace(os.sep, "/").split("/")
|
||||
if parts[0] in EXCLUDE_DIRS:
|
||||
return True
|
||||
name = parts[-1]
|
||||
if name in EXCLUDE_EXACTLY:
|
||||
return True
|
||||
for pat in EXCLUDE_FILES:
|
||||
if fnmatch.fnmatch(name, pat):
|
||||
return True
|
||||
return False
|
||||
|
||||
with zipfile.ZipFile(OUT, "w", zipfile.ZIP_DEFLATED) as zf:
|
||||
for root, dirs, files in os.walk("."):
|
||||
dirs[:] = [d for d in dirs if d not in EXCLUDE_DIRS and not d.startswith(".")]
|
||||
for f in files:
|
||||
path = os.path.join(root, f)
|
||||
rel = os.path.relpath(path, ".")
|
||||
if not is_excluded(rel):
|
||||
zf.write(path, rel)
|
||||
print(f" + {rel}")
|
||||
print(f"\n✓ {OUT}")
|
||||
EOF
|
||||
- ls -lh rpa-tdi-dashboard-prod.zip
|
||||
|
||||
- name: deploy
|
||||
image: alpine
|
||||
depends_on: [build]
|
||||
environment:
|
||||
WIN_HOST:
|
||||
from_secret: win_host
|
||||
WIN_USER:
|
||||
from_secret: win_user
|
||||
WIN_KEY:
|
||||
from_secret: win_ssh_key
|
||||
commands:
|
||||
- apk add --no-cache openssh-client --quiet
|
||||
- mkdir -p ~/.ssh
|
||||
- echo "$WIN_KEY" > ~/.ssh/id_rsa
|
||||
- chmod 600 ~/.ssh/id_rsa
|
||||
- scp -o StrictHostKeyChecking=no rpa-tdi-dashboard-prod.zip $WIN_USER@$WIN_HOST:"C:/ATG_RUN/Dashboard/"
|
||||
- ssh -o StrictHostKeyChecking=no $WIN_USER@$WIN_HOST
|
||||
"powershell -Command Stop-Service rpa-dashboard -ErrorAction SilentlyContinue"
|
||||
- ssh $WIN_USER@$WIN_HOST
|
||||
"powershell -Command Expand-Archive -Force C:/ATG_RUN/Dashboard/rpa-tdi-dashboard-prod.zip C:/ATG_RUN/Dashboard/"
|
||||
- ssh $WIN_USER@$WIN_HOST
|
||||
"powershell -Command Start-Service rpa-dashboard"
|
||||
- echo "✓ Deploy completato su Windows ($WIN_HOST)"
|
||||
@@ -1,42 +1,23 @@
|
||||
---
|
||||
# .woodpecker.yml — RPA TDI Dashboard Service
|
||||
# Forge: Gitea — Runner: Ubuntu cloud + Docker
|
||||
# deploy-test.yml — Build + Deploy su VM Linux (Docker + Traefik)
|
||||
#
|
||||
# Flusso:
|
||||
# push / PR → lint + syntax
|
||||
# tag prod → lint + syntax + build + deploy (automatico)
|
||||
# Trigger: git tag test && git push --force --tags
|
||||
#
|
||||
# Per pubblicare:
|
||||
# git tag prod && git push --tags
|
||||
# Prerequisiti sulla VM Linux:
|
||||
# - /ATG_RUN_TEST/Dashboard/.env → già presente
|
||||
# - Woodpecker runner con volumes abilitati (WOODPECKER_BACKEND_DOCKER_VOLUMES=true)
|
||||
# - Traefik in esecuzione sulla rete "traefik_public"
|
||||
|
||||
when:
|
||||
event: [push, pull_request, tag, manual]
|
||||
event: [tag, manual]
|
||||
tag: test
|
||||
|
||||
steps:
|
||||
- name: lint
|
||||
image: python:3.12-slim
|
||||
when:
|
||||
event: [push, pull_request, tag, manual]
|
||||
commands:
|
||||
- pip install flake8 --quiet
|
||||
- flake8 . --max-line-length=120 --exclude=__pycache__
|
||||
|
||||
- name: syntax
|
||||
image: python:3.12-slim
|
||||
when:
|
||||
event: [push, pull_request, tag, manual]
|
||||
depends_on: [lint]
|
||||
commands:
|
||||
- pip install python-dotenv --quiet
|
||||
- python -m compileall -q .
|
||||
|
||||
- name: build
|
||||
image: python:3.12-slim
|
||||
when:
|
||||
event: [tag, manual]
|
||||
tag: prod
|
||||
image: python:3.14
|
||||
commands:
|
||||
- apt-get update -qq && apt-get install -y zip --quiet
|
||||
- pip install --upgrade pip --quiet
|
||||
- pip install python-dotenv rcssmin rjsmin --quiet
|
||||
- |
|
||||
python - <<'EOF'
|
||||
@@ -72,14 +53,8 @@ steps:
|
||||
EOF
|
||||
- ls -lh rpa-tdi-dashboard-prod.zip
|
||||
|
||||
# Copia i file su /ATG_RUN_TEST/Dashboard e riavvia il container
|
||||
# Prerequisiti sulla VM:
|
||||
# - /ATG_RUN_TEST/Dashboard/.env → già presente con le variabili locali
|
||||
# - Woodpecker runner configurato con volumes abilitati (WOODPECKER_BACKEND_DOCKER_VOLUMES=true)
|
||||
- name: deploy
|
||||
image: docker:cli
|
||||
when:
|
||||
event: [tag, manual]
|
||||
depends_on: [build]
|
||||
volumes:
|
||||
- /ATG_RUN_TEST/Dashboard:/app
|
||||
@@ -88,16 +63,21 @@ steps:
|
||||
- apk add --no-cache unzip --quiet
|
||||
- unzip -o rpa-tdi-dashboard-prod.zip -d /app
|
||||
- echo "✓ File estratti in /ATG_RUN_TEST/Dashboard"
|
||||
- docker stop rpa-dashboard-test 2>/dev/null || true
|
||||
- docker rm rpa-dashboard-test 2>/dev/null || true
|
||||
- docker stop rpa-dashboard-test 2>/dev/null || true
|
||||
- docker rm rpa-dashboard-test 2>/dev/null || true
|
||||
- docker run -d
|
||||
--name rpa-dashboard-test
|
||||
--restart unless-stopped
|
||||
--network traefik_public
|
||||
-v /ATG_RUN_TEST/Dashboard:/app
|
||||
-v /ATG_RUN_TEST/db:/rpa-db
|
||||
-w /app
|
||||
-e RPA_DB_DIR=/rpa-db
|
||||
-p 8473:8473
|
||||
python:3.12-slim
|
||||
--label "traefik.enable=true"
|
||||
--label "traefik.http.routers.rpa-dashboard.rule=Host(`dashboard.57.131.52.95.nip.io`)"
|
||||
--label "traefik.http.routers.rpa-dashboard.entrypoints=websecure"
|
||||
--label "traefik.http.routers.rpa-dashboard.tls.certresolver=letsencrypt"
|
||||
--label "traefik.http.services.rpa-dashboard.loadbalancer.server.port=8473"
|
||||
python:3.14
|
||||
sh -c "pip install -r requirements.txt -q && python Dashboard.py"
|
||||
- echo "✓ Container avviato su http://57.131.52.95:8473"
|
||||
- echo "✓ Container avviato su https://dashboard.57.131.52.95.nip.io"
|
||||
@@ -1,111 +0,0 @@
|
||||
# RPA Dashboard — Autodeploy con Woodpecker CI
|
||||
|
||||
## Panoramica
|
||||
|
||||
Il deploy avviene automaticamente tramite **Woodpecker CI** collegato a **Gitea**.
|
||||
Non serve nessun intervento manuale: basta taggare un commit con `prod`.
|
||||
|
||||
---
|
||||
|
||||
## Flusso
|
||||
|
||||
```
|
||||
push / PR → lint + syntax check (verifica automatica ad ogni commit)
|
||||
|
||||
tag prod → lint → syntax → build → deploy
|
||||
└─ estrae i file su /ATG_RUN_TEST/Dashboard
|
||||
└─ riavvia il container Docker
|
||||
└─ dashboard live su http://57.131.52.95:8473
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Pubblicare una nuova versione
|
||||
|
||||
### Automatico — tag `prod` (raccomandato)
|
||||
|
||||
```bash
|
||||
# 1. Commit delle modifiche
|
||||
git add .
|
||||
git commit -m "descrizione modifica"
|
||||
|
||||
# 2. Spostare il tag prod sul commit corrente e pubblicare
|
||||
git tag -f prod
|
||||
git push --force --tags
|
||||
```
|
||||
|
||||
Woodpecker riceve il webhook da Gitea e avvia la pipeline in automatico.
|
||||
|
||||
### Manuale — dal pannello Woodpecker
|
||||
|
||||
Apri la pipeline su Woodpecker UI → pulsante **"trigger manually"**.
|
||||
Esegue build + deploy senza bisogno di taggare (utile per test o fix rapidi).
|
||||
|
||||
---
|
||||
|
||||
## Step della pipeline (`.woodpecker.yml`)
|
||||
|
||||
| Step | push / PR | tag `prod` | manuale | Cosa fa |
|
||||
|---|---|---|---|---|
|
||||
| `lint` | ✓ | ✓ | ✓ | flake8 — controlla stile e errori Python |
|
||||
| `syntax` | ✓ | ✓ | ✓ | `py_compile` su tutti i `.py` |
|
||||
| `build` | — | ✓ | ✓ | crea `rpa-tdi-dashboard-prod.zip` (esclude `.env`, `__pycache__`, `*.md`, ecc.) |
|
||||
| `deploy` | — | ✓ | ✓ | estrae lo zip in `/ATG_RUN_TEST/Dashboard`, riavvia il container |
|
||||
|
||||
---
|
||||
|
||||
## Infrastruttura
|
||||
|
||||
| Componente | Dettaglio |
|
||||
|---|---|
|
||||
| Forge | Gitea (self-hosted) |
|
||||
| CI | Woodpecker CI — Ubuntu cloud + Docker |
|
||||
| VM | `57.131.52.95` |
|
||||
| Porta dashboard | `8473` |
|
||||
| Cartella deploy | `/ATG_RUN_TEST/Dashboard` |
|
||||
| Cartella DB | `/ATG_RUN_TEST/db` |
|
||||
| Container | `rpa-dashboard-test` |
|
||||
|
||||
---
|
||||
|
||||
## Prerequisiti sulla VM (setup iniziale, una tantum)
|
||||
|
||||
```bash
|
||||
# Creare le cartelle
|
||||
mkdir -p /ATG_RUN_TEST/Dashboard
|
||||
mkdir -p /ATG_RUN_TEST/db
|
||||
|
||||
# Creare il .env con le variabili locali Linux
|
||||
cat > /ATG_RUN_TEST/Dashboard/.env <<EOF
|
||||
LOGIN=true
|
||||
DASHBOARD_USER=TDI_admin
|
||||
DASHBOARD_PASSWORD=Dashboard_TDI_26!
|
||||
RPA_REPORT_PORT=8473
|
||||
EOF
|
||||
|
||||
# Copiare i file .db nella cartella db
|
||||
# es. cp rpa_FORMAZIONE.db /ATG_RUN_TEST/db/
|
||||
```
|
||||
|
||||
Abilitare i volume mounts nel Woodpecker runner (nel file di config dell'agent):
|
||||
|
||||
```env
|
||||
WOODPECKER_BACKEND_DOCKER_VOLUMES=true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Verifica deploy
|
||||
|
||||
```bash
|
||||
# Stato del container
|
||||
docker ps | grep rpa-dashboard-test
|
||||
|
||||
# Log in tempo reale
|
||||
docker logs -f rpa-dashboard-test
|
||||
|
||||
# Riavvio manuale (se necessario)
|
||||
docker restart rpa-dashboard-test
|
||||
```
|
||||
|
||||
Dashboard: `http://57.131.52.95:8473/login`
|
||||
Reference in New Issue
Block a user