[PYTHON] Informationen zu CI / CD in der Umgebung von Chalice x Circle CI

Vorwort

https://chalice.readthedocs.io/en/latest/

AWS Chalice ist ein Framework, mit dem Sie eine Serverless-Umgebung so einfach wie Heroku erstellen können, indem Sie AWS Lambda und API Gateway kombinieren. Derzeit wird nur Python als Entwicklungssprache unterstützt (es ist nicht bekannt, ob es in Zukunft unterstützt wird). Wenn Sie jedoch die Einschränkungen akzeptieren, wird anscheinend eine Umgebung bereitgestellt, die einfacher und einfacher zu entwickeln ist als andere serverlose Frameworks Ich denke. Selbst in meiner Umgebung verwende ich Chalice häufig, um eine ziemlich breite Palette von Prozessen zu entwickeln, z. B. das Erstellen einfacher APIs, Batches und Cron-Prozesse.

Ich werde in diesem Artikel nicht erklären, was Sie mit Kelch tun können.

Und da Herr Sutajio einen Artikel über den Test geschrieben hat (https://qiita.com/studio3104/items/8a6b7e5f696e8453d97a), welche ist die CI / CD-Umgebung für die Entwicklung mit Chalice? Ich möchte einen Artikel schreiben, der auf meinem eigenen Beispiel basiert. Hier wird als CI-Umgebung "Circle CI" verwendet.

Es gibt mehrere Themen, aber hier werden die folgenden Themen beschrieben.

--monorepo kompatibel

Unterstützt Monorepo (Differenzprüfung für jedes Projekt)

Kelch ist ein Stil, bei dem für jede Funktion, die Sie erstellen möchten, ein Projektgerüst in Form von "Kelch neues Projekt sada" erstellt und entwickelt wird. Wenn Sie für jedes Projekt ein Repository wie GitHub erstellen, wird es fragmentierter. Ich hätte gerne eine Monorepo-Konfiguration, aber wenn ich einfach mehrere Projekte in einem Repository ablege, können alle Projekte getestet, verifiziert und bereitgestellt werden, wenn einige Projekte während CI / CD geändert werden. Es neigt dazu zu laufen und verlangsamt die CI / CD.

Als grundlegende Strategie möchte ich die Form "nur CI / CD für Projekte ausführen, die sich im GitHub-Repository geändert haben" annehmen.

Um dies zu realisieren, habe ich auf den Inhalt des folgenden Blogs verwiesen. Ein Skript, das den Inhalt des Head auf GitHub vergleicht, um festzustellen, ob es Unterschiede gibt. https://blog.hatappi.me/entry/2018/10/08/232625

$ cat tools/is_changed 
#!/bin/bash

if [ "${CIRCLE_BRANCH}" = "master" ]; then
  DIFF_TARGET="HEAD^ HEAD"
else
  DIFF_TARGET="origin/master"
fi

DIFF_FILES=(`git diff ${DIFF_TARGET} --name-only --relative=${1}`)

if [ ${#DIFF_FILES[@]} -eq 0 ]; then
  exit 1
else
  exit 0
fi

Wenn Sie ein Skript auf diese Weise vorbereiten und das Chalice-Projekt, das Sie zum Zeitpunkt von CI / CD überprüfen möchten, an das Argument des Skripts übergeben, können Sie den Unterschied für jedes Projekt überprüfen, das Projekt ohne Unterschied überspringen und nur dem mit Unterschied folgen Es ist möglich, die CI-Verarbeitung von durchzuführen.

$ cat tools/echo_changed 

for dir in ${PROJECTS}; do \
  if ${WORKDIR}/is_changed "${dir}"; then
    echo "changed."
  else
    echo "nothing change."
  fi
done

unit test / code coverage Ich denke, Herr Sutajio hat ausführlich beschrieben, wie man den Test schreibt, deshalb werde ich die Details hier weglassen.

In meiner Umgebung verwende ich eine Kombination aus "Coverage" und "Pytest". Wir führen Unittests durch und messen, wie viel Testabdeckung dadurch erreicht wird.

$ coverage run -m pytest
$ coverage report
Name                Stmts   Miss  Cover
---------------------------------------
app.py                 35     22    37%
tests/__init__.py       0      0   100%
tests/conftest.py       4      0   100%
tests/test_app.py       5      0   100%
---------------------------------------
TOTAL                  44     22    50%

Wenn Sie die Abdeckung in einer Umgebung mit einem Komponententest ausführen, können Sie einen Bericht wie den oben genannten ausgeben. Sie können den HTML-Bericht als Artefakte für Circle CI speichern und im CI-Ergebnisbildschirm anzeigen.

    - run:
        name: Run Tests
        command: |
          $HOME/.local/bin/coverage run -m pytest
          $HOME/.local/bin/coverage report
          $HOME/.local/bin/coverage html  # open htmlcov/index.html in a browser
    - store_artifacts:
        path: htmlcov

Detaillierte Einstellungen finden Sie in den folgenden offiziellen Dokumenten.

https://circleci.com/docs/2.0/code-coverage/#python

Wenn Sie den Test stoppen möchten, wenn er unter eine bestimmte Abdeckungsrate fällt, können Sie "Abdeckungsbericht - Fehlernummer [num]" ausführen und "Rückgabecode = 2" zurückgeben, wenn die Abdeckung kleiner oder gleich der Zahl ist. .. Das heißt, Sie können CI stoppen, wenn der Schwellenwert nicht erreicht wird.

Wenn Sie die Verarbeitung dieses Bereichs als Shell schreiben, ist dies wie folgt. Von allen Projekten in Monorepo wird bei Unterschieden eine Einheitentest- / Abdeckungsmessung durchgeführt. Wenn der Test fehlschlägt oder sogar eine Abdeckung unter dem Schwellenwert liegt, wird CI gestoppt.

$ cat tools/coverage 

ret=0
for dir in ${PROJECTS}; do 
  if ${WORKDIR}/is_changed "${dir}"; then
    cd ${WORKDIR}/../${dir}/ 
    sudo pip install -r requirements.txt
    coverage run -m pytest
    coverage report --fail-under=${THRESHOLD}
    r=$?
    coverage html -d ../htmlcov/${dir}
    if [ $r != 0 ]; then ret=$r; fi
  else
    echo "nothing change."
  fi
done

exit $ret

lint / code smells Zusätzlich zu Tests und Abdeckungsmessungen wird in CI / CD-Flows häufig die Tools Lint und Code Smells verwendet, um ** "schlechtes Schreiben" ** heuristisch zu identifizieren.

Ich werde auch nicht auf Details eingehen, aber in meiner Umgebung werde ich eine Kombination aus "pep8 (pycodestyle)" und "pyflakes" verwenden. Beide Tools behandeln das CI nach Bedarf als "Rückkehrcode = 1", wenn eine Anzeige vorliegt.

Das Folgende ist ein Beispielergebnis von Pyflakes, es wird jedoch darauf hingewiesen, dass die Variable "sada" deklariert, aber in den folgenden Fällen nicht verwendet wird.

$ pyflakes app.py 
app.py:32: local variable 'sada' is assigned to but never used

Wenn Sie jedoch die Standardeinstellungen vornehmen, erhalten Sie in jedem Fall Punkte, auf die sehr detailliert hingewiesen werden muss. Daher ist es eine realistische Operation, die Einstellungsdatei entsprechend der Umgebung zu beschreiben und zu ignorieren oder die Regeln entsprechend der Umgebung zu beschreiben. Ich denke.

Wenn Sie die Verarbeitung dieses Bereichs als Shell schreiben, ist dies wie folgt.

$ cat tools/lint 

ret=0
for dir in ${PROJECTS}; do 
  if ${WORKDIR}/is_changed "${dir}"; then
    cd ${WORKDIR}/../${dir}/ 
    sudo pip install -r requirements.txt
    pep8 ${WORKDIR}/../${dir}/*.py --config ${WORKDIR}/../.config/pep8 
    pyflakes ${WORKDIR}/../${dir}/*.py 
    r=$?
    if [ $r != 0 ]; then ret=$r; fi
  else
    echo "nothing change."
  fi
done

exit $ret

Validierung der Kelchkonfigurationsdatei

Mit den oben genannten Inhalten denke ich, dass allgemeines CI implementiert werden kann, aber im Fall von charice ist es notwendig, eine Einstellungsdatei ** (config.json, deploy /) ** für jede Stufe und diese Einstellung vorzubereiten Ich möchte auch die Gültigkeit der Datei überprüfen.

Der einfachste Weg, dies zu tun, besteht darin, einfach den Befehl "chalice package" auf CI / CD auszuführen und zu prüfen, ob Sie chalice ordnungsgemäß verpacken können, um die Gültigkeit der Konfigurationsdatei zu überprüfen.

$ cat tools/package 

for dir in ${PROJECTS}; do 
  if ${WORKDIR}/is_changed "${dir}"; then
    cd ${WORKDIR}/../${dir}/ 
    sudo pip install -r requirements.txt
    chalice package /tmp/${CIRCLE_SHA1}
  else
    echo "nothing change."
  fi
done

Vulnerabilitätsdiagnose

Heutzutage gibt es viele sensible Fälle in Bezug auf die Anwendungssicherheit, daher möchte ich nicht, dass der Code, der so störend wie möglich ist, in die Anwendung gelangt. Daher möchte ich jedes Mal zum CI-Zeitpunkt überprüfen, ob eine der von mir verwendeten Bibliotheken Schwachstellen enthält.

Ich denke, es gibt einige Lösungen, aber hier nutzen wir den Service eines Sicherheitsunternehmens namens ** snyk ** (https://snyk.io/).

snyk ist ein SaaS, das die Möglichkeit bietet, im Quellcode eine Schwachstellenprüfung (Schwachstellendiagnose) durchzuführen. Es unterstützt verschiedene Sprachen, aber natürlich wird auch Python verwendet, das von Chalice verwendet wird. Schauen Sie sich grundsätzlich den Inhalt von "require.txt" an, um die verwendete Bibliothek zu verstehen, und prüfen Sie, ob die Version der Bibliothek in der Schwachstellendatenbank enthalten ist.

Da es einfach ist, eine Verbindung mit GitHub herzustellen, ist es einfach, es in den CI-Flow zu integrieren. Es ist unbegrenzt für öffentliches OSS und Sie können es kostenlos bis zu 200 Tests in Ihrem privaten Repository verwenden. https://snyk.io/plans/

Anstatt die Definition in circle.yml zu schreiben, besteht snyk aus einer Verknüpfung mit GitHub. Ich überlasse die detaillierte Einstellmethode usw. dem offiziellen Dokument. https://snyk.io/docs/github/

auto deploy Zum Schluss noch zum CD-Teil von CI / CD. Da Kelch einfach mit einem Befehl wie "Kelchbereitstellung" bereitgestellt werden kann, ist es einfach, automatisch eine Quelle bereitzustellen, die aufgrund von CI keine Probleme aufweist.

Das Folgende ist der Prozess der "Kelchbereitstellung" auf den neuesten Stand nur für Projekte mit Unterschieden, die in der Shell geschrieben sind.

$ cat tools/deploy 

for dir in ${PROJECTS}; do \
  echo "${WORKDIR}/../${dir}/"
  if ${WORKDIR}/is_changed "${dir}"; then
    cd ${WORKDIR}/../${dir}/
    sudo pip install -r requirements.txt
    AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} chalice deploy --stage ${STAGE}
  else 
    echo "nothing change."
  fi
done

Ich denke, es ist umstritten, ob CI-Tools für die automatische Bereitstellung in Produktionsumgebungen verwendet werden sollen. (In meiner Umgebung führe ich keine automatische Bereitstellung in der Produktionsumgebung durch, sondern häufig nur in der Verifizierungsumgebung.)

Anstatt zusammenzufassen

AWS Chalice ist ein Framework, mit dem Sie problemlos serverlose Verarbeitung in Form von Heroku schreiben können, obwohl es auf Python beschränkt ist. Ich denke, es hat den Vorteil, dass es Lambda-Verarbeitung wie eine normale Anwendung schreiben kann. Aufgrund seiner Vorteile ist es auch in einer Umgebung ohne Server wie Lambda einfach, es wie oben beschrieben in den CI / CD-Fluss zu integrieren.

Also lasst uns alle auch Kelch benutzen. Happy Chalice Life and Serverless Life!!

Recommended Posts

Informationen zu CI / CD in der Umgebung von Chalice x Circle CI
Denken Sie daran, eine Python 3-Umgebung in einer Mac-Umgebung zu erstellen
Installieren Sie LightGBM in einer virtuellen OSX-Umgebung