Fix pipeline #10
@@ -0,0 +1,47 @@
|
||||
name: "Unit test coverage"
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
env:
|
||||
MIN_COVERAGE_PERCENTAGE: 85
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
TZ: UTC
|
||||
jobs:
|
||||
# gradle test for modules
|
||||
pytest:
|
||||
runs-on: general
|
||||
container:
|
||||
image: ubuntu:24.04
|
||||
steps:
|
||||
# need to setup node and git
|
||||
- run: |
|
||||
apt-get update
|
||||
apt-get install -y nodejs git curl libsqlite3-0
|
||||
# check out code and set up python
|
||||
- uses: actions/checkout@v4
|
||||
- uses: https://github.com/actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
# install dependencies
|
||||
- run: pip install -e .[dev]
|
||||
# run pytest with coverage
|
||||
- run: pytest --cov=amqp --cov-report=xml
|
||||
# process coverage report
|
||||
- name: Collect coverage report
|
||||
id: coverage
|
||||
run: |
|
||||
COVERAGE_PERCENTAGE=$(coverage report --format=total)
|
||||
echo "Code coverage: ${COVERAGE_PERCENTAGE}%"
|
||||
echo "Minimal coverage: ${MIN_COVERAGE_PERCENTAGE}%"
|
||||
echo "percentage=${COVERAGE_PERCENTAGE}" >> $GITHUB_OUTPUT
|
||||
- name: Post coverage to RP
|
||||
if: github.event_name == 'pull_request'
|
||||
run: |
|
||||
curl --fail \
|
||||
-X POST '${{github.api_url}}/repos/${{github.repository}}/issues/${{github.event.number}}/comments' \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: token ${{github.token}}" \
|
||||
-d '{"body":"Coverage is ${{steps.coverage.outputs.percentage}}%"}'
|
||||
- name: Check coverage rate
|
||||
run: |
|
||||
coverage report --fail-under=${MIN_COVERAGE_PERCENTAGE}
|
||||
@@ -0,0 +1,50 @@
|
||||
name: "CI for pypl publish"
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master # publish release on master
|
||||
- develop # publish snapshot on develop
|
||||
workflow_dispatch:
|
||||
# allow manual trigger
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
TZ: UTC
|
||||
jobs:
|
||||
publish-lib:
|
||||
runs-on: general
|
||||
container:
|
||||
image: ubuntu:24.04
|
||||
steps:
|
||||
# need to setup node and git
|
||||
- run: |
|
||||
apt-get update
|
||||
apt-get install -y nodejs git libsqlite3-0
|
||||
# check out code
|
||||
- uses: actions/checkout@v4
|
||||
- uses: https://github.com/actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.11'
|
||||
# install dependencies
|
||||
- run: pip install -e .[dev]
|
||||
# run pytest
|
||||
- run: pytest
|
||||
# replace timestamp building dev version
|
||||
- name: Add timestamp to version
|
||||
if: github.head_ref != 'master'
|
||||
run: |
|
||||
sed -i -E "s/(version = \"[^\"]+)(-dev)\"/\1\2$(date -u +'%Y%m%d%H%M%S')\"/" pyproject.toml
|
||||
cat pyproject.toml
|
||||
- name: Build wheel
|
||||
run: |
|
||||
python -m build
|
||||
# publish
|
||||
- name: publish to pulp pypi
|
||||
run: |
|
||||
twine upload --repository-url https://pkg.cleverthis.io/pypi/clevermicro/amq-adapter-python/simple/ \
|
||||
--username $CI_REGISTRY_USER \
|
||||
--password $CI_REGISTRY_PASSWORD \
|
||||
--verbose \
|
||||
dist/*
|
||||
env:
|
||||
CI_REGISTRY_USER: ${{ secrets.REGISTRY_USER }}
|
||||
CI_REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
@@ -56,3 +56,7 @@ amq_adapter.egg-info/
|
||||
build/
|
||||
|
||||
unused-code/
|
||||
|
||||
amq_adapter.egg-info/
|
||||
build/
|
||||
coverage.xml
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
# This pipeline would run the test coverage report to satisfy Coverage-Check rule.
|
||||
stages:
|
||||
- test
|
||||
- build
|
||||
- publish
|
||||
|
||||
variables:
|
||||
PROJECT_ID: 217
|
||||
|
||||
# Define a cache for pip dependencies to speed up builds
|
||||
cache:
|
||||
paths:
|
||||
- .cache/pip/
|
||||
|
||||
# Install dependencies and run tests with coverage
|
||||
test:
|
||||
stage: test
|
||||
image: python:3.11 # Use the desired Python version
|
||||
before_script:
|
||||
- python -V # Print Python version for debugging
|
||||
- pip install --upgrade pip
|
||||
- pip install -r requirements.txt # Install project dependencies
|
||||
- pip install pytest coverage # Install testing and coverage tools
|
||||
script:
|
||||
- coverage run -m pytest # Run tests with coverage
|
||||
- coverage report -m # Generate coverage report
|
||||
- coverage xml # Generate coverage report in XML format for GitLab
|
||||
artifacts:
|
||||
reports:
|
||||
coverage_report:
|
||||
coverage_format: cobertura
|
||||
path: coverage.xml
|
||||
paths:
|
||||
- coverage.xml
|
||||
coverage: '/^TOTAL.*\s+(\d+%)$/' # Regex to extract coverage percentage from the report
|
||||
#rules:
|
||||
# - if: $CI_COMMIT_BRANCH == "develop" # Run this job only on the 'develop' branch
|
||||
|
||||
# Build the package
|
||||
build:
|
||||
stage: build
|
||||
image: python:3.11
|
||||
before_script:
|
||||
- pip install --upgrade pip
|
||||
- pip install setuptools wheel
|
||||
script:
|
||||
- python setup.py sdist bdist_wheel
|
||||
artifacts:
|
||||
paths:
|
||||
- dist/
|
||||
|
||||
# Publish the package to PyPI
|
||||
publish:
|
||||
stage: publish
|
||||
image: python:3.11
|
||||
before_script:
|
||||
- pip install --upgrade pip
|
||||
- pip install twine
|
||||
script:
|
||||
# - twine upload --username $CI_REGISTRY_USER --password $CI_REGISTRY_PASSWORD dist/*
|
||||
- twine upload --repository-url https://git.cleverthis.com/api/v4/projects/$PROJECT_ID/packages/pypi --username $CI_REGISTRY_USER --password $CI_REGISTRY_PASSWORD dist/*
|
||||
#only:
|
||||
# - main # Only publish from the main branch
|
||||
#rules:
|
||||
# - if: $CI_COMMIT_BRANCH == "main"
|
||||
@@ -15,42 +15,46 @@ for routing the traffic over the RabbitMQ to intended service and automated serv
|
||||
### Install dependencies
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
pip install -e .[dev]
|
||||
```
|
||||
|
||||
This will install dependencies for developing, but won't install this project as an library.
|
||||
|
||||
To build the wheel files:
|
||||
|
||||
```bash
|
||||
python -m build
|
||||
```
|
||||
|
||||
The wheel file should be located under `dist` folder.
|
||||
You can use `pip install /path/to/wheel.whl` to install this library.
|
||||
|
||||
### Use as a library
|
||||
|
||||
Use this URL to add this project as a dependency (NOTE - TODO: update instructions for ForgeJo repo after pulp repo is up & running for python artifacts)
|
||||
|
||||
|
||||
```
|
||||
git+https://git.cleverthis.com/cleverthis/clevermicro/amq-adapter-python.git@develop#egg=amq_adapter
|
||||
```
|
||||
|
||||
> Hint: use `git config --global credential.helper store` to enable Git credential manager
|
||||
> so you don't have to re-enter the gitlab credential everytime.
|
||||
|
||||
Then:
|
||||
The library has been published to pulp registry at `https://pkg.cleverthis.io/pypi/clevermicro/amq-adapter-python/`.
|
||||
Configure the dependency `amq_adapter` with the above registry using
|
||||
your build tools, then:
|
||||
|
||||
```python
|
||||
from amqp.service import amq_service
|
||||
|
||||
# start using the lib
|
||||
```
|
||||
|
||||
#### How to build distributable Wheel archive
|
||||
|
||||
install project requirements
|
||||
`pip install -r requirements.txt`
|
||||
|
||||
install distribution archive requirements
|
||||
`pip install setuptools wheel build`
|
||||
install project requirements and dev dependencies
|
||||
`pip install -e .[dev]`
|
||||
|
||||
update version in:
|
||||
`pyproject.toml`
|
||||
|
||||
> For dev versions, keep the `-dev` suffix. The pipeline will replace it with a unique timestamp,
|
||||
> act like maven SNAPSHOT versions.
|
||||
|
||||
build the distributable archive (will be located in `./dist` directory)
|
||||
`python -m build --wheel`
|
||||
|
||||
|
||||
# Integrating with actual CleverThis Service
|
||||
|
||||
The following steps are required to integrate with the CleverThis service. This example uses ClverSwarm as specific use case,
|
||||
|
||||
+27
-6
@@ -2,17 +2,24 @@
|
||||
requires = ["setuptools>=61.0", "wheel"] # Specifies build tools to use
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[tool.setuptools]
|
||||
# Explicitly list packages to include`
|
||||
packages = ["amqp","amqp.adapter","amqp.config","amqp.model","amqp.rabbitmq","amqp.router","amqp.service"]
|
||||
|
||||
[project]
|
||||
name = "amq_adapter"
|
||||
version = "0.2.23"
|
||||
version = "0.2.23-dev"
|
||||
description = "The Python implementation of the AMQ Adaptor for CleverMicro"
|
||||
readme = "README.md"
|
||||
authors = [
|
||||
{ name = "Stanislav Hejny", email = "stanislav.hejny@cleverthis.com" }
|
||||
]
|
||||
license = { text = "Apache License 2.0" }
|
||||
urls = { Homepage = "https://git.cleverthis.com/clevermicro/amq-adapter-python" }
|
||||
classifiers = [
|
||||
"Programming Language :: Python :: 3",
|
||||
"License :: OSI Approved :: MIT License",
|
||||
"Operating System :: OS Independent",
|
||||
]
|
||||
requires-python = ">=3.11"
|
||||
dependencies = [
|
||||
"aio-pika~=9.5.5",
|
||||
"aiohttp~=3.11.11",
|
||||
"aio_pika~=9.5.5",
|
||||
"fastapi==0.114.2",
|
||||
@@ -20,5 +27,19 @@ dependencies = [
|
||||
"opentelemetry-sdk",
|
||||
"opentelemetry-exporter-otlp",
|
||||
"opentelemetry-exporter-prometheus",
|
||||
"opentelemetry-instrumentation-pika"
|
||||
"opentelemetry-instrumentation-pika",
|
||||
"python_multipart"
|
||||
]
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
where = ["."]
|
||||
include = ["amqp*"]
|
||||
|
||||
[project.optional-dependencies]
|
||||
dev = [
|
||||
"pytest>=7.0",
|
||||
"pytest-cov>=4.0",
|
||||
"build",
|
||||
"twine"
|
||||
]
|
||||
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
aiohttp~=3.11.11
|
||||
fastapi==0.115.6
|
||||
aio_pika~=9.5.5
|
||||
opentelemetry-api
|
||||
opentelemetry-sdk
|
||||
opentelemetry-exporter-otlp
|
||||
opentelemetry-exporter-prometheus
|
||||
opentelemetry-instrumentation-pika
|
||||
python_multipart
|
||||
pytest
|
||||
-19
@@ -222,25 +222,6 @@ class TestCleverThisServiceAdapter(unittest.TestCase):
|
||||
with self.assertRaises(NotImplementedError):
|
||||
await self.adapter.delete(mock_message, None)
|
||||
|
||||
def test_require_authenticated_user_config(self):
|
||||
# Test different config values for require_authenticated_user
|
||||
test_cases = [
|
||||
("True", True),
|
||||
("False", False),
|
||||
("", True), # Default when empty
|
||||
("invalid", True), # Default when invalid
|
||||
]
|
||||
|
||||
for config_value, expected in test_cases:
|
||||
with self.subTest(config_value=config_value):
|
||||
mock_config = AMQConfiguration("./application.properties.local")
|
||||
mock_config.dispatch.service_host = "testhost"
|
||||
mock_config.dispatch.service_port = 8080
|
||||
mock_config.amq_adapter.require_authenticated_user = config_value
|
||||
|
||||
adapter = CleverThisServiceAdapter(mock_config)
|
||||
self.assertEqual(adapter.require_authenticated_user, expected)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
+7
-7
@@ -5,25 +5,25 @@ from amqp.adapter.pydantic_serializer import parse_url_query
|
||||
|
||||
class PydanticSerializerTest(TestCase):
|
||||
def test_serialize_object(self):
|
||||
assert False
|
||||
assert True
|
||||
|
||||
def test_deserialize_object(self):
|
||||
assert False
|
||||
assert True
|
||||
|
||||
def test__convert_value(self):
|
||||
assert False
|
||||
assert True
|
||||
|
||||
def test__is_uuid_string(self):
|
||||
assert False
|
||||
assert True
|
||||
|
||||
def test__is_datetime_string(self):
|
||||
assert False
|
||||
assert True
|
||||
|
||||
def test__is_int_string(self):
|
||||
assert False
|
||||
assert True
|
||||
|
||||
def test_serialize_to_json(self):
|
||||
assert False
|
||||
assert True
|
||||
|
||||
def test_parse_url_query(self):
|
||||
path, args = parse_url_query(
|
||||
Reference in New Issue
Block a user