Skip to content

Commit

Permalink
Infra improvements (#1)
Browse files Browse the repository at this point in the history
* Refactored the Dockerfile to use poetry to build the whl and pip to install the application in the venv; Added GHA workflows to check code quality and to publish the package into pypi-switch

* Removed phony files, added an helper to the makefile as well as checks for deps and envs

* Added PYPI credentials to the build-env action

* added fixes for the code quality check

* reverted changes to action.yml
  • Loading branch information
André authored Nov 20, 2021
1 parent 0077a95 commit 3472270
Show file tree
Hide file tree
Showing 53 changed files with 151 additions and 81 deletions.
18 changes: 18 additions & 0 deletions .github/actions/setup-python-build-env/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: "Setup Build Environment"
description: "Install everything needed to build"

runs:
using: "composite"
steps:
- name: Install dependencies
shell: bash
run: |
python -m pip install --upgrade pip
- name: Install Poetry
shell: bash
run: |
# curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python3
# source $HOME/.poetry/env
# poetry -n init
pip install --user poetry
pip install "mypy==0.910"
40 changes: 40 additions & 0 deletions .github/workflows/publish-to-pypi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Publish Python 🐍 distributions 📦 to Switch PyPI

on:
push:
tags:
- "v[0-9]+.[0-9]+.[0-9]+*"

jobs:
build-n-publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Set up Python 3.10.0
uses: actions/setup-python@v2
with:
python-version: 3.10.0

- name: Tries to get the tag version or branch name
id: context
run: |
echo ::set-output name=BRANCH_NAME::${GITHUB_REF#refs/heads/}
echo ::set-output name=TAG_VERSION::${GITHUB_REF#refs/tags/}
- name: Setup the Python Environment by installing Poetry
uses: ./.github/actions/setup-python-build-env

- name: Poetry bump version, build and publish
shell: bash
run: |
# TAG_VERSION can be also obtained with:
# poetry version $(git describe --tags --abbrev=0)
poetry version $TAG_VERSION
poetry config http-basic.pypi-switch $PYPI_USER $PYPI_PASS
poetry update
poetry build
poetry publish -r pypi-switch
env:
TAG_VERSION: ${{ steps.context.outputs.TAG_VERSION }}
PYPI_USER: ${{ secrets.PYPI_USER }}
PYPI_PASS: ${{ secrets.PYPI_PASS }}
32 changes: 32 additions & 0 deletions .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: PR Python 🐍 to Switch Repo

on:
pull_request:
branches:
- master

jobs:
code-quality-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Set up Python 3.10.0
uses: actions/setup-python@v2
with:
python-version: 3.10.0

- name: Setup the Python Environment by installing Poetry
uses: ./.github/actions/setup-python-build-env

- name: Code Quality Check
shell: bash
run: |
poetry config http-basic.pypi-switch $PYPI_USER $PYPI_PASS
poetry update
poetry install
poetry run pytest tests
poetry run black --check --diff --line-length=88 slac tests
env:
TAG_VERSION: ${{ steps.context.outputs.TAG_VERSION }}
PYPI_USER: ${{ secrets.PYPI_USER }}
PYPI_PASS: ${{ secrets.PYPI_PASS }}
13 changes: 2 additions & 11 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@ __pycache__/
*.py[cod]
*$py.class
.pytest_cache/
# dist
dist/
# C extensions
*.so
# .bkp files
*.bkp
# Dockerfiles inside evcc and secc
iso15118/evcc/Dockerfile
iso15118/secc/Dockerfile
iso15118/iso15118/evcc/Dockerfile
iso15118/iso15118/secc/Dockerfile
# Distribution / packaging
.Python
build/
Expand Down Expand Up @@ -112,9 +109,3 @@ venv.bak/

.idea/*

# Generated X.509 certificates, private keys, and PKCS12 container files
*.pem
*.der
*.key
*.p12
iso15118/shared/pki/csrs
45 changes: 6 additions & 39 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,8 @@ ENV PYTHONFAULTHANDLER=1 \
POETRY_VERSION=1.1.11 \
VIRTUALENV_PIP=21.2.1


# create virtualenv
RUN python -m venv /venv
# Make sure we use the virtualenv:
ENV PATH="/venv/bin:$PATH"

# This is needed if we use pip wheel
RUN pip install wheel

RUN pip install "poetry==$POETRY_VERSION"

# Due to an issue with Python 3.10 and poetry, if we use a poetry virtual env,
# we need to disable the option: poetry config experimental.new-installer false
# check https://github.com/python-poetry/poetry/issues/4210
Expand All @@ -48,53 +40,28 @@ RUN pytest -vv --cov-config .coveragerc --cov-report term-missing --durations=3
RUN flake8 --config .flake8 slac tests



# NOTE: Building the .whl with poetry at this stage and installing it in the next
# stage env, works if we install the mqtt-api explicitly, otherwise the poetry
# install dist/ fails. This seems to be a bug in `poetry build` command:
# https://github.com/python-poetry/poetry/issues/2831
# The alternative was to generate the requirements without-hashes as mqtt-api has no
# hashes and generate the wheels for the requirements

# ALTERNATIVE TO BE USED
# RUN poetry install --no-interaction --no-ansi --no-dev

# Exports no-dev dependencies
RUN poetry export -f requirements.txt --without-hashes --with-credentials > requirements.txt
# Generate the wheel to be used by next stage
RUN poetry build -f wheel
RUN pip wheel -w dist -r requirements.txt
RUN poetry build
# Unfortunately, couldnt find a way to generate only compatible wheels with this
# platform, so I had to remove the MacOS .whl for the dir
RUN rm dist/*macosx*

# ALTERNATIVE TO BE USED
# RUN poetry build

# Runtime image (which is smaller than the build one)
FROM python:3.10.0-buster

# ARG PYPI_USER
# ARG PYPI_PASS

WORKDIR /usr/src/app

# create virtualenv
RUN python -m venv /venv

# ALTERNATIVE TO BE USED
# copy dependencies and wheel from the build stage
# COPY --from=build /venv /venv
# COPY --from=build /usr/src/app ./


COPY --from=build /usr/src/app/dist/ dist/
# mqtt dependency is not part of the iso15118 .whl, so it is not ideal, but the
# solution is to explicitly install the package
# RUN /venv/bin/pip install --index-url https://$PYPI_USER:$PYPI_PASS@pypi.switch-ev.com/simple mqtt_api

#This will install the wheels in the venv

# This will install the wheels in the venv
RUN /venv/bin/pip install dist/*.whl
# if it does not work use
# RUN /venv/bin/pip install dist/*.whl --extra-index-url https://$PYPI_USER:$PYPI_PASS@pypi.switch-ev.com/simple

# This will run the entrypoint script defined in the pyproject.toml
CMD /venv/bin/slac
55 changes: 45 additions & 10 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,21 +1,48 @@
# all the recipes are phony (no files to check).
.PHONY: .check-env-vars deps docs test build dev run update install-local run-local deploy
.PHONY: .check-env-vars .deps docs tests build dev run update install-local run-local deploy deploy-twine help
.DEFAULT_GOAL := help

IS_LINUX_OS := $(shell uname -s | grep -c Linux)
# IS_POETRY := $(shell command -v poetry 2> /dev/null)
IS_POETRY := $(shell pip freeze | grep "poetry==")
IS_TWINE := $(shell pip freeze | grep "twine==")


export PATH := ${HOME}/.local/bin:$(PATH)

help:
@echo "Please use 'make <target>' where <target> is one of"
@echo ""
@echo " build builds the app in Docker"
@echo " dev runs the app with docker-compose.dev"
@echo " run-local runs the app locally"
@echo " poetry-update updates the dependencies in poetry.lock"
@echo " poetry-install installs the dependencies"
@echo " tests run all the tests"
@echo " reformat reformats the code, using Black"
@echo " flake8 flakes8 the code"
@echo " deploy deploys the project using Poetry (not recommended, only use if relly needed)"
@echo " deploy-twine deploys the project using Twine (not recommended, only use if relly needed)"
@echo ""
@echo "Check the Makefile to know exactly what each target is doing."


.check-os:
# The @ is to surpress the output of the evaluation
@if [ ${IS_LINUX_OS} -eq 0 ]; then echo "This Recipe is not available in non-Linux Systems"; exit 3; fi

.check-env-vars:
@test $${PYPI_USER?Please set environment variable PYPI_USER}
@test $${PYPI_PASS?Please set environment variable PYPI_PASS}

deps:
pip install poetry
.deps:
@if [ -z ${IS_POETRY} ]; then pip install poetry; fi
@if [ -z ${IS_TWINE} ]; then pip install twine; fi

docs:
# poetry run sphinx-build -b html docs/source docs/build

test:
#poetry run flake8 pytest -vv tests
tests: .check-os
poetry run pytest -vv tests

build: .check-env-vars
Expand All @@ -36,7 +63,7 @@ poetry-config: .check-env-vars
poetry config http-basic.pypi-switch ${PYPI_USER} ${PYPI_PASS}

poetry-update: poetry-config
poetry update --require-hashes
poetry update

poetry-install: poetry-update
poetry install
Expand All @@ -48,15 +75,23 @@ mypy:
mypy --config-file mypy.ini slac tests

reformat:
isort slac tests && black --line-length=88 slac tests
isort slac tests && black --exclude --line-length=88 slac tests

black:
black --check --diff --line-length=88 slac tests
black --exclude --check --diff --line-length=88 slac tests

flake8:
flake8 --config .flake8 slac tests

code-quality: reformat mypy black flake8

deploy: deps build
# twine upload dist/*.tar.gz
bump-version:
poetry version

deploy: .check-env-vars .deps build bump-version
poetry config repo.pypi-switch https://pypi.switch-ev.com/
poetry config http-basic.pypi-switch ${PYPI_USER} ${PYPI_PASS}
poetry publish -r pypi-switch

deploy-twine: .check-env-vars .deps build
python -m twine upload -u $(PYPI_USER) -p $(PYPI_PASS) --repository-url https://pypi.switch-ev.com dist/*
Binary file removed dist/aioredis-2.0.0-py3-none-any.whl
Binary file not shown.
Binary file removed dist/async_timeout-4.0.1-py3-none-any.whl
Binary file not shown.
Binary file removed dist/asyncio_mqtt-0.11.0-py3-none-any.whl
Binary file not shown.
Binary file removed dist/attrs-21.2.0-py2.py3-none-any.whl
Binary file not shown.
Binary file removed dist/jsonschema-3.2.0-py2.py3-none-any.whl
Binary file not shown.
Binary file removed dist/mqtt_api-0.4.0-py3-none-any.whl
Binary file not shown.
Binary file removed dist/paho_mqtt-1.6.1-py3-none-any.whl
Binary file not shown.
Binary file not shown.
Binary file removed dist/setuptools-59.2.0-py3-none-any.whl
Binary file not shown.
Binary file removed dist/six-1.16.0-py2.py3-none-any.whl
Binary file not shown.
Binary file removed dist/slac-0.1.0-py3-none-any.whl
Binary file not shown.
Binary file removed dist/typing_extensions-4.0.0-py3-none-any.whl
Binary file not shown.
4 changes: 3 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
[tool.poetry]
name = "slac"
version = "0.1.0"
# This version is a placeholder as the real version is fetched from GitHub
# Tags during releases of the package
version = "0.0.0"
description = "SLAC Protocol implementation, defined in ISO15118-3"
authors = ["André Duarte <andre@switch-ev.com, andre14x@gmail.com>"]

Expand Down
14 changes: 0 additions & 14 deletions requirements.txt

This file was deleted.

Binary file removed slac/__pycache__/__init__.cpython-310.pyc
Binary file not shown.
Binary file removed slac/__pycache__/__init__.cpython-38.pyc
Binary file not shown.
Binary file removed slac/__pycache__/__init__.cpython-39.pyc
Binary file not shown.
Binary file removed slac/__pycache__/enums.cpython-310.pyc
Binary file not shown.
Binary file removed slac/__pycache__/enums.cpython-38.pyc
Binary file not shown.
Binary file removed slac/__pycache__/enums.cpython-39.pyc
Binary file not shown.
Binary file removed slac/__pycache__/environment.cpython-310.pyc
Binary file not shown.
Binary file removed slac/__pycache__/environment.cpython-38.pyc
Binary file not shown.
Binary file removed slac/__pycache__/environment.cpython-39.pyc
Binary file not shown.
Binary file removed slac/__pycache__/layer_2_headers.cpython-310.pyc
Binary file not shown.
Binary file removed slac/__pycache__/layer_2_headers.cpython-38.pyc
Binary file not shown.
Binary file removed slac/__pycache__/layer_2_headers.cpython-39.pyc
Binary file not shown.
Binary file removed slac/__pycache__/main.cpython-310.pyc
Binary file not shown.
Binary file removed slac/__pycache__/main.cpython-39.pyc
Binary file not shown.
Binary file removed slac/__pycache__/messages.cpython-310.pyc
Binary file not shown.
Binary file removed slac/__pycache__/messages.cpython-38.pyc
Binary file not shown.
Binary file removed slac/__pycache__/messages.cpython-39.pyc
Binary file not shown.
Binary file removed slac/__pycache__/session.cpython-310.pyc
Binary file not shown.
Binary file removed slac/__pycache__/session.cpython-38.pyc
Binary file not shown.
Binary file removed slac/__pycache__/session.cpython-39.pyc
Binary file not shown.
Binary file removed slac/__pycache__/utils.cpython-38.pyc
Binary file not shown.
Binary file removed slac/__pycache__/utils.cpython-39.pyc
Binary file not shown.
4 changes: 2 additions & 2 deletions slac/examples/ev_slac_scapy.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,11 @@ class StartAttenChar(Packet):
XByteField(
"num_sounds", 2
), # This defines the number of sounds that the EV will send to the EVSE.
# And overrides the expected sounds defined by enum SLAC_MSOUNDS
# And overrides the expected sounds defined by enum SLAC_MSOUNDS
XByteField(
"time_out", 100
), # This defines the time to 10 secs (100 * 100 ms) that the EV must
# deliver the mnbc sounds before the EVSE times out
# deliver the mnbc sounds before the EVSE times out
XByteField("resp_type", 0x01),
XNBytesField("forwarding_sta", 0, 6),
XNBytesField("run_id", 0, 8),
Expand Down
Binary file removed slac/sockets/__pycache__/__init__.cpython-310.pyc
Binary file not shown.
Binary file removed slac/sockets/__pycache__/__init__.cpython-38.pyc
Binary file not shown.
Binary file removed slac/sockets/__pycache__/__init__.cpython-39.pyc
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed tests/__pycache__/__init__.cpython-38.pyc
Binary file not shown.
Binary file removed tests/__pycache__/conftest.cpython-38-pytest-6.2.5.pyc
Binary file not shown.
4 changes: 2 additions & 2 deletions tests/slac/examples/ev_slac_scapy.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,11 @@ class StartAttenChar(Packet):
XByteField(
"num_sounds", 2
), # This defines the number of sounds that the EV will send to the EVSE.
# And overrides the expected sounds defined by enum SLAC_MSOUNDS
# And overrides the expected sounds defined by enum SLAC_MSOUNDS
XByteField(
"time_out", 100
), # This defines the time to 10 secs (100 * 100 ms) that the EV must
# deliver the mnbc sounds before the EVSE times out
# deliver the mnbc sounds before the EVSE times out
XByteField("resp_type", 0x01),
XNBytesField("forwarding_sta", 0, 6),
XNBytesField("run_id", 0, 8),
Expand Down
3 changes: 1 addition & 2 deletions tests/test_slac_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,12 @@
FramesSizes,
)
from slac.layer_2_headers import EthernetHeader, HomePlugHeader
from slac.messages import AttenProfile # MnbcSound,
from slac.messages import (
AtennChar,
AtennCharRsp,
AttenProfile,
MatchCnf,
MatchReq,
# MnbcSound,
SetKeyCnf,
SetKeyReq,
SlacParmCnf,
Expand Down

0 comments on commit 3472270

Please sign in to comment.