diff --git a/.github/workflows/publish-to-pypi.yml b/.github/workflows/publish-to-pypi.yml new file mode 100644 index 0000000..54f9cc7 --- /dev/null +++ b/.github/workflows/publish-to-pypi.yml @@ -0,0 +1,97 @@ +name: Publish Python 🐍 distribution 📦 to PyPI + +on: + push: + tags: + - '*' + +jobs: + build: + name: Build distribution 📦 + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + - name: Install pypa/build + run: >- + python3 -m + pip install + build + --user + - name: Build a binary wheel and a source tarball + run: python3 -m build + - name: Store the distribution packages + uses: actions/upload-artifact@v4 + with: + name: python-package-distributions + path: dist/ + + publish-to-pypi: + name: >- + Publish Python 🐍 distribution 📦 to PyPI + needs: + - build + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/httpetcd + permissions: + id-token: write # IMPORTANT: mandatory for trusted publishing + + steps: + - name: Download all the dists + uses: actions/download-artifact@v4 + with: + name: python-package-distributions + path: dist/ + - name: Publish distribution 📦 to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + + github-release: + name: >- + Sign the Python 🐍 distribution 📦 with Sigstore + and upload them to GitHub Release + needs: + - publish-to-pypi + runs-on: ubuntu-latest + + permissions: + contents: write # IMPORTANT: mandatory for making GitHub Releases + id-token: write # IMPORTANT: mandatory for sigstore + + steps: + - name: Download all the dists + uses: actions/download-artifact@v4 + with: + name: python-package-distributions + path: dist/ + - name: Sign the dists with Sigstore + uses: sigstore/gh-action-sigstore-python@v3.0.0 + with: + inputs: >- + ./dist/*.tar.gz + ./dist/*.whl + - name: Create GitHub Release + env: + GITHUB_TOKEN: ${{ github.token }} + run: >- + gh release create + "$GITHUB_REF_NAME" + --repo "$GITHUB_REPOSITORY" + --notes "" + - name: Upload artifact signatures to GitHub Release + env: + GITHUB_TOKEN: ${{ github.token }} + # Upload to GitHub Release using the `gh` CLI. + # `dist/` contains the built packages, and the + # sigstore-produced signatures and certificates. + run: >- + gh release upload + "$GITHUB_REF_NAME" dist/** + --repo "$GITHUB_REPOSITORY" diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml new file mode 100644 index 0000000..ebe595f --- /dev/null +++ b/.github/workflows/tests.yaml @@ -0,0 +1,66 @@ +name: tests + +on: + push: + pull_request: + +jobs: + Lint: + runs-on: ubuntu-24.04 + strategy: + fail-fast: true + matrix: + python-version: ["3.8"] + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install tox + run: pip install tox + - name: pep8 + run: | + tox -e pep8 + tests: + runs-on: ubuntu-24.04 + strategy: + fail-fast: true + matrix: + python-version: ["3.8", "3.10", "3.12", "3.13"] + services: + etcd: + image: quay.io/coreos/etcd:v3.5.8 + ports: + - 2379:2379 + - 2380:2380 + env: + ETCD_ADVERTISE_CLIENT_URLS: http://127.0.0.1:2379 + ETCD_LISTEN_CLIENT_URLS: http://0.0.0.0:2379 + ETCD_INITIAL_ADVERTISE_PEER_URLS: http://127.0.0.1:2380 + ETCD_LISTEN_PEER_URLS: http://0.0.0.0:2380 + ETCD_NAME: etcd-test-instance + ETCD_ENDPOINT: http://127.0.0.1:2379 + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + - name: Install required packages + run: | + sudo apt update + sudo apt install libev-dev -y + - name: Install tox + run: pip install tox + - name: Unit tests + run: | + tox -e ${{ matrix.python-version }} + - name: Wait for etcd to be ready + run: | + for i in $(seq 1 10); do + nc -z 127.0.0.1 2379 && echo "etcd is ready!" && break + echo "Waiting for etcd..." + sleep 1 + done + - name: Functional tests + run: | + tox -e ${{ matrix.python-version }}-functional diff --git a/test-requirements.txt b/test-requirements.txt index 69be271..ac9046b 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,5 +1,5 @@ hacking<3 # Apache-2.0 -nose==1.3.7 # LGPL -nose-timer>=0.6.0,<1 # MIT +pytest>=8.0.0,<9.0.0 # MIT License (MIT) +pytest-timer>=1.0.0,<2.0.0 # MIT License (MIT) coverage>=3.6,<6 # Apache-2.0 mock>=1.0.1,<3.0.5 # BSD diff --git a/tox.ini b/tox.ini index 55f54da..cac75fe 100644 --- a/tox.ini +++ b/tox.ini @@ -13,14 +13,15 @@ project_name = httpetcd [testenv] setenv = PYTHONDONTWRITEBYTECODE = 1 - TEST_PATH={[base]project_name}.tests.unit - functional: TEST_PATH={[base]project_name}.tests.functional + PACKAGE_NAME=httpetcd + TEST_PATH={[base]project_name}/tests/unit + functional: TEST_PATH={[base]project_name}/tests/functional passenv = CI_* functional: ETCD_ENDPOINT deps = -r{toxinidir}/requirements.txt -r{toxinidir}/test-requirements.txt commands = - coverage run -p --source {toxinidir}/{[base]project_name} -m nose {posargs} {env:TEST_PATH} --with-timer --with-xunit + coverage run -p -m pytest {posargs} --timer-top-n=10 {env:TEST_PATH} [testenv:pep8] deps = hacking<3 @@ -49,7 +50,7 @@ basepython = python3 envdir = {toxworkdir}/cover commands = coverage erase - coverage run -m nose {posargs} {[base]project_name}.tests.unit + coverage run -m pytest {posargs} {[base]project_name}.tests.unit coverage html -d cover coverage report --skip-covered