diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 000000000..7eb8d3641 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,17 @@ +[run] +source = src/conductor +omit = + tests/* + examples/* + */__init__.py + +[report] +exclude_lines = + pragma: no cover + def __repr__ + raise NotImplementedError + if __name__ == .__main__.: + pass + raise ImportError + except ImportError: + if TYPE_CHECKING: \ No newline at end of file diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index c637bfa30..1296d452c 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -2,17 +2,99 @@ name: Continuous Integration on: [pull_request, workflow_dispatch] +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: unit-test: runs-on: ubuntu-latest + env: + COVERAGE_FILE: coverage.xml + COVERAGE_DIR: .coverage-reports steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Test - run: > - DOCKER_BUILDKIT=1 docker build . - --progress=plain - --build-arg CONDUCTOR_AUTH_KEY=${{ secrets.CONDUCTOR_AUTH_KEY }} - --build-arg CONDUCTOR_AUTH_SECRET=${{ secrets.CONDUCTOR_AUTH_SECRET }} - --build-arg CONDUCTOR_SERVER_URL=${{ secrets.CONDUCTOR_SERVER_URL }} - --target=unit_test \ No newline at end of file + - name: Checkout code + uses: actions/checkout@v4 + + - name: Build test image + run: | + DOCKER_BUILDKIT=1 docker build . \ + --target python_test_base \ + -t conductor-sdk-test:latest + + - name: Prepare coverage directory + run: | + mkdir -p ${{ env.COVERAGE_DIR }} + chmod 777 ${{ env.COVERAGE_DIR }} + touch ${{ env.COVERAGE_FILE }} + chmod 666 ${{ env.COVERAGE_FILE }} + + - name: Run unit tests + id: unit_tests + continue-on-error: true + run: | + docker run --rm \ + -e CONDUCTOR_AUTH_KEY=${{ secrets.CONDUCTOR_AUTH_KEY }} \ + -e CONDUCTOR_AUTH_SECRET=${{ secrets.CONDUCTOR_AUTH_SECRET }} \ + -e CONDUCTOR_SERVER_URL=${{ secrets.CONDUCTOR_SERVER_URL }} \ + -v ${{ github.workspace }}/${{ env.COVERAGE_DIR }}:/package/${{ env.COVERAGE_DIR }}:rw \ + conductor-sdk-test:latest \ + /bin/sh -c "cd /package && COVERAGE_FILE=/package/${{ env.COVERAGE_DIR }}/.coverage.unit coverage run --source=src/conductor -m unittest discover --verbose --start-directory=./tests/unit" + + - name: Run backward compatibility tests + id: bc_tests + continue-on-error: true + run: | + docker run --rm \ + -e CONDUCTOR_AUTH_KEY=${{ secrets.CONDUCTOR_AUTH_KEY }} \ + -e CONDUCTOR_AUTH_SECRET=${{ secrets.CONDUCTOR_AUTH_SECRET }} \ + -e CONDUCTOR_SERVER_URL=${{ secrets.CONDUCTOR_SERVER_URL }} \ + -v ${{ github.workspace }}/${{ env.COVERAGE_DIR }}:/package/${{ env.COVERAGE_DIR }}:rw \ + conductor-sdk-test:latest \ + /bin/sh -c "cd /package && COVERAGE_FILE=/package/${{ env.COVERAGE_DIR }}/.coverage.bc coverage run --source=src/conductor -m unittest discover --verbose --start-directory=./tests/backwardcompatibility" + + - name: Run serdeser tests + id: serdeser_tests + continue-on-error: true + run: | + docker run --rm \ + -e CONDUCTOR_AUTH_KEY=${{ secrets.CONDUCTOR_AUTH_KEY }} \ + -e CONDUCTOR_AUTH_SECRET=${{ secrets.CONDUCTOR_AUTH_SECRET }} \ + -e CONDUCTOR_SERVER_URL=${{ secrets.CONDUCTOR_SERVER_URL }} \ + -v ${{ github.workspace }}/${{ env.COVERAGE_DIR }}:/package/${{ env.COVERAGE_DIR }}:rw \ + conductor-sdk-test:latest \ + /bin/sh -c "cd /package && COVERAGE_FILE=/package/${{ env.COVERAGE_DIR }}/.coverage.serdeser coverage run --source=src/conductor -m unittest discover --verbose --start-directory=./tests/serdesertest" + + - name: Generate coverage report + id: coverage_report + continue-on-error: true + run: | + docker run --rm \ + -v ${{ github.workspace }}/${{ env.COVERAGE_DIR }}:/package/${{ env.COVERAGE_DIR }}:rw \ + -v ${{ github.workspace }}/${{ env.COVERAGE_FILE }}:/package/${{ env.COVERAGE_FILE }}:rw \ + conductor-sdk-test:latest \ + /bin/sh -c "cd /package && coverage combine /package/${{ env.COVERAGE_DIR }}/.coverage.* && coverage report && coverage xml" + + - name: Verify coverage file + id: verify_coverage + if: always() + continue-on-error: true + run: | + if [ ! -s "${{ env.COVERAGE_FILE }}" ]; then + echo "Coverage file is empty or does not exist" + ls -la ${{ env.COVERAGE_FILE }} ${{ env.COVERAGE_DIR }} + exit 1 + fi + echo "Coverage file exists and is not empty" + + - name: Upload coverage to Codecov + if: always() && steps.verify_coverage.outcome == 'success' + continue-on-error: true + uses: codecov/codecov-action@v3 + with: + token: ${{ secrets.CODECOV_TOKEN }} + file: ${{ env.COVERAGE_FILE }} + + - name: Check test results + if: steps.unit_tests.outcome == 'failure' || steps.bc_tests.outcome == 'failure' || steps.serdeser_tests.outcome == 'failure' + run: exit 1 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index fcde662df..37e9a6616 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,10 +10,8 @@ WORKDIR /package RUN pwd RUN ls -ltr ENV PYTHONPATH /package/src:/package/tests -RUN python3 -m pip install pylint -#RUN python3 -m pylint --disable=all ./src -RUN python3 -m pip install coverage -RUN python3 -m pip install -r ./requirements.txt +RUN python3 -m pip install -r ./requirements.txt && \ + python3 -m pip install -r ./requirements.dev.txt FROM python_test_base as unit_test ARG CONDUCTOR_AUTH_KEY diff --git a/README.md b/README.md index 3cc3842e3..8120b2029 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ # Conductor OSS Python SDK +[![CI Status](https://github.com/conductor-oss/python-sdk/actions/workflows/pull_request.yml/badge.svg)](https://github.com/conductor-oss/python-sdk/actions/workflows/pull_request.yml) +[![codecov](https://codecov.io/gh/conductor-oss/python-sdk/branch/main/graph/badge.svg?token=K10D161X4R)](https://codecov.io/gh/conductor-oss/python-sdk) Python SDK for working with https://github.com/conductor-oss/conductor. diff --git a/requirements.dev.txt b/requirements.dev.txt new file mode 100644 index 000000000..5884736cb --- /dev/null +++ b/requirements.dev.txt @@ -0,0 +1,3 @@ +pylint >= 2.17.5 +coverage >= 7.2.7 +pytest-cov >= 4.1.0 \ No newline at end of file