Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add Python CI #2

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
15 changes: 15 additions & 0 deletions .yamllint
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: remove before merge and add this as another PR.

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
extends: default

rules:
# Rule to enforce the use of double quotes
quoted-strings:
quote-type: double
required: false
# Additional rules can be configured as needed
line-length:
max: 120
indentation:
spaces: 2
document-start: disable
...
37 changes: 37 additions & 0 deletions actions/python/code-quality/format/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
name: Format Code
description: Checks and ensures the code is formatted according to the defined
style guidelines.

inputs:
python_version:
description: Python version to use
default: "3.12"
required: false
poetry_install_options:
description: Options for installing dependencies via poetry
required: false
default: "--only=code_quality --no-root"
poetry_export_options:
description: Options for exporting dependencies to check for hash
changes for cache invalidation
required: false
default: "--only=code_quality"
uniqueg marked this conversation as resolved.
Show resolved Hide resolved

runs:
using: composite
steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up environment
uses: elixir-cloud-aai/actions/python/setup/poetry@main
with:
python_version: ${{ inputs.python_version }}
poetry_install_options: ${{ inputs.poetry_install_options }}
poetry_export_options: ${{ inputs.poetry_export_options }}

- name: Check code style
shell: bash
run: poetry run ruff format --check
...
36 changes: 36 additions & 0 deletions actions/python/code-quality/lint/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
name: Lint Code
description: Lints the code to ensure code quality and adherence to standards.

inputs:
python_version:
description: Python version to use
default: "3.12"
required: false
poetry_install_options:
description: Options for installing dependencies via poetry
required: false
default: "--only=code_quality --no-root"
poetry_export_options:
description: Options for exporting dependencies to check for hash
changes for cache invalidation
required: false
default: "--only=code_quality"

runs:
using: composite
steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up environment
uses: elixir-cloud-aai/actions/python/setup/poetry@main
with:
python_version: ${{ inputs.python_version }}
poetry_install_options: ${{ inputs.poetry_install_options }}
poetry_export_options: ${{ inputs.poetry_export_options }}

- name: Check code quality
shell: bash
run: poetry run ruff check .
...
36 changes: 36 additions & 0 deletions actions/python/code-quality/spell-check/action.yaml
uniqueg marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
name: Spell Check
description: Runs a spell check on the codebase to identify spelling errors.

inputs:
python_version:
description: Python version to use
default: "3.12"
required: false
poetry_install_options:
description: Options for installing dependencies via poetry
required: false
default: "--only=code_quality --no-root"
poetry_export_options:
description: Options for exporting dependencies to check for hash
changes for cache invalidation
required: false
default: "--only=code_quality"

runs:
using: composite
steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up environment
uses: elixir-cloud-aai/actions/python/setup/poetry@main
with:
python_version: ${{ inputs.python_version }}
poetry_install_options: ${{ inputs.poetry_install_options }}
poetry_export_options: ${{ inputs.poetry_export_options }}

- name: Check spellings
shell: bash
run: poetry run typos .
...
42 changes: 42 additions & 0 deletions actions/python/code-quality/type-check/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
name: Type Check
description: Runs a type check on the codebase to ensure type safety and
correctness.

inputs:
python_version:
description: Python version to use
default: "3.12"
required: false
poetry_install_options:
description: Options for installing dependencies via poetry
required: false
default: "--with=code_quality --with=types --no-root"
poetry_export_options:
description: Options for exporting dependencies to check for hash
changes for cache invalidation
required: false
default: "--with=code_quality --with=types"
file_path:
description: The path to the file or directory to type check
required: false
default: "."


runs:
using: composite
steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up environment
uses: elixir-cloud-aai/actions/python/setup/poetry@main
with:
python_version: ${{ inputs.python_version }}
poetry_install_options: ${{ inputs.poetry_install_options }}
poetry_export_options: ${{ inputs.poetry_export_options }}

- name: Check types
shell: bash
run: poetry run mypy ${{ inputs.file_path }}
...
60 changes: 60 additions & 0 deletions actions/python/code-test/integration-test/action.yaml
uniqueg marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
name: Integration Test
description: Set up environment, run integration tests, and upload coverage report.

inputs:
os:
default: ubuntu-latest
description: The operating system to use
required: false
python_version:
default: "3.12"
description: The version of Python to use
required: false
poetry_install_options:
default: "--with=test"
description: Options for installing dependencies via poetry
required: false
poetry_export_options:
default: "--with=test"
description: Options for exporting dependencies for cache invalidation
required: false
codecov_token:
description: Codecov token for uploading coverage reports
required: true
file_path:
description: The path to the file or directory to integration test
required: false
default: "tests/test_integration"

