Sentiment-Analysis / .github /workflows /mlops_pipeline.yaml
Faffio's picture
Creazione Appunti del progetto
2539bae
name: MLOps CI Pipeline
# 1. TRIGGER: Quando deve partire questa pipeline?
# Parte su ogni "push" sul ramo main e su ogni "pull request"
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
# Appena attivato il trigger, viene avviato build docker sotto (job2) che richieste l'esecuzione di run_test(job1), se ok parte la creazione dell'immagine docker
jobs:
# JOB 1: Esecuzione dei Test Automatici
run_tests:
runs-on: ubuntu-latest # Usa una macchina Linux di GitHub
steps:
# A. Scarica il codice dalla tua repository
- name: Checkout code
uses: actions/checkout@v3 # serve proprio a dire al robot di GitHub: "Scarica la versione del codice contenuta in questo specifico commit che ha appena fatto scattare il trigger".
# Dobbiamo testare sui nuovi file che stiamo pushando, per questo ci assicuriamo di farlo con i nuovi file
# B. Installa Python 3.9 (lo stesso del Dockerfile)
- name: Set up Python 3.9
uses: actions/setup-python@v4
with:
python-version: "3.9"
cache: 'pip' # <--- FONDAMENTALE: Cacha le librerie (così non riscarica le dipendenze ogni volta)
# C. Installa le librerie
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Continuous Training (Simulation)
run: |
# Eseguiamo lo script che controlla i dati e simula il training
python src/train.py
# D. Lancia Pytest
- name: Run Tests
run: |
python -m pytest
# JOB 2: Verifica della Build Docker
# Questo job parte SOLO se "run_tests" ha successo (needs: run_tests)
build_and_push_docker:
needs: run_tests
runs-on: ubuntu-latest
# Importante: Eseguiamo il push solo se siamo sul ramo 'main'
# (non vogliamo pushare immagini di test da altri rami)
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
steps:
- name: Checkout code
uses: actions/checkout@v3
# 1. Login su Docker Hub (usa i segreti che hai appena creato)
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
# 2. Build e Push vero e proprio
- name: Build and Push
run: |
# Usa la variabile ${{ secrets.DOCKER_USERNAME }} creata nel repository
IMAGE_TAG=${{ secrets.DOCKER_USERNAME }}/reputation-monitor:latest
echo "Building image: $IMAGE_TAG"
docker build -t $IMAGE_TAG . # Il punto finale indica di usare il Dockerfile nella root della repo, cioè il punto sta a significare "cartella corrente" e va a cercare in automatico il Dockerfile
echo "Pushing image to Docker Hub..."
docker push $IMAGE_TAG
# JOB 3: Push su Hugging Face
deploy_to_huggingface:
needs: run_tests # Parte solo se i test passano
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
lfs: true
- name: Push to Hub
env:
HF_TOKEN: ${{ secrets.HF_TOKEN }} # Ho creato un token write su HuggingFace che viene utilizzato qui per pushare
# Sostituisci col nome del tuo utente HF e del tuo space
HF_USERNAME: Faffio # Nome utente
SPACE_NAME: Sentiment-Analysis # Nome dello space che ho creato nel mio account
run: |
# Uso --force per imporre l'aggiornamento di GitHub su Hugging face ignorando la storia di quello che c'è all'interno di Hugging face (se ne frega di quello che c'è dentro, cancella e riaggiorna)
git push --force https://$HF_USERNAME:$HF_TOKEN@huggingface.co/spaces/$HF_USERNAME/$SPACE_NAME main
# I file vengono salvati nella repository PRIMA che il test parta. È il fatto che tu abbia "pushato" i file che sveglia il robot e gli fa iniziare il lavoro.
# Ecco la sequenza temporale esatta:
# ⏳ La Timeline Reale
# Tu fai git push: I tuoi file vengono caricati su GitHub. In questo istante, il codice nella repository è già aggiornato (anche se fosse rotto).
# GitHub vede il cambiamento: "Ehi, è arrivato nuovo codice! Devo lanciare la pipeline".
# Parte la CI (Test & Build): GitHub scarica quel codice appena caricato ed esegue i test e la build Docker.
# Esito:
# 🟢 Se passa: Accanto al tuo commit compare una spunta verde. Tutto bene.
# 🔴 Se fallisce: Accanto al tuo commit compare una croce rossa. MA i file restano lì. GitHub non cancella il tuo codice se il test fallisce; ti avvisa solo che è "bacato".
# Se il codice rotto viene caricato comunque, a che serve il test?
# Professionalmente si crea un ramo diverso della repository, un nuovo branch che non va in produzione, e si pusha li facendo partire CI/CD. POi se tutto ok viene anche aggiornato il main che è sacro
# Aggiunta anche una funzione per Pushare il docker container in Hugging Face su uno space creato sul mio account, ho creato il token, lo space e modificato il file readme mettendo codice yaml all'inizio per Hugging face