Spaces:
Sleeping
Sleeping
| 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 |