PYTHONPATH -VariableOffizieller Python -Verpackungshandbuch
Ein Modul in Python ist eine einzige Datei (mit einer .py -Erweiterung), die Python -Code enthält. Es besteht typischerweise aus Klassen, Funktionen und Variablen, die von anderen Python -Code verwendet werden können. Module werden verwendet, um Code in logische Einheiten zu organisieren und die Wiederverwendbarkeit von Code zu erleichtern.
Betrachten Sie beispielsweise ein Modul namens math_operations.py , das Funktionen enthält, um mathematische Operationen wie Addition, Subtraktion, Multiplikation usw. durchzuführen. Sie können diese Funktionen in anderen Python -Skripten importieren und verwenden.
# math_operations.py
def add ( x , y ):
return x + y
def subtract ( x , y ):
return x - y Ein Paket in Python ist eine Sammlung von Modulen, die in einem Verzeichnis zusammengefasst sind. Ein Paket wird in der Regel durch ein Verzeichnis dargestellt, das eine __init__.py -Datei (die leer sein kann) und eine oder mehrere Python -Module enthält. Die __init__.py -Datei zeigt Python an, dass das Verzeichnis als Paket behandelt werden sollte.
Betrachten Sie beispielsweise ein Paket namens my_package :
my_package/
├── __init__.py
├── module1.py
└── module2.py
Hier ist my_package ein Paket mit module1.py und module2.py , das mit DOT -Notation ( my_package.module1 , my_package.module2 ) importiert werden kann.
Ein Unterpaket in Python ist ein Paket, das in einem anderen Paket verschachtelt ist. Dies bedeutet, dass ein Paket andere Pakete sowie Module enthalten kann. Unterhöfe werden durch das Organisieren von Verzeichnissen und das Hinzufügen __init__.py py-Dateien erstellt, um die Paketstruktur zu definieren.
Zum Beispiel:
my_parent_package/
├── __init__.py
└── my_sub_package/
├── __init__.py
├── module3.py
└── module4.py
In dieser Struktur ist my_sub_package ein Unterpaket von my_parent_package und kann seine eigenen Module enthalten ( module3.py , module4.py ). Das Unterpackungen kann mit DOT-Notation importiert werden ( my_parent_package.my_sub_package.module3 ).
Ein Vertriebspaket (oder einfach Vertrieb ) in Python bezieht sich auf eine verpackte Sammlung von Python -Code und Ressourcen, die für die Installation zur Verfügung gestellt werden. Es enthält in der Regel Module, Pakete, Datendateien, Konfigurationsdateien und andere Ressourcen, die für einen bestimmten Zweck benötigt werden (z. B. eine Bibliothek oder Anwendung).
Verteilungspakete werden häufig mit Python -Paketmanagern wie pip verteilt und installiert und können in Paket -Repositories wie PYPI (Python Package Index) für die einfache Verteilung und Installation durch andere Entwickler hochgeladen werden.
Zu den beliebten Vertriebspaketen gehören beispielsweise numpy , fast-api , pandas usw., die mit pip installiert werden und Funktionen bereitstellen, die in Python-Projekten verwendet werden können.
sdist -Formatsetup.pypython setup.py build sdist aus, um die Quellverteilung aufzubauenpip install ./dist/<package_name>.tar.gz um das Paket zu installierenpip list , um festzustellen, ob das Paket installiert ist. Wenn Änderungen im Paket vorgenommen werden, verwenden Sie pip install . Das wird das neueste Paket im laufenden Fliegen erstellen und installieren.
Oder verwenden Sie einfach bearbeitbar, damit Sie das Paket nicht immer wieder aufbauen müssen. Evrerytime werden neue Änderungen vorgenommen:
pip install --editable . sdist ist kurz für die Quellverteilung, eine .tar -Datei, die unseren Code als "SDIST" enthält. Dies bedeutet, dass das Verteilungspaket nur eine Teilmenge unseres Quellcodes enthält.
Eine "Quellverteilung" ist im Wesentlichen ein Ordner mit Reißverschluss, der unseren Quellcode enthält.
wheel Quellverteilung ( sdist ) :
*.py ), Konfigurationsdateien und andere projektbezogene Assets.python setup.py sdist erstellt werden. Räder ( bdist_wheel ) :
sdist ..whl -Erweiterung.python setup.py bdist_wheel . Schnellere Installation :
*.whl ) ist normalerweise schneller als die Installation aus Quellverteilungen ( *.tar.gz ).Benutzerfreundlichkeit für Benutzer :
sdist als auch bdist_wheelsdist als auch bdist_wheel für Python -Pakete zu erstellen und zu veröffentlichen, um verschiedene Anwendungsfälle und -plattformen aufzunehmen.python setup.py sdist bdist_wheelKompilierungsanforderungen :
Leider werden das Bauen von Rädern für alle Betriebssysteme schwierig, wenn Sie einen Kompilierungsschritt benötigen, sodass einige OSS -Wartenden nur Räder für ein einzelnes Betriebssystem bauen.
pip die setup.py (oder äquivalente Dateien) auf Ihrem Computer direkt nach dem Herunterladen des SDIST aus.Das Erstellen des Rades erfordert möglicherweise Code kompiliert
gcc , wenn sich der Quellcode in C befindet, andere Sprachen jedoch ihre eigenen Compiler benötigen. Der Benutzer muss diese auf dem Maschine installieren oder die pip install ... fällt einfach aus. Dies kann passieren, wenn Sie numpy , pandas , scipy , pytorch , tensorflow usw. installieren. setup.py kann beliebiger Code enthalten. Dies ist sehr unsicher. Ein setup.py kann böswilliger Code enthalten.
Abhängigkeitsverwaltung :
gcc usw.) installieren, um erfolgreich Pakete zu installieren, die eine Kompilierung erfordern.Sicherheitsbedenken :
setup.py für die Paketinstallation kann unsicher sein, da der beliebige Code ausgeführt wird.wheelEin Radfilename wird in Teile unterteilt, die durch Bindestriche getrennt sind:
{dist}-{version}(-{build})?-{python}-{abi}-{platform}.whl Jeder Abschnitt in {brackets} ist ein Tag oder eine Komponente des Radnamens, der eine Bedeutung über das, was das Rad enthält und wo das Rad enthält, enthält oder nicht funktioniert.
Zum Beispiel: dist/packaging-0.0.0-py3-none-any.whl
packaging ist der Paketname0.0.0 ist die Verisonennummerpy3 bezeichnet es für Python3 baut aufabi -Tag. ABI steht für die Binärschnittstelle von Application.any Bestandteile dafür, dass dieses Paket auf einer beliebigen Plattform gearbeitet wird.Andere Beispiele:
cryptography-2.9.2-cp35-abi3-macosx_10_9_x86_64.whlchardet-3.0.4-py2.py3-none-any.whlPyYAML-5.3.1-cp38-cp38-win_amd64.whlnumpy-1.18.4-cp38-cp38-win32.whlscipy-1.4.1-cp36-cp36m-macosx_10_6_intel.whlDer Grund dafür ist, dass die Raddatei den vorgeführten Binärcode enthält, mit dem das Paket schnell installiert wird.
Paketwartung :
sdist als auch bdist_wheel -Verteilungen bereitzustellen, um die Kompatibilität und die Benutzerfreundlichkeit für Benutzer zu maximieren.Betrachten Sie die Benutzererfahrung :
build das CLI -Tool und pyproject.toml auf"Build -Abhängigkeiten" sind alles, was in Ihrem System installiert werden muss, um Ihr Verteilungspaket in ein SDIST oder Rad aufzubauen.
Zum Beispiel mussten wir pip install wheel um python setup.py bdist_wheel auszuführen, sodass wheel eine Build -Abhängigkeit für Gebäuderäder ist.
setup.py -Dateien können komplex werden.
Möglicherweise müssen Sie eine pip install ... externe Bibliotheken und in Ihre setup.py -Datei importieren, um komplexe Build -Prozesse zu erfüllen.
Die Vorlesung zeigt pytorch und airflow als Beispiele für Pakete mit komplexen setup.py -Dateien.
Irgendwie müssen Sie in der Lage sein, Build -Abhängigkeiten außerhalb von setup.py zu dokumentieren.
Wenn sie in der Datei setup.py dokumentiert würden, könnten Sie die Datei setup.py nicht ausführen, um die dokumentierten Abhängigkeiten zu lesen (z. B. wenn sie irgendwo in der Datei in einer list angegeben würden).
Dies ist das ursprüngliche Problem, pyproject.toml lösen sollte.
# pyproject.toml
[ build-system ]
# Minimum requirements for the build system to execute.
requires = [ " setuptools>=62.0.0 " , " wheel " ] pyproject.toml sitzt neben setup.py in der Dateibaum
Das build CLI Tool ( pip install build ) ist ein spezielles Projekt der Python Packaging Authority (PYPA), das
[build-system] in der pyproject.toml ,,pip install build
# both setup.py and pypproject.toml should be together, ideally in the root directory
# python -m build --sdist --wheel path/to/dir/with/setup.py/and/pyproject.toml
python -m build --sdist --wheel . setup.py zu setup.cfg config -DateiWechsel von
# setup.py
from pathlib import Path
from setuptools import find_packages , setup
import wheel
# Function to read the contents of README.md
def read_file ( filename : str ) -> str :
filepath = Path ( __file__ ). resolve (). parent / filename
with open ( filepath , encoding = "utf-8" ) as file :
return file . read ()
setup (
name = "packaging-demo" ,
version = "0.0.0" ,
packages = find_packages (),
# package meta-data
author = "Amit Vikram Raj" ,
author_email = "[email protected]" ,
description = "Demo for Python Packaging" ,
license = "MIT" ,
# Set the long description from README.md
long_description = read_file ( "README.md" ),
long_description_content_type = "text/markdown" ,
# install requires: libraries that are needed for the package to work
install_requires = [
"numpy" , # our package depends on numpy
],
# setup requires: the libraries that are needed to setup/build
# the package distribution
# setup_requires=[
# "wheel", # to build the binary distribution we need wheel package
# ],
)ZU
# setup.py
from setuptools import setup
# Now setup.py takes it's configurations from setup.cfg file
setup () # setup.cfg
[metadata]
name = packaging-demo
version = attr: packaging_demo.VERSION
author = Amit Vikram Raj
author_email = [email protected]
description = Demo for Python Packaging
long_description = file: README.md
keywords = one, two
license = MIT
classifiers =
Framework :: Django
Programming Language :: Python :: 3
[options]
zip_safe = False
include_package_data = True
# same as find_packages() in setup()
packages = find:
python_requires = >=3.8
install_requires =
numpy
importlib-metadata ; python_version<"3.10"Auch die addtionale Einstellung wird an die Datei
pyproject.tomlübergeben. Hier haben wirbuild-systemähnlich wiesetup_requiresinsetup.pyangegeben
# pyproject.toml
[ build-system ]
# Minimum requirements for the build system to execute
requires = [ " setuptools " , " wheel " , " numpy<1.24.3 " ]
# Adding ruff.toml to pyproject.toml
[ tool . ruff ]
line-length = 99
[ tool . ruff . lint ]
# 1. Enable flake8-bugbear (`B`) rules, in addition to the defaults.
select = [ " E " , " F " , " B " , " ERA " ]
# 2. Avoid enforcing line-length violations (`E501`)
ignore = [ " E501 " ]
# 3. Avoid trying to fix flake8-bugbear (`B`) violations.
unfixable = [ " B " ]
# 4. Ignore `E402` (import violations) in all `__init__.py` files, and in select subdirectories.
[ tool . ruff . lint . per-file-ignores ]
"__init__.py" = [ " E402 " ]
"**/{tests,docs,tools}/*" = [ " E402 " ]
# copying isort configurations from .isort.cfg to pyproject.toml
[ tool . isort ]
profile = " black "
multi_line_output = " VERTICAL_HANGING_INDENT "
force_grid_wrap = 2
line_length = 99
# copying balck config from .black.toml to pyproject.toml
[ tool . black ]
line-length = 99
exclude = " .venv "
# copying flake8 config from .flake8 to pyproject.toml
[ tool . flake8 ]
docstring-convention = " all "
extend-ignore = [ " D107 " , " D212 " , " E501 " , " W503 " , " W605 " , " D203 " , " D100 " ,
" E305 " , " E701 " , " DAR101 " , " DAR201 " ]
exclude = [ " .venv " ]
max-line-length = 99
# radon
radon-max-cc = 10
# copying pylint config from .pylintrc to pyproject.toml
[ tool . pylint . "messages control" ]
disable = [
" line-too-long " ,
" trailing-whitespace " ,
" missing-function-docstring " ,
" consider-using-f-string " ,
" import-error " ,
" too-few-public-methods " ,
" redefined-outer-name " ,
] Wir haben setup.py als verherrlichte Konfigurationsdatei behandelt und nicht wirklich die Tatsache ausnutzt, dass es sich um eine Python -Datei handelt, indem sie Logik hinzufügen.
Dies ist häufiger als nicht. Außerdem gab es eine allgemeine Verschiebung von der Verwendung von Python für Konfigurationsdateien, da dies der Verwendung der Konfigurationsdateien Komplexität ergibt (z. B. die Installation von Bibliotheken, um die Konfigurationsdatei auszuführen).
setup.cfg ist eine Begleitdatei für setup.py , mit der wir unsere Paketkonfiguration in einer statischen Textdatei definieren können - insbesondere eine INI -Formatdatei.
Alle Werte, die wir nicht direkt als Argumente an Setup () übergeben, werden durch den Aufruf von setup () in einer setup.cfg -Datei gesucht, die bei Verwendung in der Dateibaum neben Setup.py sitzen soll.
Jetzt sammeln wir viele Dateien!
setup.pysetup.cfgpyproject.tomlREADME.md.pylintrc Dateien für Lining pre-commit-config.yaml andere Tools .blackrc Codequalität ruff.toml .mypy .flake8CHANGELOG oder CHANGELOG.mdVERSION oder version.txt Es stellt sich heraus, dass fast alle diese Dateien durch pyproject.toml ersetzt werden können. Fast jedes Lining / Code -Qualitäts -Tool unterstützt das Parsen eines Abschnitts namens [tool.<name>] EG [tool.black] Abschnitt von pyproject.toml zum Lesen seiner Konfiguration!
Die Dokumente jedes einzelnen Tools sollten Ihnen mitteilen, wie Sie dies erreichen können.
Oben gezeigt wird ein pyproject.toml mit Konfigurationen für viele der im Kurs verwendeten Lining -Tools.
Kann
setup.cfgundsetup.pyebenfalls ersetzt werden?
setup.cfg nach pyproject.tomlVon
setup.cfg
# setup.cfg
[metadata]
name = packaging-demo
version = attr: packaging_demo.VERSION
author = Amit Vikram Raj
author_email = [email protected]
description = Demo for Python Packaging
long_description = file: README.md
keywords = one, two
license = MIT
classifiers =
Programming Language :: Python :: 3
[options]
zip_safe = False
include_package_data = True
# same as find_packages() in setup()
packages = find:
python_requires = >=3.8
install_requires =
numpy
importlib-metadata ; python_version<"3.10"ZU
# pyproject.toml
[ build-system ]
# Minimum requirements for the build system to execute
requires = [ " setuptools>=61.0.0 " , " wheel " ]
# Adding these from setup.cfg in pyproject.toml file
[ project ]
name = " packaging-demo "
authors = [{ name = " Amit Vikram Raj " , email = " [email protected] " }]
description = " Demo for Python Packaging "
readme = " README.md "
requires-python = " >=3.8 "
keywords = [ " one " , " two " ]
license = { text = " MIT " }
classifiers = [ " Programming Language :: Python :: 3 " ]
dependencies = [ " numpy " , ' importlib-metadata; python_version<"3.10" ' ]
dynamic = [ " version " ]
# version = "0.0.3"
# https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html#dynamic-metadata
[ tool . setuptools . dynamic ]
# every while making changes in package, you can change the verison in one of these files
# version = {attr = "packaging_demo.VERSION"} # version read by 'packaging_demo/__init__.py' file
version = { file = [ " version.txt " ]} # version read by 'version.txt' file in root folder
python -m build --sdist --wheel .- perfekt ausgeführt, wir haben eine andere Konfigurationsdatei (setup.cfg) losgeworden
setup.py durch build-backend ersetzen PEP 517 fügte pyproject.toml Like SO ein build-backend -Argument hinzu:
[ build-system ]
# Defined by PEP 518:
requires = [ " flit " ]
# Defined by this PEP:
build-backend = " flit.api:main " # The above toml config is equivalent to
import flit . api
backend = flit . api . main Der build-backend definiert einen Einstiegspunkt (in diesem Fall ausführbares Python-Modul), mit dem die build CLI tatsächlich die Arbeit zum Analysieren pyproject.toml und dem Bau des Rades und SDIST verwendet.
Dies bedeutet, dass Sie heute Ihr eigenes Build-Backend implementieren können, indem Sie ein Programm schreiben, das dies ausführt, und Sie es verwenden können, indem Sie Ihr Paket zu requires = [...] und den Einstiegspunkt in build-backend = ...
Wenn Sie in pyproject.toml keinen build-backend angeben, wird Setuptools angenommen und das Paket wird Bulit-Bulit-Bulit-Bulit-Buliten vorerst in Ordnung.
setup.py entfernen und python -m build --sdist --wheel . Es läuft perfekt ohne es, da der Standardwert des build-system in build-backend = "setuptools.build_meta" in build CLI festgelegt wird, das unser Paket erstellt. Sie können jedoch setuptools dennoch explizit als Ihr Build -Backend so deklarieren
# pyproject.toml
...
[ build-system ]
requires = [ " setuptools>=61.0.0 " , " wheel " ]
build-backend = " setuptools.build_meta "
... Jedes Build -Backend erweitert typischerweise die Datei pyproject.toml mit eigenen Konfigurationsoptionen. Zum Beispiel,
# pyproject.toml
...
[ tool . setuptools . package-data ]
package_demo = [ " *.json " ]
[ tool . setuptools . dynamic ]
version = { file = " version.txt " }
long_description = { file = " README.md " }
... Wenn Sie setuptools in Ihrem Projekt verwenden, können Sie diese Abschnitte zu pyproject.toml hinzufügen. Weitere Informationen zum Dokumentation setuptools finden Sie mehr darüber
Es ist oft vorteilhaft, Nicht-Python-Dateien wie Datendateien oder Binärdateien in Ihr Paket einzubeziehen, da Ihr Python-Code oft auf diesen Nicht-Python-Dateien basiert.
Und dann haben wir gesehen, dass wir diese Dateien in unserem Paketordner in unserem Paketordner einfügen müssen, da es sich um unseren Paketordner befindet, der nach der Installation in unseren virtuellen Umgebungen unserer Benutzer landet.
Wir haben auch festgestellt, dass alle Nicht-Python-Dateien standardmäßig nicht in diesen endgültigen Ordner der virtuellen Umgebung geschaffen werden. Machen Sie es während des Build -Verfahrens nicht wirklich in unseren Paketordner.
Wie können wir also sicherstellen, dass diese Dateien in unserem Rad/Dist -Build unseres Pakets landen? Zum Beispiel Demo mit cities.json -Datei, die wir in unserem Paket wollen, wie sie von states_info.py -Datei verwendet wird.
Offizielle
setuptools-Dokumente für die Datenunterstützung
# pyprject.toml
[ tool . setuptools ]
# ...
# By default, include-package-data is true in pyproject.toml, so you do
# NOT have to specify this line.
include-package-data = true Setuptools standardmäßig enthält dies den Wert, der auf true include-package-data ist, wie in den offiziellen Dokumenten gezeigt, aber wir müssen ein zusätzliches MANIFEST.in erstellen.
IMP: Importieren alle Ordner in das Paketverzeichnis sollten
__init__.py-Datei enthalten, in dem wir das Datenverzeichnis einschließen, das wir einschließen möchten, weil die setuptoolsfind_packages()recusrive prozess nicht in fo; ders eingehen, die__init__.py-Datei enthalten.
# MANIFEST.in
include packaging_demo/*.json
include packaging_demo/my_folder/*.json
OR
Recursive include all json files in the package directory
recursive-include packaging_demo/ *.json
Dokumente zum Konfigurieren von Manifest.in -Datei
MANIFEST.in -Datei Aus Setuptools -Dokumenten können wir dies in unserer Datei pyproject.toml hinzufügen:
# this is by default true so no need to explicitly add it
# but as mentioned in the docs, it is false for other methods like setup.py or setup.cfg
[ tool . setuptools ]
include-package-data = true
# add the data here, it's finding the files recursively
[ tool . setuptools . package-data ]
package_demo = [ " *.json " ]build-backend -Systeme als setuptools Abgesehen von setuptools können wir diese Build -Backend -Systeme verwenden. Der Punkt ist zu beachten, wenn andere Systeme die pyproject.toml -Coffiguration verwendet werden.
Luke
[ build-system ]
requires = [ " hatchling " ]
build-backend = " hatchling.build "Poesie
[ build-system ]
requires = [ " poetry-core>=1.0.0 " ]
build-backend = " poetry.core.masonry.api " Dokumentieren Sie die genauen Versionen unserer Abhängigkeiten und ihrer Abhängigkeiten und so weiter.
Es ist ratsam, so wenig wie möglich mit unserem Paket in Verbindung zu haben, da dies zu Abhängigkeitshölle oder Abhängigkeitskonflikten mit einem anderen Paket führen kann, wie in den Vorträgen erläutert.
Je komplexer der Abhängigkeitsbaum höher ist, die Wahrscheinlichkeit von Konflikten mit der zukünftigen Version anderer Bibliotheken.
Abhängigkeitsgrafikanalyse durch Eric
Die festgehaltenen Versionen von Abhängigkeiten und Python -Versionen zu führen, ist für Fehlerbehebungszwecke empfohlen:
pip freeze > requirements.txt pip install pipdeptree graphviz
sudo apt-get install graphviz
# generate the dependency graph
pipdeptree -p packaging-demo --graph-output png > dependency-graph.png[ project . optional-dependencies ]
dev = [ " ruff " , " mypy " , " black " ] # installing our package with optional dependencies
pip install ' .[dev] ' [ project . optional-dependencies ]
# for developement
dev = [ " ruff " , " mypy " , " black " ]
# plugin based architecture
colors = [ " rich " ] # plugin based installation
pip install ' .[colors] '
# here we demo with rich library, if user wants the output to be
# colorized then they can install our package like this.
# we can add multiple optional dependencies like:
pip install ' .[colors, dev] ' [ project . optional-dependencies ]
# for developement
dev = [ " ruff " , " mypy " , " black " ]
# plugin based architecture
colors = [ " rich " ]
# install all dependencies
all = [ " packaging-demo[dev, colors] " ] # Installing all dependencies all at once
pip install ' .[all] ' Wir können SNYK verwenden, um zu überprüfen, wie stabil, gut unterstützt, wenn Sicherheitsprobleme usw. für die Abhängigkeiten vorhanden sind, die wir für unser Paket verwenden werden, und dann die Entscheidung über die Verwendung in unserem Projekt treffen.
Um unser Paket zu PYPI [Python Packaging Index] zu publish, wie im offiziellen Leitfaden angegeben, verwenden wir twine CLI -Tool.
pip install twine
twine upload --helpGenerieren Sie API -Token für PYPI -Test oder PYPI prod
Erstellen Sie Ihr Python -Paket: python -m build --sdist --wheel "${PACKAGE_DIR}" , hier bauen wir sowohl sdist als auch rad, wie empfohlen.
Führen Sie das Twine-Tool aus: twine upload --repository testpypi ./dist/* , Aufladung zum Test-Pypi
CMake und Makefile
sudo apt-get install makeTaskfile
justfile
Pyinvoke
Dev
$ rightarrow $ QA/Inszenierung$ rightarrow $ Prod



# .github/workflows/publish.yaml
name : Build, Test, and Publish
# triggers: whenever there is new changes pulled/pushed on this
# repo under given conditions, run the below jobs
on :
pull_request :
types : [opened, synchronize]
push :
branches :
- main
# Manually trigger a workflow
# https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#workflow_dispatch
workflow_dispatch :
jobs :
build-test-and-publish :
runs-on : ubuntu-latest
steps :
# github actions checksout, clones our repo, and checks out the branch we're working in
- uses : actions/checkout@v3
with :
# Number of commits to fetch. 0 indicates all history for all branches and tags
# fetching all tags so to aviod duplicate version tagging in 'Tag with the Release Version'
fetch-depth : 0
- name : Set up Python 3.8
uses : actions/setup-python@v3
with :
python-version : 3.8
# tagging the release version to avoid duplicate releases
- name : Tag with the Release Version
run : |
git tag $(cat version.txt)
- name : Install Python Dependencies
run : |
/bin/bash -x run.sh install
- name : Lint, Format, and Other Static Code Quality Check
run : |
/bin/bash -x run.sh lint:ci
- name : Build Python Package
run : |
/bin/bash -x run.sh build
- name : Publish to Test PyPI
# setting -x in below publish:test will not leak any secrets as they are masked in github
if : ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
run : |
/bin/bash -x run.sh publish:test
env :
TEST_PYPI_TOKEN : ${{ secrets.TEST_PYPI_TOKEN }}
- name : Publish to Prod PyPI
if : ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
run : |
/bin/bash -x run.sh publish:prod
env :
PROD_PYPI_TOKEN : ${{ secrets.PROD_PYPI_TOKEN }}
- name : Push Tags
if : ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
run : |
git push origin --tagsSperrenanforderungen
Abhängigkeitsdach
Immer wenn Github -Aktionen im Github CI ausgeführt werden, jedes Mal, wenn es auf einem frischen Behälter ausgeführt wird. So müssen wir jedes Mal immer wieder Abhängigkeiten von PIP herunterladen und neu installieren. Das ist nicht gut, da es ineffektiv ist und unseren Workflow verlangsamt.
Daher möchten wir alle Abhängigkeiten installieren, wenn der Workflow zuerst lief, und sie jedes Mal verwenden, wenn ein neuer Worfllow ausgeführt wird.
GitHub -Aktionen liefern diese Funktionalität, indem sie die Abhängigkeiten zwischengeschnitten, die installierten Abhängigkeiten ( ~/.cache/pip ) gespeichert und jedes Mal heruntergeladen werden, wenn ein neuer Workflow ausgeführt wird. Dokumente
- uses : actions/cache@v3
with :
path : ~/.cache/pip
key : ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys : |
${{ runner.os }}-pip-setup-python -Github-Aktion steps :
- uses : actions/checkout@v4
- uses : actions/setup-python@v5
with :
python-version : ' 3.9 '
cache : ' pip ' # caching pip dependencies
- run : pip install -r requirements.txtParallelisierung
# See .github/workflows/publish.yaml
jobs :
check-verison-txt :
...
lint-format-and-static-code-checks :
....
build-wheel-and-sdist :
...
publish :
needs :
- check-verison-txt
- lint-format-and-static-code-checks
- build-wheel-and-sdist
...