diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6429593..c42fbb6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,9 +5,8 @@ on: workflow_dispatch: env: - PACT_BROKER_BASE_URL: https://test.pactflow.io + PACT_BROKER_BASE_URL: https://saf.pactflow.io PACT_BROKER_TOKEN: ${{ secrets.PACTFLOW_TOKEN_FOR_CI_CD_WORKSHOP }} - REACT_APP_API_BASE_URL: http://localhost:8080 GIT_COMMIT: ${{ github.sha }} GIT_REF: ${{ github.ref }} @@ -18,11 +17,38 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-python@v4 with: - python-version: '3.8' + python-version: "3.8" + # - name: Install python version + # uses: gabrielfalcao/pyenv-action@v10 + # with: + # default: 3.8.13 + # command: pip install -U pip # upgrade pip after installing python + # - name: Create virtualenv for python 3.5.7 + # run: pyenv local 3.8.13 && python3 -mvenv .venv + # - name: venv + # run: pyenv local 3.8.13 && python3 -mvenv .venv3813 + - name: install pyenv + run: curl https://pyenv.run | bash + - name: set pyenv on path + run: | + export PYENV_ROOT="$HOME/.pyenv" + command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH" >> .bashrc + eval "$(pyenv init -)" >> .bashrc + eval "$(pyenv virtualenv-init -)" >> .bashrc + source ~/.bashrc + echo PATH="$PYENV_ROOT/bin:$PATH" >> $GITHUB_ENV + - name: Install poetry + run: pip install poetry + - name: Setup Virtual env + run: make venv - name: Install run: make deps - - name: Test - run: make test + - name: Activate virtual env + run: | + source .venv/bin/activate + make test + # - name: Test + # run: make test - name: Publish pacts run: GIT_BRANCH=${GIT_REF:11} make publish_pacts diff --git a/.gitignore b/.gitignore index d48568e..cb74cbf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ .venv .aws-sam .idea +.vscode .python-version -__pycache__ \ No newline at end of file +__pycache__ +pacts +.pytest_cache diff --git a/Makefile b/Makefile index eb62920..7a1c9bd 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ fake_ci: .env publish_pacts: .env - @"${PACT_CLI}" publish ${PWD}/pacts --consumer-app-version ${GIT_COMMIT} --tag ${GIT_BRANCH} + @"${PACT_CLI}" publish ${PWD}/pacts --consumer-app-version ${GIT_COMMIT} --tag ${GIT_BRANCH} --branch ${GIT_BRANCH} ## ===================== ## Build/test tasks @@ -142,10 +142,10 @@ venv: @echo "\n$(green)Use it! (populate .python-version)$(sgr0)" pyenv local ${PROJECT} -deploy: +deploy_sam: scripts/deploy.sh -publish: +publish_sam: scripts/publish.sh logs: diff --git a/README.md b/README.md index 78f496e..a03c779 100644 --- a/README.md +++ b/README.md @@ -25,32 +25,34 @@ You're probably familiar with layered architectures such as Ports and Adaptors ( This code base is setup with this modularity in mind: -* [Lambda Handler](src/_lambda/product.py) -* [Event Service](src/product/product_service.py) -* Business Logic - * [Product](src/product/product.py) - * [Repository](src/product/product_repository.py) +- [Lambda Handler](src/_lambda/product.py) +- [Event Service](src/product/product_service.py) +- Business Logic + - [Product](src/product/product.py) + - [Repository](src/product/product_repository.py) The target of our [consumer pact test](tests/unit/product_service_pact_test.py) is the [Event Service](src/product/product_service.js), which is responsible for consuming a Product update event, and persisting it to a database (the Repository). See also: -* https://dius.com.au/2017/09/22/contract-testing-serverless-and-asynchronous-applications/ -* https://dius.com.au/2018/10/01/contract-testing-serverless-and-asynchronous-applications---part-2/ +- https://dius.com.au/2017/09/22/contract-testing-serverless-and-asynchronous-applications/ +- https://dius.com.au/2018/10/01/contract-testing-serverless-and-asynchronous-applications---part-2/ ## Usage + ### Testing -* Run the unit tests: `make test` -* Run a (local) lambda integration test: `make integration` +- Run the unit tests: `make test` +- Run a (local) lambda integration test: `make integration` ### Running -* Deploy the actual app: `make deploy` (see below for more background) -* Publish a test event: `make publish` -* View the lambda logs: `make logs` +- Deploy the actual app: `make deploy_sam` (see below for more background) +- Publish a test event: `make publish_sam` +- View the lambda logs: `make logs` Here is some sample output publishing and viewing the logs: + ``` ➜ example-consumer-js-sns git:(master) ✗ npm run publish diff --git a/pacts/pactflow-example-consumer-python-sns-pactflow-example-provider-python-sns.json b/pacts/pactflow-example-consumer-python-sns-pactflow-example-provider-python-sns.json deleted file mode 100644 index fdb3dc4..0000000 --- a/pacts/pactflow-example-consumer-python-sns-pactflow-example-provider-python-sns.json +++ /dev/null @@ -1,64 +0,0 @@ -{ - "consumer": { - "name": "pactflow-example-consumer-python-sns" - }, - "provider": { - "name": "pactflow-example-provider-python-sns" - }, - "messages": [ - { - "description": "a product event update", - "providerStates": [ - - ], - "contents": { - "id": "some-uuid-1234-5678", - "type": "Product Range", - "name": "Some Product", - "event": "UPDATED" - }, - "matchingRules": { - "body": { - "$.id": { - "matchers": [ - { - "match": "type" - } - ] - }, - "$.type": { - "matchers": [ - { - "match": "type" - } - ] - }, - "$.name": { - "matchers": [ - { - "match": "type" - } - ] - }, - "$.event": { - "matchers": [ - { - "match": "regex", - "regex": "^(CREATED|UPDATED|DELETED)$" - } - ] - } - } - }, - "metaData": { - "Content-Type": "application/json", - "topic": "products" - } - } - ], - "metadata": { - "pactSpecification": { - "version": "3.0.0" - } - } -} \ No newline at end of file diff --git a/tests/unit/product_service_pact_test.py b/tests/unit/product_service_pact_test.py index aea625c..7e4c46b 100644 --- a/tests/unit/product_service_pact_test.py +++ b/tests/unit/product_service_pact_test.py @@ -6,8 +6,8 @@ from src.product.product_service import receive_product_update CONSUMER_NAME = "pactflow-example-consumer-python-sns" -PROVIDER_NAME = os.getenv("PACT_PROVIDER", "pactflow-example-provider-python-sns") -PACT_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "pacts") +PROVIDER_NAME = os.getenv("PACT_PROVIDER", "pactflow-example-provider-js-sns") +PACT_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)),"..","..", "pacts") @pytest.fixture(scope="session") def consumer():