runs:
using: composite
steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up environment
uses: elixir-cloud-aai/actions/python/setup/poetry@main
with:
os: ${{ inputs.os }}
python_version: ${{ inputs.python_version }}
poetry_install_options: ${{ inputs.poetry_install_options }}
poetry_export_options: ${{ inputs.poetry_export_options }}

- name: Run integration tests and generate coverage report
shell: bash
run: |
poetry run pytest \
--cov-report term \
--cov-report xml:test_integration.xml \
--cov=${{ inputs.file_path }}

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ inputs.codecov_token }}
flags: test_integration
files: ./test_integration.xml
fail_ci_if_error: true
verbose: true
...
60 changes: 60 additions & 0 deletions actions/python/code-test/unit-test/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
name: Unit Test
description: Set up environment, run unit tests, and upload coverage report.

inputs:
os:
default: ubuntu-latest
description: The operating system to use
required: false
JaeAeich marked this conversation as resolved.
Show resolved Hide resolved
python_version:
default: "3.12"
description: The version of Python to use
required: false
poetry_install_options:
default: "--with=test"
description: Options for installing dependencies via poetry
required: false
poetry_export_options:
default: "--with=test"
description: Options for exporting dependencies for cache invalidation
required: false
codecov_token:
description: Codecov token for uploading coverage reports
required: true
file_path:
description: The path to the file or directory to unit test
required: false
default: "tests/test_unit"

runs:
using: composite
steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up environment
uses: elixir-cloud-aai/actions/python/setup/poetry@main
with:
os: ${{ inputs.os }}
python_version: ${{ inputs.python_version }}
poetry_install_options: ${{ inputs.poetry_install_options }}
poetry_export_options: ${{ inputs.poetry_export_options }}

- name: Run unit tests and generate coverage report
shell: bash
run: |
poetry run pytest \
--cov-report term \
--cov-report xml:test_unit.xml \
--cov=${{ inputs.file_path }}

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ inputs.codecov_token }}
flags: test_unit
files: ./test_unit.xml
fail_ci_if_error: true
verbose: true
...
64 changes: 64 additions & 0 deletions actions/python/docs/autogenerated-docs-check/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
name: Documentation Check
description: Verifies that the API documentation is up to date.

inputs:
os:
default: ubuntu-latest
description: The operating system to use
required: false
python_version:
default: "3.12"
description: The version of Python to use
required: false
poetry_install_options:
default: "--with=docs --with=types --no-root"
description: Options to pass to poetry install
required: false
poetry_export_options:
default: "--with=docs --with=types"
description: Options to pass to poetry export for cache invalidation
required: false
file_path:
description: File path for which the docs will be generated
required: true
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Make this an optional fields too, grep and awk name of the project from pyproject and search if that dir exists, if so take that as file_path otherwise check if user has provided a file_path, else err.

We should aim to make all the fields non required, or atleast the input should not depend on project, ie codecov_token will be secret.CODECOV_TOKEN regardless of the project hence this will be easier to template. Essentially if we can ideally make all the deafults such that their is no values passed that are related to project, we can template all the CI work in one single repo.

auto_doc_dir:
description: Directory path that stores all the auto generated docs for
the packages
default: "/docs/source/pages"
required: false

runs:
using: composite
steps:
- uses: actions/checkout@v4

- name: Set up environment
uses: elixir-cloud-aai/actions/python/setup/poetry@main
with:
os: ${{ inputs.os }}
python-version: ${{ inputs.python_version }}
poetry-install-options: ${{ inputs.poetry_install_options }}
poetry-export-options: ${{ inputs.poetry_export_options }}

- name: Generate API docs
shell: bash
run: |
poetry run sphinx-apidoc \
-o /tmp/docs/source/pages \
${{ inputs.file_path }}/

- name: Compare current docs with latest docs
shell: bash
run: |
shasum /tmp/docs/source/pages/* > /tmp/docs.sha
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Using shasum for doc comparison may be overly sensitive

Consider using a more robust method for comparing documentation that isn't as sensitive to minor formatting changes.

        diff -rq /tmp/docs/source/pages/ ${{ inputs.auto_doc_dir }}/ | grep -v "Only in" > /tmp/docs_diff.txt
        if [ -s /tmp/docs_diff.txt ]; then
          echo "Differences found in documentation:"
          cat /tmp/docs_diff.txt
        else
          echo "No significant differences found in documentation."
        fi

shasum ${{ inputs.auto_doc_dir }}/* > docs/project_doc.sha
awk '{print $1}' /tmp/docs.sha > /tmp/docs_hashes.sha
awk '{print $1}' docs/project_doc.sha > docs/project_doc_hashes.sha
diff=$(diff /tmp/docs_hashes.sha docs/project_doc_hashes.sha) || true
if [[ -n "$diff" ]]; then
echo "::error::API documentation is out of date."
exit 1
else
echo "API documentation is up to date."
...
Loading