Differences

This shows you the differences between two versions of the page.

Link to this comparison view

ss:laboratoare:04 [2025/02/20 16:30]
127.0.0.1 external edit
ss:laboratoare:04 [2026/03/23 18:50] (current)
ciprian.popescu0411 [Partea 4: Protejarea branch-ului ''main'']
Line 1: Line 1:
-===== Laboratorul 04. =====+====== Laborator 4: Implementarea unui pipeline CI/CD pentru un proiect embedded ======
  
 +În laboratorul anterior am configurat mediul de lucru și am testat comunicarea între ESP32-CAM și clientul Python. În acest laborator vom automatiza procesul de verificare a codului folosind un pipeline **CI/CD (Continuous Integration / Continuous Delivery)** cu **GitHub Actions**.
  
 +===== Obiective =====
 +
 +  - Înțelegerea conceptelor de CI/CD și a avantajelor lor în proiecte embedded.
 +  - Configurarea unui repository GitHub pentru proiect.
 +  - Crearea unui workflow GitHub Actions care:
 +    * Compilează firmware-ul ESP32 automat la fiecare push.
 +    * Verifică codul Python cu linting și analiză de securitate.
 +    * Rulează analiza statică pe codul C++ al firmware-ului.
 +  - Salvarea artifactului ''​firmware.bin''​ pentru deployment.
 +
 +===== De ce CI/CD pentru embedded? =====
 +
 +Într-un proiect clasic de software, CI/CD este standard. Dar și în embedded este esențial:
 +
 +  * **Preveniți "it compiles on my machine"​** — compilarea se face într-un mediu curat, reproductibil.
 +  * **Detectare timpurie** — o eroare de compilare sau un warning critic este prins automat, înainte de upload pe dispozitiv.
 +  * **Artefacte de release** — fișierul ''​firmware.bin''​ este generat automat și poate fi distribuit fără ca cineva să aibă PlatformIO instalat.
 +
 +===== Partea 1: Pregătirea repository-ului de GitHub =====
 +
 +==== 1.1 Inițializare Git ====
 +
 +Dacă proiectul nu este deja într-un repository git:
 +
 +<code bash>
 +cd /​path/​to/​proiect
 +git init
 +</​code>​
 +
 +==== 1.2 Crearea fișierului ''​.gitignore''​ ====
 +
 +Asigurați-vă că fișierul ''​.gitignore''​ generat de PlatformIO exclude fișierele generate și mediile virtuale:
 +
 +<​code>​
 +# PlatformIO
 +.pio/
 +
 +# Python
 +.venv/
 +__pycache__/​
 +*.pyc
 +
 +# IDE
 +.vscode/
 +.idea/
 +
 +# OS
 +.DS_Store
 +Thumbs.db
 +</​code>​
 +
 +==== 1.3 Push pe GitHub ====
 +
 +Creați un repository nou pe GitHub (fără README), apoi:
 +
 +<code bash>
 +git add .
 +git commit -m "​Initial commit"​
 +git branch -M main
 +git remote add origin https://​github.com/​UTILIZATOR/​NUMELE-REPO.git
 +git push -u origin main
 +</​code>​
 +
 +<​note>​
 +Înlocuiți ''​UTILIZATOR''​ cu username-ul vostru GitHub și ''​NUMELE-REPO''​ cu numele repository-ului creat.
 +</​note>​
 +
 +===== Partea 2: Crearea workflow-ului CI =====
 +
 +Workflow-urile GitHub Actions sunt definite ca fișiere YAML în directorul ''​.github/​workflows/''​.
 +
 +==== 2.1 Structura fișierului ====
 +
 +Creați fișierul ''​.github/​workflows/​ci.yml'':​
 +
 +<file yaml ci.yml>
 +name: ESP32-CAM CI Pipeline
 +
 +# Declanșare la push sau pull request pe branch-ul main
 +on:
 +  push:
 +    branches: [ "​main"​ ]
 +  pull_request:​
 +    branches: [ "​main"​ ]
 +
 +jobs:
 +  # =============================================
 +  # Job 1: Compilarea firmware-ului ESP32
 +  # =============================================
 +  build-firmware:​
 +    name: Build ESP32 Firmware
 +    runs-on: ubuntu-latest
 +
 +    steps:
 +      - name: Checkout code
 +        uses: actions/​checkout@v4
 +
 +      - name: Set up Python
 +        uses: actions/​setup-python@v5
 +        with:
 +          python-version:​ '​3.12'​
 +
 +      - name: Install PlatformIO
 +        run: pip install platformio
 +
 +      - name: Build Firmware (ESP32-CAM AI-Thinker)
 +        run: pio run -e esp32cam
 +
 +      # Salvăm firmware.bin ca artifact descărcabil
 +      - name: Upload Firmware Artifact
 +        uses: actions/​upload-artifact@v4
 +        with:
 +          name: firmware-esp32cam
 +          path: .pio/​build/​esp32cam/​firmware.bin
 +
 +  # =============================================
 +  # Job 2: Analiza statică C++ (Firmware)
 +  # =============================================
 +  analyze-firmware:​
 +    name: Static Analysis (C++)
 +    runs-on: ubuntu-latest
 +
 +    steps:
 +      - name: Checkout code
 +        uses: actions/​checkout@v4
 +
 +      - name: Install Cppcheck
 +        run: sudo apt-get install -y cppcheck
 +
 +      - name: Run Cppcheck
 +        run: |
 +          cppcheck --enable=all \
 +                   ​--inconclusive \
 +                   ​--std=c++11 \
 +                   -I include/ \
 +                   ​--suppress=missingIncludeSystem \
 +                   ​--suppress=missingInclude \
 +                   ​--suppress=unusedFunction \
 +                   ​--suppress=cstyleCast \
 +                   ​--error-exitcode=1 \
 +                   src/
 +
 +  # =============================================
 +  # Job 3: Verificarea codului Python (Receiver)
 +  # =============================================
 +  check-python:​
 +    name: Python Lint & Security
 +    runs-on: ubuntu-latest
 +
 +    steps:
 +      - name: Checkout code
 +        uses: actions/​checkout@v4
 +
 +      - name: Set up Python
 +        uses: actions/​setup-python@v5
 +        with:
 +          python-version:​ '​3.12'​
 +
 +      - name: Install dependencies
 +        run: |
 +          pip install pylint bandit
 +          # opencv-python-headless se folosește în CI (fără display)
 +          pip install paho-mqtt opencv-python-headless numpy
 +
 +      - name: Lint with Pylint
 +        # || true = soft-fail, pipeline-ul nu eșuează pe warning-uri pylint
 +        run: pylint --disable=C0114,​C0115,​C0116,​C0103 receiver.py || true
 +
 +      - name: Security scan with Bandit
 +        run: bandit receiver.py -ll
 +</​file>​
 +
 +==== 2.2 Explicarea workflow-ului ====
 +
 +Acest workflow definește **3 job-uri independente** care rulează în paralel:
 +
 +^ Job ^ Ce face ^ Când eșuează ^
 +| ''​build-firmware''​ | Compilează codul ESP32 cu PlatformIO | Erori de compilare (sintaxă, linkare) |
 +| ''​analyze-firmware''​ | Rulează ''​cppcheck''​ pe codul C++ | Buffer overflows, memory leaks, variabile neinițializate |
 +| ''​check-python''​ | Rulează ''​pylint''​ + ''​bandit''​ pe receiver | Probleme de stil, parole hardcodate, funcții nesigure |
 +
 +<code text>
 +  push/PR
 +    │
 +    ├──► build-firmware ──► firmware.bin (artifact)
 +    │
 +    ├──► analyze-firmware ──► raport cppcheck
 +    │
 +    └──► check-python ──► raport pylint + bandit
 +</​code>​
 +
 +===== Partea 3: Testarea pipeline-ului =====
 +
 +==== 3.1 Commit și push ====
 +
 +<code bash>
 +git add .github/​workflows/​ci.yml
 +git commit -m "Add CI pipeline"​
 +git push
 +</​code>​
 +
 +==== 3.2 Verificare pe GitHub ====
 +
 +  - Deschideți repository-ul pe GitHub.
 +  - Navigați la tab-ul **Actions**.
 +  - Ar trebui să vedeți workflow-ul ''​ESP32-CAM CI Pipeline''​ rulând.
 +  - Faceți clic pe el pentru a vedea detaliile fiecărui job.
 +
 +==== 3.3 Descărcarea firmware-ului ====
 +
 +Dacă build-ul reușește:
 +
 +  - Deschideți run-ul din Actions.
 +  - La secțiunea **Artifacts**,​ veți vedea ''​firmware-esp32cam''​.
 +  - Descărcați-l — conține ''​firmware.bin''​ gata de upload pe dispozitiv.
 +
 +<note tip>
 +După descărcare,​ puteți flash-ui direct pe ESP32-CAM folosind ''​esptool''​ **fără a avea PlatformIO instalat**:
 +
 +<code bash>
 +pip install esptool
 +esptool.py --chip esp32 --port /​dev/​ttyUSB0 --baud 460800 write_flash 0x10000 firmware.bin
 +</​code>​
 +
 +Pe Windows, înlocuiți ''/​dev/​ttyUSB0''​ cu portul COM corespunzător (ex: ''​COM3''​).
 +
 +Acest lucru este util pentru distribuirea firmware-ului către colegi sau pentru deployment pe dispozitive fără a recompila codul sursă.
 +</​note>​
 +
 +===== Partea 4: Protejarea branch-ului ''​main''​ =====
 +
 +Pentru a preveni merge-ul codului care nu trece CI-ul:
 +
 +  - Pe GitHub: **Settings → Rules → Rulesets → New ruleset → New branch ruleset**.
 +  - La **Target branches** adăugați branch-ul ''​main''​.
 +  - Activați **Require status checks to pass** și adăugați cele 3 job-uri: ''​Build ESP32 Firmware'',​ ''​Static Analysis (C++)'',​ ''​Python Lint & Security''​.
 +  - Salvați ruleset-ul.
 +
 +<note important>​
 +Interfața GitHub se poate schimba. Pe unele repository-uri mai vechi, opțiunea se găsește la **Settings → Branches → Add rule**.
 +</​note>​
 +
 +De acum, nimeni nu poate face merge pe ''​main''​ dacă pipeline-ul eșuează.
 +
 +===== Exerciții =====
 +
 +  - **Provocați un eșec**: Introduceți intenționat o eroare de compilare în ''​main.cpp''​ (ex: ștergeți un '';''​),​ faceți push pe un branch separat și creați un Pull Request. Observați cum pipeline-ul blochează merge-ul.
 +
 +  - **Adăugați un job de test**: Creați un job nou în workflow care rulează un test simplu Python — de exemplu, verificați că ''​receiver.py''​ poate fi parsat fără erori de sintaxă:
 +
 +<code yaml>
 +- name: Smoke test
 +  run: python -m py_compile receiver.py
 +</​code>​
 +
 +  - **Release automat**: Adăugați un pas care creează un GitHub Release cu ''​firmware.bin''​ atașat, doar când se face push pe un tag (ex: ''​v1.0''​). Hint: folosiți ''​if:​ startsWith(github.ref,​ '​refs/​tags/'​)''​ și action-ul ''​softprops/​action-gh-release''​.
ss/laboratoare/04.1740061822.txt.gz · Last modified: 2025/02/26 00:06 (external edit)
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0