diff --git a/.flake8 b/.flake8 index 2a063f543..5bc3ec1d5 100644 --- a/.flake8 +++ b/.flake8 @@ -1,5 +1,5 @@ [flake8] ignore = E226,E302,E41,W503 max-line-length = 160 -max-complexity = 15 +max-complexity = 12 exclude = .git,venv,.venv,.tox,.pytest_cache,.direnv \ No newline at end of file diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index d23372edd..86b4dd48f 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -4,29 +4,29 @@ on: [push, pull_request] jobs: build: - runs-on: ubuntu-latest strategy: matrix: - python-version: [3.7, 3.8, 3.9] + python-version: [3.7, 3.8, 3.9, "3.10"] + fail-fast: false steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r requirements_dev.txt - - name: Lint with flake8, pydocstyle - run: | - flake8 - pydocstyle pact - - name: Test with pytest - run: | - tox -e test - - name: Test examples - run: | - make examples + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements_dev.txt + - name: Lint with flake8, pydocstyle + run: | + flake8 + pydocstyle pact + - name: Test with pytest + run: | + tox -e test + - name: Test examples + run: | + make examples diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0990bf448..19e48a49d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,10 +4,10 @@ _Before raising an issue, please ensure that you are using the latest version of Please provide the following information with your issue to enable us to respond as quickly as possible. -* The relevant versions of the packages you are using. -* The steps to recreate your issue. -* The full stacktrace if there is an exception. -* An executable code example where possible. You can fork this repository and use the [e2e] directory to quickly recreate your issue. +- The relevant versions of the packages you are using. +- The steps to recreate your issue. +- The full stacktrace if there is an exception. +- An executable code example where possible. You can fork this repository and use the [e2e] directory to quickly recreate your issue. # Contributing @@ -27,6 +27,7 @@ you submit. [e2e]: https://github.com/pact-foundation/pact-python/tree/master/e2e ## Commit messages + Pact Python is adopting the Conventional Changelog commit message conventions. Please ensure you follow the guidelines, we don't want to be that person, but the commit messages are very important to the automation of our release process. Take a look at the git history (git log) to get the gist of it. @@ -40,4 +41,25 @@ npm i -g cz-conventional-changelog git cz to commit and commitizen will guide you. -There is a pypi package that does similar [commitizen]: https://pypi.org/project/commitizen/. This would make a great feature to add! There is a check on the travis build that your commits follow this convention. On creating a PR any commits that don't will instantly fail the build and you will have to rename them. \ No newline at end of file +There is a pypi package that does similar [commitizen]: https://pypi.org/project/commitizen/. This would make a great feature to add! There is a check on the travis build that your commits follow this convention. On creating a PR any commits that don't will instantly fail the build and you will have to rename them. + +## Running the tests + +You can run the tests locally with `make test`, this will run the tests with `tox` + +You will need `pyenv` to test on different versions `3.6`, `3.7`, `3.8`, `3.9`, `3.10` + +`pyenv install 3.6.15 3.7.13 3.8.13 3.9.14 3.10.6` - Download and install python versions +`pyenv local 3.6.15 3.8.13 3.7.13 3.9.14 3.10.6` - Set these versions locally for the project +`make test` - Run the tests + +### MacOS Setup Guide + +See the following guides to setup `Python` and configure `pyenv` on your Mac. + +- https://yellowdesert.consulting/2018/02/04/python-on-mac-one-of-the-good-ways/ +- https://yellowdesert.consulting/2020/10/24/tox-testing-multiple-python-versions-with-pyenv/ + +## Running the examples + +Make sure you have docker running! diff --git a/Makefile b/Makefile index 160b84665..c12e80dc6 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,6 @@ help: @echo "" @echo " clean to clear build and distribution directories" @echo " deps to install the required files for development" - @echo " verifier to run the verifier end to end tests" @echo " examples to run the example end to end tests (consumer, fastapi, flask, messaging)" @echo " consumer to run the example consumer tests" @echo " fastapi to run the example FastApi provider tests" @@ -136,4 +135,4 @@ venv: ln -sf ${CURDIR}/.venv ~/.pyenv/versions/${PROJECT} @echo "\n$(green)Use it! (populate .python-version)$(sgr0)" - pyenv local ${PROJECT} + pyenv local ${PROJECT} \ No newline at end of file diff --git a/README.md b/README.md index bdb604c54..369cc3535 100644 --- a/README.md +++ b/README.md @@ -290,6 +290,54 @@ Like({ For more information see [Matching](https://docs.pact.io/getting_started/matching) +## Uploading pact files to a Pact Broker + +There are two ways to publish your pact files, to a Pact Broker. + +1. [Pact CLI tools](https://docs.pact.io/pact_broker/client_cli) **recommended** +2. Pact Python API + +### CLI + +See [Publishing and retrieving pacts](https://docs.pact.io/pact_broker/publishing_and_retrieving_pacts) + +Example uploading to a Pact Broker + +``` +pact-broker publish /path/to/pacts/consumer-provider.json --consumer-app-version 1.0.0 --branch main --broker-base-url https://test.pactflow.io --broker-username someUsername --broker-password somePassword +``` + +Example uploading to a Pactflow Broker + +``` +pact-broker publish /path/to/pacts/consumer-provider.json --consumer-app-version 1.0.0 --branch main --broker-base-url https://test.pactflow.io --broker-token SomeToken +``` + +### Python API + +```python +broker = Broker(broker_base_url="http://localhost") +broker.publish("TestConsumer", + "2.0.1", + branch='consumer-branch', + pact_dir='.') + +output, logs = verifier.verify_pacts('./userserviceclient-userservice.json') + +``` + +The parameters for this differ slightly in naming from their CLI equivalents: +| CLI | native Python | +|-----------------|-------------------------------------------------------------------------------------------------| +| `--branch` | `branch` | +| `--build-url` | `build_url` | +| `--auto-detect-version-properties` | `auto_detect_version_properties` | +| `--tag=TAG` | `consumer_tags` | +| `--tag-with-git-branch` | `tag_with_git_branch` | +| `PACT_DIRS_OR_FILES` | `pact_dir` | +| `--consumer-app-version` | `version` | +| `n/a` | `consumer_name` | + ## Verifying Pacts Against a Service In addition to writing Pacts for Python consumers, you can also verify those Pacts @@ -409,7 +457,28 @@ You can use the Verifier class. This allows you to write native python code and verifier = Verifier(provider='UserService', provider_base_url=PACT_URL) -output, logs = verifier.verify_pacts('./userserviceclient-userservice.json') +# Using a local pact file + +success, logs = verifier.verify_pacts('./userserviceclient-userservice.json') +assert success == 0 + +# Using a pact broker + +- For OSS Pact Broker, use broker_username / broker_password +- For Pactflow Pact Broker, use broker_token + +success, logs = verifier.verify_with_broker( + # broker_username=PACT_BROKER_USERNAME, + # broker_password=PACT_BROKER_PASSWORD, + broker_url=PACT_BROKER_URL, + broker_token=PACT_BROKER_TOKEN, + publish_version=APPLICATION_VERSION, + publish_verification_results=True, + verbose=True, + provider_version_branch=PROVIDER_BRANCH, + enable_pending=True, +) +assert success == 0 ``` diff --git a/examples/consumer/requirements.txt b/examples/consumer/requirements.txt index eb82e9fb0..ae4e28d3c 100644 --- a/examples/consumer/requirements.txt +++ b/examples/consumer/requirements.txt @@ -1,3 +1,3 @@ -pytest==5.4.1 +pytest==7.1.3 requests>=2.26.0 testcontainers==3.3.0 \ No newline at end of file diff --git a/examples/fastapi_provider/requirements.txt b/examples/fastapi_provider/requirements.txt index dfb69dbb2..cfa21178a 100644 --- a/examples/fastapi_provider/requirements.txt +++ b/examples/fastapi_provider/requirements.txt @@ -1,5 +1,5 @@ fastapi==0.67.0 -pytest==5.4.1 +pytest==7.1.3 requests>=2.26.0 uvicorn>=0.14.0 testcontainers==3.3.0 \ No newline at end of file diff --git a/examples/flask_provider/requirements.txt b/examples/flask_provider/requirements.txt index ff10a2485..6e5390f14 100644 --- a/examples/flask_provider/requirements.txt +++ b/examples/flask_provider/requirements.txt @@ -1,5 +1,5 @@ Flask==1.1.4 -pytest==5.4.1 +pytest==7.1.3 requests>=2.26.0 testcontainers==3.3.0 markupsafe==2.0.1 \ No newline at end of file diff --git a/examples/message/requirements.txt b/examples/message/requirements.txt index a77d27936..38a94be3d 100644 --- a/examples/message/requirements.txt +++ b/examples/message/requirements.txt @@ -1,3 +1,3 @@ Flask==1.1.1 -pytest==5.4.1 +pytest==7.1.3 requests>=2.26.0 \ No newline at end of file diff --git a/requirements_dev.txt b/requirements_dev.txt index 55d787e2e..8f0f9f661 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -8,7 +8,7 @@ psutil==5.7.0 pycodestyle==2.6.0 pydocstyle==4.0.1 tox==3.14.0 -pytest==5.4.1 +pytest==7.1.3 pytest-cov==2.11.1 requests>=2.26.0 tox-travis==0.8 diff --git a/tox.ini b/tox.ini index be16f7d07..5fcd4028c 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist=py{36,37,38,39}-{test,install} +envlist=py{36,37,38,39,310}-{test,install} [testenv] deps= test: -rrequirements_dev.txt